Merge branch 'linux1'
[oweals/cde.git] / cde / programs / dthelp / parser / pass2 / 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:09:48 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 /* compare two wide character strings to length "n" */
60 #if defined(M_PROTO)
61 int w_strncmp(const M_WCHAR *string1, const M_WCHAR *string2, int max)
62 #else
63 int w_strcmp(string1, string2, max)
64 M_WCHAR *string1;
65 M_WCHAR *string2;
66 int      max;
67 #endif
68 {
69 M_WCHAR c1, c2, null;
70
71 if (string1 == string2) return 0;
72 if (max <= 0) return 0;
73
74 null = (M_WCHAR) 0;
75 if (!string1) string1 = &null;
76 if (!string2) string2 = &null;
77
78 while (--max >= 0)
79     {
80     c1 = *string1++;
81     c2 = *string2++;
82     if (c1 < c2) return -1;
83     if (c1 > c2) return  1;
84     if (!c1) return 0;
85     }
86 return 0;
87 }
88
89
90 /* copy a wide character string */
91 #if defined(M_PROTO)
92 M_WCHAR *w_strcpy(M_WCHAR *string1, const M_WCHAR *string2)
93 #else
94 M_WCHAR *w_strcpy(string1, string2)
95 M_WCHAR *string1;
96 M_WCHAR *string2;
97 #endif
98 {
99 M_WCHAR *string1start;
100
101 string1start = string1;
102
103 while (*string1++ = *string2++);
104
105 return string1start;
106 }
107
108
109 /* copy a wide character string, stopping after "max" moves */
110 #if defined(M_PROTO)
111 M_WCHAR *w_strncpy(M_WCHAR *string1, const M_WCHAR *string2, int max)
112 #else
113 M_WCHAR *w_strncpy(string1, string2, max)
114 M_WCHAR *string1;
115 M_WCHAR *string2;
116 int      max;
117 #endif
118 {
119 M_WCHAR *string1start;
120
121 string1start = string1;
122
123 while ((--max >= 0) && (*string1++ = *string2++));
124
125 return string1start;
126 }
127
128
129 /* get the length of a wide character string */
130 #if defined(M_PROTO)
131 int w_strlen(const M_WCHAR *string)
132 #else
133 int w_strlen(string)
134 M_WCHAR *string;
135 #endif
136 {
137 int length;
138
139 length = 0;
140 if (string)
141     while (*string++) length++;
142
143 return length;
144 }
145
146
147 /* find wide character "chr" in wide string "string" */
148 #if defined(M_PROTO)
149 M_WCHAR *w_strchr(M_WCHAR *string, const M_WCHAR chr)
150 #else
151 M_WCHAR *w_strchr(string, chr)
152 M_WCHAR *string, chr;
153 #endif
154 {
155 M_WCHAR *where;
156
157 where = string;
158
159 while (*where)
160     {
161     if (*where == chr) return where;
162     where++;
163     }
164
165 if (!chr)
166     return where;
167 else
168     return NULL;
169 }
170
171
172 /* find wide character "chr" in wide string "string" */
173 #if defined(M_PROTO)
174 M_WCHAR *w_strstr(M_WCHAR *string1, M_WCHAR *string2)
175 #else
176 M_WCHAR *w_strstr(string1, string2)
177 M_WCHAR *string1, *string2;
178 #endif
179 {
180 M_WCHAR *where1, *where2;
181
182 if (!*string2) return string1;
183
184 where1 = string1;
185 where2 = string2;
186
187 while (*where1)
188     {
189     if (*where1 == *where2)
190         {
191         string1 = where1;
192
193         while (*where1 && *where2 && (*where1 == *where2))
194             {
195             where1++;
196             where2++;
197             }
198         
199         if (!*where2) return string1;
200         if (!*where1) return NULL;
201
202         where1 = string1;
203         where2 = string2;
204         }
205     where1++;
206     }
207
208 return NULL;
209 }
210
211
212 /* make a multi-byte string from a wide character string */
213 #if defined(M_PROTO)
214 char *MakeMByteString(const M_WCHAR *wc_string)
215 #else
216 char *MakeMByteString(wc_string)
217 M_WCHAR *wc_string;
218 #endif
219 {
220 char   *mb_string;
221 int     length, retVal;
222 M_WCHAR wc;
223 static M_WCHAR empty[] = {0};
224
225 if (!wc_string)
226     wc_string = empty;
227
228 /* Do a little work to compensate for m_malloc allocating sizeof(M_WCHAR)
229  * bytes for each increment in the size requested.
230 */
231 length = (w_strlen(wc_string) * MB_CUR_MAX) + 1;
232 length = (length + sizeof(M_WCHAR) - 1) / sizeof(M_WCHAR);
233 mb_string = (char *) m_malloc(length, "multi-byte string");
234
235 length = 0;
236 while (wc = *wc_string++)
237     {
238     if ((retVal = wctomb(&mb_string[length], wc)) > 0)
239         length += retVal;
240     }
241 mb_string[length] = 0;
242
243 return mb_string;
244 }
245
246
247 /* make a wide character string from a multi-byte string */
248 #if defined(M_PROTO)
249 M_WCHAR *MakeWideCharString(const char *mb_string)
250 #else
251 M_WCHAR *MakeWideCharString(mb_string)
252 char *mb_string;
253 #endif
254 {
255 M_WCHAR *wc_string, *wc_stringStart;
256 int      length, incr;
257 char     c;
258
259 if (!mb_string)
260     mb_string = "";
261
262 length = strlen(mb_string);
263 wc_stringStart = wc_string =
264     (M_WCHAR *) m_malloc(length + 1, "wide character string");
265
266 length = 0;
267 while (mb_string[length])
268     {
269     if ((incr = mbtowc(wc_string, &mb_string[length], MB_CUR_MAX)) < 0)
270         {
271         char badOne[2], buffer[32];
272
273         badOne[0] = mb_string[length];
274         badOne[1] = 0;
275         sprintf(buffer, "0x%x", mb_string[length]);
276         m_err2("invalid multibyte character found: '%c' (%s)", badOne, buffer);
277         incr = 1;
278         }
279     length += incr;
280     wc_string++;
281     }
282 *wc_string = (M_WCHAR) 0;
283
284 return wc_stringStart;
285 }
286
287
288 /* Get-wide-char procedure */
289 int mb_getwc(m_ptr)
290 void *m_ptr;
291 {
292 int  c;
293 M_WCHAR wc;
294 char badch[2];
295 char mbyte[32]; /* make this bigger than any possible multi-byte char */
296 int  length;
297
298 length = 0;
299 if ((c = getc((FILE *) m_ptr)) == EOF) return(EOF);
300
301 while (1)
302     {
303     mbyte[length++] = c;
304     mbyte[length]   = 0;
305     if (mblen(mbyte,length) != -1) break; /* hurray! */
306     if (length == MB_CUR_MAX)
307         { /* reached max without a hit */
308         m_error("An invalid multi-byte character was found in the input");
309         c = ' ';
310         length = 1;
311         break;
312         }
313     if ((c = getc((FILE *) m_ptr)) == EOF)
314         { /* huh? */
315         m_error("End-of-file found in within a multi-byte character");
316         return(EOF);
317         }
318     }
319 mbtowc(&wc,mbyte,length);
320
321 return((int) wc);
322 }