* posix/glob.h (__glob_opendir_hook, __glob_readdir_hook,
[glibc.git] / locale / programs / stringtrans.c
blob10b04fa62eb2e9ff588feb8fb1efe1d75eaf6da9
1 /* Copyright (C) 1996 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If
17 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
24 #include <assert.h>
25 #include <stdlib.h>
27 #include "charset.h"
28 #include "stringtrans.h"
31 /* Global variable. */
32 enum encoding_method encoding_method = ENC_UCS4;
35 void *xmalloc (size_t __n);
36 void *xrealloc (void *__p, size_t __n);
39 #define ADDC(ch) \
40 do \
41 { \
42 if (bufact == bufmax) \
43 { \
44 bufmax *= 2; \
45 buf = xrealloc (buf, bufmax); \
46 } \
47 buf[bufact++] = (ch); \
48 } \
49 while (0)
52 char *
53 translate_string (char *str, struct charset_t *charset)
55 char *buf;
56 size_t bufact = 0;
57 size_t bufmax = 56;
59 buf = (char *) xmalloc (bufmax);
61 while (str[0] != '\0')
63 char *tp;
64 unsigned int value;
66 if (str[0] != '<')
68 ADDC (*str++);
69 continue;
72 tp = &str[1];
73 while (tp[0] != '\0' && tp[0] != '>')
74 if (tp[0] == '\\')
75 if (tp[1] != '\0')
76 tp += 2;
77 else
78 ++tp;
79 else
80 ++tp;
82 if (tp[0] == '\0')
84 free (buf);
85 return NULL;
88 value = charset_find_value (charset, str + 1, tp - (str + 1));
89 if (value == ILLEGAL_CHAR_VALUE)
91 free (buf);
92 return NULL;
94 else
96 /* Encode string using current method. */
97 char *cp;
99 if (bufmax - bufact < 8)
101 bufmax *= 2;
102 buf = (char *) xrealloc (buf, bufmax);
105 cp = &buf[bufact];
106 if (encode_char (value, &cp) < 0)
108 free (buf);
109 return NULL;
111 bufact = cp - buf;
114 str = &tp[1];
117 ADDC ('\0');
119 return buf;;
124 encode_char (unsigned int value, char **cpp)
126 switch (encoding_method)
128 case ENC_UCS1:
129 if (value > 255)
130 return -11;
131 *(*cpp)++ = (char) value;
132 break;
134 case ENC_UCS4:
135 *(*cpp)++ = (char) (value >> 24);
136 *(*cpp)++ = (char) ((value >> 16) & 0xff);
137 *(*cpp)++ = (char) ((value >> 8) & 0xff);
138 *(*cpp)++ = (char) (value & 0xff);
139 break;
141 default:
142 return -1;
145 return 0;