1 /* UTF-8 strings utilities
2 Copyright (C) 2007 Free Software Foundation, Inc.
7 The file_date routine is mostly from GNU's fileutils package,
8 written by Richard Stallman and David MacKenzie.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
33 #include "lib/global.h"
34 #include "lib/strutil.h"
36 /* using function for utf-8 from glib */
38 static const char replch
[] = "\xEF\xBF\xBD";
41 str_unichar_iscombiningmark (gunichar uni
)
43 int type
= g_unichar_type (uni
);
44 return (type
== G_UNICODE_COMBINING_MARK
)
45 || (type
== G_UNICODE_ENCLOSING_MARK
)
46 || (type
== G_UNICODE_NON_SPACING_MARK
);
50 str_utf8_insert_replace_char (GString
* buffer
)
52 g_string_append (buffer
, replch
);
56 str_utf8_is_valid_string (const char *text
)
58 return g_utf8_validate (text
, -1, NULL
);
62 str_utf8_is_valid_char (const char *ch
, size_t size
)
64 switch (g_utf8_get_char_validated (ch
, size
))
76 str_utf8_cnext_char (const char **text
)
78 (*text
) = g_utf8_next_char (*text
);
82 str_utf8_cprev_char (const char **text
)
84 (*text
) = g_utf8_prev_char (*text
);
88 str_utf8_cnext_char_safe (const char **text
)
90 if (str_utf8_is_valid_char (*text
, -1) == 1)
91 (*text
) = g_utf8_next_char (*text
);
97 str_utf8_cprev_char_safe (const char **text
)
99 const char *result
= g_utf8_prev_char (*text
);
100 const char *t
= result
;
101 str_utf8_cnext_char_safe (&t
);
109 str_utf8_fix_string (char *text
)
113 while (text
[0] != '\0')
115 uni
= g_utf8_get_char_validated (text
, -1);
116 if ((uni
!= (gunichar
) (-1)) && (uni
!= (gunichar
) (-2)))
118 text
= g_utf8_next_char (text
);
129 str_utf8_isspace (const char *text
)
131 gunichar uni
= g_utf8_get_char_validated (text
, -1);
132 return g_unichar_isspace (uni
);
136 str_utf8_ispunct (const char *text
)
138 gunichar uni
= g_utf8_get_char_validated (text
, -1);
139 return g_unichar_ispunct (uni
);
143 str_utf8_isalnum (const char *text
)
145 gunichar uni
= g_utf8_get_char_validated (text
, -1);
146 return g_unichar_isalnum (uni
);
150 str_utf8_isdigit (const char *text
)
152 gunichar uni
= g_utf8_get_char_validated (text
, -1);
153 return g_unichar_isdigit (uni
);
157 str_utf8_isprint (const char *ch
)
159 gunichar uni
= g_utf8_get_char_validated (ch
, -1);
160 return g_unichar_isprint (uni
);
164 str_utf8_iscombiningmark (const char *ch
)
166 gunichar uni
= g_utf8_get_char_validated (ch
, -1);
167 return str_unichar_iscombiningmark (uni
);
171 str_utf8_cnext_noncomb_char (const char **text
)
174 while ((*text
)[0] != '\0')
176 str_utf8_cnext_char_safe (text
);
178 if (!str_utf8_iscombiningmark (*text
))
185 str_utf8_cprev_noncomb_char (const char **text
, const char *begin
)
188 while ((*text
) != begin
)
190 str_utf8_cprev_char_safe (text
);
192 if (!str_utf8_iscombiningmark (*text
))
199 str_utf8_toupper (const char *text
, char **out
, size_t * remain
)
204 uni
= g_utf8_get_char_validated (text
, -1);
205 if (uni
== (gunichar
) (-1) || uni
== (gunichar
) (-2))
208 uni
= g_unichar_toupper (uni
);
209 left
= g_unichar_to_utf8 (uni
, NULL
);
213 left
= g_unichar_to_utf8 (uni
, *out
);
220 str_utf8_tolower (const char *text
, char **out
, size_t * remain
)
225 uni
= g_utf8_get_char_validated (text
, -1);
226 if (uni
== (gunichar
) (-1) || uni
== (gunichar
) (-2))
229 uni
= g_unichar_tolower (uni
);
230 left
= g_unichar_to_utf8 (uni
, NULL
);
234 left
= g_unichar_to_utf8 (uni
, *out
);
241 str_utf8_length (const char *text
)
248 while (!g_utf8_validate (start
, -1, &end
) && start
[0] != '\0')
252 result
+= g_utf8_strlen (start
, end
- start
);
260 result
= g_utf8_strlen (text
, -1);
264 if (start
[0] != '\0' && start
!= end
)
266 result
+= g_utf8_strlen (start
, end
- start
);
274 str_utf8_length2 (const char *text
, int size
)
281 while (!g_utf8_validate (start
, -1, &end
) && start
[0] != '\0' && size
> 0)
285 result
+= g_utf8_strlen (start
, min (end
- start
, size
));
288 result
+= (size
> 0);
295 result
= g_utf8_strlen (text
, size
);
299 if (start
[0] != '\0' && start
!= end
&& size
> 0)
301 result
+= g_utf8_strlen (start
, min (end
- start
, size
));
309 str_utf8_length_noncomb (const char *text
)
312 const char *t
= text
;
316 str_utf8_cnext_noncomb_char (&t
);
324 str_utf8_questmark_sustb (char **string, size_t * left, GString * buffer)
326 char *next = g_utf8_next_char (*string);
327 (*left) -= next - (*string);
329 g_string_append_c (buffer, '?');
334 str_utf8_conv_gerror_message (GError
*error
, const char *def_msg
)
336 if ((error
!= NULL
) && (error
->message
!= NULL
))
337 return g_strdup (error
->message
);
339 return g_strdup (def_msg
!= NULL
? def_msg
: "");
343 str_utf8_vfs_convert_to (GIConv coder
, const char *string
,
344 int size
, GString
* buffer
)
348 if (coder
== str_cnv_not_convert
)
350 g_string_append_len (buffer
, string
, size
);
351 result
= ESTR_SUCCESS
;
354 result
= str_nconvert (coder
, (char *) string
, size
, buffer
);
361 char text
[BUF_MEDIUM
* 6];
366 /* utiliti function, that make string valid in utf8 and all characters printable
367 * return width of string too*/
368 static const struct term_form
*
369 str_utf8_make_make_term_form (const char *text
, size_t length
)
371 static struct term_form result
;
376 result
.text
[0] = '\0';
379 actual
= result
.text
;
381 /* check if text start with combining character,
382 * add space at begin in this case */
383 if (length
!= 0 && text
[0] != '\0')
385 uni
= g_utf8_get_char_validated (text
, -1);
386 if ((uni
!= (gunichar
) (-1)) && (uni
!= (gunichar
) (-2)))
388 if (str_unichar_iscombiningmark (uni
))
398 while (length
!= 0 && text
[0] != '\0') {
399 uni
= g_utf8_get_char_validated (text
, -1);
400 if ((uni
!= (gunichar
)(-1)) && (uni
!= (gunichar
)(-2))) {
401 if (g_unichar_isprint(uni
)) {
402 left
= g_unichar_to_utf8 (uni
, actual
);
404 if (!str_unichar_iscombiningmark (uni
)) {
406 if (g_unichar_iswide(uni
)) result
.width
++;
407 } else result
.compose
= 1;
413 text
= g_utf8_next_char (text
);
417 memcpy (actual
, replch
, strlen (replch
));
418 actual
+= strlen (replch
);
421 if (length
!= (size_t) (-1)) length
--; }
428 str_utf8_term_form (const char *text
)
430 static char result
[BUF_MEDIUM
* 6];
431 const struct term_form
*pre_form
;
434 pre_form
= str_utf8_make_make_term_form (text
, (size_t) (-1));
435 if (pre_form
->compose
)
438 g_utf8_normalize (pre_form
->text
, -1,
439 G_NORMALIZE_DEFAULT_COMPOSE
);
440 g_strlcpy (result
, composed
, sizeof (result
));
445 g_strlcpy (result
, pre_form
->text
, sizeof (result
));
459 /* utiliti function, that copy all characters from cheked to actual */
461 utf8_tool_copy_chars_to_end (struct utf8_tool
*tool
)
468 while (tool
->cheked
[0] != '\0')
470 uni
= g_utf8_get_char (tool
->cheked
);
471 tool
->compose
|= str_unichar_iscombiningmark (uni
);
472 left
= g_unichar_to_utf8 (uni
, NULL
);
473 if (tool
->remain
<= left
)
475 left
= g_unichar_to_utf8 (uni
, tool
->actual
);
476 tool
->actual
+= left
;
477 tool
->remain
-= left
;
478 tool
->cheked
= g_utf8_next_char (tool
->cheked
);
483 /* utiliti function, that copy characters from cheked to actual until ident is
484 * smaller than to_ident */
486 utf8_tool_copy_chars_to (struct utf8_tool
*tool
, int to_ident
)
494 while (tool
->cheked
[0] != '\0')
496 uni
= g_utf8_get_char (tool
->cheked
);
497 if (!str_unichar_iscombiningmark (uni
))
500 if (g_unichar_iswide (uni
))
502 if (tool
->ident
+ w
> to_ident
)
511 left
= g_unichar_to_utf8 (uni
, NULL
);
512 if (tool
->remain
<= left
)
514 left
= g_unichar_to_utf8 (uni
, tool
->actual
);
515 tool
->actual
+= left
;
516 tool
->remain
-= left
;
517 tool
->cheked
= g_utf8_next_char (tool
->cheked
);
523 /* utiliti function, add count spaces to actual */
525 utf8_tool_insert_space (struct utf8_tool
*tool
, int count
)
529 if (tool
->remain
<= (gsize
) count
)
531 memset (tool
->actual
, ' ', count
);
532 tool
->actual
+= count
;
533 tool
->remain
-= count
;
537 /* utiliti function, add one characters to actual */
539 utf8_tool_insert_char (struct utf8_tool
*tool
, char ch
)
541 if (tool
->remain
<= 1)
543 tool
->actual
[0] = ch
;
549 /* utiliti function, thah skip characters from cheked until ident is greater or
550 * equal to to_ident */
552 utf8_tool_skip_chars_to (struct utf8_tool
*tool
, int to_ident
)
556 while (to_ident
> tool
->ident
&& tool
->cheked
[0] != '\0')
558 uni
= g_utf8_get_char (tool
->cheked
);
559 if (!str_unichar_iscombiningmark (uni
))
562 if (g_unichar_iswide (uni
))
565 tool
->cheked
= g_utf8_next_char (tool
->cheked
);
567 uni
= g_utf8_get_char (tool
->cheked
);
568 while (str_unichar_iscombiningmark (uni
))
570 tool
->cheked
= g_utf8_next_char (tool
->cheked
);
571 uni
= g_utf8_get_char (tool
->cheked
);
577 utf8_tool_compose (char *buffer
, size_t size
)
580 g_utf8_normalize (buffer
, -1, G_NORMALIZE_DEFAULT_COMPOSE
);
581 g_strlcpy (buffer
, composed
, size
);
587 str_utf8_fit_to_term (const char *text
, int width
, align_crt_t just_mode
)
589 static char result
[BUF_MEDIUM
* 6];
590 const struct term_form
*pre_form
;
591 struct utf8_tool tool
;
593 pre_form
= str_utf8_make_make_term_form (text
, (size_t) (-1));
594 tool
.cheked
= pre_form
->text
;
595 tool
.actual
= result
;
596 tool
.remain
= sizeof (result
);
599 if (pre_form
->width
<= (gsize
)width
)
602 switch (HIDE_FIT (just_mode
))
606 tool
.ident
= (width
- pre_form
->width
) / 2;
609 tool
.ident
= width
- pre_form
->width
;
613 utf8_tool_insert_space (&tool
, tool
.ident
);
614 utf8_tool_copy_chars_to_end (&tool
);
615 utf8_tool_insert_space (&tool
, width
- pre_form
->width
- tool
.ident
);
619 if (IS_FIT (just_mode
))
622 utf8_tool_copy_chars_to (&tool
, width
/ 2);
623 utf8_tool_insert_char (&tool
, '~');
626 utf8_tool_skip_chars_to (&tool
, pre_form
->width
- width
+ 1);
627 utf8_tool_copy_chars_to_end (&tool
);
628 utf8_tool_insert_space (&tool
,
629 width
- (pre_form
->width
- tool
.ident
+
635 switch (HIDE_FIT (just_mode
))
638 tool
.ident
= (width
- pre_form
->width
) / 2;
641 tool
.ident
= width
- pre_form
->width
;
645 utf8_tool_skip_chars_to (&tool
, 0);
646 utf8_tool_insert_space (&tool
, tool
.ident
);
647 utf8_tool_copy_chars_to (&tool
, width
);
648 utf8_tool_insert_space (&tool
, width
- tool
.ident
);
652 tool
.actual
[0] = '\0';
654 utf8_tool_compose (result
, sizeof (result
));
659 str_utf8_term_trim (const char *text
, int width
)
661 static char result
[BUF_MEDIUM
* 6];
662 const struct term_form
*pre_form
;
663 struct utf8_tool tool
;
665 pre_form
= str_utf8_make_make_term_form (text
, (size_t) (-1));
667 tool
.cheked
= pre_form
->text
;
668 tool
.actual
= result
;
669 tool
.remain
= sizeof (result
);
672 if ((gsize
)width
< pre_form
->width
)
676 memset (tool
.actual
, '.', width
);
677 tool
.actual
+= width
;
678 tool
.remain
-= width
;
682 memset (tool
.actual
, '.', 3);
687 utf8_tool_skip_chars_to (&tool
, pre_form
->width
- width
+ 3);
688 utf8_tool_copy_chars_to_end (&tool
);
693 utf8_tool_copy_chars_to_end (&tool
);
696 tool
.actual
[0] = '\0';
698 utf8_tool_compose (result
, sizeof (result
));
703 str_utf8_term_width2 (const char *text
, size_t length
)
705 const struct term_form
*result
;
707 result
= str_utf8_make_make_term_form (text
, length
);
708 return result
->width
;
712 str_utf8_term_width1 (const char *text
)
714 return str_utf8_term_width2 (text
, (size_t) (-1));
718 str_utf8_term_char_width (const char *text
)
720 gunichar uni
= g_utf8_get_char_validated (text
, -1);
721 return (str_unichar_iscombiningmark (uni
)) ? 0
722 : ((g_unichar_iswide (uni
)) ? 2 : 1);
726 str_utf8_msg_term_size (const char *text
, int *lines
, int *columns
)
736 tmp
= g_strdup (text
);
740 q
= strchr (p
, '\n');
747 width
= str_utf8_term_width1 (p
);
748 if (width
> (*columns
))
761 str_utf8_term_substring (const char *text
, int start
, int width
)
763 static char result
[BUF_MEDIUM
* 6];
764 const struct term_form
*pre_form
;
765 struct utf8_tool tool
;
767 pre_form
= str_utf8_make_make_term_form (text
, (size_t) (-1));
769 tool
.cheked
= pre_form
->text
;
770 tool
.actual
= result
;
771 tool
.remain
= sizeof (result
);
775 utf8_tool_skip_chars_to (&tool
, 0);
778 utf8_tool_insert_space (&tool
, tool
.ident
);
780 utf8_tool_copy_chars_to (&tool
, width
);
781 utf8_tool_insert_space (&tool
, width
- tool
.ident
);
783 tool
.actual
[0] = '\0';
785 utf8_tool_compose (result
, sizeof (result
));
790 str_utf8_trunc (const char *text
, int width
)
792 static char result
[MC_MAXPATHLEN
* 6 * 2];
793 const struct term_form
*pre_form
;
794 struct utf8_tool tool
;
796 pre_form
= str_utf8_make_make_term_form (text
, (size_t) (-1));
798 tool
.cheked
= pre_form
->text
;
799 tool
.actual
= result
;
800 tool
.remain
= sizeof (result
);
803 if (pre_form
->width
> (gsize
)width
)
806 utf8_tool_copy_chars_to (&tool
, width
/ 2);
807 utf8_tool_insert_char (&tool
, '~');
810 utf8_tool_skip_chars_to (&tool
, pre_form
->width
- width
+ 1);
811 utf8_tool_copy_chars_to_end (&tool
);
815 utf8_tool_copy_chars_to_end (&tool
);
818 tool
.actual
[0] = '\0';
820 utf8_tool_compose (result
, sizeof (result
));
825 str_utf8_offset_to_pos (const char *text
, size_t length
)
827 if (str_utf8_is_valid_string (text
))
828 return g_utf8_offset_to_pointer (text
, length
) - text
;
832 GString
*buffer
= g_string_new (text
);
834 str_utf8_fix_string (buffer
->str
);
835 result
= g_utf8_offset_to_pointer (buffer
->str
, length
) - buffer
->str
;
836 g_string_free (buffer
, TRUE
);
842 str_utf8_column_to_pos (const char *text
, size_t pos
)
851 while (text
[0] != '\0')
853 uni
= g_utf8_get_char_validated (text
, 6);
854 if ((uni
!= (gunichar
) (-1)) && (uni
!= (gunichar
) (-2)))
856 if (g_unichar_isprint (uni
))
858 if (!str_unichar_iscombiningmark (uni
))
861 if (g_unichar_iswide (uni
))
869 text
= g_utf8_next_char (text
);
876 if ((gsize
)width
> pos
)
886 str_utf8_create_search_needle (const char *needle
, int case_sen
)
892 return g_utf8_normalize (needle
, -1, G_NORMALIZE_ALL
);
896 char *fold
= g_utf8_casefold (needle
, -1);
897 char *result
= g_utf8_normalize (fold
, -1, G_NORMALIZE_ALL
);
907 str_utf8_release_search_needle (char *needle
, int case_sen
)
915 str_utf8_search_first (const char *text
, const char *search
, int case_sen
)
920 const char *result
= NULL
;
923 fold_text
= (case_sen
) ? (char *) text
: g_utf8_casefold (text
, -1);
924 deco_text
= g_utf8_normalize (fold_text
, -1, G_NORMALIZE_ALL
);
929 match
= g_strstr_len (match
, -1, search
);
932 if ((!str_utf8_iscombiningmark (match
) || (match
== deco_text
)) &&
933 !str_utf8_iscombiningmark (match
+ strlen (search
)))
940 str_utf8_cnext_noncomb_char (&m
);
941 str_utf8_cnext_noncomb_char (&result
);
946 str_utf8_cnext_char (&match
);
950 while (match
!= NULL
&& result
== NULL
);
960 str_utf8_search_last (const char *text
, const char *search
, int case_sen
)
965 const char *result
= NULL
;
968 fold_text
= (case_sen
) ? (char *) text
: g_utf8_casefold (text
, -1);
969 deco_text
= g_utf8_normalize (fold_text
, -1, G_NORMALIZE_ALL
);
973 match
= g_strrstr_len (deco_text
, -1, search
);
976 if ((!str_utf8_iscombiningmark (match
) || (match
== deco_text
)) &&
977 !str_utf8_iscombiningmark (match
+ strlen (search
)))
984 str_utf8_cnext_noncomb_char (&m
);
985 str_utf8_cnext_noncomb_char (&result
);
994 while (match
!= NULL
&& result
== NULL
);
1004 str_utf8_normalize (const char *text
)
1006 GString
*fixed
= g_string_new ("");
1013 while (!g_utf8_validate (start
, -1, &end
) && start
[0] != '\0')
1017 tmp
= g_utf8_normalize (start
, end
- start
, G_NORMALIZE_ALL
);
1018 g_string_append (fixed
, tmp
);
1021 g_string_append_c (fixed
, end
[0]);
1027 result
= g_utf8_normalize (text
, -1, G_NORMALIZE_ALL
);
1031 if (start
[0] != '\0' && start
!= end
)
1033 tmp
= g_utf8_normalize (start
, end
- start
, G_NORMALIZE_ALL
);
1034 g_string_append (fixed
, tmp
);
1037 result
= g_strdup (fixed
->str
);
1039 g_string_free (fixed
, TRUE
);
1045 str_utf8_casefold_normalize (const char *text
)
1047 GString
*fixed
= g_string_new ("");
1054 while (!g_utf8_validate (start
, -1, &end
) && start
[0] != '\0')
1058 fold
= g_utf8_casefold (start
, end
- start
);
1059 tmp
= g_utf8_normalize (fold
, -1, G_NORMALIZE_ALL
);
1060 g_string_append (fixed
, tmp
);
1064 g_string_append_c (fixed
, end
[0]);
1070 fold
= g_utf8_casefold (text
, -1);
1071 result
= g_utf8_normalize (fold
, -1, G_NORMALIZE_ALL
);
1076 if (start
[0] != '\0' && start
!= end
)
1078 fold
= g_utf8_casefold (start
, end
- start
);
1079 tmp
= g_utf8_normalize (fold
, -1, G_NORMALIZE_ALL
);
1080 g_string_append (fixed
, tmp
);
1084 result
= g_strdup (fixed
->str
);
1086 g_string_free (fixed
, TRUE
);
1092 str_utf8_compare (const char *t1
, const char *t2
)
1097 n1
= str_utf8_normalize (t1
);
1098 n2
= str_utf8_normalize (t2
);
1100 result
= strcmp (n1
, n2
);
1109 str_utf8_ncompare (const char *t1
, const char *t2
)
1114 n1
= str_utf8_normalize (t1
);
1115 n2
= str_utf8_normalize (t2
);
1117 result
= strncmp (n1
, n2
, min (strlen (n1
), strlen (n2
)));
1126 str_utf8_casecmp (const char *t1
, const char *t2
)
1131 n1
= str_utf8_casefold_normalize (t1
);
1132 n2
= str_utf8_casefold_normalize (t2
);
1134 result
= strcmp (n1
, n2
);
1143 str_utf8_ncasecmp (const char *t1
, const char *t2
)
1148 n1
= str_utf8_casefold_normalize (t1
);
1149 n2
= str_utf8_casefold_normalize (t2
);
1151 result
= strncmp (n1
, n2
, min (strlen (n1
), strlen (n2
)));
1160 str_utf8_prefix (const char *text
, const char *prefix
)
1162 char *t
= str_utf8_normalize (text
);
1163 char *p
= str_utf8_normalize (prefix
);
1166 const char *nnt
= t
;
1167 const char *nnp
= p
;
1170 while (nt
[0] != '\0' && np
[0] != '\0')
1172 str_utf8_cnext_char_safe (&nnt
);
1173 str_utf8_cnext_char_safe (&nnp
);
1174 if (nnt
- nt
!= nnp
- np
)
1176 if (strncmp (nt
, np
, nnt
- nt
) != 0)
1191 str_utf8_caseprefix (const char *text
, const char *prefix
)
1193 char *t
= str_utf8_casefold_normalize (text
);
1194 char *p
= str_utf8_casefold_normalize (prefix
);
1197 const char *nnt
= t
;
1198 const char *nnp
= p
;
1201 while (nt
[0] != '\0' && np
[0] != '\0')
1203 str_utf8_cnext_char_safe (&nnt
);
1204 str_utf8_cnext_char_safe (&nnp
);
1205 if (nnt
- nt
!= nnp
- np
)
1207 if (strncmp (nt
, np
, nnt
- nt
) != 0)
1222 str_utf8_create_key_gen (const char *text
, int case_sen
,
1223 gchar
* (*keygen
) (const gchar
*, gssize size
))
1228 result
= str_utf8_normalize (text
);
1230 const char *start
, *end
;
1232 GString
*fixed
= g_string_new ("");
1235 while (!g_utf8_validate (start
, -1, &end
) && start
[0] != '\0')
1239 fold
= g_utf8_casefold (start
, end
- start
);
1240 key
= keygen (fold
, -1);
1241 g_string_append (fixed
, key
);
1245 g_string_append_c (fixed
, end
[0]);
1251 fold
= g_utf8_casefold (text
, -1);
1252 result
= keygen (fold
, -1);
1257 if (start
[0] != '\0' && start
!= end
)
1259 fold
= g_utf8_casefold (start
, end
- start
);
1260 key
= keygen (fold
, -1);
1261 g_string_append (fixed
, key
);
1265 result
= g_strdup (fixed
->str
);
1267 g_string_free (fixed
, TRUE
);
1273 str_utf8_create_key (const char *text
, int case_sen
)
1275 return str_utf8_create_key_gen (text
, case_sen
, g_utf8_collate_key
);
1278 #ifdef MC__USE_STR_UTF8_CREATE_KEY_FOR_FILENAME
1280 str_utf8_create_key_for_filename (const char *text
, int case_sen
)
1282 return str_utf8_create_key_gen (text
, case_sen
,
1283 g_utf8_collate_key_for_filename
);
1288 str_utf8_key_collate (const char *t1
, const char *t2
, int case_sen
)
1291 return strcmp (t1
, t2
);
1295 str_utf8_release_key (char *key
, int case_sen
)
1302 str_utf8_init (void)
1304 struct str_class result
;
1306 result
.conv_gerror_message
= str_utf8_conv_gerror_message
;
1307 result
.vfs_convert_to
= str_utf8_vfs_convert_to
;
1308 result
.insert_replace_char
= str_utf8_insert_replace_char
;
1309 result
.is_valid_string
= str_utf8_is_valid_string
;
1310 result
.is_valid_char
= str_utf8_is_valid_char
;
1311 result
.cnext_char
= str_utf8_cnext_char
;
1312 result
.cprev_char
= str_utf8_cprev_char
;
1313 result
.cnext_char_safe
= str_utf8_cnext_char_safe
;
1314 result
.cprev_char_safe
= str_utf8_cprev_char_safe
;
1315 result
.cnext_noncomb_char
= str_utf8_cnext_noncomb_char
;
1316 result
.cprev_noncomb_char
= str_utf8_cprev_noncomb_char
;
1317 result
.isspace
= str_utf8_isspace
;
1318 result
.ispunct
= str_utf8_ispunct
;
1319 result
.isalnum
= str_utf8_isalnum
;
1320 result
.isdigit
= str_utf8_isdigit
;
1321 result
.isprint
= str_utf8_isprint
;
1322 result
.iscombiningmark
= str_utf8_iscombiningmark
;
1323 result
.toupper
= str_utf8_toupper
;
1324 result
.tolower
= str_utf8_tolower
;
1325 result
.length
= str_utf8_length
;
1326 result
.length2
= str_utf8_length2
;
1327 result
.length_noncomb
= str_utf8_length_noncomb
;
1328 result
.fix_string
= str_utf8_fix_string
;
1329 result
.term_form
= str_utf8_term_form
;
1330 result
.fit_to_term
= str_utf8_fit_to_term
;
1331 result
.term_trim
= str_utf8_term_trim
;
1332 result
.term_width2
= str_utf8_term_width2
;
1333 result
.term_width1
= str_utf8_term_width1
;
1334 result
.term_char_width
= str_utf8_term_char_width
;
1335 result
.msg_term_size
= str_utf8_msg_term_size
;
1336 result
.term_substring
= str_utf8_term_substring
;
1337 result
.trunc
= str_utf8_trunc
;
1338 result
.offset_to_pos
= str_utf8_offset_to_pos
;
1339 result
.column_to_pos
= str_utf8_column_to_pos
;
1340 result
.create_search_needle
= str_utf8_create_search_needle
;
1341 result
.release_search_needle
= str_utf8_release_search_needle
;
1342 result
.search_first
= str_utf8_search_first
;
1343 result
.search_last
= str_utf8_search_last
;
1344 result
.compare
= str_utf8_compare
;
1345 result
.ncompare
= str_utf8_ncompare
;
1346 result
.casecmp
= str_utf8_casecmp
;
1347 result
.ncasecmp
= str_utf8_ncasecmp
;
1348 result
.prefix
= str_utf8_prefix
;
1349 result
.caseprefix
= str_utf8_caseprefix
;
1350 result
.create_key
= str_utf8_create_key
;
1351 #ifdef MC__USE_STR_UTF8_CREATE_KEY_FOR_FILENAME
1352 /* case insensitive sort files in "a1 a2 a10" order */
1353 result
.create_key_for_filename
= str_utf8_create_key_for_filename
;
1355 /* case insensitive sort files in "a1 a10 a2" order */
1356 result
.create_key_for_filename
= str_utf8_create_key
;
1358 result
.key_collate
= str_utf8_key_collate
;
1359 result
.release_key
= str_utf8_release_key
;