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