1*c2c66affSColin Finck /*
2*c2c66affSColin Finck * Utility routines
3*c2c66affSColin Finck *
4*c2c66affSColin Finck * Copyright 1998 Bertho A. Stultiens
5*c2c66affSColin Finck * Copyright 2002 Ove Kaaven
6*c2c66affSColin Finck *
7*c2c66affSColin Finck * This library is free software; you can redistribute it and/or
8*c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
9*c2c66affSColin Finck * License as published by the Free Software Foundation; either
10*c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
11*c2c66affSColin Finck *
12*c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
13*c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
14*c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15*c2c66affSColin Finck * Lesser General Public License for more details.
16*c2c66affSColin Finck *
17*c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
18*c2c66affSColin Finck * License along with this library; if not, write to the Free Software
19*c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20*c2c66affSColin Finck */
21*c2c66affSColin Finck
22*c2c66affSColin Finck #include "config.h"
23*c2c66affSColin Finck #include "wine/port.h"
24*c2c66affSColin Finck
25*c2c66affSColin Finck #include <assert.h>
26*c2c66affSColin Finck #include <stdio.h>
27*c2c66affSColin Finck #include <stdlib.h>
28*c2c66affSColin Finck #include <stdarg.h>
29*c2c66affSColin Finck #include <string.h>
30*c2c66affSColin Finck #include <ctype.h>
31*c2c66affSColin Finck
32*c2c66affSColin Finck #include "widl.h"
33*c2c66affSColin Finck #include "utils.h"
34*c2c66affSColin Finck #include "parser.h"
35*c2c66affSColin Finck
36*c2c66affSColin Finck #define CURRENT_LOCATION { input_name ? input_name : "stdin", line_number, parser_text }
37*c2c66affSColin Finck
38*c2c66affSColin Finck static const int want_near_indication = 0;
39*c2c66affSColin Finck
make_print(char * str)40*c2c66affSColin Finck static void make_print(char *str)
41*c2c66affSColin Finck {
42*c2c66affSColin Finck while(*str)
43*c2c66affSColin Finck {
44*c2c66affSColin Finck if(!isprint(*str))
45*c2c66affSColin Finck *str = ' ';
46*c2c66affSColin Finck str++;
47*c2c66affSColin Finck }
48*c2c66affSColin Finck }
49*c2c66affSColin Finck
generic_msg(const loc_info_t * loc_info,const char * s,const char * t,va_list ap)50*c2c66affSColin Finck static void generic_msg(const loc_info_t *loc_info, const char *s, const char *t, va_list ap)
51*c2c66affSColin Finck {
52*c2c66affSColin Finck fprintf(stderr, "%s:%d: %s: ", loc_info->input_name, loc_info->line_number, t);
53*c2c66affSColin Finck vfprintf(stderr, s, ap);
54*c2c66affSColin Finck
55*c2c66affSColin Finck if (want_near_indication)
56*c2c66affSColin Finck {
57*c2c66affSColin Finck char *cpy;
58*c2c66affSColin Finck if(loc_info->near_text)
59*c2c66affSColin Finck {
60*c2c66affSColin Finck cpy = xstrdup(loc_info->near_text);
61*c2c66affSColin Finck make_print(cpy);
62*c2c66affSColin Finck fprintf(stderr, " near '%s'", cpy);
63*c2c66affSColin Finck free(cpy);
64*c2c66affSColin Finck }
65*c2c66affSColin Finck }
66*c2c66affSColin Finck }
67*c2c66affSColin Finck
68*c2c66affSColin Finck
error_loc(const char * s,...)69*c2c66affSColin Finck void error_loc(const char *s, ...)
70*c2c66affSColin Finck {
71*c2c66affSColin Finck loc_info_t cur_loc = CURRENT_LOCATION;
72*c2c66affSColin Finck va_list ap;
73*c2c66affSColin Finck va_start(ap, s);
74*c2c66affSColin Finck generic_msg(&cur_loc, s, "error", ap);
75*c2c66affSColin Finck va_end(ap);
76*c2c66affSColin Finck exit(1);
77*c2c66affSColin Finck }
78*c2c66affSColin Finck
79*c2c66affSColin Finck /* yyerror: yacc assumes this is not newline terminated. */
parser_error(const char * s)80*c2c66affSColin Finck void parser_error(const char *s)
81*c2c66affSColin Finck {
82*c2c66affSColin Finck error_loc("%s\n", s);
83*c2c66affSColin Finck }
84*c2c66affSColin Finck
error_loc_info(const loc_info_t * loc_info,const char * s,...)85*c2c66affSColin Finck void error_loc_info(const loc_info_t *loc_info, const char *s, ...)
86*c2c66affSColin Finck {
87*c2c66affSColin Finck va_list ap;
88*c2c66affSColin Finck va_start(ap, s);
89*c2c66affSColin Finck generic_msg(loc_info, s, "error", ap);
90*c2c66affSColin Finck va_end(ap);
91*c2c66affSColin Finck exit(1);
92*c2c66affSColin Finck }
93*c2c66affSColin Finck
parser_warning(const char * s,...)94*c2c66affSColin Finck int parser_warning(const char *s, ...)
95*c2c66affSColin Finck {
96*c2c66affSColin Finck loc_info_t cur_loc = CURRENT_LOCATION;
97*c2c66affSColin Finck va_list ap;
98*c2c66affSColin Finck va_start(ap, s);
99*c2c66affSColin Finck generic_msg(&cur_loc, s, "warning", ap);
100*c2c66affSColin Finck va_end(ap);
101*c2c66affSColin Finck return 0;
102*c2c66affSColin Finck }
103*c2c66affSColin Finck
error(const char * s,...)104*c2c66affSColin Finck void error(const char *s, ...)
105*c2c66affSColin Finck {
106*c2c66affSColin Finck va_list ap;
107*c2c66affSColin Finck va_start(ap, s);
108*c2c66affSColin Finck fprintf(stderr, "error: ");
109*c2c66affSColin Finck vfprintf(stderr, s, ap);
110*c2c66affSColin Finck va_end(ap);
111*c2c66affSColin Finck exit(2);
112*c2c66affSColin Finck }
113*c2c66affSColin Finck
warning(const char * s,...)114*c2c66affSColin Finck void warning(const char *s, ...)
115*c2c66affSColin Finck {
116*c2c66affSColin Finck va_list ap;
117*c2c66affSColin Finck va_start(ap, s);
118*c2c66affSColin Finck fprintf(stderr, "warning: ");
119*c2c66affSColin Finck vfprintf(stderr, s, ap);
120*c2c66affSColin Finck va_end(ap);
121*c2c66affSColin Finck }
122*c2c66affSColin Finck
warning_loc_info(const loc_info_t * loc_info,const char * s,...)123*c2c66affSColin Finck void warning_loc_info(const loc_info_t *loc_info, const char *s, ...)
124*c2c66affSColin Finck {
125*c2c66affSColin Finck va_list ap;
126*c2c66affSColin Finck va_start(ap, s);
127*c2c66affSColin Finck generic_msg(loc_info, s, "warning", ap);
128*c2c66affSColin Finck va_end(ap);
129*c2c66affSColin Finck }
130*c2c66affSColin Finck
chat(const char * s,...)131*c2c66affSColin Finck void chat(const char *s, ...)
132*c2c66affSColin Finck {
133*c2c66affSColin Finck if(debuglevel & DEBUGLEVEL_CHAT)
134*c2c66affSColin Finck {
135*c2c66affSColin Finck va_list ap;
136*c2c66affSColin Finck va_start(ap, s);
137*c2c66affSColin Finck fprintf(stderr, "chat: ");
138*c2c66affSColin Finck vfprintf(stderr, s, ap);
139*c2c66affSColin Finck va_end(ap);
140*c2c66affSColin Finck }
141*c2c66affSColin Finck }
142*c2c66affSColin Finck
dup_basename(const char * name,const char * ext)143*c2c66affSColin Finck char *dup_basename(const char *name, const char *ext)
144*c2c66affSColin Finck {
145*c2c66affSColin Finck int namelen;
146*c2c66affSColin Finck int extlen = strlen(ext);
147*c2c66affSColin Finck char *base;
148*c2c66affSColin Finck char *slash;
149*c2c66affSColin Finck
150*c2c66affSColin Finck if(!name)
151*c2c66affSColin Finck name = "widl.tab";
152*c2c66affSColin Finck
153*c2c66affSColin Finck slash = strrchr(name, '/');
154*c2c66affSColin Finck if (!slash)
155*c2c66affSColin Finck slash = strrchr(name, '\\');
156*c2c66affSColin Finck
157*c2c66affSColin Finck if (slash)
158*c2c66affSColin Finck name = slash + 1;
159*c2c66affSColin Finck
160*c2c66affSColin Finck namelen = strlen(name);
161*c2c66affSColin Finck
162*c2c66affSColin Finck /* +6 for later extension (strlen("_r.rgs")) and +1 for '\0' */
163*c2c66affSColin Finck base = xmalloc(namelen +6 +1);
164*c2c66affSColin Finck strcpy(base, name);
165*c2c66affSColin Finck if(!strcasecmp(name + namelen-extlen, ext))
166*c2c66affSColin Finck {
167*c2c66affSColin Finck base[namelen - extlen] = '\0';
168*c2c66affSColin Finck }
169*c2c66affSColin Finck return base;
170*c2c66affSColin Finck }
171*c2c66affSColin Finck
widl_getline(char ** linep,size_t * lenp,FILE * fp)172*c2c66affSColin Finck size_t widl_getline(char **linep, size_t *lenp, FILE *fp)
173*c2c66affSColin Finck {
174*c2c66affSColin Finck char *line = *linep;
175*c2c66affSColin Finck size_t len = *lenp;
176*c2c66affSColin Finck size_t n = 0;
177*c2c66affSColin Finck
178*c2c66affSColin Finck if (!line)
179*c2c66affSColin Finck {
180*c2c66affSColin Finck len = 64;
181*c2c66affSColin Finck line = xmalloc(len);
182*c2c66affSColin Finck }
183*c2c66affSColin Finck
184*c2c66affSColin Finck while (fgets(&line[n], len - n, fp))
185*c2c66affSColin Finck {
186*c2c66affSColin Finck n += strlen(&line[n]);
187*c2c66affSColin Finck if (line[n - 1] == '\n')
188*c2c66affSColin Finck break;
189*c2c66affSColin Finck else if (n == len - 1)
190*c2c66affSColin Finck {
191*c2c66affSColin Finck len *= 2;
192*c2c66affSColin Finck line = xrealloc(line, len);
193*c2c66affSColin Finck }
194*c2c66affSColin Finck }
195*c2c66affSColin Finck
196*c2c66affSColin Finck *linep = line;
197*c2c66affSColin Finck *lenp = len;
198*c2c66affSColin Finck return n;
199*c2c66affSColin Finck }
200*c2c66affSColin Finck
xmalloc(size_t size)201*c2c66affSColin Finck void *xmalloc(size_t size)
202*c2c66affSColin Finck {
203*c2c66affSColin Finck void *res;
204*c2c66affSColin Finck
205*c2c66affSColin Finck assert(size > 0);
206*c2c66affSColin Finck res = malloc(size);
207*c2c66affSColin Finck if(res == NULL)
208*c2c66affSColin Finck {
209*c2c66affSColin Finck error("Virtual memory exhausted.\n");
210*c2c66affSColin Finck }
211*c2c66affSColin Finck memset(res, 0x55, size);
212*c2c66affSColin Finck return res;
213*c2c66affSColin Finck }
214*c2c66affSColin Finck
215*c2c66affSColin Finck
xrealloc(void * p,size_t size)216*c2c66affSColin Finck void *xrealloc(void *p, size_t size)
217*c2c66affSColin Finck {
218*c2c66affSColin Finck void *res;
219*c2c66affSColin Finck
220*c2c66affSColin Finck assert(size > 0);
221*c2c66affSColin Finck res = realloc(p, size);
222*c2c66affSColin Finck if(res == NULL)
223*c2c66affSColin Finck {
224*c2c66affSColin Finck error("Virtual memory exhausted.\n");
225*c2c66affSColin Finck }
226*c2c66affSColin Finck return res;
227*c2c66affSColin Finck }
228*c2c66affSColin Finck
xstrdup(const char * str)229*c2c66affSColin Finck char *xstrdup(const char *str)
230*c2c66affSColin Finck {
231*c2c66affSColin Finck char *s;
232*c2c66affSColin Finck
233*c2c66affSColin Finck assert(str != NULL);
234*c2c66affSColin Finck s = xmalloc(strlen(str)+1);
235*c2c66affSColin Finck return strcpy(s, str);
236*c2c66affSColin Finck }
237*c2c66affSColin Finck
strendswith(const char * str,const char * end)238*c2c66affSColin Finck int strendswith(const char* str, const char* end)
239*c2c66affSColin Finck {
240*c2c66affSColin Finck int l = strlen(str);
241*c2c66affSColin Finck int m = strlen(end);
242*c2c66affSColin Finck return l >= m && strcmp(str + l - m, end) == 0;
243*c2c66affSColin Finck }
244*c2c66affSColin Finck
245*c2c66affSColin Finck /*******************************************************************
246*c2c66affSColin Finck * buffer management
247*c2c66affSColin Finck *
248*c2c66affSColin Finck * Function for writing to a memory buffer.
249*c2c66affSColin Finck */
250*c2c66affSColin Finck
251*c2c66affSColin Finck int byte_swapped = 0;
252*c2c66affSColin Finck unsigned char *output_buffer;
253*c2c66affSColin Finck size_t output_buffer_pos;
254*c2c66affSColin Finck size_t output_buffer_size;
255*c2c66affSColin Finck
256*c2c66affSColin Finck static struct resource
257*c2c66affSColin Finck {
258*c2c66affSColin Finck unsigned char *data;
259*c2c66affSColin Finck size_t size;
260*c2c66affSColin Finck } resources[16];
261*c2c66affSColin Finck static unsigned int nb_resources;
262*c2c66affSColin Finck
check_output_buffer_space(size_t size)263*c2c66affSColin Finck static void check_output_buffer_space( size_t size )
264*c2c66affSColin Finck {
265*c2c66affSColin Finck if (output_buffer_pos + size >= output_buffer_size)
266*c2c66affSColin Finck {
267*c2c66affSColin Finck output_buffer_size = max( output_buffer_size * 2, output_buffer_pos + size );
268*c2c66affSColin Finck output_buffer = xrealloc( output_buffer, output_buffer_size );
269*c2c66affSColin Finck }
270*c2c66affSColin Finck }
271*c2c66affSColin Finck
init_output_buffer(void)272*c2c66affSColin Finck void init_output_buffer(void)
273*c2c66affSColin Finck {
274*c2c66affSColin Finck output_buffer_size = 1024;
275*c2c66affSColin Finck output_buffer_pos = 0;
276*c2c66affSColin Finck output_buffer = xmalloc( output_buffer_size );
277*c2c66affSColin Finck }
278*c2c66affSColin Finck
flush_output_buffer(const char * name)279*c2c66affSColin Finck void flush_output_buffer( const char *name )
280*c2c66affSColin Finck {
281*c2c66affSColin Finck int fd = open( name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666 );
282*c2c66affSColin Finck if (fd == -1) error( "Error creating %s\n", name );
283*c2c66affSColin Finck if (write( fd, output_buffer, output_buffer_pos ) != output_buffer_pos)
284*c2c66affSColin Finck error( "Error writing to %s\n", name );
285*c2c66affSColin Finck close( fd );
286*c2c66affSColin Finck free( output_buffer );
287*c2c66affSColin Finck }
288*c2c66affSColin Finck
put_resource_id(const char * str)289*c2c66affSColin Finck static inline void put_resource_id( const char *str )
290*c2c66affSColin Finck {
291*c2c66affSColin Finck if (str[0] != '#')
292*c2c66affSColin Finck {
293*c2c66affSColin Finck while (*str)
294*c2c66affSColin Finck {
295*c2c66affSColin Finck unsigned char ch = *str++;
296*c2c66affSColin Finck put_word( toupper(ch) );
297*c2c66affSColin Finck }
298*c2c66affSColin Finck put_word( 0 );
299*c2c66affSColin Finck }
300*c2c66affSColin Finck else
301*c2c66affSColin Finck {
302*c2c66affSColin Finck put_word( 0xffff );
303*c2c66affSColin Finck put_word( atoi( str + 1 ));
304*c2c66affSColin Finck }
305*c2c66affSColin Finck }
306*c2c66affSColin Finck
add_output_to_resources(const char * type,const char * name)307*c2c66affSColin Finck void add_output_to_resources( const char *type, const char *name )
308*c2c66affSColin Finck {
309*c2c66affSColin Finck size_t data_size = output_buffer_pos;
310*c2c66affSColin Finck size_t header_size = 5 * sizeof(unsigned int) + 2 * sizeof(unsigned short);
311*c2c66affSColin Finck
312*c2c66affSColin Finck assert( nb_resources < sizeof(resources)/sizeof(resources[0]) );
313*c2c66affSColin Finck
314*c2c66affSColin Finck if (type[0] != '#') header_size += (strlen( type ) + 1) * sizeof(unsigned short);
315*c2c66affSColin Finck else header_size += 2 * sizeof(unsigned short);
316*c2c66affSColin Finck if (name[0] != '#') header_size += (strlen( name ) + 1) * sizeof(unsigned short);
317*c2c66affSColin Finck else header_size += 2 * sizeof(unsigned short);
318*c2c66affSColin Finck
319*c2c66affSColin Finck header_size = (header_size + 3) & ~3;
320*c2c66affSColin Finck align_output( 4 );
321*c2c66affSColin Finck check_output_buffer_space( header_size );
322*c2c66affSColin Finck resources[nb_resources].size = header_size + output_buffer_pos;
323*c2c66affSColin Finck memmove( output_buffer + header_size, output_buffer, output_buffer_pos );
324*c2c66affSColin Finck
325*c2c66affSColin Finck output_buffer_pos = 0;
326*c2c66affSColin Finck put_dword( data_size ); /* ResSize */
327*c2c66affSColin Finck put_dword( header_size ); /* HeaderSize */
328*c2c66affSColin Finck put_resource_id( type ); /* ResType */
329*c2c66affSColin Finck put_resource_id( name ); /* ResName */
330*c2c66affSColin Finck align_output( 4 );
331*c2c66affSColin Finck put_dword( 0 ); /* DataVersion */
332*c2c66affSColin Finck put_word( 0 ); /* Memory options */
333*c2c66affSColin Finck put_word( 0 ); /* Language */
334*c2c66affSColin Finck put_dword( 0 ); /* Version */
335*c2c66affSColin Finck put_dword( 0 ); /* Characteristics */
336*c2c66affSColin Finck
337*c2c66affSColin Finck resources[nb_resources++].data = output_buffer;
338*c2c66affSColin Finck init_output_buffer();
339*c2c66affSColin Finck }
340*c2c66affSColin Finck
flush_output_resources(const char * name)341*c2c66affSColin Finck void flush_output_resources( const char *name )
342*c2c66affSColin Finck {
343*c2c66affSColin Finck int fd;
344*c2c66affSColin Finck unsigned int i;
345*c2c66affSColin Finck
346*c2c66affSColin Finck /* all output must have been saved with add_output_to_resources() first */
347*c2c66affSColin Finck assert( !output_buffer_pos );
348*c2c66affSColin Finck
349*c2c66affSColin Finck put_dword( 0 ); /* ResSize */
350*c2c66affSColin Finck put_dword( 32 ); /* HeaderSize */
351*c2c66affSColin Finck put_word( 0xffff ); /* ResType */
352*c2c66affSColin Finck put_word( 0x0000 );
353*c2c66affSColin Finck put_word( 0xffff ); /* ResName */
354*c2c66affSColin Finck put_word( 0x0000 );
355*c2c66affSColin Finck put_dword( 0 ); /* DataVersion */
356*c2c66affSColin Finck put_word( 0 ); /* Memory options */
357*c2c66affSColin Finck put_word( 0 ); /* Language */
358*c2c66affSColin Finck put_dword( 0 ); /* Version */
359*c2c66affSColin Finck put_dword( 0 ); /* Characteristics */
360*c2c66affSColin Finck
361*c2c66affSColin Finck fd = open( name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666 );
362*c2c66affSColin Finck if (fd == -1) error( "Error creating %s\n", name );
363*c2c66affSColin Finck if (write( fd, output_buffer, output_buffer_pos ) != output_buffer_pos)
364*c2c66affSColin Finck error( "Error writing to %s\n", name );
365*c2c66affSColin Finck for (i = 0; i < nb_resources; i++)
366*c2c66affSColin Finck {
367*c2c66affSColin Finck if (write( fd, resources[i].data, resources[i].size ) != resources[i].size)
368*c2c66affSColin Finck error( "Error writing to %s\n", name );
369*c2c66affSColin Finck free( resources[i].data );
370*c2c66affSColin Finck }
371*c2c66affSColin Finck close( fd );
372*c2c66affSColin Finck nb_resources = 0;
373*c2c66affSColin Finck free( output_buffer );
374*c2c66affSColin Finck }
375*c2c66affSColin Finck
put_data(const void * data,size_t size)376*c2c66affSColin Finck void put_data( const void *data, size_t size )
377*c2c66affSColin Finck {
378*c2c66affSColin Finck check_output_buffer_space( size );
379*c2c66affSColin Finck memcpy( output_buffer + output_buffer_pos, data, size );
380*c2c66affSColin Finck output_buffer_pos += size;
381*c2c66affSColin Finck }
382*c2c66affSColin Finck
put_byte(unsigned char val)383*c2c66affSColin Finck void put_byte( unsigned char val )
384*c2c66affSColin Finck {
385*c2c66affSColin Finck check_output_buffer_space( 1 );
386*c2c66affSColin Finck output_buffer[output_buffer_pos++] = val;
387*c2c66affSColin Finck }
388*c2c66affSColin Finck
put_word(unsigned short val)389*c2c66affSColin Finck void put_word( unsigned short val )
390*c2c66affSColin Finck {
391*c2c66affSColin Finck if (byte_swapped) val = (val << 8) | (val >> 8);
392*c2c66affSColin Finck put_data( &val, sizeof(val) );
393*c2c66affSColin Finck }
394*c2c66affSColin Finck
put_dword(unsigned int val)395*c2c66affSColin Finck void put_dword( unsigned int val )
396*c2c66affSColin Finck {
397*c2c66affSColin Finck if (byte_swapped)
398*c2c66affSColin Finck val = ((val << 24) | ((val << 8) & 0x00ff0000) | ((val >> 8) & 0x0000ff00) | (val >> 24));
399*c2c66affSColin Finck put_data( &val, sizeof(val) );
400*c2c66affSColin Finck }
401*c2c66affSColin Finck
put_qword(unsigned int val)402*c2c66affSColin Finck void put_qword( unsigned int val )
403*c2c66affSColin Finck {
404*c2c66affSColin Finck if (byte_swapped)
405*c2c66affSColin Finck {
406*c2c66affSColin Finck put_dword( 0 );
407*c2c66affSColin Finck put_dword( val );
408*c2c66affSColin Finck }
409*c2c66affSColin Finck else
410*c2c66affSColin Finck {
411*c2c66affSColin Finck put_dword( val );
412*c2c66affSColin Finck put_dword( 0 );
413*c2c66affSColin Finck }
414*c2c66affSColin Finck }
415*c2c66affSColin Finck
416*c2c66affSColin Finck /* pointer-sized word */
put_pword(unsigned int val)417*c2c66affSColin Finck void put_pword( unsigned int val )
418*c2c66affSColin Finck {
419*c2c66affSColin Finck if (pointer_size == 8) put_qword( val );
420*c2c66affSColin Finck else put_dword( val );
421*c2c66affSColin Finck }
422*c2c66affSColin Finck
put_str(int indent,const char * format,...)423*c2c66affSColin Finck void put_str( int indent, const char *format, ... )
424*c2c66affSColin Finck {
425*c2c66affSColin Finck int n;
426*c2c66affSColin Finck va_list args;
427*c2c66affSColin Finck
428*c2c66affSColin Finck check_output_buffer_space( 4 * indent );
429*c2c66affSColin Finck memset( output_buffer + output_buffer_pos, ' ', 4 * indent );
430*c2c66affSColin Finck output_buffer_pos += 4 * indent;
431*c2c66affSColin Finck
432*c2c66affSColin Finck for (;;)
433*c2c66affSColin Finck {
434*c2c66affSColin Finck size_t size = output_buffer_size - output_buffer_pos;
435*c2c66affSColin Finck va_start( args, format );
436*c2c66affSColin Finck n = vsnprintf( (char *)output_buffer + output_buffer_pos, size, format, args );
437*c2c66affSColin Finck va_end( args );
438*c2c66affSColin Finck if (n == -1) size *= 2;
439*c2c66affSColin Finck else if ((size_t)n >= size) size = n + 1;
440*c2c66affSColin Finck else
441*c2c66affSColin Finck {
442*c2c66affSColin Finck output_buffer_pos += n;
443*c2c66affSColin Finck return;
444*c2c66affSColin Finck }
445*c2c66affSColin Finck check_output_buffer_space( size );
446*c2c66affSColin Finck }
447*c2c66affSColin Finck }
448*c2c66affSColin Finck
align_output(unsigned int align)449*c2c66affSColin Finck void align_output( unsigned int align )
450*c2c66affSColin Finck {
451*c2c66affSColin Finck size_t size = align - (output_buffer_pos % align);
452*c2c66affSColin Finck
453*c2c66affSColin Finck if (size == align) return;
454*c2c66affSColin Finck check_output_buffer_space( size );
455*c2c66affSColin Finck memset( output_buffer + output_buffer_pos, 0, size );
456*c2c66affSColin Finck output_buffer_pos += size;
457*c2c66affSColin Finck }
458