2 Basic support for extended character sets.
5 Roland Illig <roland.illig@gmx.de>, 2005.
7 This file is part of the Midnight Commander.
9 The Midnight Commander is free software; you can redistribute it
10 and/or modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
14 The Midnight Commander is distributed in the hope that it will be
15 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
16 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
34 * String type conversion
37 extern gboolean
ecs_mbstr_to_str(ecs_char
**ret_str
, const char *s
)
39 #ifdef EXTCHARSET_ENABLED
45 str
= g_new(ecs_char
, maxlen
+ 1);
46 len
= mbstowcs(str
, s
, maxlen
+ 1);
47 if (len
== (size_t) -1) {
52 assert(len
<= maxlen
);
53 *ret_str
= g_renew(ecs_char
, str
, len
+ 1);
56 *ret_str
= g_strdup(s
);
61 extern gboolean
ecs_str_to_mbstr(char **ret_str
, const ecs_char
*s
)
63 #ifdef EXTCHARSET_ENABLED
67 maxlen
= ecs_strlen(s
) * MB_CUR_MAX
;
69 str
= g_new(char, maxlen
+ 1);
70 len
= wcstombs(str
, s
, maxlen
+ 1);
71 if (len
== (size_t) -1) {
76 assert(len
<= maxlen
);
77 *ret_str
= g_renew(char, str
, len
+ 1);
80 *ret_str
= g_strdup(s
);
86 * Character classification
89 #ifdef EXTCHARSET_ENABLED
92 # define ECS_CTYPE(wf, cf, c) \
95 # define ECS_CTYPE(wf, cf, c) \
96 (((unsigned char) c != c) ? FALSE : (cf(c)))
99 # define ECS_CTYPE(wf, cf, c) \
103 extern gboolean
ecs_isalnum(ecs_char c
)
105 return ECS_CTYPE(iswalnum
, isalnum
, c
);
108 extern gboolean
ecs_isalpha(ecs_char c
)
110 return ECS_CTYPE(iswalpha
, isalpha
, c
);
113 extern gboolean
ecs_iscntrl(ecs_char c
)
115 return ECS_CTYPE(iswcntrl
, iscntrl
, c
);
118 extern gboolean
ecs_isdigit(ecs_char c
)
120 return ECS_CTYPE(iswdigit
, isdigit
, c
);
123 extern gboolean
ecs_isgraph(ecs_char c
)
125 return ECS_CTYPE(iswgraph
, isgraph
, c
);
128 extern gboolean
ecs_islower(ecs_char c
)
130 return ECS_CTYPE(iswlower
, islower
, c
);
133 extern gboolean
ecs_isprint(ecs_char c
)
135 return ECS_CTYPE(iswprint
, isprint
, c
);
138 extern gboolean
ecs_ispunct(ecs_char c
)
140 return ECS_CTYPE(iswpunct
, ispunct
, c
);
143 extern gboolean
ecs_isspace(ecs_char c
)
145 return ECS_CTYPE(iswspace
, isspace
, c
);
148 extern gboolean
ecs_isupper(ecs_char c
)
150 return ECS_CTYPE(iswupper
, isupper
, c
);
153 extern gboolean
ecs_isxdigit(ecs_char c
)
155 return ECS_CTYPE(iswxdigit
, isxdigit
, c
);
161 * ISO C90 <string.h> functions
164 /* left out: ecs_strcpy */
165 /* left out: ecs_strncpy */
166 /* left out: ecs_strcat */
167 /* left out: ecs_strncat */
170 ecs_strcmp(const ecs_char
*a
, const ecs_char
*b
)
173 unsigned long ca
, cb
;
175 for (i
= 0; a
[i
] == b
[i
]; i
++) {
176 if (a
[i
] == ECS_CHAR('\0'))
179 ca
= (unsigned long) a
[i
];
180 cb
= (unsigned long) b
[i
];
181 return (ca
< cb
) ? -1 : (ca
> cb
) ? 1 : 0;
184 /* left out: ecs_strcoll */
185 /* left out: ecs_strncmp */
186 /* left out: ecs_strxfrm */
189 ecs_strchr(const ecs_char
*s
, ecs_char c
)
193 for (i
= 0; s
[i
] != c
; i
++) {
194 if (s
[i
] == ECS_CHAR('\0'))
197 return (ecs_char
*) s
+ i
;
201 ecs_strcspn(const ecs_char
*haystack
, const ecs_char
*needles
)
205 for (i
= 0; haystack
[i
] != ECS_CHAR('\0'); i
++) {
206 for (j
= 0; needles
[j
] != ECS_CHAR('\0'); j
++) {
207 if (haystack
[i
] == needles
[j
])
214 /* left out: ecs_strpbrk */
217 ecs_strrchr(const ecs_char
*s
, ecs_char c
)
222 for (i
= 0, pos
= NULL
;; i
++) {
224 pos
= (ecs_char
*) s
+ i
;
225 if (s
[i
] == ECS_CHAR('\0'))
231 ecs_strspn(const ecs_char
*s
, const ecs_char
*chars
)
235 for (i
= 0; s
[i
] != ECS_CHAR('\0'); i
++) {
236 if (ecs_strchr(chars
, s
[i
]) == NULL
)
243 ecs_strstr(const ecs_char
*s
, const ecs_char
*sub
)
247 for (i
= 0; s
[i
] != ECS_CHAR('\0'); i
++) {
248 for (j
= 0; sub
[j
] != ECS_CHAR('\0'); j
++) {
249 if (s
[i
+ j
] != sub
[j
])
252 return (ecs_char
*) s
+ i
;
259 /* left out: ecs_strtok */
262 ecs_strlen(const ecs_char
*s
)
266 for (i
= 0; s
[i
] != ECS_CHAR('\0'); i
++)
275 ecs_char
*ecs_xstrdup(const ecs_char
*s
)
281 retval
= g_new(ecs_char
, len
+ 1);
282 memcpy(retval
, s
, (len
+ 1) * sizeof(ecs_char
));
287 ecs_strlcpy(ecs_char
*dst
, const ecs_char
*src
, size_t dstsize
)
289 size_t n
= 0; /* number of copied characters */
292 while (n
< dstsize
- 1 && *src
!= ECS_CHAR('\0')) {
296 *dst
= ECS_CHAR('\0');
299 while (*src
!= ECS_CHAR('\0')) {
308 ecs_strlcat(ecs_char
*dst
, const ecs_char
*src
, size_t dstsize
)
312 while (di
< dstsize
&& dst
[di
] != ECS_CHAR('\0'))
314 return di
+ ecs_strlcpy(dst
+ di
, src
, dstsize
- di
);
318 ecs_strbox(const ecs_char
*s
, size_t *ret_width
, size_t *ret_height
)
320 size_t nlines
= 0, ncolumns
= 0, colindex
= 0, i
;
322 for (i
= 0; s
[i
] != ECS_CHAR('\0'); i
++) {
323 if (s
[i
] == ECS_CHAR('\n')) {
327 if (!ecs_isprint(s
[i
]))
330 /* FIXME: This code assumes that each printable
331 * character occupies one cell on the screen. */
333 if (colindex
> ncolumns
)
337 *ret_width
= ncolumns
;
338 *ret_height
= nlines
;