Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dthelp / parser.ccdf / htag / util / wchar.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: wchar.c /main/3 1995/11/08 11:46:43 rswiston $ */
24 /*
25                Copyright 1992 Hewlett-Packard Co.
26 */
27
28 #include "basic.h"
29
30
31 /* compare two wide character strings */
32 #if defined(M_PROTO)
33 int w_strcmp(const M_WCHAR *string1, const M_WCHAR *string2)
34 #else
35 int w_strcmp(string1, string2)
36 M_WCHAR *string1;
37 M_WCHAR *string2;
38 #endif
39 {
40 M_WCHAR c1, c2, null;
41
42 if (string1 == string2) return 0;
43
44 null = (M_WCHAR) 0;
45 if (!string1) string1 = &null;
46 if (!string2) string2 = &null;
47
48 while (1)
49     {
50     c1 = *string1++;
51     c2 = *string2++;
52     if (c1 < c2) return -1;
53     if (c1 > c2) return  1;
54     if (!c1) return 0;
55     }
56 }
57
58
59 /* copy a wide character string */
60 #if defined(M_PROTO)
61 M_WCHAR *w_strcpy(M_WCHAR *string1, const M_WCHAR *string2)
62 #else
63 M_WCHAR *w_strcpy(string1, string2)
64 M_WCHAR *string1;
65 M_WCHAR *string2;
66 #endif
67 {
68 M_WCHAR *string1start;
69
70 string1start = string1;
71
72 while (*string1++ = *string2++);
73
74 return string1start;
75 }
76
77
78 /* copy a wide character string, stopping after "max" moves */
79 #if defined(M_PROTO)
80 M_WCHAR *w_strncpy(M_WCHAR *string1, const M_WCHAR *string2, int max)
81 #else
82 M_WCHAR *w_strncpy(string1, string2, max)
83 M_WCHAR *string1;
84 M_WCHAR *string2;
85 int      max;
86 #endif
87 {
88 M_WCHAR *string1start;
89
90 string1start = string1;
91
92 while ((--max >= 0) && (*string1++ = *string2++));
93
94 return string1start;
95 }
96
97
98 /* get the length of a wide character string */
99 #if defined(M_PROTO)
100 int w_strlen(const M_WCHAR *string)
101 #else
102 int w_strlen(string)
103 M_WCHAR *string;
104 #endif
105 {
106 int length;
107
108 length = 0;
109 if (string)
110     while (*string++) length++;
111
112 return length;
113 }
114
115
116 /* find wide character "chr" in wide string "string" */
117 #if defined(M_PROTO)
118 M_WCHAR *w_strchr(M_WCHAR *string, const M_WCHAR chr)
119 #else
120 M_WCHAR *w_strchr(string, chr)
121 M_WCHAR *string, chr;
122 #endif
123 {
124 M_WCHAR *where;
125
126 where = string;
127
128 while (*where)
129     {
130     if (*where == chr) return where;
131     where++;
132     }
133
134 if (!chr)
135     return where;
136 else
137     return NULL;
138 }
139
140
141 /* find wide character "chr" in wide string "string" */
142 #if defined(M_PROTO)
143 M_WCHAR *w_strstr(M_WCHAR *string1, M_WCHAR *string2)
144 #else
145 M_WCHAR *w_strstr(string1, string2)
146 M_WCHAR *string1, *string2;
147 #endif
148 {
149 M_WCHAR *where1, *where2;
150
151 if (!*string2) return string1;
152
153 where1 = string1;
154 where2 = string2;
155
156 while (*where1)
157     {
158     if (*where1 == *where2)
159         {
160         string1 = where1;
161
162         while (*where1 && *where2 && (*where1 == *where2))
163             {
164             where1++;
165             where2++;
166             }
167         
168         if (!*where2) return string1;
169         if (!*where1) return NULL;
170
171         where1 = string1;
172         where2 = string2;
173         }
174     where1++;
175     }
176
177 return NULL;
178 }
179
180
181 /* make a multi-byte string from a wide character string */
182 #if defined(M_PROTO)
183 char *MakeMByteString(const M_WCHAR *wc_string)
184 #else
185 char *MakeMByteString(wc_string)
186 M_WCHAR *wc_string;
187 #endif
188 {
189 char   *mb_string;
190 int     length;
191 M_WCHAR wc;
192
193 /* Do a little work to compensate for m_malloc allocating sizeof(M_WCHAR)
194  * bytes for each increment in the size requested.
195 */
196 length = (w_strlen(wc_string) * MB_CUR_MAX) + 1;
197 length = (length + sizeof(M_WCHAR) - 1) / sizeof(M_WCHAR);
198 mb_string = (char *) m_malloc(length, "multi-byte string");
199
200 length = 0;
201 while (wc = *wc_string++)
202     {
203     length += wctomb(&mb_string[length], wc);
204     }
205 mb_string[length] = 0;
206
207 return mb_string;
208 }
209
210
211 /* make a wide character string from a multi-byte string */
212 #if defined(M_PROTO)
213 M_WCHAR *MakeWideCharString(const char *mb_string)
214 #else
215 M_WCHAR *MakeWideCharString(mb_string)
216 char *mb_string;
217 #endif
218 {
219 M_WCHAR *wc_string, *wc_stringStart;
220 int      length, incr;
221 char     c;
222
223 length = strlen(mb_string);
224 wc_stringStart = wc_string =
225     (M_WCHAR *) m_malloc(length + 1, "wide character string");
226
227 length = 0;
228 while (mb_string[length])
229     {
230     if ((incr = mbtowc(wc_string, &mb_string[length], MB_CUR_MAX)) < 0)
231         {
232         char badOne[2], buffer[32];
233
234         badOne[0] = mb_string[length];
235         badOne[1] = 0;
236         sprintf(buffer, "0x%x", mb_string[length]);
237         m_err2("invalid multibyte character found: '%c' (%s)", badOne, buffer);
238         incr = 1;
239         }
240     length += incr;
241     wc_string++;
242     }
243 *wc_string = (M_WCHAR) 0;
244
245 return wc_stringStart;
246 }
247
248
249 /* Get-wide-char procedure */
250 int mb_getwc(m_ptr)
251 void *m_ptr;
252 {
253 int  c;
254 M_WCHAR wc;
255 char badch[2];
256 char mbyte[32]; /* make this bigger than any possible multi-byte char */
257 int  length;
258
259 length = 0;
260 if ((c = getc((FILE *) m_ptr)) == EOF) return(EOF);
261
262 while (1)
263     {
264     mbyte[length++] = c;
265     mbyte[length]   = 0;
266     if (mblen(mbyte,length) != -1) break; /* hurray! */
267     if (length == MB_CUR_MAX)
268         { /* reached max without a hit */
269         m_error("An invalid multi-byte character was found in the input");
270         c = ' ';
271         length = 1;
272         break;
273         }
274     if ((c = getc((FILE *) m_ptr)) == EOF)
275         { /* huh? */
276         m_error("End-of-file found in within a multi-byte character");
277         return(EOF);
278         }
279     }
280 mbtowc(&wc,mbyte,length);
281
282 return((int) wc);
283 }