README: Mention Gitlab.
[wine.git] / tools / widl / utils.c
blobaad40f6b0872604c4e711529ce04f68625d73f5b
1 /*
2 * Utility routines
4 * Copyright 1998 Bertho A. Stultiens
5 * Copyright 2002 Ove Kaaven
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "config.h"
24 #include <assert.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <stdarg.h>
28 #include <string.h>
29 #include <ctype.h>
31 #include "widl.h"
32 #include "utils.h"
33 #include "parser.h"
35 #define CURRENT_LOCATION { input_name ? input_name : "stdin", line_number, parser_text }
37 static const int want_near_indication = 0;
39 static void make_print(char *str)
41 while(*str)
43 if(!isprint(*str))
44 *str = ' ';
45 str++;
49 static void generic_msg(const loc_info_t *loc_info, const char *s, const char *t, va_list ap)
51 fprintf(stderr, "%s:%d: %s: ", loc_info->input_name, loc_info->line_number, t);
52 vfprintf(stderr, s, ap);
54 if (want_near_indication)
56 char *cpy;
57 if(loc_info->near_text)
59 cpy = xstrdup(loc_info->near_text);
60 make_print(cpy);
61 fprintf(stderr, " near '%s'", cpy);
62 free(cpy);
68 void error_loc(const char *s, ...)
70 loc_info_t cur_loc = CURRENT_LOCATION;
71 va_list ap;
72 va_start(ap, s);
73 generic_msg(&cur_loc, s, "error", ap);
74 va_end(ap);
75 exit(1);
78 /* yyerror: yacc assumes this is not newline terminated. */
79 void parser_error(const char *s)
81 error_loc("%s\n", s);
84 void error_loc_info(const loc_info_t *loc_info, const char *s, ...)
86 va_list ap;
87 va_start(ap, s);
88 generic_msg(loc_info, s, "error", ap);
89 va_end(ap);
90 exit(1);
93 int parser_warning(const char *s, ...)
95 loc_info_t cur_loc = CURRENT_LOCATION;
96 va_list ap;
97 va_start(ap, s);
98 generic_msg(&cur_loc, s, "warning", ap);
99 va_end(ap);
100 return 0;
103 void error(const char *s, ...)
105 va_list ap;
106 va_start(ap, s);
107 fprintf(stderr, "error: ");
108 vfprintf(stderr, s, ap);
109 va_end(ap);
110 exit(2);
113 void warning(const char *s, ...)
115 va_list ap;
116 va_start(ap, s);
117 fprintf(stderr, "warning: ");
118 vfprintf(stderr, s, ap);
119 va_end(ap);
122 void warning_loc_info(const loc_info_t *loc_info, const char *s, ...)
124 va_list ap;
125 va_start(ap, s);
126 generic_msg(loc_info, s, "warning", ap);
127 va_end(ap);
130 void chat(const char *s, ...)
132 if(debuglevel & DEBUGLEVEL_CHAT)
134 va_list ap;
135 va_start(ap, s);
136 fprintf(stderr, "chat: ");
137 vfprintf(stderr, s, ap);
138 va_end(ap);
142 size_t widl_getline(char **linep, size_t *lenp, FILE *fp)
144 char *line = *linep;
145 size_t len = *lenp;
146 size_t n = 0;
148 if (!line)
150 len = 64;
151 line = xmalloc(len);
154 while (fgets(&line[n], len - n, fp))
156 n += strlen(&line[n]);
157 if (line[n - 1] == '\n')
158 break;
159 else if (n == len - 1)
161 len *= 2;
162 line = xrealloc(line, len);
166 *linep = line;
167 *lenp = len;
168 return n;
171 size_t strappend(char **buf, size_t *len, size_t pos, const char* fmt, ...)
173 size_t size;
174 va_list ap;
175 char *ptr;
176 int n;
178 assert( buf && len );
179 assert( (*len == 0 && *buf == NULL) || (*len != 0 && *buf != NULL) );
181 if (*buf)
183 size = *len;
184 ptr = *buf;
186 else
188 size = 100;
189 ptr = xmalloc( size );
192 for (;;)
194 va_start( ap, fmt );
195 n = vsnprintf( ptr + pos, size - pos, fmt, ap );
196 va_end( ap );
197 if (n == -1) size *= 2;
198 else if (pos + (size_t)n >= size) size = pos + n + 1;
199 else break;
200 ptr = xrealloc( ptr, size );
203 *len = size;
204 *buf = ptr;
205 return n;
208 /*******************************************************************
209 * buffer management
211 * Function for writing to a memory buffer.
214 unsigned char *output_buffer;
215 size_t output_buffer_pos;
216 size_t output_buffer_size;
218 static struct resource
220 unsigned char *data;
221 size_t size;
222 } resources[16];
223 static unsigned int nb_resources;
225 static inline void put_resource_id( const char *str )
227 if (str[0] != '#')
229 while (*str)
231 unsigned char ch = *str++;
232 put_word( toupper(ch) );
234 put_word( 0 );
236 else
238 put_word( 0xffff );
239 put_word( atoi( str + 1 ));
243 void add_output_to_resources( const char *type, const char *name )
245 size_t data_size = output_buffer_pos;
246 size_t header_size = 5 * sizeof(unsigned int) + 2 * sizeof(unsigned short);
248 assert( nb_resources < ARRAY_SIZE( resources ));
250 if (type[0] != '#') header_size += (strlen( type ) + 1) * sizeof(unsigned short);
251 else header_size += 2 * sizeof(unsigned short);
252 if (name[0] != '#') header_size += (strlen( name ) + 1) * sizeof(unsigned short);
253 else header_size += 2 * sizeof(unsigned short);
255 header_size = (header_size + 3) & ~3;
256 align_output( 4 );
257 check_output_buffer_space( header_size );
258 resources[nb_resources].size = header_size + output_buffer_pos;
259 memmove( output_buffer + header_size, output_buffer, output_buffer_pos );
261 output_buffer_pos = 0;
262 put_dword( data_size ); /* ResSize */
263 put_dword( header_size ); /* HeaderSize */
264 put_resource_id( type ); /* ResType */
265 put_resource_id( name ); /* ResName */
266 align_output( 4 );
267 put_dword( 0 ); /* DataVersion */
268 put_word( 0 ); /* Memory options */
269 put_word( 0 ); /* Language */
270 put_dword( 0 ); /* Version */
271 put_dword( 0 ); /* Characteristics */
273 resources[nb_resources++].data = output_buffer;
274 init_output_buffer();
277 void flush_output_resources( const char *name )
279 unsigned int i;
281 /* all output must have been saved with add_output_to_resources() first */
282 assert( !output_buffer_pos );
284 put_dword( 0 ); /* ResSize */
285 put_dword( 32 ); /* HeaderSize */
286 put_word( 0xffff ); /* ResType */
287 put_word( 0x0000 );
288 put_word( 0xffff ); /* ResName */
289 put_word( 0x0000 );
290 put_dword( 0 ); /* DataVersion */
291 put_word( 0 ); /* Memory options */
292 put_word( 0 ); /* Language */
293 put_dword( 0 ); /* Version */
294 put_dword( 0 ); /* Characteristics */
296 for (i = 0; i < nb_resources; i++)
298 put_data( resources[i].data, resources[i].size );
299 free( resources[i].data );
301 flush_output_buffer( name );
302 nb_resources = 0;
305 /* pointer-sized word */
306 void put_pword( unsigned int val )
308 if (pointer_size == 8) put_qword( val );
309 else put_dword( val );
312 void put_str( int indent, const char *format, ... )
314 int n;
315 va_list args;
317 check_output_buffer_space( 4 * indent );
318 memset( output_buffer + output_buffer_pos, ' ', 4 * indent );
319 output_buffer_pos += 4 * indent;
321 for (;;)
323 size_t size = output_buffer_size - output_buffer_pos;
324 va_start( args, format );
325 n = vsnprintf( (char *)output_buffer + output_buffer_pos, size, format, args );
326 va_end( args );
327 if (n == -1) size *= 2;
328 else if ((size_t)n >= size) size = n + 1;
329 else
331 output_buffer_pos += n;
332 return;
334 check_output_buffer_space( size );