ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

utils.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.