Update.
[glibc.git] / locale / programs / stringtrans.c
blobb810129678e09d351b36e1f5f94d0d8dddf2784f
1 /* Copyright (C) 1996, 1997, 1998 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 not,
17 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 char *cp; \
43 if (bufact + (encoding_method == ENC_UCS4 ? 4 : 1) >= bufmax) \
44 { \
45 bufmax *= 2; \
46 buf = xrealloc (buf, bufmax); \
47 } \
48 cp = &buf[bufact]; \
49 if (encode_char (ch, &cp) < 0) \
50 { \
51 free (buf); \
52 return NULL; \
53 } \
54 bufact = cp - buf; \
55 } \
56 while (0)
59 char *
60 translate_string (char *str, struct charset_t *charset)
62 char *buf;
63 size_t bufact = 0;
64 size_t bufmax = 56;
66 buf = (char *) xmalloc (bufmax);
68 while (str[0] != '\0')
70 char *tp;
71 unsigned int value;
73 if (str[0] != '<')
75 ADDC (*str++);
76 continue;
79 tp = &str[1];
80 while (tp[0] != '\0' && tp[0] != '>')
81 if (tp[0] == '\\')
82 if (tp[1] != '\0')
83 tp += 2;
84 else
85 ++tp;
86 else
87 ++tp;
89 if (tp[0] == '\0')
91 free (buf);
92 return NULL;
95 value = charset_find_value (&charset->char_table, str + 1,
96 tp - (str + 1));
97 if ((wchar_t) value == ILLEGAL_CHAR_VALUE)
99 free (buf);
100 return NULL;
102 else
103 /* Encode string using current method. */
104 ADDC (value);
106 str = &tp[1];
109 ADDC ('\0');
111 return buf;
116 encode_char (unsigned int value, char **cpp)
118 switch (encoding_method)
120 case ENC_UCS1:
121 if (value > 255)
122 return -1;
123 *(*cpp)++ = (char) value;
124 break;
126 case ENC_UCS4:
127 #if __BYTE_ORDER == __BIG_ENDIAN
128 *(*cpp)++ = (char) (value >> 24);
129 *(*cpp)++ = (char) ((value >> 16) & 0xff);
130 *(*cpp)++ = (char) ((value >> 8) & 0xff);
131 *(*cpp)++ = (char) (value & 0xff);
132 #else
133 *(*cpp)++ = (char) (value & 0xff);
134 *(*cpp)++ = (char) ((value >>= 8) & 0xff);
135 *(*cpp)++ = (char) ((value >>= 8) & 0xff);
136 *(*cpp)++ = (char) ((value >>= 8) & 0xff);
137 #endif
138 break;
140 default:
141 return -1;
144 return 0;