]>
git.ipfire.org Git - thirdparty/bash.git/blob - include/shmbutil.h
1 /* shmbutil.h -- utility functions for multibyte characters. */
3 /* Copyright (C) 2002-2004 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
21 #if !defined (_SH_MBUTIL_H_)
26 /* Include config.h for HANDLE_MULTIBYTE */
29 #if defined (HANDLE_MULTIBYTE)
32 extern size_t xmbsrtowcs
__P((wchar_t *, const char **, size_t, mbstate_t *));
33 extern size_t xdupmbstowcs
__P((wchar_t **, char ***, const char *));
35 extern size_t mbstrlen
__P((const char *));
37 extern char *xstrchr
__P((const char *, int));
40 #define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2)
41 #define MB_NULLWCH(x) ((x) == 0)
44 #define MBSLEN(s) (((s) && (s)[0]) ? ((s)[1] ? mbstrlen (s) : 1) : 0)
45 #define MB_STRLEN(s) ((MB_CUR_MAX > 1) ? MBSLEN (s) : STRLEN (s))
47 #define MBLEN(s, n) ((MB_CUR_MAX > 1) ? mblen ((s), (n)) : 1)
48 #define MBRLEN(s, n, p) ((MB_CUR_MAX > 1) ? mbrlen ((s), (n), (p)) : 1)
50 #else /* !HANDLE_MULTIBYTE */
59 #define xstrchr(s, c) strchr(s, c)
62 #define MB_INVALIDCH(x) (0)
63 #define MB_NULLWCH(x) (0)
66 #define MB_STRLEN(s) (STRLEN(s))
69 #define MBRLEN(s, n, p) 1
75 #endif /* !HANDLE_MULTIBYTE */
77 /* Declare and initialize a multibyte state. Call must be terminated
79 #if defined (HANDLE_MULTIBYTE)
80 # define DECLARE_MBSTATE \
82 memset (&state, '\0', sizeof (mbstate_t))
84 # define DECLARE_MBSTATE
85 #endif /* !HANDLE_MULTIBYTE */
87 /* Initialize or reinitialize a multibyte state named `state'. Call must be
88 terminated with `;'. */
89 #if defined (HANDLE_MULTIBYTE)
90 # define INITIALIZE_MBSTATE memset (&state, '\0', sizeof (mbstate_t))
92 # define INITIALIZE_MBSTATE
93 #endif /* !HANDLE_MULTIBYTE */
95 /* Advance one (possibly multi-byte) character in string _STR of length
96 _STRSIZE, starting at index _I. STATE must have already been declared. */
97 #if defined (HANDLE_MULTIBYTE)
98 # define ADVANCE_CHAR(_str, _strsize, _i) \
101 if (MB_CUR_MAX > 1) \
103 mbstate_t state_bak; \
107 _f = is_basic ((_str)[_i]); \
113 mblength = mbrlen ((_str) + (_i), (_strsize) - (_i), &state); \
116 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
121 else if (mblength == 0) \
131 # define ADVANCE_CHAR(_str, _strsize, _i) (_i)++
132 #endif /* !HANDLE_MULTIBYTE */
134 /* Advance one (possibly multibyte) character in the string _STR of length
136 SPECIAL: assume that _STR will be incremented by 1 after this call. */
137 #if defined (HANDLE_MULTIBYTE)
138 # define ADVANCE_CHAR_P(_str, _strsize) \
141 if (MB_CUR_MAX > 1) \
143 mbstate_t state_bak; \
147 _f = is_basic (*(_str)); \
153 mblength = mbrlen ((_str), (_strsize), &state); \
156 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
162 (_str) += (mblength < 1) ? 0 : (mblength - 1); \
167 # define ADVANCE_CHAR_P(_str, _strsize)
168 #endif /* !HANDLE_MULTIBYTE */
170 /* Back up one (possibly multi-byte) character in string _STR of length
171 _STRSIZE, starting at index _I. STATE must have already been declared. */
172 #if defined (HANDLE_MULTIBYTE)
173 # define BACKUP_CHAR(_str, _strsize, _i) \
176 if (MB_CUR_MAX > 1) \
178 mbstate_t state_bak; \
180 int _x, _p; /* _x == temp index into string, _p == prev index */ \
186 mblength = mbrlen ((_str) + (_x), (_strsize) - (_x), &state); \
188 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
193 else if (mblength == 0) \
197 _p = _x; /* _p == start of prev mbchar */ \
208 # define BACKUP_CHAR(_str, _strsize, _i) (_i)--
209 #endif /* !HANDLE_MULTIBYTE */
211 /* Back up one (possibly multibyte) character in the string _BASE of length
212 _STRSIZE starting at _STR (_BASE <= _STR <= (_BASE + _STRSIZE) ).
213 SPECIAL: DO NOT assume that _STR will be decremented by 1 after this call. */
214 #if defined (HANDLE_MULTIBYTE)
215 # define BACKUP_CHAR_P(_base, _strsize, _str) \
218 if (MB_CUR_MAX > 1) \
220 mbstate_t state_bak; \
222 char *_x, _p; /* _x == temp pointer into string, _p == prev pointer */ \
225 while (_x < (_str)) \
228 mblength = mbrlen (_x, (_strsize) - _x, &state); \
230 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
235 else if (mblength == 0) \
239 _p = _x; /* _p == start of prev mbchar */ \
250 # define BACKUP_CHAR_P(_base, _strsize, _str) (_str)--
251 #endif /* !HANDLE_MULTIBYTE */
253 /* Copy a single character from the string _SRC to the string _DST.
254 _SRCEND is a pointer to the end of _SRC. */
255 #if defined (HANDLE_MULTIBYTE)
256 # define COPY_CHAR_P(_dst, _src, _srcend) \
259 if (MB_CUR_MAX > 1) \
261 mbstate_t state_bak; \
265 _k = is_basic (*(_src)); \
271 mblength = mbrlen ((_src), (_srcend) - (_src), &state); \
273 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
279 mblength = (mblength < 1) ? 1 : mblength; \
281 for (_k = 0; _k < mblength; _k++) \
282 *(_dst)++ = *(_src)++; \
285 *(_dst)++ = *(_src)++; \
289 # define COPY_CHAR_P(_dst, _src, _srcend) *(_dst)++ = *(_src)++
290 #endif /* !HANDLE_MULTIBYTE */
292 /* Copy a single character from the string _SRC at index _SI to the string
293 _DST at index _DI. _SRCEND is a pointer to the end of _SRC. */
294 #if defined (HANDLE_MULTIBYTE)
295 # define COPY_CHAR_I(_dst, _di, _src, _srcend, _si) \
298 if (MB_CUR_MAX > 1) \
300 mbstate_t state_bak; \
304 _k = is_basic (*((_src) + (_si))); \
310 mblength = mbrlen ((_src) + (_si), (_srcend) - ((_src)+(_si)), &state); \
312 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
318 mblength = (mblength < 1) ? 1 : mblength; \
320 for (_k = 0; _k < mblength; _k++) \
321 _dst[_di++] = _src[_si++]; \
324 _dst[_di++] = _src[_si++]; \
328 # define COPY_CHAR_I(_dst, _di, _src, _srcend, _si) _dst[_di++] = _src[_si++]
329 #endif /* !HANDLE_MULTIBYTE */
331 /****************************************************************
333 * The following are only guaranteed to work in subst.c *
335 ****************************************************************/
337 #if defined (HANDLE_MULTIBYTE)
338 # define SCOPY_CHAR_I(_dst, _escchar, _sc, _src, _si, _slen) \
341 if (MB_CUR_MAX > 1) \
343 mbstate_t state_bak; \
347 _i = is_basic (*((_src) + (_si))); \
353 mblength = mbrlen ((_src) + (_si), (_slen) - (_si), &state); \
355 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
361 mblength = (mblength < 1) ? 1 : mblength; \
363 temp = xmalloc (mblength + 2); \
364 temp[0] = _escchar; \
365 for (_i = 0; _i < mblength; _i++) \
366 temp[_i + 1] = _src[_si++]; \
367 temp[mblength + 1] = '\0'; \
373 _dst[0] = _escchar; \
379 # define SCOPY_CHAR_I(_dst, _escchar, _sc, _src, _si, _slen) \
380 _dst[0] = _escchar; \
382 #endif /* !HANDLE_MULTIBYTE */
384 #if defined (HANDLE_MULTIBYTE)
385 # define SCOPY_CHAR_M(_dst, _src, _srcend, _si) \
388 if (MB_CUR_MAX > 1) \
390 mbstate_t state_bak; \
394 _i = is_basic (*((_src) + (_si))); \
400 mblength = mbrlen ((_src) + (_si), (_srcend) - ((_src) + (_si)), &state); \
402 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
408 mblength = (mblength < 1) ? 1 : mblength; \
410 FASTCOPY(((_src) + (_si)), (_dst), mblength); \
412 (_dst) += mblength; \
417 *(_dst)++ = _src[(_si)]; \
423 # define SCOPY_CHAR_M(_dst, _src, _srcend, _si) \
424 *(_dst)++ = _src[(_si)]; \
426 #endif /* !HANDLE_MULTIBYTE */
429 # define SADD_MBCHAR(_dst, _src, _si, _srcsize) \
432 if (MB_CUR_MAX > 1) \
435 mbstate_t state_bak; \
438 i = is_basic (*((_src) + (_si))); \
444 mblength = mbrlen ((_src) + (_si), (_srcsize) - (_si), &state); \
446 if (mblength == (size_t)-1 || mblength == (size_t)-2) \
454 _dst = (char *)xmalloc (mblength + 1); \
455 for (i = 0; i < mblength; i++) \
456 (_dst)[i] = (_src)[(_si)++]; \
457 (_dst)[mblength] = '\0'; \
465 # define SADD_MBCHAR(_dst, _src, _si, _srcsize)
468 /* Watch out when using this -- it's just straight textual subsitution */
469 #if defined (HANDLE_MULTIBYTE)
470 # define SADD_MBQCHAR_BODY(_dst, _src, _si, _srcsize) \
473 mbstate_t state_bak; \
476 i = is_basic (*((_src) + (_si))); \
482 mblength = mbrlen ((_src) + (_si), (_srcsize) - (_si), &state); \
484 if (mblength == (size_t)-1 || mblength == (size_t)-2) \
492 (_dst) = (char *)xmalloc (mblength + 2); \
493 (_dst)[0] = CTLESC; \
494 for (i = 0; i < mblength; i++) \
495 (_dst)[i+1] = (_src)[(_si)++]; \
496 (_dst)[mblength+1] = '\0'; \
500 #endif /* HANDLE_MULTIBYTE */
501 #endif /* _SH_MBUTIL_H_ */