Convert GetCharWidth to Unicode.
[wine] / tools / wmc / utils.c
1 /*
2  * Utility routines
3  *
4  * Copyright 1998,2000 Bertho A. Stultiens
5  *
6  */
7
8 #include "config.h"
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <stdarg.h>
13 #include <string.h>
14 #include <assert.h>
15 #include <ctype.h>
16
17 #include "wmctypes.h"
18 #include "utils.h"
19 #include "wmc.h"
20
21 #define SUPPRESS_YACC_ERROR_MESSAGE
22
23 static void generic_msg(const char *s, const char *t, va_list ap)
24 {
25         fprintf(stderr, "%s %s: %d, %d: ", t, input_name ? input_name : "stdin", line_number, char_number);
26         vfprintf(stderr, s, ap);
27         fprintf(stderr, "\n");
28 }
29
30 /*
31  * The yyerror routine should not exit because we use the error-token
32  * to determine the syntactic error in the source. However, YACC
33  * uses the same routine to print an error just before the error
34  * token is reduced.
35  * The extra routine 'xyyerror' is used to exit after giving a real
36  * message.
37  */
38 int yyerror(const char *s, ...)
39 {
40 #ifndef SUPPRESS_YACC_ERROR_MESSAGE
41         va_list ap;
42         va_start(ap, s);
43         generic_msg(s, "Yacc error", ap);
44         va_end(ap);
45 #endif
46         return 1;
47 }
48
49 int xyyerror(const char *s, ...)
50 {
51         va_list ap;
52         va_start(ap, s);
53         generic_msg(s, "Error", ap);
54         va_end(ap);
55         exit(1);
56         return 1;
57 }
58
59 int yywarning(const char *s, ...)
60 {
61         va_list ap;
62         va_start(ap, s);
63         generic_msg(s, "Warning", ap);
64         va_end(ap);
65         return 0;
66 }
67
68 void internal_error(const char *file, int line, const char *s, ...)
69 {
70         va_list ap;
71         va_start(ap, s);
72         fprintf(stderr, "Internal error (please report) %s %d: ", file, line);
73         vfprintf(stderr, s, ap);
74         fprintf(stderr, "\n");
75         va_end(ap);
76         exit(3);
77 }
78
79 void error(const char *s, ...)
80 {
81         va_list ap;
82         va_start(ap, s);
83         fprintf(stderr, "Error: ");
84         vfprintf(stderr, s, ap);
85         fprintf(stderr, "\n");
86         va_end(ap);
87         exit(2);
88 }
89
90 void warning(const char *s, ...)
91 {
92         va_list ap;
93         va_start(ap, s);
94         fprintf(stderr, "Warning: ");
95         vfprintf(stderr, s, ap);
96         fprintf(stderr, "\n");
97         va_end(ap);
98 }
99
100 char *dup_basename(const char *name, const char *ext)
101 {
102         int namelen;
103         int extlen = strlen(ext);
104         char *base;
105         char *slash;
106
107         if(!name)
108                 name = "wmc.tab";
109
110         slash = strrchr(name, '/');
111         if (slash)
112                 name = slash + 1;
113
114         namelen = strlen(name);
115
116         /* +4 for later extension and +1 for '\0' */
117         base = (char *)xmalloc(namelen +4 +1);
118         strcpy(base, name);
119         if(!strcasecmp(name + namelen-extlen, ext))
120         {
121                 base[namelen - extlen] = '\0';
122         }
123         return base;
124 }
125
126 void *xmalloc(size_t size)
127 {
128     void *res;
129
130     assert(size > 0);
131     assert(size < 102400);
132     res = malloc(size);
133     if(res == NULL)
134     {
135         error("Virtual memory exhausted.\n");
136     }
137     /*
138      * We set it to 0.
139      * This is *paramount* because we depend on it
140      * just about everywhere in the rest of the code.
141      */
142     memset(res, 0, size);
143     return res;
144 }
145
146
147 void *xrealloc(void *p, size_t size)
148 {
149     void *res;
150
151     assert(size > 0);
152     assert(size < 102400);
153     res = realloc(p, size);
154     if(res == NULL)
155     {
156         error("Virtual memory exhausted.\n");
157     }
158     return res;
159 }
160
161 char *xstrdup(const char *str)
162 {
163         char *s;
164
165         assert(str != NULL);
166         s = (char *)xmalloc(strlen(str)+1);
167         return strcpy(s, str);
168 }
169
170 int unistrlen(const WCHAR *s)
171 {
172         int n;
173         for(n = 0; *s; n++, s++)
174                 ;
175         return n;
176 }
177
178 WCHAR *unistrcpy(WCHAR *dst, const WCHAR *src)
179 {
180         WCHAR *t = dst;
181         while(*src)
182                 *t++ = *src++;
183         *t = 0;
184         return dst;
185 }
186
187 WCHAR *xunistrdup(const WCHAR * str)
188 {
189         WCHAR *s;
190
191         assert(str != NULL);
192         s = (WCHAR *)xmalloc((unistrlen(str)+1) * sizeof(WCHAR));
193         return unistrcpy(s, str);
194 }
195
196 int unistricmp(const WCHAR *s1, const WCHAR *s2)
197 {
198         int i;
199         int once = 0;
200         static char warn[] = "Don't know the uppercase equivalent of non acsii characters;"
201                              "comparison might yield wrong results";
202         while(*s1 && *s2)
203         {
204                 if((*s1 & 0xffff) > 0x7f || (*s2 & 0xffff) > 0x7f)
205                 {
206                         if(!once)
207                         {
208                                 once++;
209                                 yywarning(warn);
210                         }
211                         i = *s1++ - *s2++;
212                 }
213                 else
214                         i = toupper(*s1++) - toupper(*s2++);
215                 if(i)
216                         return i;
217         }
218
219         if((*s1 & 0xffff) > 0x7f || (*s2 & 0xffff) > 0x7f)
220         {
221                 if(!once)
222                         yywarning(warn);
223                 return *s1 - *s2;
224         }
225         else
226                 return  toupper(*s1) - toupper(*s2);
227 }
228
229 int unistrcmp(const WCHAR *s1, const WCHAR *s2)
230 {
231         int i;
232         while(*s1 && *s2)
233         {
234                 i = *s1++ - *s2++;
235                 if(i)
236                         return i;
237         }
238
239         return *s1 - *s2;
240 }
241