This source file includes following definitions.
- str_ascii_insert_replace_char
- str_ascii_is_valid_string
- str_ascii_is_valid_char
- str_ascii_cnext_char
- str_ascii_cprev_char
- str_ascii_cnext_noncomb_char
- str_ascii_cprev_noncomb_char
- str_ascii_isspace
- str_ascii_ispunct
- str_ascii_isalnum
- str_ascii_isdigit
- str_ascii_isprint
- str_ascii_iscombiningmark
- str_ascii_toupper
- str_ascii_tolower
- str_ascii_length
- str_ascii_length2
- str_ascii_conv_gerror_message
- str_ascii_vfs_convert_to
- str_ascii_term_form
- str_ascii_fit_to_term
- str_ascii_term_trim
- str_ascii_term_width2
- str_ascii_term_width1
- str_ascii_term_char_width
- str_ascii_term_substring
- str_ascii_trunc
- str_ascii_offset_to_pos
- str_ascii_column_to_pos
- str_ascii_create_search_needle
- str_ascii_release_search_needle
- str_ascii_search_first
- str_ascii_search_last
- str_ascii_compare
- str_ascii_ncompare
- str_ascii_casecmp
- str_ascii_ncasecmp
- str_ascii_fix_string
- str_ascii_create_key
- str_ascii_key_collate
- str_ascii_release_key
- str_ascii_prefix
- str_ascii_caseprefix
- str_ascii_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #include <config.h>
27
28 #include <ctype.h>
29 #include <stdlib.h>
30
31 #include "lib/global.h"
32 #include "lib/strutil.h"
33
34
35
36
37
38
39
40
41
42
43
44
45
46 static const char replch = '?';
47
48
49
50
51
52 static void
53 str_ascii_insert_replace_char (GString * buffer)
54 {
55 g_string_append_c (buffer, replch);
56 }
57
58
59
60 static gboolean
61 str_ascii_is_valid_string (const char *text)
62 {
63 (void) text;
64 return TRUE;
65 }
66
67
68
69 static int
70 str_ascii_is_valid_char (const char *ch, size_t size)
71 {
72 (void) ch;
73 (void) size;
74 return 1;
75 }
76
77
78
79 static void
80 str_ascii_cnext_char (const char **text)
81 {
82 (*text)++;
83 }
84
85
86
87 static void
88 str_ascii_cprev_char (const char **text)
89 {
90 (*text)--;
91 }
92
93
94
95 static int
96 str_ascii_cnext_noncomb_char (const char **text)
97 {
98 if (*text[0] == '\0')
99 return 0;
100
101 (*text)++;
102 return 1;
103 }
104
105
106
107 static int
108 str_ascii_cprev_noncomb_char (const char **text, const char *begin)
109 {
110 if ((*text) == begin)
111 return 0;
112
113 (*text)--;
114 return 1;
115 }
116
117
118
119 static gboolean
120 str_ascii_isspace (const char *text)
121 {
122 return g_ascii_isspace ((gchar) text[0]);
123 }
124
125
126
127 static gboolean
128 str_ascii_ispunct (const char *text)
129 {
130 return g_ascii_ispunct ((gchar) text[0]);
131 }
132
133
134
135 static gboolean
136 str_ascii_isalnum (const char *text)
137 {
138 return g_ascii_isalnum ((gchar) text[0]);
139 }
140
141
142
143 static gboolean
144 str_ascii_isdigit (const char *text)
145 {
146 return g_ascii_isdigit ((gchar) text[0]);
147 }
148
149
150
151 static gboolean
152 str_ascii_isprint (const char *text)
153 {
154 return g_ascii_isprint ((gchar) text[0]);
155 }
156
157
158
159 static gboolean
160 str_ascii_iscombiningmark (const char *text)
161 {
162 (void) text;
163 return FALSE;
164 }
165
166
167
168 static int
169 str_ascii_toupper (const char *text, char **out, size_t * remain)
170 {
171 if (*remain <= 1)
172 return FALSE;
173
174 (*out)[0] = (char) g_ascii_toupper ((gchar) text[0]);
175 (*out)++;
176 (*remain)--;
177 return TRUE;
178 }
179
180
181
182 static gboolean
183 str_ascii_tolower (const char *text, char **out, size_t * remain)
184 {
185 if (*remain <= 1)
186 return FALSE;
187
188 (*out)[0] = (char) g_ascii_tolower ((gchar) text[0]);
189 (*out)++;
190 (*remain)--;
191 return TRUE;
192 }
193
194
195
196 static int
197 str_ascii_length (const char *text)
198 {
199 return strlen (text);
200 }
201
202
203
204 static int
205 str_ascii_length2 (const char *text, int size)
206 {
207 return (size >= 0) ? MIN (strlen (text), (gsize) size) : strlen (text);
208 }
209
210
211
212 static gchar *
213 str_ascii_conv_gerror_message (GError * mcerror, const char *def_msg)
214 {
215
216 if (mcerror != NULL)
217 return g_strdup (mcerror->message);
218
219 return g_strdup (def_msg != NULL ? def_msg : "");
220 }
221
222
223
224 static estr_t
225 str_ascii_vfs_convert_to (GIConv coder, const char *string, int size, GString * buffer)
226 {
227 (void) coder;
228 g_string_append_len (buffer, string, size);
229 return ESTR_SUCCESS;
230 }
231
232
233
234 static const char *
235 str_ascii_term_form (const char *text)
236 {
237 static char result[BUF_MEDIUM];
238 char *actual;
239 size_t remain;
240 size_t length;
241 size_t pos = 0;
242
243 actual = result;
244 remain = sizeof (result);
245 length = strlen (text);
246
247
248 for (; pos < length && remain > 1; pos++, actual++, remain--)
249 {
250 actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
251 actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
252 }
253
254 actual[0] = '\0';
255 return result;
256 }
257
258
259
260 static const char *
261 str_ascii_fit_to_term (const char *text, int width, align_crt_t just_mode)
262 {
263 static char result[BUF_MEDIUM];
264 char *actual;
265 size_t remain;
266 int ident = 0;
267 size_t length;
268 size_t pos = 0;
269
270 length = strlen (text);
271 actual = result;
272 remain = sizeof (result);
273
274 if ((int) length <= width)
275 {
276 switch (HIDE_FIT (just_mode))
277 {
278 case J_CENTER_LEFT:
279 case J_CENTER:
280 ident = (width - length) / 2;
281 break;
282 case J_RIGHT:
283 ident = width - length;
284 break;
285 default:
286 break;
287 }
288
289
290 if ((int) remain <= ident)
291 goto finally;
292 memset (actual, ' ', ident);
293 actual += ident;
294 remain -= ident;
295
296
297 for (; pos < (gsize) length && remain > 1; pos++, actual++, remain--)
298 {
299 actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
300 actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
301 }
302
303
304 if (width - length - ident > 0)
305 {
306 if (remain <= width - length - ident)
307 goto finally;
308 memset (actual, ' ', width - length - ident);
309 actual += width - length - ident;
310 }
311 }
312 else if (IS_FIT (just_mode))
313 {
314
315 for (; pos + 1 <= (gsize) width / 2 && remain > 1; actual++, pos++, remain--)
316 {
317 actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
318 actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
319 }
320
321 if (remain <= 1)
322 goto finally;
323 actual[0] = '~';
324 actual++;
325 remain--;
326
327 pos += length - width + 1;
328
329
330 for (; pos < length && remain > 1; pos++, actual++, remain--)
331 {
332 actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
333 actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
334 }
335 }
336 else
337 {
338 switch (HIDE_FIT (just_mode))
339 {
340 case J_CENTER:
341 ident = (length - width) / 2;
342 break;
343 case J_RIGHT:
344 ident = length - width;
345 break;
346 default:
347 break;
348 }
349
350
351
352 pos += ident;
353 for (; pos < (gsize) (ident + width) && remain > 1; pos++, actual++, remain--)
354 {
355 actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
356 actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
357 }
358
359 }
360
361 finally:
362 if (actual >= result + sizeof (result))
363 actual = result + sizeof (result) - 1;
364 actual[0] = '\0';
365 return result;
366 }
367
368
369
370 static const char *
371 str_ascii_term_trim (const char *text, int width)
372 {
373 static char result[BUF_MEDIUM];
374 size_t remain;
375 char *actual;
376 size_t length;
377
378 length = strlen (text);
379 actual = result;
380 remain = sizeof (result);
381
382 if (width > 0)
383 {
384 size_t pos;
385
386 if (width >= (int) length)
387 {
388
389 for (pos = 0; pos < length && remain > 1; pos++, actual++, remain--)
390 {
391 actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
392 actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
393 }
394 }
395 else if (width <= 3)
396 {
397 memset (actual, '.', width);
398 actual += width;
399 }
400 else
401 {
402 memset (actual, '.', 3);
403 actual += 3;
404 remain -= 3;
405
406
407 for (pos = length - width + 3; pos < length && remain > 1; pos++, actual++, remain--)
408 {
409 actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
410 actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
411 }
412 }
413 }
414
415 actual[0] = '\0';
416 return result;
417 }
418
419
420
421 static int
422 str_ascii_term_width2 (const char *text, size_t length)
423 {
424 return (length != (size_t) (-1)) ? MIN (strlen (text), length) : strlen (text);
425 }
426
427
428
429 static int
430 str_ascii_term_width1 (const char *text)
431 {
432 return str_ascii_term_width2 (text, (size_t) (-1));
433 }
434
435
436
437 static int
438 str_ascii_term_char_width (const char *text)
439 {
440 (void) text;
441 return 1;
442 }
443
444
445
446 static const char *
447 str_ascii_term_substring (const char *text, int start, int width)
448 {
449 static char result[BUF_MEDIUM];
450 size_t remain;
451 char *actual;
452 size_t length;
453
454 actual = result;
455 remain = sizeof (result);
456 length = strlen (text);
457
458 if (start < (int) length)
459 {
460 size_t pos;
461
462
463 for (pos = start; pos < length && width > 0 && remain > 1;
464 pos++, width--, actual++, remain--)
465 {
466 actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
467 actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
468 }
469 }
470
471
472 for (; width > 0 && remain > 1; actual++, remain--, width--)
473 actual[0] = ' ';
474
475 actual[0] = '\0';
476 return result;
477 }
478
479
480
481 static const char *
482 str_ascii_trunc (const char *text, int width)
483 {
484 static char result[MC_MAXPATHLEN];
485 int remain;
486 char *actual;
487 size_t pos = 0;
488 size_t length;
489
490 actual = result;
491 remain = sizeof (result);
492 length = strlen (text);
493
494 if ((int) length > width)
495 {
496
497 for (; pos + 1 <= (gsize) width / 2 && remain > 1; actual++, pos++, remain--)
498 {
499 actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
500 actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
501 }
502
503 if (remain <= 1)
504 goto finally;
505 actual[0] = '~';
506 actual++;
507 remain--;
508
509 pos += length - width + 1;
510
511
512 for (; pos < length && remain > 1; pos++, actual++, remain--)
513 {
514 actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
515 actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
516 }
517 }
518 else
519 {
520
521 for (; pos < length && remain > 1; pos++, actual++, remain--)
522 {
523 actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
524 actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
525 }
526 }
527
528 finally:
529 actual[0] = '\0';
530 return result;
531 }
532
533
534
535 static int
536 str_ascii_offset_to_pos (const char *text, size_t length)
537 {
538 (void) text;
539 return (int) length;
540 }
541
542
543
544 static int
545 str_ascii_column_to_pos (const char *text, size_t pos)
546 {
547 (void) text;
548 return (int) pos;
549 }
550
551
552
553 static char *
554 str_ascii_create_search_needle (const char *needle, gboolean case_sen)
555 {
556 (void) case_sen;
557 return (char *) needle;
558 }
559
560
561
562 static void
563 str_ascii_release_search_needle (char *needle, gboolean case_sen)
564 {
565 (void) case_sen;
566 (void) needle;
567
568 }
569
570
571
572 static const char *
573 str_ascii_search_first (const char *text, const char *search, gboolean case_sen)
574 {
575 char *fold_text;
576 char *fold_search;
577 const char *match;
578
579 fold_text = case_sen ? (char *) text : g_ascii_strdown (text, -1);
580 fold_search = case_sen ? (char *) search : g_ascii_strdown (search, -1);
581
582 match = g_strstr_len (fold_text, -1, fold_search);
583 if (match != NULL)
584 {
585 size_t offset;
586
587 offset = match - fold_text;
588 match = text + offset;
589 }
590
591 if (!case_sen)
592 {
593 g_free (fold_text);
594 g_free (fold_search);
595 }
596
597 return match;
598 }
599
600
601
602 static const char *
603 str_ascii_search_last (const char *text, const char *search, gboolean case_sen)
604 {
605 char *fold_text;
606 char *fold_search;
607 const char *match;
608
609 fold_text = case_sen ? (char *) text : g_ascii_strdown (text, -1);
610 fold_search = case_sen ? (char *) search : g_ascii_strdown (search, -1);
611
612 match = g_strrstr_len (fold_text, -1, fold_search);
613 if (match != NULL)
614 {
615 size_t offset;
616
617 offset = match - fold_text;
618 match = text + offset;
619 }
620
621 if (!case_sen)
622 {
623 g_free (fold_text);
624 g_free (fold_search);
625 }
626
627 return match;
628 }
629
630
631
632 static int
633 str_ascii_compare (const char *t1, const char *t2)
634 {
635 return strcmp (t1, t2);
636 }
637
638
639
640 static int
641 str_ascii_ncompare (const char *t1, const char *t2)
642 {
643 return strncmp (t1, t2, MIN (strlen (t1), strlen (t2)));
644 }
645
646
647
648 static int
649 str_ascii_casecmp (const char *t1, const char *t2)
650 {
651 return g_ascii_strcasecmp (t1, t2);
652 }
653
654
655
656 static int
657 str_ascii_ncasecmp (const char *t1, const char *t2)
658 {
659 return g_ascii_strncasecmp (t1, t2, MIN (strlen (t1), strlen (t2)));
660 }
661
662
663
664 static void
665 str_ascii_fix_string (char *text)
666 {
667 for (; text[0] != '\0'; text++)
668 text[0] = ((unsigned char) text[0] < 128) ? text[0] : '?';
669 }
670
671
672
673 static char *
674 str_ascii_create_key (const char *text, gboolean case_sen)
675 {
676 (void) case_sen;
677 return (char *) text;
678 }
679
680
681
682 static int
683 str_ascii_key_collate (const char *t1, const char *t2, gboolean case_sen)
684 {
685 return case_sen ? strcmp (t1, t2) : g_ascii_strcasecmp (t1, t2);
686 }
687
688
689
690 static void
691 str_ascii_release_key (char *key, gboolean case_sen)
692 {
693 (void) key;
694 (void) case_sen;
695 }
696
697
698
699 static int
700 str_ascii_prefix (const char *text, const char *prefix)
701 {
702 int result;
703
704 for (result = 0; text[result] != '\0' && prefix[result] != '\0'
705 && text[result] == prefix[result]; result++);
706
707 return result;
708 }
709
710
711
712 static int
713 str_ascii_caseprefix (const char *text, const char *prefix)
714 {
715 int result;
716
717 for (result = 0; text[result] != '\0' && prefix[result] != '\0'
718 && g_ascii_toupper (text[result]) == g_ascii_toupper (prefix[result]); result++);
719
720 return result;
721 }
722
723
724
725
726
727 struct str_class
728 str_ascii_init (void)
729 {
730 struct str_class result;
731
732 result.conv_gerror_message = str_ascii_conv_gerror_message;
733 result.vfs_convert_to = str_ascii_vfs_convert_to;
734 result.insert_replace_char = str_ascii_insert_replace_char;
735 result.is_valid_string = str_ascii_is_valid_string;
736 result.is_valid_char = str_ascii_is_valid_char;
737 result.cnext_char = str_ascii_cnext_char;
738 result.cprev_char = str_ascii_cprev_char;
739 result.cnext_char_safe = str_ascii_cnext_char;
740 result.cprev_char_safe = str_ascii_cprev_char;
741 result.cnext_noncomb_char = str_ascii_cnext_noncomb_char;
742 result.cprev_noncomb_char = str_ascii_cprev_noncomb_char;
743 result.char_isspace = str_ascii_isspace;
744 result.char_ispunct = str_ascii_ispunct;
745 result.char_isalnum = str_ascii_isalnum;
746 result.char_isdigit = str_ascii_isdigit;
747 result.char_isprint = str_ascii_isprint;
748 result.char_iscombiningmark = str_ascii_iscombiningmark;
749 result.char_toupper = str_ascii_toupper;
750 result.char_tolower = str_ascii_tolower;
751 result.length = str_ascii_length;
752 result.length2 = str_ascii_length2;
753 result.length_noncomb = str_ascii_length;
754 result.fix_string = str_ascii_fix_string;
755 result.term_form = str_ascii_term_form;
756 result.fit_to_term = str_ascii_fit_to_term;
757 result.term_trim = str_ascii_term_trim;
758 result.term_width2 = str_ascii_term_width2;
759 result.term_width1 = str_ascii_term_width1;
760 result.term_char_width = str_ascii_term_char_width;
761 result.term_substring = str_ascii_term_substring;
762 result.trunc = str_ascii_trunc;
763 result.offset_to_pos = str_ascii_offset_to_pos;
764 result.column_to_pos = str_ascii_column_to_pos;
765 result.create_search_needle = str_ascii_create_search_needle;
766 result.release_search_needle = str_ascii_release_search_needle;
767 result.search_first = str_ascii_search_first;
768 result.search_last = str_ascii_search_last;
769 result.compare = str_ascii_compare;
770 result.ncompare = str_ascii_ncompare;
771 result.casecmp = str_ascii_casecmp;
772 result.ncasecmp = str_ascii_ncasecmp;
773 result.prefix = str_ascii_prefix;
774 result.caseprefix = str_ascii_caseprefix;
775 result.create_key = str_ascii_create_key;
776 result.create_key_for_filename = str_ascii_create_key;
777 result.key_collate = str_ascii_key_collate;
778 result.release_key = str_ascii_release_key;
779
780 return result;
781 }
782
783