Allow NULL as argument to SysFreeString in accordance with SDK.
[wine] / tools / wrc / utils.c
1 /*
2  * Utility routines
3  *
4  * Copyright 1998 Bertho A. Stultiens
5  *
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <stdarg.h>
11 #include <string.h>
12 #include <assert.h>
13 #include <ctype.h>
14
15 #include <config.h>
16 #include "wrc.h"
17 #include "utils.h"
18 #include "parser.h"
19
20 #define WANT_NEAR_INDICATION
21
22
23 #ifdef WANT_NEAR_INDICATION
24 void make_print(char *str)
25 {
26         while(*str)
27         {
28                 if(!isprint(*str))
29                         *str = ' ';
30                 str++;
31         }
32 }
33 #endif
34
35 int yyerror(const char *s, ...)
36 {
37         va_list ap;
38         va_start(ap, s);
39         fprintf(stderr, "Error %s: %d, %d: ", input_name ? input_name : "stdin", line_number, char_number);
40         vfprintf(stderr, s, ap);
41 #ifdef WANT_NEAR_INDICATION
42         {
43                 char *cpy = xstrdup(yytext);
44                 make_print(cpy);
45                 fprintf(stderr, " near '%s'\n", cpy);
46                 free(cpy);
47         }
48 #else
49         fprintf(stderr, "\n");
50 #endif
51         va_end(ap);
52         exit(1);
53         return 1;
54 }
55
56 int yywarning(const char *s, ...)
57 {
58         va_list ap;
59         va_start(ap, s);
60         fprintf(stderr, "Warning %s: %d, %d: ", input_name ? input_name : "stdin", line_number, char_number);
61         vfprintf(stderr, s, ap);
62 #ifdef WANT_NEAR_INDICATION
63         {
64                 char *cpy = xstrdup(yytext);
65                 make_print(cpy);
66                 fprintf(stderr, " near '%s'\n", cpy);
67                 free(cpy);
68         }
69 #else
70         fprintf(stderr, "\n");
71 #endif
72         va_end(ap);
73         return 0;
74 }
75
76 void internal_error(const char *file, int line, const char *s, ...)
77 {
78         va_list ap;
79         va_start(ap, s);
80         fprintf(stderr, "Internal error (please report) %s %d: ", file, line);
81         vfprintf(stderr, s, ap);
82         fprintf(stderr, "\n");
83         va_end(ap);
84         exit(3);
85 }
86
87 void error(const char *s, ...)
88 {
89         va_list ap;
90         va_start(ap, s);
91         fprintf(stderr, "Error: ");
92         vfprintf(stderr, s, ap);
93         fprintf(stderr, "\n");
94         va_end(ap);
95         exit(2);
96 }
97
98 void warning(const char *s, ...)
99 {
100         va_list ap;
101         va_start(ap, s);
102         fprintf(stderr, "Warning: ");
103         vfprintf(stderr, s, ap);
104         fprintf(stderr, "\n");
105         va_end(ap);
106 }
107
108 void chat(const char *s, ...)
109 {
110         if(debuglevel & DEBUGLEVEL_CHAT)
111         {
112                 va_list ap;
113                 va_start(ap, s);
114                 fprintf(stderr, "FYI: ");
115                 vfprintf(stderr, s, ap);
116                 fprintf(stderr, "\n");
117                 va_end(ap);
118         }
119 }
120
121 char *dup_basename(const char *name, const char *ext)
122 {
123         int namelen;
124         int extlen = strlen(ext);
125         char *base;
126         char *slash;
127
128         if(!name)
129                 name = "wrc.tab";
130
131         slash = strrchr(name, '/');
132         if (slash)
133                 name = slash + 1;
134
135         namelen = strlen(name);
136
137         /* +4 for later extension and +1 for '\0' */
138         base = (char *)xmalloc(namelen +4 +1);
139         strcpy(base, name);
140         if(!strcasecmp(name + namelen-extlen, ext))
141         {
142                 base[namelen - extlen] = '\0';
143         }
144         return base;
145 }
146
147 void *xmalloc(size_t size)
148 {
149     void *res;
150
151     assert(size > 0);
152     assert(size < 102400);
153     res = malloc(size);
154     if(res == NULL)
155     {
156         error("Virtual memory exhausted.\n");
157     }
158     memset(res, 0, size);
159     return res;
160 }
161
162
163 void *xrealloc(void *p, size_t size)
164 {
165     void *res;
166
167     assert(size > 0);
168     assert(size < 102400);
169     res = realloc(p, size);
170     if(res == NULL)
171     {
172         error("Virtual memory exhausted.\n");
173     }
174     return res;
175 }
176
177 char *xstrdup(const char *str)
178 {
179         char *s = (char *)xmalloc(strlen(str)+1);
180         return strcpy(s, str);
181 }
182
183 int string_compare(const string_t *s1, const string_t *s2)
184 {
185         if(s1->type == str_char && s2->type == str_char)
186         {
187                 return strcasecmp(s1->str.cstr, s2->str.cstr);
188         }
189         else
190         {
191                 internal_error(__FILE__, __LINE__, "Cannot yet compare unicode strings");
192         }
193         return 0;
194 }
195
196 int wstrlen(const short *s)
197 {
198         int cnt = 0;
199         while(*s++)
200                 cnt++;
201         return cnt;
202 }
203
204 short *wstrcpy(short *dst, const short *src)
205 {
206         short *d = dst;
207         while(*src)
208                 *d++ = *src++;
209         return dst;
210 }
211
212 int wstricmp(const short *s1, const short *s2)
213 {
214         char *cs1 = dupwstr2cstr(s1);
215         char *cs2 = dupwstr2cstr(s2);
216         int retval = strcasecmp(cs1, cs2);
217         free(cs1);
218         free(cs2);
219         warning("Comparing unicode strings without case -> converting to ascii");
220         return retval;;
221 }
222
223 short *dupcstr2wstr(const char *str)
224 {
225         int len = strlen(str) + 1;
226         short *ws = (short *)xmalloc(len*2);
227         short *wptr;
228
229         wptr = ws;
230         /* FIXME: codepage translation */
231         while(*str)
232                 *wptr++ = (short)(*str++ & 0xff);
233         *wptr = 0;
234         return ws;
235 }
236
237 char *dupwstr2cstr(const short *str)
238 {
239         int len = wstrlen(str) + 1;
240         char *cs = (char *)xmalloc(len);
241         char *cptr;
242
243         cptr = cs;
244         /* FIXME: codepage translation */
245         while(*str)
246                 *cptr++ = (char)*str++;
247         *cptr = 0;
248         return cs;
249 }
250