source: trunk/tools/wrc/utils.c@ 10367

Last change on this file since 10367 was 8938, checked in by sandervl, 23 years ago

PF: Unicode update

File size: 12.0 KB
Line 
1/*
2 * Utility routines
3 *
4 * Copyright 1998 Bertho A. Stultiens
5 *
6 */
7
8#include "config.h"
9
10#include <assert.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <stdarg.h>
14#include <string.h>
15#include <assert.h>
16#include <ctype.h>
17
18#include "wine/unicode.h"
19#include "wrc.h"
20#include "utils.h"
21#include "parser.h"
22#include "preproc.h"
23
24
25/*
26 * Ease debugging on OS/2.
27 */
28#if defined(__DEBUG_ALLOC__) && defined(__IBMC__)
29#undef malloc
30#define malloc(a) _debug_malloc(a, pszFile, iLine)
31#undef realloc
32#define realloc(a,b) _debug_realloc(a, b, pszFile, iLine)
33#endif
34
35
36/* #define WANT_NEAR_INDICATION */
37
38static const union cptable *current_codepage;
39
40#ifdef WANT_NEAR_INDICATION
41void make_print(char *str)
42{
43 while(*str)
44 {
45 if(!isprint(*str))
46 *str = ' ';
47 str++;
48 }
49}
50#endif
51
52static void generic_msg(const char *s, const char *t, const char *n, va_list ap)
53{
54 fprintf(stderr, "%s:%d:%d: %s: ", input_name ? input_name : "stdin", line_number, char_number, t);
55 vfprintf(stderr, s, ap);
56#ifdef WANT_NEAR_INDICATION
57 {
58 char *cpy;
59 if(n)
60 {
61 cpy = xstrdup(n);
62 make_print(cpy);
63 fprintf(stderr, " near '%s'", cpy);
64 free(cpy);
65 }
66 }
67#endif
68 fprintf(stderr, "\n");
69}
70
71
72int yyerror(const char *s, ...)
73{
74 va_list ap;
75 va_start(ap, s);
76 generic_msg(s, "Error", yytext, ap);
77 va_end(ap);
78 exit(1);
79 return 1;
80}
81
82int yywarning(const char *s, ...)
83{
84 va_list ap;
85 va_start(ap, s);
86 generic_msg(s, "Warning", yytext, ap);
87 va_end(ap);
88 return 0;
89}
90
91int pperror(const char *s, ...)
92{
93 va_list ap;
94 va_start(ap, s);
95 generic_msg(s, "Error", pptext, ap);
96 va_end(ap);
97 exit(1);
98 return 1;
99}
100
101int ppwarning(const char *s, ...)
102{
103 va_list ap;
104 va_start(ap, s);
105 generic_msg(s, "Warning", pptext, ap);
106 va_end(ap);
107 return 0;
108}
109
110
111void internal_error(const char *file, int line, const char *s, ...)
112{
113 va_list ap;
114 va_start(ap, s);
115 fprintf(stderr, "Internal error (please report) %s %d: ", file, line);
116 vfprintf(stderr, s, ap);
117 fprintf(stderr, "\n");
118 va_end(ap);
119 exit(3);
120}
121
122void error(const char *s, ...)
123{
124 va_list ap;
125 va_start(ap, s);
126 fprintf(stderr, "Error: ");
127 vfprintf(stderr, s, ap);
128 fprintf(stderr, "\n");
129 va_end(ap);
130 exit(2);
131}
132
133void warning(const char *s, ...)
134{
135 va_list ap;
136 va_start(ap, s);
137 fprintf(stderr, "Warning: ");
138 vfprintf(stderr, s, ap);
139 fprintf(stderr, "\n");
140 va_end(ap);
141}
142
143void chat(const char *s, ...)
144{
145 if(debuglevel & DEBUGLEVEL_CHAT)
146 {
147 va_list ap;
148 va_start(ap, s);
149 fprintf(stderr, "FYI: ");
150 vfprintf(stderr, s, ap);
151 fprintf(stderr, "\n");
152 va_end(ap);
153 }
154}
155
156char *dup_basename(const char *name, const char *ext)
157{
158 int namelen;
159 int extlen = strlen(ext);
160 char *base;
161 char *slash;
162
163 if(!name)
164 name = "wrc.tab";
165
166 slash = strrchr(name, '/');
167 if (slash)
168 name = slash + 1;
169
170 namelen = strlen(name);
171
172 /* +4 for later extension and +1 for '\0' */
173 base = (char *)xmalloc(namelen +4 +1);
174 strcpy(base, name);
175 if(!strcasecmp(name + namelen-extlen, ext))
176 {
177 base[namelen - extlen] = '\0';
178 }
179 return base;
180}
181
182#if defined(__DEBUG_ALLOC__) && defined(__IBMC__)
183void *_xmalloc(size_t size, char *pszFile, int iLine)
184#else
185void *xmalloc(size_t size)
186#endif
187{
188 void *res;
189
190 assert(size > 0);
191 res = malloc(size);
192 if(res == NULL)
193 {
194 error("Virtual memory exhausted.\n");
195 }
196 /*
197 * We set it to 0.
198 * This is *paramount* because we depend on it
199 * just about everywhere in the rest of the code.
200 */
201 memset(res, 0, size);
202 return res;
203}
204
205
206
207#if defined(__DEBUG_ALLOC__) && defined(__IBMC__)
208void *_xrealloc(void *p, size_t size, char *pszFile, int iLine)
209#else
210void *xrealloc(void *p, size_t size)
211#endif
212{
213 void *res;
214
215 assert(size > 0);
216 res = realloc(p, size);
217 if(res == NULL)
218 {
219 error("Virtual memory exhausted.\n");
220 }
221 return res;
222}
223
224#if defined(__DEBUG_ALLOC__) && defined(__IBMC__)
225char *_xstrdup(const char *str, char *pszFile, int iLine)
226#else
227char *xstrdup(const char *str)
228#endif
229{
230 char *s;
231
232 assert(str != NULL);
233 #if defined(__DEBUG_ALLOC__) && defined(__IBMC__)
234 s = (char *)_xmalloc(strlen(str)+1, pszFile, iLine);
235 #else
236 s = (char *)xmalloc(strlen(str)+1);
237 #endif
238 return strcpy(s, str);
239}
240
241short *dupcstr2wstr(const char *str)
242{
243 int len;
244 WCHAR *ws;
245
246 if (!current_codepage) set_language( LANG_NEUTRAL, SUBLANG_NEUTRAL );
247 len = cp_mbstowcs( current_codepage, 0, str, strlen(str), NULL, 0 );
248 ws = xmalloc( sizeof(WCHAR) * (len + 1) );
249 len = cp_mbstowcs( current_codepage, 0, str, strlen(str), ws, len );
250 ws[len] = 0;
251 return ws;
252}
253
254char *dupwstr2cstr(const short *str)
255{
256 int len;
257 char *cs;
258
259 if (!current_codepage) set_language( LANG_NEUTRAL, SUBLANG_NEUTRAL );
260 len = cp_wcstombs( current_codepage, 0, str, strlenW(str), NULL, 0, NULL, NULL );
261 cs = xmalloc( len + 1 );
262 len = cp_wcstombs( current_codepage, 0, str, strlenW(str), cs, len, NULL, NULL );
263 cs[len] = 0;
264 return cs;
265}
266
267/*
268 *****************************************************************************
269 * Function : compare_name_id
270 * Syntax : int compare_name_id(name_id_t *n1, name_id_t *n2)
271 * Input :
272 * Output :
273 * Description :
274 * Remarks :
275 *****************************************************************************
276*/
277int compare_name_id(name_id_t *n1, name_id_t *n2)
278{
279 if(n1->type == name_ord && n2->type == name_ord)
280 {
281 return n1->name.i_name - n2->name.i_name;
282 }
283 else if(n1->type == name_str && n2->type == name_str)
284 {
285 if(n1->name.s_name->type == str_char
286 && n2->name.s_name->type == str_char)
287 {
288 return strcasecmp(n1->name.s_name->str.cstr, n2->name.s_name->str.cstr);
289 }
290 else if(n1->name.s_name->type == str_unicode
291 && n2->name.s_name->type == str_unicode)
292 {
293 return strcmpiW(n1->name.s_name->str.wstr, n2->name.s_name->str.wstr);
294 }
295 else
296 {
297 internal_error(__FILE__, __LINE__, "Can't yet compare strings of mixed type");
298 }
299 }
300 else if(n1->type == name_ord && n2->type == name_str)
301 return 1;
302 else if(n1->type == name_str && n2->type == name_ord)
303 return -1;
304 else
305 internal_error(__FILE__, __LINE__, "Comparing name-ids with unknown types (%d, %d)",
306 n1->type, n2->type);
307
308 return 0; /* Keep the compiler happy */
309}
310
311string_t *convert_string(const string_t *str, enum str_e type)
312{
313 string_t *ret = xmalloc(sizeof(*ret));
314
315 if((str->type == str_char) && (type == str_unicode))
316 {
317 ret->str.wstr = dupcstr2wstr(str->str.cstr);
318 ret->type = str_unicode;
319 ret->size = strlenW(ret->str.wstr);
320 }
321 else if((str->type == str_unicode) && (type == str_char))
322 {
323 ret->str.cstr = dupwstr2cstr(str->str.wstr);
324 ret->type = str_char;
325 ret->size = strlen(ret->str.cstr);
326 }
327 else if(str->type == str_unicode)
328 {
329 ret->type = str_unicode;
330 ret->size = strlenW(str->str.wstr);
331 ret->str.wstr = xmalloc(sizeof(WCHAR)*(ret->size+1));
332 strcpyW(ret->str.wstr, str->str.wstr);
333 }
334 else /* str->type == str_char */
335 {
336 ret->type = str_char;
337 ret->size = strlen(str->str.cstr);
338 ret->str.cstr = xmalloc( ret->size + 1 );
339 strcpy(ret->str.cstr, str->str.cstr);
340 }
341 return ret;
342}
343
344
345struct lang2cp
346{
347 unsigned short lang;
348 unsigned short sublang;
349 unsigned int cp;
350} lang2cp_t;
351
352/* language to codepage conversion table */
353/* specific sublanguages need only be specified if their codepage */
354/* differs from the default (SUBLANG_NEUTRAL) */
355static const struct lang2cp lang2cps[] =
356{
357 { LANG_AFRIKAANS, SUBLANG_NEUTRAL, 1252 },
358 { LANG_ALBANIAN, SUBLANG_NEUTRAL, 1250 },
359 { LANG_ARABIC, SUBLANG_NEUTRAL, 1256 },
360 { LANG_BASQUE, SUBLANG_NEUTRAL, 1252 },
361 { LANG_BRETON, SUBLANG_NEUTRAL, 1252 },
362 { LANG_BULGARIAN, SUBLANG_NEUTRAL, 1251 },
363 { LANG_BYELORUSSIAN, SUBLANG_NEUTRAL, 1251 },
364 { LANG_CATALAN, SUBLANG_NEUTRAL, 1252 },
365 { LANG_CHINESE, SUBLANG_NEUTRAL, 936 },
366 { LANG_CORNISH, SUBLANG_NEUTRAL, 1252 },
367 { LANG_CZECH, SUBLANG_NEUTRAL, 1250 },
368 { LANG_DANISH, SUBLANG_NEUTRAL, 1252 },
369 { LANG_DUTCH, SUBLANG_NEUTRAL, 1252 },
370 { LANG_ENGLISH, SUBLANG_NEUTRAL, 1252 },
371 { LANG_ESPERANTO, SUBLANG_NEUTRAL, 1252 },
372 { LANG_ESTONIAN, SUBLANG_NEUTRAL, 1257 },
373 { LANG_FAEROESE, SUBLANG_NEUTRAL, 1252 },
374 { LANG_FINNISH, SUBLANG_NEUTRAL, 1252 },
375 { LANG_FRENCH, SUBLANG_NEUTRAL, 1252 },
376 { LANG_GAELIC, SUBLANG_NEUTRAL, 1252 },
377 { LANG_GERMAN, SUBLANG_NEUTRAL, 1252 },
378 { LANG_GREEK, SUBLANG_NEUTRAL, 1253 },
379 { LANG_HEBREW, SUBLANG_NEUTRAL, 1255 },
380 { LANG_HUNGARIAN, SUBLANG_NEUTRAL, 1250 },
381 { LANG_ICELANDIC, SUBLANG_NEUTRAL, 1252 },
382 { LANG_INDONESIAN, SUBLANG_NEUTRAL, 1252 },
383 { LANG_ITALIAN, SUBLANG_NEUTRAL, 1252 },
384 { LANG_JAPANESE, SUBLANG_NEUTRAL, 932 },
385 { LANG_KOREAN, SUBLANG_NEUTRAL, 949 },
386 { LANG_LATVIAN, SUBLANG_NEUTRAL, 1257 },
387 { LANG_LITHUANIAN, SUBLANG_NEUTRAL, 1257 },
388 { LANG_MACEDONIAN, SUBLANG_NEUTRAL, 1251 },
389 { LANG_MALAY, SUBLANG_NEUTRAL, 1252 },
390 { LANG_NEUTRAL, SUBLANG_NEUTRAL, 1252 },
391 { LANG_NORWEGIAN, SUBLANG_NEUTRAL, 1252 },
392 { LANG_POLISH, SUBLANG_NEUTRAL, 1250 },
393 { LANG_PORTUGUESE, SUBLANG_NEUTRAL, 1252 },
394 { LANG_ROMANIAN, SUBLANG_NEUTRAL, 1250 },
395 { LANG_RUSSIAN, SUBLANG_NEUTRAL, 1251 },
396 { LANG_SERBO_CROATIAN, SUBLANG_NEUTRAL, 1250 },
397 { LANG_SERBO_CROATIAN, SUBLANG_SERBIAN, 1251 },
398 { LANG_SLOVAK, SUBLANG_NEUTRAL, 1250 },
399 { LANG_SLOVENIAN, SUBLANG_NEUTRAL, 1250 },
400 { LANG_SPANISH, SUBLANG_NEUTRAL, 1252 },
401 { LANG_SWEDISH, SUBLANG_NEUTRAL, 1252 },
402 { LANG_THAI, SUBLANG_NEUTRAL, 874 },
403 { LANG_TURKISH, SUBLANG_NEUTRAL, 1254 },
404 { LANG_UKRAINIAN, SUBLANG_NEUTRAL, 1251 },
405 { LANG_VIETNAMESE, SUBLANG_NEUTRAL, 1258 },
406 { LANG_WALON, SUBLANG_NEUTRAL, 1252 },
407 { LANG_WELSH, SUBLANG_NEUTRAL, 1252 }
408};
409
410void set_language( unsigned short lang, unsigned short sublang )
411{
412 unsigned int i;
413 unsigned int cp = 0, defcp = 0;
414
415 for (i = 0; i < sizeof(lang2cps)/sizeof(lang2cps[0]); i++)
416 {
417 if (lang2cps[i].lang != lang) continue;
418 if (lang2cps[i].sublang == sublang)
419 {
420 cp = lang2cps[i].cp;
421 break;
422 }
423 if (lang2cps[i].sublang == SUBLANG_NEUTRAL) defcp = lang2cps[i].cp;
424 }
425
426 if (!cp) cp = defcp;
427 if (!cp)
428 error( "No codepage value for language %04x", MAKELANGID(lang,sublang) );
429 if (!(current_codepage = cp_get_table( cp )))
430 error( "Bad codepage %d for language %04x", cp, MAKELANGID(lang,sublang) );
431}
432
433#if defined(__WIN32OS2__)
434INT WINAPI strcasecmp( LPCSTR p1, LPCSTR p2 )
435{
436 return stricmp( p1, p2 );
437}
438
439INT WINAPI lstrcmpiA(LPCSTR p1, LPCSTR p2)
440{
441 return stricmp( p1, p2 );
442}
443
444#endif
Note: See TracBrowser for help on using the repository browser.