Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286/* * Utility routines * * Copyright 1998 Bertho A. Stultiens * Copyright 2002 Ove Kaaven * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
#include "config.h"
#include <assert.h>#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <ctype.h>
#include "widl.h"#include "utils.h"#include "parser.h"
void error_at( const struct location *where, const char *s, ... ){ char buffer[1024];
va_list ap; va_start( ap, s ); vsnprintf( buffer, sizeof(buffer), s, ap ); va_end( ap );
parser_error( where, buffer ); exit( 1 );}
void error(const char *s, ...){ va_list ap; va_start(ap, s); fprintf(stderr, "error: "); vfprintf(stderr, s, ap); va_end(ap); exit(2);}
void warning(const char *s, ...){ va_list ap; va_start(ap, s); fprintf(stderr, "warning: "); vfprintf(stderr, s, ap); va_end(ap);}
void warning_at( const struct location *where, const char *s, ... ){ char buffer[1024];
va_list ap; va_start( ap, s ); vsnprintf( buffer, sizeof(buffer), s, ap ); va_end( ap );
parser_warning( where, buffer );}
void chat(const char *s, ...){ if(debuglevel & DEBUGLEVEL_CHAT) { va_list ap; va_start(ap, s); fprintf(stderr, "chat: "); vfprintf(stderr, s, ap); va_end(ap); }}
size_t widl_getline(char **linep, size_t *lenp, FILE *fp){ char *line = *linep; size_t len = *lenp; size_t n = 0;
if (!line) { len = 64; line = xmalloc(len); }
while (fgets(&line[n], len - n, fp)) { n += strlen(&line[n]); if (line[n - 1] == '\n') break; else if (n == len - 1) { len *= 2; line = xrealloc(line, len); } }
*linep = line; *lenp = len; return n;}
size_t strappend(char **buf, size_t *len, size_t pos, const char* fmt, ...){ size_t size; va_list ap; char *ptr; int n;
assert( buf && len ); assert( (*len == 0 && *buf == NULL) || (*len != 0 && *buf != NULL) );
if (*buf) { size = *len; ptr = *buf; } else { size = 100; ptr = xmalloc( size ); }
for (;;) { va_start( ap, fmt ); n = vsnprintf( ptr + pos, size - pos, fmt, ap ); va_end( ap ); if (n == -1) size *= 2; else if (pos + (size_t)n >= size) size = pos + n + 1; else break; ptr = xrealloc( ptr, size ); }
*len = size; *buf = ptr; return n;}
/******************************************************************* * buffer management * * Function for writing to a memory buffer. */
unsigned char *output_buffer;size_t output_buffer_pos;size_t output_buffer_size;
static struct resource{ unsigned char *data; size_t size;} resources[16];static unsigned int nb_resources;
static inline void put_resource_id( const char *str ){ if (str[0] != '#') { while (*str) { unsigned char ch = *str++; put_word( toupper(ch) ); } put_word( 0 ); } else { put_word( 0xffff ); put_word( atoi( str + 1 )); }}
void add_output_to_resources( const char *type, const char *name ){ size_t data_size = output_buffer_pos; size_t header_size = 5 * sizeof(unsigned int) + 2 * sizeof(unsigned short);
assert( nb_resources < ARRAY_SIZE( resources ));
if (type[0] != '#') header_size += (strlen( type ) + 1) * sizeof(unsigned short); else header_size += 2 * sizeof(unsigned short); if (name[0] != '#') header_size += (strlen( name ) + 1) * sizeof(unsigned short); else header_size += 2 * sizeof(unsigned short);
header_size = (header_size + 3) & ~3; align_output( 4 ); check_output_buffer_space( header_size ); resources[nb_resources].size = header_size + output_buffer_pos; memmove( output_buffer + header_size, output_buffer, output_buffer_pos );
output_buffer_pos = 0; put_dword( data_size ); /* ResSize */ put_dword( header_size ); /* HeaderSize */ put_resource_id( type ); /* ResType */ put_resource_id( name ); /* ResName */ align_output( 4 ); put_dword( 0 ); /* DataVersion */ put_word( 0 ); /* Memory options */ put_word( 0 ); /* Language */ put_dword( 0 ); /* Version */ put_dword( 0 ); /* Characteristics */
resources[nb_resources++].data = output_buffer; init_output_buffer();}
void flush_output_resources( const char *name ){ unsigned int i;
/* all output must have been saved with add_output_to_resources() first */ assert( !output_buffer_pos );
put_dword( 0 ); /* ResSize */ put_dword( 32 ); /* HeaderSize */ put_word( 0xffff ); /* ResType */ put_word( 0x0000 ); put_word( 0xffff ); /* ResName */ put_word( 0x0000 ); put_dword( 0 ); /* DataVersion */ put_word( 0 ); /* Memory options */ put_word( 0 ); /* Language */ put_dword( 0 ); /* Version */ put_dword( 0 ); /* Characteristics */
for (i = 0; i < nb_resources; i++) { put_data( resources[i].data, resources[i].size ); free( resources[i].data ); } flush_output_buffer( name ); nb_resources = 0;}
/* pointer-sized word */void put_pword( unsigned int val ){ if (pointer_size == 8) put_qword( val ); else put_dword( val );}
void put_str( int indent, const char *format, ... ){ int n; va_list args;
check_output_buffer_space( 4 * indent ); memset( output_buffer + output_buffer_pos, ' ', 4 * indent ); output_buffer_pos += 4 * indent;
for (;;) { size_t size = output_buffer_size - output_buffer_pos; va_start( args, format ); n = vsnprintf( (char *)output_buffer + output_buffer_pos, size, format, args ); va_end( args ); if (n == -1) size *= 2; else if ((size_t)n >= size) size = n + 1; else { output_buffer_pos += n; return; } check_output_buffer_space( size ); }}