Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpreproc.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 1998 Bertho A. Stultiens (BS) 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 */ 00018 00019 #include "config.h" 00020 #include "wine/port.h" 00021 00022 #include <assert.h> 00023 #include <ctype.h> 00024 #include <fcntl.h> 00025 #include <stdio.h> 00026 #include <stdlib.h> 00027 #include <string.h> 00028 #include <stdarg.h> 00029 #ifdef HAVE_UNISTD_H 00030 # include <unistd.h> 00031 #endif 00032 #ifdef HAVE_IO_H 00033 # include <io.h> 00034 #endif 00035 00036 #include "wine/wpp.h" 00037 #include "wpp_private.h" 00038 00039 struct pp_status pp_status; 00040 00041 #define HASHKEY 2039 00042 00043 typedef struct pp_def_state 00044 { 00045 struct pp_def_state *next; 00046 pp_entry_t *defines[HASHKEY]; 00047 } pp_def_state_t; 00048 00049 static pp_def_state_t *pp_def_state; 00050 00051 #define MAXIFSTACK 64 00052 static pp_if_state_t if_stack[MAXIFSTACK]; 00053 static int if_stack_idx = 0; 00054 00055 #if 0 00056 void pp_print_status(void) __attribute__((destructor)); 00057 void pp_print_status(void) 00058 { 00059 int i; 00060 int sum; 00061 int total = 0; 00062 pp_entry_t *ppp; 00063 00064 fprintf(stderr, "Defines statistics:\n"); 00065 for(i = 0; i < HASHKEY; i++) 00066 { 00067 sum = 0; 00068 for(ppp = pp_def_state->defines[i]; ppp; ppp = ppp->next) 00069 sum++; 00070 total += sum; 00071 if (sum) fprintf(stderr, "%4d, %3d\n", i, sum); 00072 } 00073 fprintf(stderr, "Total defines: %d\n", total); 00074 } 00075 #endif 00076 00077 void *pp_xmalloc(size_t size) 00078 { 00079 void *res; 00080 00081 assert(size > 0); 00082 res = malloc(size); 00083 if(res == NULL) 00084 { 00085 /* Set the error flag */ 00086 pp_status.state = 1; 00087 } 00088 return res; 00089 } 00090 00091 void *pp_xrealloc(void *p, size_t size) 00092 { 00093 void *res; 00094 00095 assert(size > 0); 00096 res = realloc(p, size); 00097 if(res == NULL) 00098 { 00099 /* Set the error flag */ 00100 pp_status.state = 1; 00101 } 00102 return res; 00103 } 00104 00105 char *pp_xstrdup(const char *str) 00106 { 00107 char *s; 00108 int len; 00109 00110 assert(str != NULL); 00111 len = strlen(str)+1; 00112 s = pp_xmalloc(len); 00113 if(!s) 00114 return NULL; 00115 return memcpy(s, str, len); 00116 } 00117 00118 static char *wpp_default_lookup(const char *name, const char *parent_name, 00119 char **include_path, int include_path_count) 00120 { 00121 char *cpy; 00122 char *cptr; 00123 char *path; 00124 const char *ccptr; 00125 int i, fd; 00126 00127 cpy = pp_xmalloc(strlen(name)+1); 00128 if(!cpy) 00129 return NULL; 00130 cptr = cpy; 00131 00132 for(ccptr = name; *ccptr; ccptr++) 00133 { 00134 /* Convert to forward slash */ 00135 if(*ccptr == '\\') { 00136 /* kill double backslash */ 00137 if(ccptr[1] == '\\') 00138 ccptr++; 00139 *cptr = '/'; 00140 }else { 00141 *cptr = *ccptr; 00142 } 00143 cptr++; 00144 } 00145 *cptr = '\0'; 00146 00147 if(parent_name) 00148 { 00149 /* Search directory of parent include and then -I path */ 00150 const char *p; 00151 00152 if ((p = strrchr( parent_name, '/' ))) p++; 00153 else p = parent_name; 00154 path = pp_xmalloc( (p - parent_name) + strlen(cpy) + 1 ); 00155 if(!path) 00156 { 00157 free(cpy); 00158 return NULL; 00159 } 00160 memcpy( path, parent_name, p - parent_name ); 00161 strcpy( path + (p - parent_name), cpy ); 00162 fd = open( path, O_RDONLY ); 00163 if (fd != -1) 00164 { 00165 close( fd ); 00166 free( cpy ); 00167 return path; 00168 } 00169 free( path ); 00170 } 00171 /* Search -I path */ 00172 for(i = 0; i < include_path_count; i++) 00173 { 00174 path = pp_xmalloc(strlen(include_path[i]) + strlen(cpy) + 2); 00175 if(!path) 00176 { 00177 free(cpy); 00178 return NULL; 00179 } 00180 strcpy(path, include_path[i]); 00181 strcat(path, "/"); 00182 strcat(path, cpy); 00183 fd = open( path, O_RDONLY ); 00184 if (fd != -1) 00185 { 00186 close( fd ); 00187 free( cpy ); 00188 return path; 00189 } 00190 free( path ); 00191 } 00192 free( cpy ); 00193 return NULL; 00194 } 00195 00196 static void *wpp_default_open(const char *filename, int type) { 00197 return fopen(filename,"rt"); 00198 } 00199 00200 static void wpp_default_close(void *file) { 00201 fclose(file); 00202 } 00203 00204 static int wpp_default_read(void *file, char *buffer, unsigned int len){ 00205 return fread(buffer, 1, len, file); 00206 } 00207 00208 static void wpp_default_write( const char *buffer, unsigned int len ) { 00209 fwrite(buffer, 1, len, ppy_out); 00210 } 00211 00212 /* Don't comment on the hash, its primitive but functional... */ 00213 static int pphash(const char *str) 00214 { 00215 int sum = 0; 00216 while(*str) 00217 sum += *str++; 00218 return sum % HASHKEY; 00219 } 00220 00221 pp_entry_t *pplookup(const char *ident) 00222 { 00223 int idx; 00224 pp_entry_t *ppp; 00225 00226 if(!ident) 00227 return NULL; 00228 idx = pphash(ident); 00229 for(ppp = pp_def_state->defines[idx]; ppp; ppp = ppp->next) 00230 { 00231 if(!strcmp(ident, ppp->ident)) 00232 return ppp; 00233 } 00234 return NULL; 00235 } 00236 00237 static void free_pp_entry( pp_entry_t *ppp, int idx ) 00238 { 00239 if(ppp->iep) 00240 { 00241 if(ppp->iep == pp_includelogiclist) 00242 { 00243 pp_includelogiclist = ppp->iep->next; 00244 if(pp_includelogiclist) 00245 pp_includelogiclist->prev = NULL; 00246 } 00247 else 00248 { 00249 ppp->iep->prev->next = ppp->iep->next; 00250 if(ppp->iep->next) 00251 ppp->iep->next->prev = ppp->iep->prev; 00252 } 00253 free(ppp->iep->filename); 00254 free(ppp->iep); 00255 } 00256 00257 if(pp_def_state->defines[idx] == ppp) 00258 { 00259 pp_def_state->defines[idx] = ppp->next; 00260 if(pp_def_state->defines[idx]) 00261 pp_def_state->defines[idx]->prev = NULL; 00262 } 00263 else 00264 { 00265 ppp->prev->next = ppp->next; 00266 if(ppp->next) 00267 ppp->next->prev = ppp->prev; 00268 } 00269 00270 free(ppp); 00271 } 00272 00273 /* push a new (empty) define state */ 00274 int pp_push_define_state(void) 00275 { 00276 pp_def_state_t *state = pp_xmalloc( sizeof(*state) ); 00277 if(!state) 00278 return 1; 00279 00280 memset( state->defines, 0, sizeof(state->defines) ); 00281 state->next = pp_def_state; 00282 pp_def_state = state; 00283 return 0; 00284 } 00285 00286 /* pop the current define state */ 00287 void pp_pop_define_state(void) 00288 { 00289 int i; 00290 pp_entry_t *ppp; 00291 pp_def_state_t *state; 00292 00293 for (i = 0; i < HASHKEY; i++) 00294 { 00295 while ((ppp = pp_def_state->defines[i]) != NULL) free_pp_entry( ppp, i ); 00296 } 00297 state = pp_def_state; 00298 pp_def_state = state->next; 00299 free( state ); 00300 } 00301 00302 void pp_del_define(const char *name) 00303 { 00304 pp_entry_t *ppp; 00305 00306 if((ppp = pplookup(name)) == NULL) 00307 { 00308 if(pp_status.pedantic) 00309 ppy_warning("%s was not defined", name); 00310 return; 00311 } 00312 00313 free( ppp->ident ); 00314 free( ppp->subst.text ); 00315 free( ppp->filename ); 00316 free_pp_entry( ppp, pphash(name) ); 00317 00318 if(pp_status.debug) 00319 printf("Deleted (%s, %d) <%s>\n", pp_status.input, pp_status.line_number, name); 00320 } 00321 00322 pp_entry_t *pp_add_define(const char *def, const char *text) 00323 { 00324 int len; 00325 char *cptr; 00326 int idx; 00327 pp_entry_t *ppp; 00328 00329 if(!def) 00330 return NULL; 00331 idx = pphash(def); 00332 if((ppp = pplookup(def)) != NULL) 00333 { 00334 if(pp_status.pedantic) 00335 ppy_warning("Redefinition of %s\n\tPrevious definition: %s:%d", def, ppp->filename, ppp->linenumber); 00336 pp_del_define(def); 00337 } 00338 ppp = pp_xmalloc(sizeof(pp_entry_t)); 00339 if(!ppp) 00340 return NULL; 00341 memset( ppp, 0, sizeof(*ppp) ); 00342 ppp->ident = pp_xstrdup(def); 00343 if(!ppp->ident) 00344 goto error; 00345 ppp->type = def_define; 00346 ppp->subst.text = text ? pp_xstrdup(text) : NULL; 00347 if(text && !ppp->subst.text) 00348 goto error; 00349 ppp->filename = pp_xstrdup(pp_status.input ? pp_status.input : "<internal or cmdline>"); 00350 if(!ppp->filename) 00351 goto error; 00352 ppp->linenumber = pp_status.input ? pp_status.line_number : 0; 00353 ppp->next = pp_def_state->defines[idx]; 00354 pp_def_state->defines[idx] = ppp; 00355 if(ppp->next) 00356 ppp->next->prev = ppp; 00357 if(ppp->subst.text) 00358 { 00359 /* Strip trailing white space from subst text */ 00360 len = strlen(ppp->subst.text); 00361 while(len && strchr(" \t\r\n", ppp->subst.text[len-1])) 00362 { 00363 ppp->subst.text[--len] = '\0'; 00364 } 00365 /* Strip leading white space from subst text */ 00366 for(cptr = ppp->subst.text; *cptr && strchr(" \t\r", *cptr); cptr++) 00367 ; 00368 if(ppp->subst.text != cptr) 00369 memmove(ppp->subst.text, cptr, strlen(cptr)+1); 00370 } 00371 if(pp_status.debug) 00372 printf("Added define (%s, %d) <%s> to <%s>\n", pp_status.input, pp_status.line_number, ppp->ident, ppp->subst.text ? ppp->subst.text : "(null)"); 00373 00374 return ppp; 00375 00376 error: 00377 free(ppp->ident); 00378 free(ppp->subst.text); 00379 free(ppp); 00380 return NULL; 00381 } 00382 00383 pp_entry_t *pp_add_macro(char *id, marg_t *args[], int nargs, mtext_t *exp) 00384 { 00385 int idx; 00386 pp_entry_t *ppp; 00387 00388 if(!id) 00389 return NULL; 00390 idx = pphash(id); 00391 if((ppp = pplookup(id)) != NULL) 00392 { 00393 if(pp_status.pedantic) 00394 ppy_warning("Redefinition of %s\n\tPrevious definition: %s:%d", id, ppp->filename, ppp->linenumber); 00395 pp_del_define(id); 00396 } 00397 ppp = pp_xmalloc(sizeof(pp_entry_t)); 00398 if(!ppp) 00399 return NULL; 00400 memset( ppp, 0, sizeof(*ppp) ); 00401 ppp->ident = id; 00402 ppp->type = def_macro; 00403 ppp->margs = args; 00404 ppp->nargs = nargs; 00405 ppp->subst.mtext= exp; 00406 ppp->filename = pp_xstrdup(pp_status.input ? pp_status.input : "<internal or cmdline>"); 00407 if(!ppp->filename) 00408 { 00409 free(ppp); 00410 return NULL; 00411 } 00412 ppp->linenumber = pp_status.input ? pp_status.line_number : 0; 00413 ppp->next = pp_def_state->defines[idx]; 00414 pp_def_state->defines[idx] = ppp; 00415 if(ppp->next) 00416 ppp->next->prev = ppp; 00417 00418 if(pp_status.debug) 00419 { 00420 fprintf(stderr, "Added macro (%s, %d) <%s(%d)> to <", pp_status.input, pp_status.line_number, ppp->ident, nargs); 00421 for(; exp; exp = exp->next) 00422 { 00423 switch(exp->type) 00424 { 00425 case exp_text: 00426 fprintf(stderr, " \"%s\" ", exp->subst.text); 00427 break; 00428 case exp_stringize: 00429 fprintf(stderr, " #(%d) ", exp->subst.argidx); 00430 break; 00431 case exp_concat: 00432 fprintf(stderr, "##"); 00433 break; 00434 case exp_subst: 00435 fprintf(stderr, " <%d> ", exp->subst.argidx); 00436 break; 00437 } 00438 } 00439 fprintf(stderr, ">\n"); 00440 } 00441 return ppp; 00442 } 00443 00444 00445 /* 00446 *------------------------------------------------------------------------- 00447 * Include management 00448 *------------------------------------------------------------------------- 00449 */ 00450 #if defined(_Windows) || defined(__MSDOS__) 00451 #define INCLUDESEPARATOR ";" 00452 #else 00453 #define INCLUDESEPARATOR ":" 00454 #endif 00455 00456 static char **includepath; 00457 static int nincludepath = 0; 00458 00459 int wpp_add_include_path(const char *path) 00460 { 00461 char *tok; 00462 char *cpy = pp_xstrdup(path); 00463 if(!cpy) 00464 return 1; 00465 00466 tok = strtok(cpy, INCLUDESEPARATOR); 00467 while(tok) 00468 { 00469 if(*tok) { 00470 char *dir; 00471 char *cptr; 00472 char **new_path; 00473 00474 dir = pp_xstrdup(tok); 00475 if(!dir) 00476 { 00477 free(cpy); 00478 return 1; 00479 } 00480 for(cptr = dir; *cptr; cptr++) 00481 { 00482 /* Convert to forward slash */ 00483 if(*cptr == '\\') 00484 *cptr = '/'; 00485 } 00486 /* Kill eventual trailing '/' */ 00487 if(*(cptr = dir + strlen(dir)-1) == '/') 00488 *cptr = '\0'; 00489 00490 /* Add to list */ 00491 new_path = pp_xrealloc(includepath, (nincludepath+1) * sizeof(*includepath)); 00492 if(!new_path) 00493 { 00494 free(dir); 00495 free(cpy); 00496 return 1; 00497 } 00498 includepath = new_path; 00499 includepath[nincludepath] = dir; 00500 nincludepath++; 00501 } 00502 tok = strtok(NULL, INCLUDESEPARATOR); 00503 } 00504 free(cpy); 00505 return 0; 00506 } 00507 00508 char *wpp_find_include(const char *name, const char *parent_name) 00509 { 00510 return wpp_default_lookup(name, parent_name, includepath, nincludepath); 00511 } 00512 00513 void *pp_open_include(const char *name, const char *parent_name, char **newpath) 00514 { 00515 char *path; 00516 void *fp; 00517 00518 if (!(path = wpp_callbacks->lookup(name, parent_name, includepath, 00519 nincludepath))) return NULL; 00520 fp = wpp_callbacks->open(path, parent_name == NULL ? 1 : 0); 00521 00522 if (fp) 00523 { 00524 if (pp_status.debug) 00525 printf("Going to include <%s>\n", path); 00526 if (newpath) *newpath = path; 00527 else free( path ); 00528 return fp; 00529 } 00530 free( path ); 00531 return NULL; 00532 } 00533 00534 /* 00535 *------------------------------------------------------------------------- 00536 * #if, #ifdef, #ifndef, #else, #elif and #endif state management 00537 * 00538 * #if state transitions are made on basis of the current TOS and the next 00539 * required state. The state transitions are required to housekeep because 00540 * #if:s can be nested. The ignore case is activated to prevent output from 00541 * within a false clause. 00542 * Some special cases come from the fact that the #elif cases are not 00543 * binary, but three-state. The problem is that all other elif-cases must 00544 * be false when one true one has been found. A second problem is that the 00545 * #else clause is a final clause. No extra #else:s may follow. 00546 * 00547 * The states mean: 00548 * if_true Process input to output 00549 * if_false Process input but no output 00550 * if_ignore Process input but no output 00551 * if_elif Process input but no output 00552 * if_elsefalse Process input but no output 00553 * if_elsettrue Process input to output 00554 * 00555 * The possible state-sequences are [state(stack depth)] (rest can be deduced): 00556 * TOS #if 1 #else #endif 00557 * if_true(n) if_true(n+1) if_elsefalse(n+1) 00558 * if_false(n) if_ignore(n+1) if_ignore(n+1) 00559 * if_elsetrue(n) if_true(n+1) if_elsefalse(n+1) 00560 * if_elsefalse(n) if_ignore(n+1) if_ignore(n+1) 00561 * if_elif(n) if_ignore(n+1) if_ignore(n+1) 00562 * if_ignore(n) if_ignore(n+1) if_ignore(n+1) 00563 * 00564 * TOS #if 1 #elif 0 #else #endif 00565 * if_true(n) if_true(n+1) if_elif(n+1) if_elif(n+1) 00566 * if_false(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1) 00567 * if_elsetrue(n) if_true(n+1) if_elif(n+1) if_elif(n+1) 00568 * if_elsefalse(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1) 00569 * if_elif(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1) 00570 * if_ignore(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1) 00571 * 00572 * TOS #if 0 #elif 1 #else #endif 00573 * if_true(n) if_false(n+1) if_true(n+1) if_elsefalse(n+1) 00574 * if_false(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1) 00575 * if_elsetrue(n) if_false(n+1) if_true(n+1) if_elsefalse(n+1) 00576 * if_elsefalse(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1) 00577 * if_elif(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1) 00578 * if_ignore(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1) 00579 * 00580 *------------------------------------------------------------------------- 00581 */ 00582 static const char * const pp_if_state_str[] = { 00583 "if_false", 00584 "if_true", 00585 "if_elif", 00586 "if_elsefalse", 00587 "if_elsetrue", 00588 "if_ignore" 00589 }; 00590 00591 void pp_push_if(pp_if_state_t s) 00592 { 00593 if(if_stack_idx >= MAXIFSTACK) 00594 pp_internal_error(__FILE__, __LINE__, "#if-stack overflow; #{if,ifdef,ifndef} nested too deeply (> %d)", MAXIFSTACK); 00595 00596 if(pp_flex_debug) 00597 fprintf(stderr, "Push if %s:%d: %s(%d) -> %s(%d)\n", pp_status.input, pp_status.line_number, pp_if_state_str[pp_if_state()], if_stack_idx, pp_if_state_str[s], if_stack_idx+1); 00598 00599 if_stack[if_stack_idx++] = s; 00600 00601 switch(s) 00602 { 00603 case if_true: 00604 case if_elsetrue: 00605 break; 00606 case if_false: 00607 case if_elsefalse: 00608 case if_elif: 00609 case if_ignore: 00610 pp_push_ignore_state(); 00611 break; 00612 default: 00613 pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d)", (int)pp_if_state()); 00614 } 00615 } 00616 00617 pp_if_state_t pp_pop_if(void) 00618 { 00619 if(if_stack_idx <= 0) 00620 { 00621 ppy_error("#{endif,else,elif} without #{if,ifdef,ifndef} (#if-stack underflow)"); 00622 return if_error; 00623 } 00624 00625 switch(pp_if_state()) 00626 { 00627 case if_true: 00628 case if_elsetrue: 00629 break; 00630 case if_false: 00631 case if_elsefalse: 00632 case if_elif: 00633 case if_ignore: 00634 pp_pop_ignore_state(); 00635 break; 00636 default: 00637 pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d)", (int)pp_if_state()); 00638 } 00639 00640 if(pp_flex_debug) 00641 fprintf(stderr, "Pop if %s:%d: %s(%d) -> %s(%d)\n", 00642 pp_status.input, 00643 pp_status.line_number, 00644 pp_if_state_str[pp_if_state()], 00645 if_stack_idx, 00646 pp_if_state_str[if_stack[if_stack_idx <= 1 ? if_true : if_stack_idx-2]], 00647 if_stack_idx-1); 00648 00649 return if_stack[--if_stack_idx]; 00650 } 00651 00652 pp_if_state_t pp_if_state(void) 00653 { 00654 if(!if_stack_idx) 00655 return if_true; 00656 else 00657 return if_stack[if_stack_idx-1]; 00658 } 00659 00660 00661 void pp_next_if_state(int i) 00662 { 00663 switch(pp_if_state()) 00664 { 00665 case if_true: 00666 case if_elsetrue: 00667 pp_push_if(i ? if_true : if_false); 00668 break; 00669 case if_false: 00670 case if_elsefalse: 00671 case if_elif: 00672 case if_ignore: 00673 pp_push_if(if_ignore); 00674 break; 00675 default: 00676 pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d) in #{if,ifdef,ifndef} directive", (int)pp_if_state()); 00677 } 00678 } 00679 00680 int pp_get_if_depth(void) 00681 { 00682 return if_stack_idx; 00683 } 00684 00685 /* #define WANT_NEAR_INDICATION */ 00686 00687 static void generic_msg(const char *s, const char *t, const char *n, va_list ap) 00688 { 00689 fprintf(stderr, "%s:%d:%d: %s: ", pp_status.input ? pp_status.input : "stdin", 00690 pp_status.line_number, pp_status.char_number, t); 00691 vfprintf(stderr, s, ap); 00692 #ifdef WANT_NEAR_INDICATION 00693 { 00694 char *cpy, *p; 00695 if(n) 00696 { 00697 cpy = pp_xstrdup(n); 00698 if(!cpy) 00699 goto end; 00700 for (p = cpy; *p; p++) if(!isprint(*p)) *p = ' '; 00701 fprintf(stderr, " near '%s'", cpy); 00702 free(cpy); 00703 } 00704 } 00705 end: 00706 #endif 00707 fprintf(stderr, "\n"); 00708 } 00709 00710 static void wpp_default_error(const char *file, int line, int col, const char *near, const char *msg, va_list ap) 00711 { 00712 generic_msg(msg, "Error", near, ap); 00713 exit(1); 00714 } 00715 00716 static void wpp_default_warning(const char *file, int line, int col, const char *near, const char *msg, va_list ap) 00717 { 00718 generic_msg(msg, "Warning", near, ap); 00719 } 00720 00721 static const struct wpp_callbacks default_callbacks = 00722 { 00723 wpp_default_lookup, 00724 wpp_default_open, 00725 wpp_default_close, 00726 wpp_default_read, 00727 wpp_default_write, 00728 wpp_default_error, 00729 wpp_default_warning, 00730 }; 00731 00732 const struct wpp_callbacks *wpp_callbacks = &default_callbacks; 00733 00734 int ppy_error(const char *s, ...) 00735 { 00736 va_list ap; 00737 va_start(ap, s); 00738 wpp_callbacks->error(pp_status.input, pp_status.line_number, pp_status.char_number, ppy_text, s, ap); 00739 va_end(ap); 00740 pp_status.state = 1; 00741 return 1; 00742 } 00743 00744 int ppy_warning(const char *s, ...) 00745 { 00746 va_list ap; 00747 va_start(ap, s); 00748 wpp_callbacks->warning(pp_status.input, pp_status.line_number, pp_status.char_number, ppy_text, s, ap); 00749 va_end(ap); 00750 return 0; 00751 } 00752 00753 void pp_internal_error(const char *file, int line, const char *s, ...) 00754 { 00755 va_list ap; 00756 va_start(ap, s); 00757 fprintf(stderr, "Internal error (please report) %s %d: ", file, line); 00758 vfprintf(stderr, s, ap); 00759 fprintf(stderr, "\n"); 00760 va_end(ap); 00761 exit(3); 00762 } Generated on Sun May 27 2012 04:19:38 for ReactOS by
1.7.6.1
|