]> git.ipfire.org Git - thirdparty/bash.git/blob - include/shmbutil.h
commit bash-20040902 snapshot
[thirdparty/bash.git] / include / shmbutil.h
1 /* shmbutil.h -- utility functions for multibyte characters. */
2
3 /* Copyright (C) 2002-2004 Free Software Foundation, Inc.
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
7 Bash is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with Bash; see the file COPYING. If not, write to the Free Software
19 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
20
21 #if !defined (_SH_MBUTIL_H_)
22 #define _SH_MBUTIL_H_
23
24 #include "stdc.h"
25
26 /* Include config.h for HANDLE_MULTIBYTE */
27 #include <config.h>
28
29 #if defined (HANDLE_MULTIBYTE)
30
31 extern size_t xmbsrtowcs __P((wchar_t *, const char **, size_t, mbstate_t *));
32 extern size_t xdupmbstowcs __P((wchar_t **, char ***, const char *));
33
34 extern size_t mbstrlen __P((const char *));
35
36 extern char *xstrchr __P((const char *, int));
37
38 #ifndef MB_INVALIDCH
39 #define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2)
40 #define MB_NULLWCH(x) ((x) == 0)
41 #endif
42
43 #define MBSLEN(s) (((s) && (s)[0]) ? ((s)[1] ? mbstrlen (s) : 1) : 0)
44 #define MB_STRLEN(s) ((MB_CUR_MAX > 1) ? MBSLEN (s) : STRLEN (s))
45
46 #else /* !HANDLE_MULTIBYTE */
47
48 #undef MB_LEN_MAX
49 #undef MB_CUR_MAX
50
51 #define MB_LEN_MAX 1
52 #define MB_CUR_MAX 1
53
54 #undef xstrchr
55 #define xstrchr(s, c) strchr(s, c)
56
57 #ifndef MB_INVALIDCH
58 #define MB_INVALIDCH(x) (0)
59 #define MB_NULLWCH(x) (0)
60 #endif
61
62 #define MB_STRLEN(s) (STRLEN(s))
63
64 #endif /* !HANDLE_MULTIBYTE */
65
66 /* Declare and initialize a multibyte state. Call must be terminated
67 with `;'. */
68 #if defined (HANDLE_MULTIBYTE)
69 # define DECLARE_MBSTATE \
70 mbstate_t state; \
71 memset (&state, '\0', sizeof (mbstate_t))
72 #else
73 # define DECLARE_MBSTATE
74 #endif /* !HANDLE_MULTIBYTE */
75
76 /* Initialize or reinitialize a multibyte state named `state'. Call must be
77 terminated with `;'. */
78 #if defined (HANDLE_MULTIBYTE)
79 # define INITIALIZE_MBSTATE memset (&state, '\0', sizeof (mbstate_t))
80 #else
81 # define INITIALIZE_MBSTATE
82 #endif /* !HANDLE_MULTIBYTE */
83
84 /* Advance one (possibly multi-byte) character in string _STR of length
85 _STRSIZE, starting at index _I. STATE must have already been declared. */
86 #if defined (HANDLE_MULTIBYTE)
87 # define ADVANCE_CHAR(_str, _strsize, _i) \
88 do \
89 { \
90 if (MB_CUR_MAX > 1) \
91 { \
92 mbstate_t state_bak; \
93 size_t mblength; \
94 \
95 state_bak = state; \
96 mblength = mbrlen ((_str) + (_i), (_strsize) - (_i), &state); \
97 \
98 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
99 { \
100 state = state_bak; \
101 (_i)++; \
102 } \
103 else if (mblength == 0) \
104 (_i)++; \
105 else \
106 (_i) += mblength; \
107 } \
108 else \
109 (_i)++; \
110 } \
111 while (0)
112 #else
113 # define ADVANCE_CHAR(_str, _strsize, _i) (_i)++
114 #endif /* !HANDLE_MULTIBYTE */
115
116 /* Advance one (possibly multibyte) character in the string _STR of length
117 _STRSIZE.
118 SPECIAL: assume that _STR will be incremented by 1 after this call. */
119 #if defined (HANDLE_MULTIBYTE)
120 # define ADVANCE_CHAR_P(_str, _strsize) \
121 do \
122 { \
123 if (MB_CUR_MAX > 1) \
124 { \
125 mbstate_t state_bak; \
126 size_t mblength; \
127 \
128 state_bak = state; \
129 mblength = mbrlen ((_str), (_strsize), &state); \
130 \
131 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
132 { \
133 state = state_bak; \
134 mblength = 1; \
135 } \
136 else \
137 (_str) += (mblength < 1) ? 0 : (mblength - 1); \
138 } \
139 } \
140 while (0)
141 #else
142 # define ADVANCE_CHAR_P(_str, _strsize)
143 #endif /* !HANDLE_MULTIBYTE */
144
145 /* Back up one (possibly multi-byte) character in string _STR of length
146 _STRSIZE, starting at index _I. STATE must have already been declared. */
147 #if defined (HANDLE_MULTIBYTE)
148 # define BACKUP_CHAR(_str, _strsize, _i) \
149 do \
150 { \
151 if (MB_CUR_MAX > 1) \
152 { \
153 mbstate_t state_bak; \
154 size_t mblength; \
155 int _x, _p; /* _x == temp index into string, _p == prev index */ \
156 \
157 _x = _p = 0; \
158 while (_x < (_i)) \
159 { \
160 state_bak = state; \
161 mblength = mbrlen ((_str) + (_x), (_strsize) - (_x), &state); \
162 \
163 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
164 { \
165 state = state_bak; \
166 _x++; \
167 } \
168 else if (mblength == 0) \
169 _x++; \
170 else \
171 { \
172 _p = _x; /* _p == start of prev mbchar */ \
173 _x += mblength; \
174 } \
175 } \
176 (_i) = _p; \
177 } \
178 else \
179 (_i)--; \
180 } \
181 while (0)
182 #else
183 # define BACKUP_CHAR(_str, _strsize, _i) (_i)--
184 #endif /* !HANDLE_MULTIBYTE */
185
186 /* Back up one (possibly multibyte) character in the string _BASE of length
187 _STRSIZE starting at _STR (_BASE <= _STR <= (_BASE + _STRSIZE) ).
188 SPECIAL: DO NOT assume that _STR will be decremented by 1 after this call. */
189 #if defined (HANDLE_MULTIBYTE)
190 # define BACKUP_CHAR_P(_base, _strsize, _str) \
191 do \
192 { \
193 if (MB_CUR_MAX > 1) \
194 { \
195 mbstate_t state_bak; \
196 size_t mblength; \
197 char *_x, _p; /* _x == temp pointer into string, _p == prev pointer */ \
198 \
199 _x = _p = _base; \
200 while (_x < (_str)) \
201 { \
202 state_bak = state; \
203 mblength = mbrlen (_x, (_strsize) - _x, &state); \
204 \
205 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
206 { \
207 state = state_bak; \
208 _x++; \
209 } \
210 else if (mblength == 0) \
211 _x++; \
212 else \
213 { \
214 _p = _x; /* _p == start of prev mbchar */ \
215 _x += mblength; \
216 } \
217 } \
218 (_str) = _p; \
219 } \
220 else \
221 (_str)--; \
222 } \
223 while (0)
224 #else
225 # define BACKUP_CHAR_P(_base, _strsize, _str) (_str)--
226 #endif /* !HANDLE_MULTIBYTE */
227
228 /* Copy a single character from the string _SRC to the string _DST.
229 _SRCEND is a pointer to the end of _SRC. */
230 #if defined (HANDLE_MULTIBYTE)
231 # define COPY_CHAR_P(_dst, _src, _srcend) \
232 do \
233 { \
234 if (MB_CUR_MAX > 1) \
235 { \
236 mbstate_t state_bak; \
237 size_t mblength; \
238 int _k; \
239 \
240 state_bak = state; \
241 mblength = mbrlen ((_src), (_srcend) - (_src), &state); \
242 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
243 { \
244 state = state_bak; \
245 mblength = 1; \
246 } \
247 else \
248 mblength = (mblength < 1) ? 1 : mblength; \
249 \
250 for (_k = 0; _k < mblength; _k++) \
251 *(_dst)++ = *(_src)++; \
252 } \
253 else \
254 *(_dst)++ = *(_src)++; \
255 } \
256 while (0)
257 #else
258 # define COPY_CHAR_P(_dst, _src, _srcend) *(_dst)++ = *(_src)++
259 #endif /* !HANDLE_MULTIBYTE */
260
261 /* Copy a single character from the string _SRC at index _SI to the string
262 _DST at index _DI. _SRCEND is a pointer to the end of _SRC. */
263 #if defined (HANDLE_MULTIBYTE)
264 # define COPY_CHAR_I(_dst, _di, _src, _srcend, _si) \
265 do \
266 { \
267 if (MB_CUR_MAX > 1) \
268 { \
269 mbstate_t state_bak; \
270 size_t mblength; \
271 int _k; \
272 \
273 state_bak = state; \
274 mblength = mbrlen ((_src) + (_si), (_srcend) - ((_src)+(_si)), &state); \
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[_di++] = _src[_si++]; \
285 } \
286 else \
287 _dst[_di++] = _src[_si++]; \
288 } \
289 while (0)
290 #else
291 # define COPY_CHAR_I(_dst, _di, _src, _srcend, _si) _dst[_di++] = _src[_si++]
292 #endif /* !HANDLE_MULTIBYTE */
293
294 /****************************************************************
295 * *
296 * The following are only guaranteed to work in subst.c *
297 * *
298 ****************************************************************/
299
300 #if defined (HANDLE_MULTIBYTE)
301 # define SCOPY_CHAR_I(_dst, _escchar, _sc, _src, _si, _slen) \
302 do \
303 { \
304 if (MB_CUR_MAX > 1) \
305 { \
306 mbstate_t state_bak; \
307 size_t mblength; \
308 int _i; \
309 \
310 state_bak = state; \
311 mblength = mbrlen ((_src) + (_si), (_slen) - (_si), &state); \
312 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
313 { \
314 state = state_bak; \
315 mblength = 1; \
316 } \
317 else \
318 mblength = (mblength < 1) ? 1 : mblength; \
319 \
320 temp = xmalloc (mblength + 2); \
321 temp[0] = _escchar; \
322 for (_i = 0; _i < mblength; _i++) \
323 temp[_i + 1] = _src[_si++]; \
324 temp[mblength + 1] = '\0'; \
325 \
326 goto add_string; \
327 } \
328 else \
329 { \
330 _dst[0] = _escchar; \
331 _dst[1] = _sc; \
332 } \
333 } \
334 while (0)
335 #else
336 # define SCOPY_CHAR_I(_dst, _escchar, _sc, _src, _si, _slen) \
337 _dst[0] = _escchar; \
338 _dst[1] = _sc
339 #endif /* !HANDLE_MULTIBYTE */
340
341 #if defined (HANDLE_MULTIBYTE)
342 # define SCOPY_CHAR_M(_dst, _src, _srcend, _si) \
343 do \
344 { \
345 if (MB_CUR_MAX > 1) \
346 { \
347 mbstate_t state_bak; \
348 size_t mblength; \
349 \
350 state_bak = state; \
351 mblength = mbrlen ((_src) + (_si), (_srcend) - ((_src) + (_si)), &state); \
352 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
353 { \
354 state = state_bak; \
355 mblength = 1; \
356 } \
357 else \
358 mblength = (mblength < 1) ? 1 : mblength; \
359 \
360 FASTCOPY(((_src) + (_si)), (_dst), mblength); \
361 \
362 (_dst) += mblength; \
363 (_si) += mblength; \
364 } \
365 else \
366 { \
367 *(_dst)++ = _src[(_si)]; \
368 (_si)++; \
369 } \
370 } \
371 while (0)
372 #else
373 # define SCOPY_CHAR_M(_dst, _src, _srcend, _si) \
374 *(_dst)++ = _src[(_si)]; \
375 (_si)++
376 #endif /* !HANDLE_MULTIBYTE */
377
378 #if HANDLE_MULTIBYTE
379 # define SADD_MBCHAR(_dst, _src, _si, _srcsize) \
380 do \
381 { \
382 if (MB_CUR_MAX > 1) \
383 { \
384 int i; \
385 mbstate_t state_bak; \
386 size_t mblength; \
387 \
388 state_bak = state; \
389 mblength = mbrlen ((_src) + (_si), (_srcsize) - (_si), &state); \
390 if (mblength == (size_t)-1 || mblength == (size_t)-2) \
391 { \
392 state = state_bak; \
393 mblength = 1; \
394 } \
395 if (mblength < 1) \
396 mblength = 1; \
397 \
398 _dst = (char *)xmalloc (mblength + 1); \
399 for (i = 0; i < mblength; i++) \
400 (_dst)[i] = (_src)[(_si)++]; \
401 (_dst)[mblength] = '\0'; \
402 \
403 goto add_string; \
404 } \
405 } \
406 while (0)
407
408 #else
409 # define SADD_MBCHAR(_dst, _src, _si, _srcsize)
410 #endif
411
412 /* Watch out when using this -- it's just straight textual subsitution */
413 #if defined (HANDLE_MULTIBYTE)
414 # define SADD_MBQCHAR_BODY(_dst, _src, _si, _srcsize) \
415 \
416 int i; \
417 mbstate_t state_bak; \
418 size_t mblength; \
419 \
420 state_bak = state; \
421 mblength = mbrlen ((_src) + (_si), (_srcsize) - (_si), &state); \
422 if (mblength == (size_t)-1 || mblength == (size_t)-2) \
423 { \
424 state = state_bak; \
425 mblength = 1; \
426 } \
427 if (mblength < 1) \
428 mblength = 1; \
429 \
430 (_dst) = (char *)xmalloc (mblength + 2); \
431 (_dst)[0] = CTLESC; \
432 for (i = 0; i < mblength; i++) \
433 (_dst)[i+1] = (_src)[(_si)++]; \
434 (_dst)[mblength+1] = '\0'; \
435 \
436 goto add_string
437
438 #endif /* HANDLE_MULTIBYTE */
439 #endif /* _SH_MBUTIL_H_ */