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
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
)
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
)
57 if(loc_info
->near_text
)
59 cpy
= xstrdup(loc_info
->near_text
);
61 fprintf(stderr
, " near '%s'", cpy
);
68 void error_loc(const char *s
, ...)
70 loc_info_t cur_loc
= CURRENT_LOCATION
;
73 generic_msg(&cur_loc
, s
, "error", ap
);
78 /* yyerror: yacc assumes this is not newline terminated. */
79 void parser_error(const char *s
)
84 void error_loc_info(const loc_info_t
*loc_info
, const char *s
, ...)
88 generic_msg(loc_info
, s
, "error", ap
);
93 int parser_warning(const char *s
, ...)
95 loc_info_t cur_loc
= CURRENT_LOCATION
;
98 generic_msg(&cur_loc
, s
, "warning", ap
);
103 void error(const char *s
, ...)
107 fprintf(stderr
, "error: ");
108 vfprintf(stderr
, s
, ap
);
113 void warning(const char *s
, ...)
117 fprintf(stderr
, "warning: ");
118 vfprintf(stderr
, s
, ap
);
122 void warning_loc_info(const loc_info_t
*loc_info
, const char *s
, ...)
126 generic_msg(loc_info
, s
, "warning", ap
);
130 void chat(const char *s
, ...)
132 if(debuglevel
& DEBUGLEVEL_CHAT
)
136 fprintf(stderr
, "chat: ");
137 vfprintf(stderr
, s
, ap
);
142 size_t widl_getline(char **linep
, size_t *lenp
, FILE *fp
)
154 while (fgets(&line
[n
], len
- n
, fp
))
156 n
+= strlen(&line
[n
]);
157 if (line
[n
- 1] == '\n')
159 else if (n
== len
- 1)
162 line
= xrealloc(line
, len
);
171 size_t strappend(char **buf
, size_t *len
, size_t pos
, const char* fmt
, ...)
178 assert( buf
&& len
);
179 assert( (*len
== 0 && *buf
== NULL
) || (*len
!= 0 && *buf
!= NULL
) );
189 ptr
= xmalloc( size
);
195 n
= vsnprintf( ptr
+ pos
, size
- pos
, fmt
, ap
);
197 if (n
== -1) size
*= 2;
198 else if (pos
+ (size_t)n
>= size
) size
= pos
+ n
+ 1;
200 ptr
= xrealloc( ptr
, size
);
208 /*******************************************************************
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
223 static unsigned int nb_resources
;
225 static inline void put_resource_id( const char *str
)
231 unsigned char ch
= *str
++;
232 put_word( toupper(ch
) );
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;
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 */
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
)
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 */
288 put_word( 0xffff ); /* ResName */
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
);
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
, ... )
317 check_output_buffer_space( 4 * indent
);
318 memset( output_buffer
+ output_buffer_pos
, ' ', 4 * indent
);
319 output_buffer_pos
+= 4 * indent
;
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
);
327 if (n
== -1) size
*= 2;
328 else if ((size_t)n
>= size
) size
= n
+ 1;
331 output_buffer_pos
+= n
;
334 check_output_buffer_space( size
);