Upload Tizen:Base source
[external/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
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 */
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 #define MBLEN(s, n)     ((MB_CUR_MAX > 1) ? mblen ((s), (n)) : 1)
47 #define MBRLEN(s, n, p) ((MB_CUR_MAX > 1) ? mbrlen ((s), (n), (p)) : 1)
48
49 #else /* !HANDLE_MULTIBYTE */
50
51 #undef MB_LEN_MAX
52 #undef MB_CUR_MAX
53
54 #define MB_LEN_MAX      1
55 #define MB_CUR_MAX      1
56
57 #undef xstrchr
58 #define xstrchr(s, c)   strchr(s, c)
59
60 #ifndef MB_INVALIDCH
61 #define MB_INVALIDCH(x)         (0)
62 #define MB_NULLWCH(x)           (0)
63 #endif
64
65 #define MB_STRLEN(s)            (STRLEN(s))
66
67 #define MBLEN(s, n)             1
68 #define MBRLEN(s, n, p)         1
69
70 #ifndef wchar_t
71 #  define wchar_t       int
72 #endif
73
74 #endif /* !HANDLE_MULTIBYTE */
75
76 /* Declare and initialize a multibyte state.  Call must be terminated
77    with `;'. */
78 #if defined (HANDLE_MULTIBYTE)
79 #  define DECLARE_MBSTATE \
80         mbstate_t state; \
81         memset (&state, '\0', sizeof (mbstate_t))
82 #else
83 #  define DECLARE_MBSTATE
84 #endif  /* !HANDLE_MULTIBYTE */
85
86 /* Initialize or reinitialize a multibyte state named `state'.  Call must be
87    terminated with `;'. */
88 #if defined (HANDLE_MULTIBYTE)
89 #  define INITIALIZE_MBSTATE memset (&state, '\0', sizeof (mbstate_t))
90 #else
91 #  define INITIALIZE_MBSTATE
92 #endif  /* !HANDLE_MULTIBYTE */
93
94 /* Advance one (possibly multi-byte) character in string _STR of length
95    _STRSIZE, starting at index _I.  STATE must have already been declared. */
96 #if defined (HANDLE_MULTIBYTE)
97 #  define ADVANCE_CHAR(_str, _strsize, _i) \
98     do \
99       { \
100         if (MB_CUR_MAX > 1) \
101           { \
102             mbstate_t state_bak; \
103             size_t mblength; \
104 \
105             state_bak = state; \
106             mblength = mbrlen ((_str) + (_i), (_strsize) - (_i), &state); \
107 \
108             if (mblength == (size_t)-2 || mblength == (size_t)-1) \
109               { \
110                 state = state_bak; \
111                 (_i)++; \
112               } \
113             else if (mblength == 0) \
114               (_i)++; \
115             else \
116               (_i) += mblength; \
117           } \
118         else \
119           (_i)++; \
120       } \
121     while (0)
122 #else
123 #  define ADVANCE_CHAR(_str, _strsize, _i)      (_i)++
124 #endif  /* !HANDLE_MULTIBYTE */
125
126 /* Advance one (possibly multibyte) character in the string _STR of length
127    _STRSIZE.
128    SPECIAL:  assume that _STR will be incremented by 1 after this call. */
129 #if defined (HANDLE_MULTIBYTE)
130 #  define ADVANCE_CHAR_P(_str, _strsize) \
131     do \
132       { \
133         if (MB_CUR_MAX > 1) \
134           { \
135             mbstate_t state_bak; \
136             size_t mblength; \
137 \
138             state_bak = state; \
139             mblength = mbrlen ((_str), (_strsize), &state); \
140 \
141             if (mblength == (size_t)-2 || mblength == (size_t)-1) \
142               { \
143                 state = state_bak; \
144                 mblength = 1; \
145               } \
146             else \
147               (_str) += (mblength < 1) ? 0 : (mblength - 1); \
148           } \
149       } \
150     while (0)
151 #else
152 #  define ADVANCE_CHAR_P(_str, _strsize)
153 #endif  /* !HANDLE_MULTIBYTE */
154
155 /* Back up one (possibly multi-byte) character in string _STR of length
156    _STRSIZE, starting at index _I.  STATE must have already been declared. */
157 #if defined (HANDLE_MULTIBYTE)
158 #  define BACKUP_CHAR(_str, _strsize, _i) \
159     do \
160       { \
161         if (MB_CUR_MAX > 1) \
162           { \
163             mbstate_t state_bak; \
164             size_t mblength; \
165             int _x, _p; /* _x == temp index into string, _p == prev index */ \
166 \
167             _x = _p = 0; \
168             while (_x < (_i)) \
169               { \
170                 state_bak = state; \
171                 mblength = mbrlen ((_str) + (_x), (_strsize) - (_x), &state); \
172 \
173                 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
174                   { \
175                     state = state_bak; \
176                     _x++; \
177                   } \
178                 else if (mblength == 0) \
179                   _x++; \
180                 else \
181                   { \
182                     _p = _x; /* _p == start of prev mbchar */ \
183                     _x += mblength; \
184                   } \
185               } \
186             (_i) = _p; \
187           } \
188         else \
189           (_i)--; \
190       } \
191     while (0)
192 #else
193 #  define BACKUP_CHAR(_str, _strsize, _i)       (_i)--
194 #endif  /* !HANDLE_MULTIBYTE */
195
196 /* Back up one (possibly multibyte) character in the string _BASE of length
197    _STRSIZE starting at _STR (_BASE <= _STR <= (_BASE + _STRSIZE) ).
198    SPECIAL: DO NOT assume that _STR will be decremented by 1 after this call. */
199 #if defined (HANDLE_MULTIBYTE)
200 #  define BACKUP_CHAR_P(_base, _strsize, _str) \
201     do \
202       { \
203         if (MB_CUR_MAX > 1) \
204           { \
205             mbstate_t state_bak; \
206             size_t mblength; \
207             char *_x, _p; /* _x == temp pointer into string, _p == prev pointer */ \
208 \
209             _x = _p = _base; \
210             while (_x < (_str)) \
211               { \
212                 state_bak = state; \
213                 mblength = mbrlen (_x, (_strsize) - _x, &state); \
214 \
215                 if (mblength == (size_t)-2 || mblength == (size_t)-1) \
216                   { \
217                     state = state_bak; \
218                     _x++; \
219                   } \
220                 else if (mblength == 0) \
221                   _x++; \
222                 else \
223                   { \
224                     _p = _x; /* _p == start of prev mbchar */ \
225                     _x += mblength; \
226                   } \
227               } \
228             (_str) = _p; \
229           } \
230         else \
231           (_str)--; \
232       } \
233     while (0)
234 #else
235 #  define BACKUP_CHAR_P(_base, _strsize, _str) (_str)--
236 #endif  /* !HANDLE_MULTIBYTE */
237
238 /* Copy a single character from the string _SRC to the string _DST.
239    _SRCEND is a pointer to the end of _SRC. */
240 #if defined (HANDLE_MULTIBYTE)
241 #  define COPY_CHAR_P(_dst, _src, _srcend) \
242     do \
243       { \
244         if (MB_CUR_MAX > 1) \
245           { \
246             mbstate_t state_bak; \
247             size_t mblength; \
248             int _k; \
249 \
250             state_bak = state; \
251             mblength = mbrlen ((_src), (_srcend) - (_src), &state); \
252             if (mblength == (size_t)-2 || mblength == (size_t)-1) \
253               { \
254                 state = state_bak; \
255                 mblength = 1; \
256               } \
257             else \
258               mblength = (mblength < 1) ? 1 : mblength; \
259 \
260             for (_k = 0; _k < mblength; _k++) \
261               *(_dst)++ = *(_src)++; \
262           } \
263         else \
264           *(_dst)++ = *(_src)++; \
265       } \
266     while (0)
267 #else
268 #  define COPY_CHAR_P(_dst, _src, _srcend)      *(_dst)++ = *(_src)++
269 #endif  /* !HANDLE_MULTIBYTE */
270
271 /* Copy a single character from the string _SRC at index _SI to the string
272    _DST at index _DI.  _SRCEND is a pointer to the end of _SRC. */
273 #if defined (HANDLE_MULTIBYTE)
274 #  define COPY_CHAR_I(_dst, _di, _src, _srcend, _si) \
275     do \
276       { \
277         if (MB_CUR_MAX > 1) \
278           { \
279             mbstate_t state_bak; \
280             size_t mblength; \
281             int _k; \
282 \
283             state_bak = state; \
284             mblength = mbrlen ((_src) + (_si), (_srcend) - ((_src)+(_si)), &state); \
285             if (mblength == (size_t)-2 || mblength == (size_t)-1) \
286               { \
287                 state = state_bak; \
288                 mblength = 1; \
289               } \
290             else \
291               mblength = (mblength < 1) ? 1 : mblength; \
292 \
293             for (_k = 0; _k < mblength; _k++) \
294               _dst[_di++] = _src[_si++]; \
295           } \
296         else \
297           _dst[_di++] = _src[_si++]; \
298       } \
299     while (0)
300 #else
301 #  define COPY_CHAR_I(_dst, _di, _src, _srcend, _si)    _dst[_di++] = _src[_si++]
302 #endif  /* !HANDLE_MULTIBYTE */
303
304 /****************************************************************
305  *                                                              *
306  * The following are only guaranteed to work in subst.c         *
307  *                                                              *
308  ****************************************************************/
309
310 #if defined (HANDLE_MULTIBYTE)
311 #  define SCOPY_CHAR_I(_dst, _escchar, _sc, _src, _si, _slen) \
312     do \
313       { \
314         if (MB_CUR_MAX > 1) \
315           { \
316             mbstate_t state_bak; \
317             size_t mblength; \
318             int _i; \
319 \
320             state_bak = state; \
321             mblength = mbrlen ((_src) + (_si), (_slen) - (_si), &state); \
322             if (mblength == (size_t)-2 || mblength == (size_t)-1) \
323               { \
324                 state = state_bak; \
325                 mblength = 1; \
326               } \
327             else \
328               mblength = (mblength < 1) ? 1 : mblength; \
329 \
330             temp = xmalloc (mblength + 2); \
331             temp[0] = _escchar; \
332             for (_i = 0; _i < mblength; _i++) \
333               temp[_i + 1] = _src[_si++]; \
334             temp[mblength + 1] = '\0'; \
335 \
336             goto add_string; \
337           } \
338         else \
339           { \
340             _dst[0] = _escchar; \
341             _dst[1] = _sc; \
342           } \
343       } \
344     while (0)
345 #else
346 #  define SCOPY_CHAR_I(_dst, _escchar, _sc, _src, _si, _slen) \
347     _dst[0] = _escchar; \
348     _dst[1] = _sc
349 #endif  /* !HANDLE_MULTIBYTE */
350
351 #if defined (HANDLE_MULTIBYTE)
352 #  define SCOPY_CHAR_M(_dst, _src, _srcend, _si) \
353     do \
354       { \
355         if (MB_CUR_MAX > 1) \
356           { \
357             mbstate_t state_bak; \
358             size_t mblength; \
359 \
360             state_bak = state; \
361             mblength = mbrlen ((_src) + (_si), (_srcend) - ((_src) + (_si)), &state); \
362             if (mblength == (size_t)-2 || mblength == (size_t)-1) \
363               { \
364                 state = state_bak; \
365                 mblength = 1; \
366               } \
367             else \
368               mblength = (mblength < 1) ? 1 : mblength; \
369 \
370             FASTCOPY(((_src) + (_si)), (_dst), mblength); \
371 \
372             (_dst) += mblength; \
373             (_si) += mblength; \
374           } \
375         else \
376           { \
377             *(_dst)++ = _src[(_si)]; \
378             (_si)++; \
379           } \
380       } \
381     while (0)
382 #else
383 #  define SCOPY_CHAR_M(_dst, _src, _srcend, _si) \
384         *(_dst)++ = _src[(_si)]; \
385         (_si)++
386 #endif  /* !HANDLE_MULTIBYTE */
387
388 #if HANDLE_MULTIBYTE
389 #  define SADD_MBCHAR(_dst, _src, _si, _srcsize) \
390     do \
391       { \
392         if (MB_CUR_MAX > 1) \
393           { \
394             int i; \
395             mbstate_t state_bak; \
396             size_t mblength; \
397 \
398             state_bak = state; \
399             mblength = mbrlen ((_src) + (_si), (_srcsize) - (_si), &state); \
400             if (mblength == (size_t)-1 || mblength == (size_t)-2) \
401               { \
402                 state = state_bak; \
403                 mblength = 1; \
404               } \
405             if (mblength < 1) \
406               mblength = 1; \
407 \
408             _dst = (char *)xmalloc (mblength + 1); \
409             for (i = 0; i < mblength; i++) \
410               (_dst)[i] = (_src)[(_si)++]; \
411             (_dst)[mblength] = '\0'; \
412 \
413             goto add_string; \
414           } \
415       } \
416     while (0)
417
418 #else
419 #  define SADD_MBCHAR(_dst, _src, _si, _srcsize)
420 #endif
421
422 /* Watch out when using this -- it's just straight textual subsitution */
423 #if defined (HANDLE_MULTIBYTE)
424 #  define SADD_MBQCHAR_BODY(_dst, _src, _si, _srcsize) \
425 \
426             int i; \
427             mbstate_t state_bak; \
428             size_t mblength; \
429 \
430             state_bak = state; \
431             mblength = mbrlen ((_src) + (_si), (_srcsize) - (_si), &state); \
432             if (mblength == (size_t)-1 || mblength == (size_t)-2) \
433               { \
434                 state = state_bak; \
435                 mblength = 1; \
436               } \
437             if (mblength < 1) \
438               mblength = 1; \
439 \
440             (_dst) = (char *)xmalloc (mblength + 2); \
441             (_dst)[0] = CTLESC; \
442             for (i = 0; i < mblength; i++) \
443               (_dst)[i+1] = (_src)[(_si)++]; \
444             (_dst)[mblength+1] = '\0'; \
445 \
446             goto add_string
447
448 #endif /* HANDLE_MULTIBYTE */
449 #endif /* _SH_MBUTIL_H_ */