Reactos
at master 285 lines 6.8 kB view raw
1/* 2 * Utility routines 3 * 4 * Copyright 1998 Bertho A. Stultiens 5 * Copyright 2002 Ove Kaaven 6 * 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. 11 * 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. 16 * 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 20 */ 21 22#include "config.h" 23 24#include <assert.h> 25#include <stdio.h> 26#include <stdlib.h> 27#include <stdarg.h> 28#include <string.h> 29#include <ctype.h> 30 31#include "widl.h" 32#include "utils.h" 33#include "parser.h" 34 35void error_at( const struct location *where, const char *s, ... ) 36{ 37 char buffer[1024]; 38 39 va_list ap; 40 va_start( ap, s ); 41 vsnprintf( buffer, sizeof(buffer), s, ap ); 42 va_end( ap ); 43 44 parser_error( where, buffer ); 45 exit( 1 ); 46} 47 48void error(const char *s, ...) 49{ 50 va_list ap; 51 va_start(ap, s); 52 fprintf(stderr, "error: "); 53 vfprintf(stderr, s, ap); 54 va_end(ap); 55 exit(2); 56} 57 58void warning(const char *s, ...) 59{ 60 va_list ap; 61 va_start(ap, s); 62 fprintf(stderr, "warning: "); 63 vfprintf(stderr, s, ap); 64 va_end(ap); 65} 66 67void warning_at( const struct location *where, const char *s, ... ) 68{ 69 char buffer[1024]; 70 71 va_list ap; 72 va_start( ap, s ); 73 vsnprintf( buffer, sizeof(buffer), s, ap ); 74 va_end( ap ); 75 76 parser_warning( where, buffer ); 77} 78 79void chat(const char *s, ...) 80{ 81 if(debuglevel & DEBUGLEVEL_CHAT) 82 { 83 va_list ap; 84 va_start(ap, s); 85 fprintf(stderr, "chat: "); 86 vfprintf(stderr, s, ap); 87 va_end(ap); 88 } 89} 90 91size_t widl_getline(char **linep, size_t *lenp, FILE *fp) 92{ 93 char *line = *linep; 94 size_t len = *lenp; 95 size_t n = 0; 96 97 if (!line) 98 { 99 len = 64; 100 line = xmalloc(len); 101 } 102 103 while (fgets(&line[n], len - n, fp)) 104 { 105 n += strlen(&line[n]); 106 if (line[n - 1] == '\n') 107 break; 108 else if (n == len - 1) 109 { 110 len *= 2; 111 line = xrealloc(line, len); 112 } 113 } 114 115 *linep = line; 116 *lenp = len; 117 return n; 118} 119 120size_t strappend(char **buf, size_t *len, size_t pos, const char* fmt, ...) 121{ 122 size_t size; 123 va_list ap; 124 char *ptr; 125 int n; 126 127 assert( buf && len ); 128 assert( (*len == 0 && *buf == NULL) || (*len != 0 && *buf != NULL) ); 129 130 if (*buf) 131 { 132 size = *len; 133 ptr = *buf; 134 } 135 else 136 { 137 size = 100; 138 ptr = xmalloc( size ); 139 } 140 141 for (;;) 142 { 143 va_start( ap, fmt ); 144 n = vsnprintf( ptr + pos, size - pos, fmt, ap ); 145 va_end( ap ); 146 if (n == -1) size *= 2; 147 else if (pos + (size_t)n >= size) size = pos + n + 1; 148 else break; 149 ptr = xrealloc( ptr, size ); 150 } 151 152 *len = size; 153 *buf = ptr; 154 return n; 155} 156 157/******************************************************************* 158 * buffer management 159 * 160 * Function for writing to a memory buffer. 161 */ 162 163unsigned char *output_buffer; 164size_t output_buffer_pos; 165size_t output_buffer_size; 166 167static struct resource 168{ 169 unsigned char *data; 170 size_t size; 171} resources[16]; 172static unsigned int nb_resources; 173 174static inline void put_resource_id( const char *str ) 175{ 176 if (str[0] != '#') 177 { 178 while (*str) 179 { 180 unsigned char ch = *str++; 181 put_word( toupper(ch) ); 182 } 183 put_word( 0 ); 184 } 185 else 186 { 187 put_word( 0xffff ); 188 put_word( atoi( str + 1 )); 189 } 190} 191 192void add_output_to_resources( const char *type, const char *name ) 193{ 194 size_t data_size = output_buffer_pos; 195 size_t header_size = 5 * sizeof(unsigned int) + 2 * sizeof(unsigned short); 196 197 assert( nb_resources < ARRAY_SIZE( resources )); 198 199 if (type[0] != '#') header_size += (strlen( type ) + 1) * sizeof(unsigned short); 200 else header_size += 2 * sizeof(unsigned short); 201 if (name[0] != '#') header_size += (strlen( name ) + 1) * sizeof(unsigned short); 202 else header_size += 2 * sizeof(unsigned short); 203 204 header_size = (header_size + 3) & ~3; 205 align_output( 4 ); 206 check_output_buffer_space( header_size ); 207 resources[nb_resources].size = header_size + output_buffer_pos; 208 memmove( output_buffer + header_size, output_buffer, output_buffer_pos ); 209 210 output_buffer_pos = 0; 211 put_dword( data_size ); /* ResSize */ 212 put_dword( header_size ); /* HeaderSize */ 213 put_resource_id( type ); /* ResType */ 214 put_resource_id( name ); /* ResName */ 215 align_output( 4 ); 216 put_dword( 0 ); /* DataVersion */ 217 put_word( 0 ); /* Memory options */ 218 put_word( 0 ); /* Language */ 219 put_dword( 0 ); /* Version */ 220 put_dword( 0 ); /* Characteristics */ 221 222 resources[nb_resources++].data = output_buffer; 223 init_output_buffer(); 224} 225 226void flush_output_resources( const char *name ) 227{ 228 unsigned int i; 229 230 /* all output must have been saved with add_output_to_resources() first */ 231 assert( !output_buffer_pos ); 232 233 put_dword( 0 ); /* ResSize */ 234 put_dword( 32 ); /* HeaderSize */ 235 put_word( 0xffff ); /* ResType */ 236 put_word( 0x0000 ); 237 put_word( 0xffff ); /* ResName */ 238 put_word( 0x0000 ); 239 put_dword( 0 ); /* DataVersion */ 240 put_word( 0 ); /* Memory options */ 241 put_word( 0 ); /* Language */ 242 put_dword( 0 ); /* Version */ 243 put_dword( 0 ); /* Characteristics */ 244 245 for (i = 0; i < nb_resources; i++) 246 { 247 put_data( resources[i].data, resources[i].size ); 248 free( resources[i].data ); 249 } 250 flush_output_buffer( name ); 251 nb_resources = 0; 252} 253 254/* pointer-sized word */ 255void put_pword( unsigned int val ) 256{ 257 if (pointer_size == 8) put_qword( val ); 258 else put_dword( val ); 259} 260 261void put_str( int indent, const char *format, ... ) 262{ 263 int n; 264 va_list args; 265 266 check_output_buffer_space( 4 * indent ); 267 memset( output_buffer + output_buffer_pos, ' ', 4 * indent ); 268 output_buffer_pos += 4 * indent; 269 270 for (;;) 271 { 272 size_t size = output_buffer_size - output_buffer_pos; 273 va_start( args, format ); 274 n = vsnprintf( (char *)output_buffer + output_buffer_pos, size, format, args ); 275 va_end( args ); 276 if (n == -1) size *= 2; 277 else if ((size_t)n >= size) size = n + 1; 278 else 279 { 280 output_buffer_pos += n; 281 return; 282 } 283 check_output_buffer_space( size ); 284 } 285}