Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenutils.c
Go to the documentation of this file.
00001 /* 00002 * Utility routines 00003 * 00004 * Copyright 1998 Bertho A. Stultiens 00005 * Copyright 2002 Ove Kaaven 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00020 */ 00021 00022 #include "config.h" 00023 #include "wine/port.h" 00024 00025 #include <assert.h> 00026 #include <stdio.h> 00027 #include <stdlib.h> 00028 #include <stdarg.h> 00029 #include <string.h> 00030 #include <ctype.h> 00031 00032 #include "widl.h" 00033 #include "utils.h" 00034 #include "parser.h" 00035 00036 #define CURRENT_LOCATION { input_name ? input_name : "stdin", line_number, parser_text } 00037 00038 static const int want_near_indication = 0; 00039 00040 static void make_print(char *str) 00041 { 00042 while(*str) 00043 { 00044 if(!isprint(*str)) 00045 *str = ' '; 00046 str++; 00047 } 00048 } 00049 00050 static void generic_msg(const loc_info_t *loc_info, const char *s, const char *t, va_list ap) 00051 { 00052 fprintf(stderr, "%s:%d: %s: ", loc_info->input_name, loc_info->line_number, t); 00053 vfprintf(stderr, s, ap); 00054 00055 if (want_near_indication) 00056 { 00057 char *cpy; 00058 if(loc_info->near_text) 00059 { 00060 cpy = xstrdup(loc_info->near_text); 00061 make_print(cpy); 00062 fprintf(stderr, " near '%s'", cpy); 00063 free(cpy); 00064 } 00065 } 00066 } 00067 00068 00069 void error_loc(const char *s, ...) 00070 { 00071 loc_info_t cur_loc = CURRENT_LOCATION; 00072 va_list ap; 00073 va_start(ap, s); 00074 generic_msg(&cur_loc, s, "error", ap); 00075 va_end(ap); 00076 exit(1); 00077 } 00078 00079 /* yyerror: yacc assumes this is not newline terminated. */ 00080 void parser_error(const char *s) 00081 { 00082 error_loc("%s\n", s); 00083 } 00084 00085 void error_loc_info(const loc_info_t *loc_info, const char *s, ...) 00086 { 00087 va_list ap; 00088 va_start(ap, s); 00089 generic_msg(loc_info, s, "error", ap); 00090 va_end(ap); 00091 exit(1); 00092 } 00093 00094 int parser_warning(const char *s, ...) 00095 { 00096 loc_info_t cur_loc = CURRENT_LOCATION; 00097 va_list ap; 00098 va_start(ap, s); 00099 generic_msg(&cur_loc, s, "warning", ap); 00100 va_end(ap); 00101 return 0; 00102 } 00103 00104 void error(const char *s, ...) 00105 { 00106 va_list ap; 00107 va_start(ap, s); 00108 fprintf(stderr, "error: "); 00109 vfprintf(stderr, s, ap); 00110 va_end(ap); 00111 exit(2); 00112 } 00113 00114 void warning(const char *s, ...) 00115 { 00116 va_list ap; 00117 va_start(ap, s); 00118 fprintf(stderr, "warning: "); 00119 vfprintf(stderr, s, ap); 00120 va_end(ap); 00121 } 00122 00123 void warning_loc_info(const loc_info_t *loc_info, const char *s, ...) 00124 { 00125 va_list ap; 00126 va_start(ap, s); 00127 generic_msg(loc_info, s, "warning", ap); 00128 va_end(ap); 00129 } 00130 00131 void chat(const char *s, ...) 00132 { 00133 if(debuglevel & DEBUGLEVEL_CHAT) 00134 { 00135 va_list ap; 00136 va_start(ap, s); 00137 fprintf(stderr, "chat: "); 00138 vfprintf(stderr, s, ap); 00139 va_end(ap); 00140 } 00141 } 00142 00143 char *dup_basename(const char *name, const char *ext) 00144 { 00145 int namelen; 00146 int extlen = strlen(ext); 00147 char *base; 00148 char *slash; 00149 00150 if(!name) 00151 name = "widl.tab"; 00152 00153 slash = strrchr(name, '/'); 00154 if (!slash) 00155 slash = strrchr(name, '\\'); 00156 00157 if (slash) 00158 name = slash + 1; 00159 00160 namelen = strlen(name); 00161 00162 /* +4 for later extension and +1 for '\0' */ 00163 base = xmalloc(namelen +4 +1); 00164 strcpy(base, name); 00165 if(!strcasecmp(name + namelen-extlen, ext)) 00166 { 00167 base[namelen - extlen] = '\0'; 00168 } 00169 return base; 00170 } 00171 00172 size_t widl_getline(char **linep, size_t *lenp, FILE *fp) 00173 { 00174 char *line = *linep; 00175 size_t len = *lenp; 00176 size_t n = 0; 00177 00178 if (!line) 00179 { 00180 len = 64; 00181 line = xmalloc(len); 00182 } 00183 00184 while (fgets(&line[n], len - n, fp)) 00185 { 00186 n += strlen(&line[n]); 00187 if (line[n - 1] == '\n') 00188 break; 00189 else if (n == len - 1) 00190 { 00191 len *= 2; 00192 line = xrealloc(line, len); 00193 } 00194 } 00195 00196 *linep = line; 00197 *lenp = len; 00198 return n; 00199 } 00200 00201 void *xmalloc(size_t size) 00202 { 00203 void *res; 00204 00205 assert(size > 0); 00206 res = malloc(size); 00207 if(res == NULL) 00208 { 00209 error("Virtual memory exhausted.\n"); 00210 } 00211 memset(res, 0x55, size); 00212 return res; 00213 } 00214 00215 00216 void *xrealloc(void *p, size_t size) 00217 { 00218 void *res; 00219 00220 assert(size > 0); 00221 res = realloc(p, size); 00222 if(res == NULL) 00223 { 00224 error("Virtual memory exhausted.\n"); 00225 } 00226 return res; 00227 } 00228 00229 char *xstrdup(const char *str) 00230 { 00231 char *s; 00232 00233 assert(str != NULL); 00234 s = xmalloc(strlen(str)+1); 00235 return strcpy(s, str); 00236 } 00237 00238 int strendswith(const char* str, const char* end) 00239 { 00240 int l = strlen(str); 00241 int m = strlen(end); 00242 return l >= m && strcmp(str + l - m, end) == 0; 00243 } 00244 00245 /******************************************************************* 00246 * buffer management 00247 * 00248 * Function for writing to a memory buffer. 00249 */ 00250 00251 int byte_swapped = 0; 00252 unsigned char *output_buffer; 00253 size_t output_buffer_pos; 00254 size_t output_buffer_size; 00255 00256 static struct resource 00257 { 00258 unsigned char *data; 00259 size_t size; 00260 } resources[16]; 00261 static unsigned int nb_resources; 00262 00263 static void check_output_buffer_space( size_t size ) 00264 { 00265 if (output_buffer_pos + size >= output_buffer_size) 00266 { 00267 output_buffer_size = max( output_buffer_size * 2, output_buffer_pos + size ); 00268 output_buffer = xrealloc( output_buffer, output_buffer_size ); 00269 } 00270 } 00271 00272 void init_output_buffer(void) 00273 { 00274 output_buffer_size = 1024; 00275 output_buffer_pos = 0; 00276 output_buffer = xmalloc( output_buffer_size ); 00277 } 00278 00279 void flush_output_buffer( const char *name ) 00280 { 00281 int fd = open( name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666 ); 00282 if (fd == -1) error( "Error creating %s\n", name ); 00283 if (write( fd, output_buffer, output_buffer_pos ) != output_buffer_pos) 00284 error( "Error writing to %s\n", name ); 00285 close( fd ); 00286 free( output_buffer ); 00287 } 00288 00289 static inline void put_resource_id( const char *str ) 00290 { 00291 if (str[0] != '#') 00292 { 00293 while (*str) 00294 { 00295 unsigned char ch = *str++; 00296 put_word( toupper(ch) ); 00297 } 00298 put_word( 0 ); 00299 } 00300 else 00301 { 00302 put_word( 0xffff ); 00303 put_word( atoi( str + 1 )); 00304 } 00305 } 00306 00307 void add_output_to_resources( const char *type, const char *name ) 00308 { 00309 size_t data_size = output_buffer_pos; 00310 size_t header_size = 5 * sizeof(unsigned int) + 2 * sizeof(unsigned short); 00311 00312 assert( nb_resources < sizeof(resources)/sizeof(resources[0]) ); 00313 00314 if (type[0] != '#') header_size += (strlen( type ) + 1) * sizeof(unsigned short); 00315 else header_size += 2 * sizeof(unsigned short); 00316 if (name[0] != '#') header_size += (strlen( name ) + 1) * sizeof(unsigned short); 00317 else header_size += 2 * sizeof(unsigned short); 00318 00319 header_size = (header_size + 3) & ~3; 00320 align_output( 4 ); 00321 check_output_buffer_space( header_size ); 00322 resources[nb_resources].size = header_size + output_buffer_pos; 00323 memmove( output_buffer + header_size, output_buffer, output_buffer_pos ); 00324 00325 output_buffer_pos = 0; 00326 put_dword( data_size ); /* ResSize */ 00327 put_dword( header_size ); /* HeaderSize */ 00328 put_resource_id( type ); /* ResType */ 00329 put_resource_id( name ); /* ResName */ 00330 align_output( 4 ); 00331 put_dword( 0 ); /* DataVersion */ 00332 put_word( 0 ); /* Memory options */ 00333 put_word( 0 ); /* Language */ 00334 put_dword( 0 ); /* Version */ 00335 put_dword( 0 ); /* Characteristics */ 00336 00337 resources[nb_resources++].data = output_buffer; 00338 init_output_buffer(); 00339 } 00340 00341 void flush_output_resources( const char *name ) 00342 { 00343 int fd; 00344 unsigned int i; 00345 00346 /* all output must have been saved with add_output_to_resources() first */ 00347 assert( !output_buffer_pos ); 00348 00349 put_dword( 0 ); /* ResSize */ 00350 put_dword( 32 ); /* HeaderSize */ 00351 put_word( 0xffff ); /* ResType */ 00352 put_word( 0x0000 ); 00353 put_word( 0xffff ); /* ResName */ 00354 put_word( 0x0000 ); 00355 put_dword( 0 ); /* DataVersion */ 00356 put_word( 0 ); /* Memory options */ 00357 put_word( 0 ); /* Language */ 00358 put_dword( 0 ); /* Version */ 00359 put_dword( 0 ); /* Characteristics */ 00360 00361 fd = open( name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666 ); 00362 if (fd == -1) error( "Error creating %s\n", name ); 00363 if (write( fd, output_buffer, output_buffer_pos ) != output_buffer_pos) 00364 error( "Error writing to %s\n", name ); 00365 for (i = 0; i < nb_resources; i++) 00366 { 00367 if (write( fd, resources[i].data, resources[i].size ) != resources[i].size) 00368 error( "Error writing to %s\n", name ); 00369 free( resources[i].data ); 00370 } 00371 close( fd ); 00372 nb_resources = 0; 00373 free( output_buffer ); 00374 } 00375 00376 void put_data( const void *data, size_t size ) 00377 { 00378 check_output_buffer_space( size ); 00379 memcpy( output_buffer + output_buffer_pos, data, size ); 00380 output_buffer_pos += size; 00381 } 00382 00383 void put_byte( unsigned char val ) 00384 { 00385 check_output_buffer_space( 1 ); 00386 output_buffer[output_buffer_pos++] = val; 00387 } 00388 00389 void put_word( unsigned short val ) 00390 { 00391 if (byte_swapped) val = (val << 8) | (val >> 8); 00392 put_data( &val, sizeof(val) ); 00393 } 00394 00395 void put_dword( unsigned int val ) 00396 { 00397 if (byte_swapped) 00398 val = ((val << 24) | ((val << 8) & 0x00ff0000) | ((val >> 8) & 0x0000ff00) | (val >> 24)); 00399 put_data( &val, sizeof(val) ); 00400 } 00401 00402 void put_qword( unsigned int val ) 00403 { 00404 if (byte_swapped) 00405 { 00406 put_dword( 0 ); 00407 put_dword( val ); 00408 } 00409 else 00410 { 00411 put_dword( val ); 00412 put_dword( 0 ); 00413 } 00414 } 00415 00416 /* pointer-sized word */ 00417 void put_pword( unsigned int val ) 00418 { 00419 if (pointer_size == 8) put_qword( val ); 00420 else put_dword( val ); 00421 } 00422 00423 void put_str( int indent, const char *format, ... ) 00424 { 00425 int n; 00426 va_list args; 00427 00428 check_output_buffer_space( 4 * indent ); 00429 memset( output_buffer + output_buffer_pos, ' ', 4 * indent ); 00430 output_buffer_pos += 4 * indent; 00431 00432 for (;;) 00433 { 00434 size_t size = output_buffer_size - output_buffer_pos; 00435 va_start( args, format ); 00436 n = vsnprintf( (char *)output_buffer + output_buffer_pos, size, format, args ); 00437 va_end( args ); 00438 if (n == -1) size *= 2; 00439 else if ((size_t)n >= size) size = n + 1; 00440 else 00441 { 00442 output_buffer_pos += n; 00443 return; 00444 } 00445 check_output_buffer_space( size ); 00446 } 00447 } 00448 00449 void align_output( unsigned int align ) 00450 { 00451 size_t size = align - (output_buffer_pos % align); 00452 00453 if (size == align) return; 00454 check_output_buffer_space( size ); 00455 memset( output_buffer + output_buffer_pos, 0, size ); 00456 output_buffer_pos += size; 00457 } Generated on Sun May 27 2012 04:22:17 for ReactOS by
1.7.6.1
|