]> git.ipfire.org Git - thirdparty/bash.git/blame - include/shmbutil.h
Bash-4.3 patch 1
[thirdparty/bash.git] / include / shmbutil.h
CommitLineData
7117c2d2
JA
1/* shmbutil.h -- utility functions for multibyte characters. */
2
b80f6443 3/* Copyright (C) 2002-2004 Free Software Foundation, Inc.
7117c2d2
JA
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
3185942a
JA
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.
11
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.
16
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/>.
19*/
7117c2d2
JA
20
21#if !defined (_SH_MBUTIL_H_)
22#define _SH_MBUTIL_H_
23
24#include "stdc.h"
25
b80f6443
JA
26/* Include config.h for HANDLE_MULTIBYTE */
27#include <config.h>
7117c2d2
JA
28
29#if defined (HANDLE_MULTIBYTE)
495aee44 30#include "shmbchar.h"
7117c2d2
JA
31
32extern size_t xmbsrtowcs __P((wchar_t *, const char **, size_t, mbstate_t *));
b80f6443 33extern size_t xdupmbstowcs __P((wchar_t **, char ***, const char *));
7117c2d2 34
eb873671
JA
35extern size_t mbstrlen __P((const char *));
36
7117c2d2
JA
37extern char *xstrchr __P((const char *, int));
38
ac50fbac
CR
39extern int locale_mb_cur_max; /* XXX */
40
b80f6443
JA
41#ifndef MB_INVALIDCH
42#define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2)
43#define MB_NULLWCH(x) ((x) == 0)
44#endif
45
eb873671
JA
46#define MBSLEN(s) (((s) && (s)[0]) ? ((s)[1] ? mbstrlen (s) : 1) : 0)
47#define MB_STRLEN(s) ((MB_CUR_MAX > 1) ? MBSLEN (s) : STRLEN (s))
48
95732b49
JA
49#define MBLEN(s, n) ((MB_CUR_MAX > 1) ? mblen ((s), (n)) : 1)
50#define MBRLEN(s, n, p) ((MB_CUR_MAX > 1) ? mbrlen ((s), (n), (p)) : 1)
51
7117c2d2
JA
52#else /* !HANDLE_MULTIBYTE */
53
54#undef MB_LEN_MAX
55#undef MB_CUR_MAX
56
57#define MB_LEN_MAX 1
58#define MB_CUR_MAX 1
59
60#undef xstrchr
61#define xstrchr(s, c) strchr(s, c)
62
b80f6443
JA
63#ifndef MB_INVALIDCH
64#define MB_INVALIDCH(x) (0)
65#define MB_NULLWCH(x) (0)
66#endif
67
eb873671
JA
68#define MB_STRLEN(s) (STRLEN(s))
69
95732b49
JA
70#define MBLEN(s, n) 1
71#define MBRLEN(s, n, p) 1
72
3185942a
JA
73#ifndef wchar_t
74# define wchar_t int
75#endif
76
7117c2d2
JA
77#endif /* !HANDLE_MULTIBYTE */
78
79/* Declare and initialize a multibyte state. Call must be terminated
80 with `;'. */
81#if defined (HANDLE_MULTIBYTE)
82# define DECLARE_MBSTATE \
83 mbstate_t state; \
84 memset (&state, '\0', sizeof (mbstate_t))
85#else
86# define DECLARE_MBSTATE
87#endif /* !HANDLE_MULTIBYTE */
88
89/* Initialize or reinitialize a multibyte state named `state'. Call must be
90 terminated with `;'. */
91#if defined (HANDLE_MULTIBYTE)
92# define INITIALIZE_MBSTATE memset (&state, '\0', sizeof (mbstate_t))
93#else
94# define INITIALIZE_MBSTATE
95#endif /* !HANDLE_MULTIBYTE */
96
97/* Advance one (possibly multi-byte) character in string _STR of length
98 _STRSIZE, starting at index _I. STATE must have already been declared. */
99#if defined (HANDLE_MULTIBYTE)
100# define ADVANCE_CHAR(_str, _strsize, _i) \
101 do \
102 { \
ac50fbac 103 if (locale_mb_cur_max > 1) \
7117c2d2
JA
104 { \
105 mbstate_t state_bak; \
106 size_t mblength; \
495aee44 107 int _f; \
7117c2d2 108\
495aee44
CR
109 _f = is_basic ((_str)[_i]); \
110 if (_f) \
111 mblength = 1; \
112 else \
113 { \
114 state_bak = state; \
115 mblength = mbrlen ((_str) + (_i), (_strsize) - (_i), &state); \
116 } \
7117c2d2
JA
117\
118 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
119 { \
120 state = state_bak; \
121 (_i)++; \
122 } \
b80f6443
JA
123 else if (mblength == 0) \
124 (_i)++; \
7117c2d2
JA
125 else \
126 (_i) += mblength; \
127 } \
128 else \
129 (_i)++; \
130 } \
131 while (0)
132#else
133# define ADVANCE_CHAR(_str, _strsize, _i) (_i)++
134#endif /* !HANDLE_MULTIBYTE */
135
136/* Advance one (possibly multibyte) character in the string _STR of length
137 _STRSIZE.
138 SPECIAL: assume that _STR will be incremented by 1 after this call. */
139#if defined (HANDLE_MULTIBYTE)
140# define ADVANCE_CHAR_P(_str, _strsize) \
141 do \
142 { \
ac50fbac 143 if (locale_mb_cur_max > 1) \
7117c2d2
JA
144 { \
145 mbstate_t state_bak; \
146 size_t mblength; \
495aee44 147 int _f; \
7117c2d2 148\
495aee44
CR
149 _f = is_basic (*(_str)); \
150 if (_f) \
151 mblength = 1; \
152 else \
153 { \
154 state_bak = state; \
155 mblength = mbrlen ((_str), (_strsize), &state); \
156 } \
7117c2d2
JA
157\
158 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
159 { \
160 state = state_bak; \
161 mblength = 1; \
162 } \
163 else \
164 (_str) += (mblength < 1) ? 0 : (mblength - 1); \
165 } \
166 } \
167 while (0)
168#else
169# define ADVANCE_CHAR_P(_str, _strsize)
170#endif /* !HANDLE_MULTIBYTE */
171
b80f6443
JA
172/* Back up one (possibly multi-byte) character in string _STR of length
173 _STRSIZE, starting at index _I. STATE must have already been declared. */
174#if defined (HANDLE_MULTIBYTE)
175# define BACKUP_CHAR(_str, _strsize, _i) \
176 do \
177 { \
ac50fbac 178 if (locale_mb_cur_max > 1) \
b80f6443
JA
179 { \
180 mbstate_t state_bak; \
181 size_t mblength; \
182 int _x, _p; /* _x == temp index into string, _p == prev index */ \
183\
184 _x = _p = 0; \
185 while (_x < (_i)) \
186 { \
187 state_bak = state; \
188 mblength = mbrlen ((_str) + (_x), (_strsize) - (_x), &state); \
189\
190 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
191 { \
192 state = state_bak; \
193 _x++; \
194 } \
195 else if (mblength == 0) \
196 _x++; \
197 else \
198 { \
199 _p = _x; /* _p == start of prev mbchar */ \
200 _x += mblength; \
201 } \
202 } \
203 (_i) = _p; \
204 } \
205 else \
206 (_i)--; \
207 } \
208 while (0)
209#else
210# define BACKUP_CHAR(_str, _strsize, _i) (_i)--
211#endif /* !HANDLE_MULTIBYTE */
212
213/* Back up one (possibly multibyte) character in the string _BASE of length
214 _STRSIZE starting at _STR (_BASE <= _STR <= (_BASE + _STRSIZE) ).
215 SPECIAL: DO NOT assume that _STR will be decremented by 1 after this call. */
216#if defined (HANDLE_MULTIBYTE)
217# define BACKUP_CHAR_P(_base, _strsize, _str) \
218 do \
219 { \
ac50fbac 220 if (locale_mb_cur_max > 1) \
b80f6443
JA
221 { \
222 mbstate_t state_bak; \
223 size_t mblength; \
224 char *_x, _p; /* _x == temp pointer into string, _p == prev pointer */ \
225\
226 _x = _p = _base; \
227 while (_x < (_str)) \
228 { \
229 state_bak = state; \
230 mblength = mbrlen (_x, (_strsize) - _x, &state); \
231\
232 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
233 { \
234 state = state_bak; \
235 _x++; \
236 } \
237 else if (mblength == 0) \
238 _x++; \
239 else \
240 { \
241 _p = _x; /* _p == start of prev mbchar */ \
242 _x += mblength; \
243 } \
244 } \
245 (_str) = _p; \
246 } \
247 else \
248 (_str)--; \
249 } \
250 while (0)
251#else
252# define BACKUP_CHAR_P(_base, _strsize, _str) (_str)--
253#endif /* !HANDLE_MULTIBYTE */
254
7117c2d2
JA
255/* Copy a single character from the string _SRC to the string _DST.
256 _SRCEND is a pointer to the end of _SRC. */
257#if defined (HANDLE_MULTIBYTE)
258# define COPY_CHAR_P(_dst, _src, _srcend) \
259 do \
260 { \
ac50fbac 261 if (locale_mb_cur_max > 1) \
7117c2d2
JA
262 { \
263 mbstate_t state_bak; \
264 size_t mblength; \
265 int _k; \
266\
495aee44
CR
267 _k = is_basic (*(_src)); \
268 if (_k) \
269 mblength = 1; \
270 else \
271 { \
272 state_bak = state; \
273 mblength = mbrlen ((_src), (_srcend) - (_src), &state); \
274 } \
7117c2d2
JA
275 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
276 { \
277 state = state_bak; \
278 mblength = 1; \
279 } \
280 else \
281 mblength = (mblength < 1) ? 1 : mblength; \
282\
283 for (_k = 0; _k < mblength; _k++) \
284 *(_dst)++ = *(_src)++; \
285 } \
286 else \
287 *(_dst)++ = *(_src)++; \
288 } \
289 while (0)
290#else
291# define COPY_CHAR_P(_dst, _src, _srcend) *(_dst)++ = *(_src)++
292#endif /* !HANDLE_MULTIBYTE */
293
294/* Copy a single character from the string _SRC at index _SI to the string
295 _DST at index _DI. _SRCEND is a pointer to the end of _SRC. */
296#if defined (HANDLE_MULTIBYTE)
297# define COPY_CHAR_I(_dst, _di, _src, _srcend, _si) \
298 do \
299 { \
ac50fbac 300 if (locale_mb_cur_max > 1) \
7117c2d2
JA
301 { \
302 mbstate_t state_bak; \
303 size_t mblength; \
304 int _k; \
305\
495aee44
CR
306 _k = is_basic (*((_src) + (_si))); \
307 if (_k) \
308 mblength = 1; \
309 else \
310 {\
311 state_bak = state; \
312 mblength = mbrlen ((_src) + (_si), (_srcend) - ((_src)+(_si)), &state); \
313 } \
7117c2d2
JA
314 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
315 { \
316 state = state_bak; \
317 mblength = 1; \
318 } \
319 else \
320 mblength = (mblength < 1) ? 1 : mblength; \
321\
322 for (_k = 0; _k < mblength; _k++) \
323 _dst[_di++] = _src[_si++]; \
324 } \
325 else \
326 _dst[_di++] = _src[_si++]; \
327 } \
328 while (0)
329#else
330# define COPY_CHAR_I(_dst, _di, _src, _srcend, _si) _dst[_di++] = _src[_si++]
331#endif /* !HANDLE_MULTIBYTE */
332
333/****************************************************************
334 * *
335 * The following are only guaranteed to work in subst.c *
336 * *
337 ****************************************************************/
338
339#if defined (HANDLE_MULTIBYTE)
340# define SCOPY_CHAR_I(_dst, _escchar, _sc, _src, _si, _slen) \
341 do \
342 { \
ac50fbac 343 if (locale_mb_cur_max > 1) \
7117c2d2
JA
344 { \
345 mbstate_t state_bak; \
346 size_t mblength; \
347 int _i; \
348\
495aee44
CR
349 _i = is_basic (*((_src) + (_si))); \
350 if (_i) \
351 mblength = 1; \
352 else \
353 { \
354 state_bak = state; \
355 mblength = mbrlen ((_src) + (_si), (_slen) - (_si), &state); \
356 } \
7117c2d2
JA
357 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
358 { \
359 state = state_bak; \
360 mblength = 1; \
361 } \
362 else \
363 mblength = (mblength < 1) ? 1 : mblength; \
364\
365 temp = xmalloc (mblength + 2); \
366 temp[0] = _escchar; \
367 for (_i = 0; _i < mblength; _i++) \
368 temp[_i + 1] = _src[_si++]; \
369 temp[mblength + 1] = '\0'; \
370\
371 goto add_string; \
372 } \
373 else \
374 { \
375 _dst[0] = _escchar; \
376 _dst[1] = _sc; \
377 } \
378 } \
379 while (0)
380#else
381# define SCOPY_CHAR_I(_dst, _escchar, _sc, _src, _si, _slen) \
382 _dst[0] = _escchar; \
383 _dst[1] = _sc
384#endif /* !HANDLE_MULTIBYTE */
385
386#if defined (HANDLE_MULTIBYTE)
387# define SCOPY_CHAR_M(_dst, _src, _srcend, _si) \
388 do \
389 { \
ac50fbac 390 if (locale_mb_cur_max > 1) \
7117c2d2
JA
391 { \
392 mbstate_t state_bak; \
393 size_t mblength; \
495aee44 394 int _i; \
7117c2d2 395\
495aee44
CR
396 _i = is_basic (*((_src) + (_si))); \
397 if (_i) \
398 mblength = 1; \
399 else \
400 { \
401 state_bak = state; \
402 mblength = mbrlen ((_src) + (_si), (_srcend) - ((_src) + (_si)), &state); \
403 } \
7117c2d2
JA
404 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
405 { \
406 state = state_bak; \
407 mblength = 1; \
408 } \
409 else \
410 mblength = (mblength < 1) ? 1 : mblength; \
411\
412 FASTCOPY(((_src) + (_si)), (_dst), mblength); \
413\
414 (_dst) += mblength; \
415 (_si) += mblength; \
416 } \
417 else \
418 { \
419 *(_dst)++ = _src[(_si)]; \
420 (_si)++; \
421 } \
422 } \
423 while (0)
424#else
425# define SCOPY_CHAR_M(_dst, _src, _srcend, _si) \
426 *(_dst)++ = _src[(_si)]; \
427 (_si)++
428#endif /* !HANDLE_MULTIBYTE */
429
430#if HANDLE_MULTIBYTE
431# define SADD_MBCHAR(_dst, _src, _si, _srcsize) \
432 do \
433 { \
ac50fbac 434 if (locale_mb_cur_max > 1) \
7117c2d2
JA
435 { \
436 int i; \
437 mbstate_t state_bak; \
438 size_t mblength; \
439\
495aee44
CR
440 i = is_basic (*((_src) + (_si))); \
441 if (i) \
442 mblength = 1; \
443 else \
444 { \
445 state_bak = state; \
446 mblength = mbrlen ((_src) + (_si), (_srcsize) - (_si), &state); \
447 } \
7117c2d2
JA
448 if (mblength == (size_t)-1 || mblength == (size_t)-2) \
449 { \
450 state = state_bak; \
451 mblength = 1; \
452 } \
453 if (mblength < 1) \
454 mblength = 1; \
455\
456 _dst = (char *)xmalloc (mblength + 1); \
457 for (i = 0; i < mblength; i++) \
458 (_dst)[i] = (_src)[(_si)++]; \
459 (_dst)[mblength] = '\0'; \
460\
461 goto add_string; \
462 } \
463 } \
464 while (0)
465
466#else
467# define SADD_MBCHAR(_dst, _src, _si, _srcsize)
468#endif
469
ac50fbac 470/* Watch out when using this -- it's just straight textual substitution */
b80f6443
JA
471#if defined (HANDLE_MULTIBYTE)
472# define SADD_MBQCHAR_BODY(_dst, _src, _si, _srcsize) \
473\
474 int i; \
475 mbstate_t state_bak; \
476 size_t mblength; \
477\
495aee44
CR
478 i = is_basic (*((_src) + (_si))); \
479 if (i) \
480 mblength = 1; \
481 else \
482 { \
483 state_bak = state; \
484 mblength = mbrlen ((_src) + (_si), (_srcsize) - (_si), &state); \
485 } \
b80f6443
JA
486 if (mblength == (size_t)-1 || mblength == (size_t)-2) \
487 { \
488 state = state_bak; \
489 mblength = 1; \
490 } \
491 if (mblength < 1) \
492 mblength = 1; \
493\
494 (_dst) = (char *)xmalloc (mblength + 2); \
495 (_dst)[0] = CTLESC; \
496 for (i = 0; i < mblength; i++) \
497 (_dst)[i+1] = (_src)[(_si)++]; \
498 (_dst)[mblength+1] = '\0'; \
499\
500 goto add_string
501
502#endif /* HANDLE_MULTIBYTE */
7117c2d2 503#endif /* _SH_MBUTIL_H_ */