00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024
00025 #include "cpplib.h"
00026 #include "cpphash.h"
00027 #include "obstack.h"
00028
00029
00030 struct answer
00031 {
00032 struct answer *next;
00033 unsigned int count;
00034 cpp_token first[1];
00035 };
00036
00037
00038
00039 struct if_stack
00040 {
00041 struct if_stack *next;
00042 unsigned int line;
00043 const cpp_hashnode *mi_cmacro;
00044 bool skip_elses;
00045 bool was_skipping;
00046 int type;
00047 };
00048
00049
00050 typedef void (*pragma_cb) PARAMS ((cpp_reader *));
00051 struct pragma_entry
00052 {
00053 struct pragma_entry *next;
00054 const cpp_hashnode *pragma;
00055 int is_nspace;
00056 union {
00057 pragma_cb handler;
00058 struct pragma_entry *space;
00059 } u;
00060 };
00061
00062
00063
00064
00065 #define KANDR 0
00066 #define STDC89 1
00067 #define EXTENSION 2
00068
00069
00070
00071
00072
00073
00074
00075
00076 #define COND (1 << 0)
00077 #define IF_COND (1 << 1)
00078 #define INCL (1 << 2)
00079 #define IN_I (1 << 3)
00080 #define EXPAND (1 << 4)
00081
00082
00083 typedef void (*directive_handler) PARAMS ((cpp_reader *));
00084 typedef struct directive directive;
00085 struct directive
00086 {
00087 directive_handler handler;
00088 const uchar *name;
00089 unsigned short length;
00090 unsigned char origin;
00091 unsigned char flags;
00092 };
00093
00094
00095
00096 static void skip_rest_of_line PARAMS ((cpp_reader *));
00097 static void check_eol PARAMS ((cpp_reader *));
00098 static void start_directive PARAMS ((cpp_reader *));
00099 static void prepare_directive_trad PARAMS ((cpp_reader *));
00100 static void end_directive PARAMS ((cpp_reader *, int));
00101 static void directive_diagnostics
00102 PARAMS ((cpp_reader *, const directive *, int));
00103 static void run_directive PARAMS ((cpp_reader *, int,
00104 const char *, size_t));
00105 static const cpp_token *glue_header_name PARAMS ((cpp_reader *));
00106 static const cpp_token *parse_include PARAMS ((cpp_reader *));
00107 static void push_conditional PARAMS ((cpp_reader *, int, int,
00108 const cpp_hashnode *));
00109 static unsigned int read_flag PARAMS ((cpp_reader *, unsigned int));
00110 static uchar *dequote_string PARAMS ((cpp_reader *, const uchar *,
00111 unsigned int));
00112 static int strtoul_for_line PARAMS ((const uchar *, unsigned int,
00113 unsigned long *));
00114 static void do_diagnostic PARAMS ((cpp_reader *, int, int));
00115 static cpp_hashnode *lex_macro_node PARAMS ((cpp_reader *));
00116 static void do_include_common PARAMS ((cpp_reader *, enum include_type));
00117 static struct pragma_entry *lookup_pragma_entry
00118 PARAMS ((struct pragma_entry *, const cpp_hashnode *pragma));
00119 static struct pragma_entry *insert_pragma_entry
00120 PARAMS ((cpp_reader *, struct pragma_entry **, const cpp_hashnode *,
00121 pragma_cb));
00122 static void do_pragma_once PARAMS ((cpp_reader *));
00123 static void do_pragma_poison PARAMS ((cpp_reader *));
00124 static void do_pragma_system_header PARAMS ((cpp_reader *));
00125 static void do_pragma_dependency PARAMS ((cpp_reader *));
00126 static void do_linemarker PARAMS ((cpp_reader *));
00127 static const cpp_token *get_token_no_padding PARAMS ((cpp_reader *));
00128 static const cpp_token *get__Pragma_string PARAMS ((cpp_reader *));
00129 static void destringize_and_run PARAMS ((cpp_reader *, const cpp_string *));
00130 static int parse_answer PARAMS ((cpp_reader *, struct answer **, int));
00131 static cpp_hashnode *parse_assertion PARAMS ((cpp_reader *, struct answer **,
00132 int));
00133 static struct answer ** find_answer PARAMS ((cpp_hashnode *,
00134 const struct answer *));
00135 static void handle_assertion PARAMS ((cpp_reader *, const char *, int));
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 #define DIRECTIVE_TABLE \
00147 D(define, T_DEFINE = 0, KANDR, IN_I) \
00148 D(include, T_INCLUDE, KANDR, INCL | EXPAND) \
00149 D(endif, T_ENDIF, KANDR, COND) \
00150 D(ifdef, T_IFDEF, KANDR, COND | IF_COND) \
00151 D(if, T_IF, KANDR, COND | IF_COND | EXPAND) \
00152 D(else, T_ELSE, KANDR, COND) \
00153 D(ifndef, T_IFNDEF, KANDR, COND | IF_COND) \
00154 D(undef, T_UNDEF, KANDR, IN_I) \
00155 D(line, T_LINE, KANDR, EXPAND) \
00156 D(elif, T_ELIF, STDC89, COND | EXPAND) \
00157 D(error, T_ERROR, STDC89, 0) \
00158 D(pragma, T_PRAGMA, STDC89, IN_I) \
00159 D(warning, T_WARNING, EXTENSION, 0) \
00160 D(include_next, T_INCLUDE_NEXT, EXTENSION, INCL | EXPAND) \
00161 D(ident, T_IDENT, EXTENSION, IN_I) \
00162 D(import, T_IMPORT, EXTENSION, INCL | EXPAND) \
00163 D(assert, T_ASSERT, EXTENSION, 0) \
00164 D(unassert, T_UNASSERT, EXTENSION, 0) \
00165 D(sccs, T_SCCS, EXTENSION, 0)
00166
00167
00168
00169
00170
00171 #define D(name, t, o, f) static void CONCAT2(do_,name) PARAMS ((cpp_reader *));
00172 DIRECTIVE_TABLE
00173 #undef D
00174
00175 #define D(n, tag, o, f) tag,
00176 enum
00177 {
00178 DIRECTIVE_TABLE
00179 N_DIRECTIVES
00180 };
00181 #undef D
00182
00183
00184 #define D(name, t, origin, flags) \
00185 { CONCAT2(do_,name), (const uchar *) STRINGX(name), \
00186 sizeof STRINGX(name) - 1, origin, flags },
00187 static const directive dtable[] =
00188 {
00189 DIRECTIVE_TABLE
00190 };
00191 #undef D
00192 #undef DIRECTIVE_TABLE
00193
00194
00195
00196
00197 static const directive linemarker_dir =
00198 {
00199 do_linemarker, U"#", 1, KANDR, IN_I
00200 };
00201
00202 #define SEEN_EOL() (pfile->cur_token[-1].type == CPP_EOF)
00203
00204
00205 static void
00206 skip_rest_of_line (pfile)
00207 cpp_reader *pfile;
00208 {
00209
00210 while (pfile->context->prev)
00211 _cpp_pop_context (pfile);
00212
00213
00214 if (! SEEN_EOL ())
00215 while (_cpp_lex_token (pfile)->type != CPP_EOF)
00216 ;
00217 }
00218
00219
00220 static void
00221 check_eol (pfile)
00222 cpp_reader *pfile;
00223 {
00224 if (! SEEN_EOL () && _cpp_lex_token (pfile)->type != CPP_EOF)
00225 cpp_error (pfile, DL_PEDWARN, "extra tokens at end of #%s directive",
00226 pfile->directive->name);
00227 }
00228
00229
00230 static void
00231 start_directive (pfile)
00232 cpp_reader *pfile;
00233 {
00234
00235 pfile->state.in_directive = 1;
00236 pfile->state.save_comments = 0;
00237
00238
00239 pfile->directive_line = pfile->line;
00240 }
00241
00242
00243 static void
00244 end_directive (pfile, skip_line)
00245 cpp_reader *pfile;
00246 int skip_line;
00247 {
00248 if (CPP_OPTION (pfile, traditional))
00249 {
00250
00251 pfile->state.prevent_expansion--;
00252
00253 if (pfile->directive != &dtable[T_DEFINE])
00254 _cpp_remove_overlay (pfile);
00255 }
00256
00257 else if (skip_line)
00258 {
00259 skip_rest_of_line (pfile);
00260 if (!pfile->keep_tokens)
00261 {
00262 pfile->cur_run = &pfile->base_run;
00263 pfile->cur_token = pfile->base_run.base;
00264 }
00265 }
00266
00267
00268 pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
00269 pfile->state.in_directive = 0;
00270 pfile->state.in_expression = 0;
00271 pfile->state.angled_headers = 0;
00272 pfile->directive = 0;
00273 }
00274
00275
00276 static void
00277 prepare_directive_trad (pfile)
00278 cpp_reader *pfile;
00279 {
00280 if (pfile->directive != &dtable[T_DEFINE])
00281 {
00282 bool no_expand = (pfile->directive
00283 && ! (pfile->directive->flags & EXPAND));
00284 bool was_skipping = pfile->state.skipping;
00285
00286 pfile->state.skipping = false;
00287 pfile->state.in_expression = (pfile->directive == &dtable[T_IF]
00288 || pfile->directive == &dtable[T_ELIF]);
00289 if (no_expand)
00290 pfile->state.prevent_expansion++;
00291 _cpp_read_logical_line_trad (pfile);
00292 if (no_expand)
00293 pfile->state.prevent_expansion--;
00294 pfile->state.skipping = was_skipping;
00295 _cpp_overlay_buffer (pfile, pfile->out.base,
00296 pfile->out.cur - pfile->out.base);
00297 }
00298
00299
00300 pfile->state.prevent_expansion++;
00301 }
00302
00303
00304
00305 static void
00306 directive_diagnostics (pfile, dir, indented)
00307 cpp_reader *pfile;
00308 const directive *dir;
00309 int indented;
00310 {
00311
00312 if (CPP_PEDANTIC (pfile)
00313 && ! pfile->state.skipping
00314 && dir->origin == EXTENSION)
00315 cpp_error (pfile, DL_PEDWARN, "#%s is a GCC extension", dir->name);
00316
00317
00318
00319
00320
00321
00322
00323 if (CPP_WTRADITIONAL (pfile))
00324 {
00325 if (dir == &dtable[T_ELIF])
00326 cpp_error (pfile, DL_WARNING,
00327 "suggest not using #elif in traditional C");
00328 else if (indented && dir->origin == KANDR)
00329 cpp_error (pfile, DL_WARNING,
00330 "traditional C ignores #%s with the # indented",
00331 dir->name);
00332 else if (!indented && dir->origin != KANDR)
00333 cpp_error (pfile, DL_WARNING,
00334 "suggest hiding #%s from traditional C with an indented #",
00335 dir->name);
00336 }
00337 }
00338
00339
00340
00341
00342
00343
00344 int
00345 _cpp_handle_directive (pfile, indented)
00346 cpp_reader *pfile;
00347 int indented;
00348 {
00349 const directive *dir = 0;
00350 const cpp_token *dname;
00351 bool was_parsing_args = pfile->state.parsing_args;
00352 int skip = 1;
00353
00354 if (was_parsing_args)
00355 {
00356 if (CPP_OPTION (pfile, pedantic))
00357 cpp_error (pfile, DL_PEDWARN,
00358 "embedding a directive within macro arguments is not portable");
00359 pfile->state.parsing_args = 0;
00360 pfile->state.prevent_expansion = 0;
00361 }
00362 start_directive (pfile);
00363 dname = _cpp_lex_token (pfile);
00364
00365 if (dname->type == CPP_NAME)
00366 {
00367 if (dname->val.node->directive_index)
00368 dir = &dtable[dname->val.node->directive_index - 1];
00369 }
00370
00371
00372 else if (dname->type == CPP_NUMBER && CPP_OPTION (pfile, lang) != CLK_ASM)
00373 {
00374 dir = &linemarker_dir;
00375 if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, preprocessed)
00376 && ! pfile->state.skipping)
00377 cpp_error (pfile, DL_PEDWARN,
00378 "style of line directive is a GCC extension");
00379 }
00380
00381 if (dir)
00382 {
00383
00384
00385 if (! (dir->flags & IF_COND))
00386 pfile->mi_valid = false;
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 if (CPP_OPTION (pfile, preprocessed)
00398 && (indented || !(dir->flags & IN_I)))
00399 {
00400 skip = 0;
00401 dir = 0;
00402 }
00403 else
00404 {
00405
00406
00407
00408
00409 pfile->state.angled_headers = dir->flags & INCL;
00410 pfile->state.directive_wants_padding = dir->flags & INCL;
00411 if (! CPP_OPTION (pfile, preprocessed))
00412 directive_diagnostics (pfile, dir, indented);
00413 if (pfile->state.skipping && !(dir->flags & COND))
00414 dir = 0;
00415 }
00416 }
00417 else if (dname->type == CPP_EOF)
00418 ;
00419 else
00420 {
00421
00422
00423
00424
00425 if (CPP_OPTION (pfile, lang) == CLK_ASM)
00426 skip = 0;
00427 else if (!pfile->state.skipping)
00428 cpp_error (pfile, DL_ERROR, "invalid preprocessing directive #%s",
00429 cpp_token_as_text (pfile, dname));
00430 }
00431
00432 pfile->directive = dir;
00433 if (CPP_OPTION (pfile, traditional))
00434 prepare_directive_trad (pfile);
00435
00436 if (dir)
00437 (*pfile->directive->handler) (pfile);
00438 else if (skip == 0)
00439 _cpp_backup_tokens (pfile, 1);
00440
00441 end_directive (pfile, skip);
00442 if (was_parsing_args)
00443 {
00444
00445 pfile->state.parsing_args = 2;
00446 pfile->state.prevent_expansion = 1;
00447 pfile->buffer->saved_flags |= PREV_WHITE;
00448 }
00449 return skip;
00450 }
00451
00452
00453
00454 static void
00455 run_directive (pfile, dir_no, buf, count)
00456 cpp_reader *pfile;
00457 int dir_no;
00458 const char *buf;
00459 size_t count;
00460 {
00461 cpp_push_buffer (pfile, (const uchar *) buf, count,
00462 true, 1);
00463
00464 if (dir_no == T_PRAGMA)
00465 pfile->buffer->inc = pfile->buffer->prev->inc;
00466 start_directive (pfile);
00467
00468 pfile->buffer->saved_flags = 0;
00469 pfile->directive = &dtable[dir_no];
00470 if (CPP_OPTION (pfile, traditional))
00471 prepare_directive_trad (pfile);
00472 (void) (*pfile->directive->handler) (pfile);
00473 end_directive (pfile, 1);
00474 if (dir_no == T_PRAGMA)
00475 pfile->buffer->inc = NULL;
00476 _cpp_pop_buffer (pfile);
00477 }
00478
00479
00480
00481 static cpp_hashnode *
00482 lex_macro_node (pfile)
00483 cpp_reader *pfile;
00484 {
00485 const cpp_token *token = _cpp_lex_token (pfile);
00486
00487
00488
00489
00490
00491
00492
00493
00494 if (token->type == CPP_NAME)
00495 {
00496 cpp_hashnode *node = token->val.node;
00497
00498 if (node == pfile->spec_nodes.n_defined)
00499 cpp_error (pfile, DL_ERROR,
00500 "\"defined\" cannot be used as a macro name");
00501 else if (! (node->flags & NODE_POISONED))
00502 return node;
00503 }
00504 else if (token->flags & NAMED_OP)
00505 cpp_error (pfile, DL_ERROR,
00506 "\"%s\" cannot be used as a macro name as it is an operator in C++",
00507 NODE_NAME (token->val.node));
00508 else if (token->type == CPP_EOF)
00509 cpp_error (pfile, DL_ERROR, "no macro name given in #%s directive",
00510 pfile->directive->name);
00511 else
00512 cpp_error (pfile, DL_ERROR, "macro names must be identifiers");
00513
00514 return NULL;
00515 }
00516
00517
00518 static void
00519 do_define (pfile)
00520 cpp_reader *pfile;
00521 {
00522 cpp_hashnode *node = lex_macro_node (pfile);
00523
00524 if (node)
00525 {
00526
00527
00528 pfile->state.save_comments =
00529 ! CPP_OPTION (pfile, discard_comments_in_macro_exp);
00530
00531 if (_cpp_create_definition (pfile, node))
00532 if (pfile->cb.define)
00533 (*pfile->cb.define) (pfile, pfile->directive_line, node);
00534 }
00535 }
00536
00537
00538 static void
00539 do_undef (pfile)
00540 cpp_reader *pfile;
00541 {
00542 cpp_hashnode *node = lex_macro_node (pfile);
00543
00544
00545
00546 if (node && node->type == NT_MACRO)
00547 {
00548 if (pfile->cb.undef)
00549 (*pfile->cb.undef) (pfile, pfile->directive_line, node);
00550
00551 if (node->flags & NODE_WARN)
00552 cpp_error (pfile, DL_WARNING, "undefining \"%s\"", NODE_NAME (node));
00553
00554 if (CPP_OPTION (pfile, warn_unused_macros))
00555 _cpp_warn_if_unused_macro (pfile, node, NULL);
00556
00557 _cpp_free_definition (node);
00558 }
00559 check_eol (pfile);
00560 }
00561
00562
00563
00564
00565 static const cpp_token *
00566 glue_header_name (pfile)
00567 cpp_reader *pfile;
00568 {
00569 cpp_token *header = NULL;
00570 const cpp_token *token;
00571 unsigned char *buffer;
00572 size_t len, total_len = 0, capacity = 1024;
00573
00574
00575
00576 buffer = (unsigned char *) xmalloc (capacity);
00577 for (;;)
00578 {
00579 token = get_token_no_padding (pfile);
00580
00581 if (token->type == CPP_GREATER || token->type == CPP_EOF)
00582 break;
00583
00584 len = cpp_token_len (token);
00585 if (total_len + len > capacity)
00586 {
00587 capacity = (capacity + len) * 2;
00588 buffer = (unsigned char *) xrealloc (buffer, capacity);
00589 }
00590
00591 if (token->flags & PREV_WHITE)
00592 buffer[total_len++] = ' ';
00593
00594 total_len = cpp_spell_token (pfile, token, &buffer[total_len]) - buffer;
00595 }
00596
00597 if (token->type == CPP_EOF)
00598 cpp_error (pfile, DL_ERROR, "missing terminating > character");
00599 else
00600 {
00601 unsigned char *token_mem = _cpp_unaligned_alloc (pfile, total_len + 1);
00602 memcpy (token_mem, buffer, total_len);
00603 token_mem[total_len] = '\0';
00604
00605 header = _cpp_temp_token (pfile);
00606 header->type = CPP_HEADER_NAME;
00607 header->flags = 0;
00608 header->val.str.len = total_len;
00609 header->val.str.text = token_mem;
00610 }
00611
00612 free ((PTR) buffer);
00613 return header;
00614 }
00615
00616
00617
00618 static const cpp_token *
00619 parse_include (pfile)
00620 cpp_reader *pfile;
00621 {
00622 const unsigned char *dir;
00623 const cpp_token *header;
00624
00625 if (pfile->directive == &dtable[T_PRAGMA])
00626 dir = U"pragma dependency";
00627 else
00628 dir = pfile->directive->name;
00629
00630
00631 header = get_token_no_padding (pfile);
00632 if (header->type != CPP_STRING && header->type != CPP_HEADER_NAME)
00633 {
00634 if (header->type != CPP_LESS)
00635 {
00636 cpp_error (pfile, DL_ERROR,
00637 "#%s expects \"FILENAME\" or <FILENAME>", dir);
00638 return NULL;
00639 }
00640
00641 header = glue_header_name (pfile);
00642 if (header == NULL)
00643 return header;
00644 }
00645
00646 if (header->val.str.len == 0)
00647 {
00648 cpp_error (pfile, DL_ERROR, "empty file name in #%s", dir);
00649 return NULL;
00650 }
00651
00652 return header;
00653 }
00654
00655
00656 static void
00657 do_include_common (pfile, type)
00658 cpp_reader *pfile;
00659 enum include_type type;
00660 {
00661 const cpp_token *header;
00662
00663
00664
00665 if (type == IT_INCLUDE_NEXT && ! pfile->buffer->prev)
00666 {
00667 cpp_error (pfile, DL_WARNING, "#include_next in primary source file");
00668 type = IT_INCLUDE;
00669 }
00670 else if (type == IT_IMPORT && CPP_OPTION (pfile, warn_import))
00671 {
00672 CPP_OPTION (pfile, warn_import) = 0;
00673 cpp_error (pfile, DL_WARNING,
00674 "#import is obsolete, use an #ifndef wrapper in the header file");
00675 }
00676
00677 header = parse_include (pfile);
00678 if (header)
00679 {
00680
00681 if (pfile->line_maps.depth >= CPP_STACK_MAX)
00682 cpp_error (pfile, DL_ERROR, "#include nested too deeply");
00683 else
00684 {
00685 check_eol (pfile);
00686
00687 skip_rest_of_line (pfile);
00688 if (pfile->cb.include)
00689 (*pfile->cb.include) (pfile, pfile->directive_line,
00690 pfile->directive->name, header);
00691 _cpp_execute_include (pfile, header, type);
00692 }
00693 }
00694 }
00695
00696 static void
00697 do_include (pfile)
00698 cpp_reader *pfile;
00699 {
00700 do_include_common (pfile, IT_INCLUDE);
00701 }
00702
00703 static void
00704 do_import (pfile)
00705 cpp_reader *pfile;
00706 {
00707 do_include_common (pfile, IT_IMPORT);
00708 }
00709
00710 static void
00711 do_include_next (pfile)
00712 cpp_reader *pfile;
00713 {
00714 do_include_common (pfile, IT_INCLUDE_NEXT);
00715 }
00716
00717
00718
00719
00720
00721 static unsigned int
00722 read_flag (pfile, last)
00723 cpp_reader *pfile;
00724 unsigned int last;
00725 {
00726 const cpp_token *token = _cpp_lex_token (pfile);
00727
00728 if (token->type == CPP_NUMBER && token->val.str.len == 1)
00729 {
00730 unsigned int flag = token->val.str.text[0] - '0';
00731
00732 if (flag > last && flag <= 4
00733 && (flag != 4 || last == 3)
00734 && (flag != 2 || last == 0))
00735 return flag;
00736 }
00737
00738 if (token->type != CPP_EOF)
00739 cpp_error (pfile, DL_ERROR, "invalid flag \"%s\" in line directive",
00740 cpp_token_as_text (pfile, token));
00741 return 0;
00742 }
00743
00744
00745
00746
00747 static uchar *
00748 dequote_string (pfile, str, len)
00749 cpp_reader *pfile;
00750 const uchar *str;
00751 unsigned int len;
00752 {
00753 uchar *result = _cpp_unaligned_alloc (pfile, len + 1);
00754 uchar *dst = result;
00755 const uchar *limit = str + len;
00756 cppchar_t c;
00757
00758 while (str < limit)
00759 {
00760 c = *str++;
00761 if (c != '\\')
00762 *dst++ = c;
00763 else
00764 *dst++ = cpp_parse_escape (pfile, &str, limit, 0);
00765 }
00766 *dst++ = '\0';
00767 return result;
00768 }
00769
00770
00771
00772
00773 static int
00774 strtoul_for_line (str, len, nump)
00775 const uchar *str;
00776 unsigned int len;
00777 unsigned long *nump;
00778 {
00779 unsigned long reg = 0;
00780 uchar c;
00781 while (len--)
00782 {
00783 c = *str++;
00784 if (!ISDIGIT (c))
00785 return 1;
00786 reg *= 10;
00787 reg += c - '0';
00788 }
00789 *nump = reg;
00790 return 0;
00791 }
00792
00793
00794
00795
00796 static void
00797 do_line (pfile)
00798 cpp_reader *pfile;
00799 {
00800 const cpp_token *token;
00801 const char *new_file = pfile->map->to_file;
00802 unsigned long new_lineno;
00803
00804
00805 unsigned int cap = CPP_OPTION (pfile, c99) ? 2147483647 : 32767;
00806
00807
00808 token = cpp_get_token (pfile);
00809 if (token->type != CPP_NUMBER
00810 || strtoul_for_line (token->val.str.text, token->val.str.len,
00811 &new_lineno))
00812 {
00813 cpp_error (pfile, DL_ERROR,
00814 "\"%s\" after #line is not a positive integer",
00815 cpp_token_as_text (pfile, token));
00816 return;
00817 }
00818
00819 if (CPP_PEDANTIC (pfile) && (new_lineno == 0 || new_lineno > cap))
00820 cpp_error (pfile, DL_PEDWARN, "line number out of range");
00821
00822 token = cpp_get_token (pfile);
00823 if (token->type == CPP_STRING)
00824 {
00825 new_file = (const char *) dequote_string (pfile, token->val.str.text,
00826 token->val.str.len);
00827 check_eol (pfile);
00828 }
00829 else if (token->type != CPP_EOF)
00830 {
00831 cpp_error (pfile, DL_ERROR, "\"%s\" is not a valid filename",
00832 cpp_token_as_text (pfile, token));
00833 return;
00834 }
00835
00836 skip_rest_of_line (pfile);
00837 _cpp_do_file_change (pfile, LC_RENAME, new_file, new_lineno,
00838 pfile->map->sysp);
00839 }
00840
00841
00842
00843
00844 static void
00845 do_linemarker (pfile)
00846 cpp_reader *pfile;
00847 {
00848 const cpp_token *token;
00849 const char *new_file = pfile->map->to_file;
00850 unsigned long new_lineno;
00851 unsigned int new_sysp = pfile->map->sysp;
00852 enum lc_reason reason = LC_RENAME;
00853 int flag;
00854
00855
00856
00857
00858 _cpp_backup_tokens (pfile, 1);
00859
00860
00861 token = cpp_get_token (pfile);
00862 if (token->type != CPP_NUMBER
00863 || strtoul_for_line (token->val.str.text, token->val.str.len,
00864 &new_lineno))
00865 {
00866 cpp_error (pfile, DL_ERROR, "\"%s\" after # is not a positive integer",
00867 cpp_token_as_text (pfile, token));
00868 return;
00869 }
00870
00871 token = cpp_get_token (pfile);
00872 if (token->type == CPP_STRING)
00873 {
00874 new_file = (const char *) dequote_string (pfile, token->val.str.text,
00875 token->val.str.len);
00876 new_sysp = 0;
00877 flag = read_flag (pfile, 0);
00878 if (flag == 1)
00879 {
00880 reason = LC_ENTER;
00881
00882 _cpp_fake_include (pfile, new_file);
00883 flag = read_flag (pfile, flag);
00884 }
00885 else if (flag == 2)
00886 {
00887 reason = LC_LEAVE;
00888 flag = read_flag (pfile, flag);
00889 }
00890 if (flag == 3)
00891 {
00892 new_sysp = 1;
00893 flag = read_flag (pfile, flag);
00894 if (flag == 4)
00895 new_sysp = 2;
00896 }
00897
00898 check_eol (pfile);
00899 }
00900 else if (token->type != CPP_EOF)
00901 {
00902 cpp_error (pfile, DL_ERROR, "\"%s\" is not a valid filename",
00903 cpp_token_as_text (pfile, token));
00904 return;
00905 }
00906
00907 skip_rest_of_line (pfile);
00908 _cpp_do_file_change (pfile, reason, new_file, new_lineno, new_sysp);
00909 }
00910
00911
00912
00913
00914
00915 void
00916 _cpp_do_file_change (pfile, reason, to_file, file_line, sysp)
00917 cpp_reader *pfile;
00918 enum lc_reason reason;
00919 const char *to_file;
00920 unsigned int file_line;
00921 unsigned int sysp;
00922 {
00923 pfile->map = add_line_map (&pfile->line_maps, reason, sysp,
00924 pfile->line, to_file, file_line);
00925
00926 if (pfile->cb.file_change)
00927 (*pfile->cb.file_change) (pfile, pfile->map);
00928 }
00929
00930
00931
00932 static void
00933 do_diagnostic (pfile, code, print_dir)
00934 cpp_reader *pfile;
00935 int code;
00936 int print_dir;
00937 {
00938 if (_cpp_begin_message (pfile, code,
00939 pfile->cur_token[-1].line,
00940 pfile->cur_token[-1].col))
00941 {
00942 if (print_dir)
00943 fprintf (stderr, "#%s ", pfile->directive->name);
00944 pfile->state.prevent_expansion++;
00945 cpp_output_line (pfile, stderr);
00946 pfile->state.prevent_expansion--;
00947 }
00948 }
00949
00950 static void
00951 do_error (pfile)
00952 cpp_reader *pfile;
00953 {
00954 do_diagnostic (pfile, DL_ERROR, 1);
00955 }
00956
00957 static void
00958 do_warning (pfile)
00959 cpp_reader *pfile;
00960 {
00961
00962 do_diagnostic (pfile, DL_WARNING_SYSHDR, 1);
00963 }
00964
00965
00966 static void
00967 do_ident (pfile)
00968 cpp_reader *pfile;
00969 {
00970 const cpp_token *str = cpp_get_token (pfile);
00971
00972 if (str->type != CPP_STRING)
00973 cpp_error (pfile, DL_ERROR, "invalid #ident directive");
00974 else if (pfile->cb.ident)
00975 (*pfile->cb.ident) (pfile, pfile->directive_line, &str->val.str);
00976
00977 check_eol (pfile);
00978 }
00979
00980
00981
00982
00983 static struct pragma_entry *
00984 lookup_pragma_entry (chain, pragma)
00985 struct pragma_entry *chain;
00986 const cpp_hashnode *pragma;
00987 {
00988 while (chain && chain->pragma != pragma)
00989 chain = chain->next;
00990
00991 return chain;
00992 }
00993
00994
00995
00996
00997 static struct pragma_entry *
00998 insert_pragma_entry (pfile, chain, pragma, handler)
00999 cpp_reader *pfile;
01000 struct pragma_entry **chain;
01001 const cpp_hashnode *pragma;
01002 pragma_cb handler;
01003 {
01004 struct pragma_entry *new;
01005
01006 new = (struct pragma_entry *)
01007 _cpp_aligned_alloc (pfile, sizeof (struct pragma_entry));
01008 new->pragma = pragma;
01009 if (handler)
01010 {
01011 new->is_nspace = 0;
01012 new->u.handler = handler;
01013 }
01014 else
01015 {
01016 new->is_nspace = 1;
01017 new->u.space = NULL;
01018 }
01019
01020 new->next = *chain;
01021 *chain = new;
01022 return new;
01023 }
01024
01025
01026
01027
01028 void
01029 cpp_register_pragma (pfile, space, name, handler)
01030 cpp_reader *pfile;
01031 const char *space;
01032 const char *name;
01033 pragma_cb handler;
01034 {
01035 struct pragma_entry **chain = &pfile->pragmas;
01036 struct pragma_entry *entry;
01037 const cpp_hashnode *node;
01038
01039 if (!handler)
01040 abort ();
01041
01042 if (space)
01043 {
01044 node = cpp_lookup (pfile, U space, strlen (space));
01045 entry = lookup_pragma_entry (*chain, node);
01046 if (!entry)
01047 entry = insert_pragma_entry (pfile, chain, node, NULL);
01048 else if (!entry->is_nspace)
01049 goto clash;
01050 chain = &entry->u.space;
01051 }
01052
01053
01054 node = cpp_lookup (pfile, U name, strlen (name));
01055 entry = lookup_pragma_entry (*chain, node);
01056 if (entry)
01057 {
01058 if (entry->is_nspace)
01059 clash:
01060 cpp_error (pfile, DL_ICE,
01061 "registering \"%s\" as both a pragma and a pragma namespace",
01062 NODE_NAME (node));
01063 else if (space)
01064 cpp_error (pfile, DL_ICE, "#pragma %s %s is already registered",
01065 space, name);
01066 else
01067 cpp_error (pfile, DL_ICE, "#pragma %s is already registered", name);
01068 }
01069 else
01070 insert_pragma_entry (pfile, chain, node, handler);
01071 }
01072
01073
01074 void
01075 _cpp_init_internal_pragmas (pfile)
01076 cpp_reader *pfile;
01077 {
01078
01079 cpp_register_pragma (pfile, 0, "once", do_pragma_once);
01080
01081
01082 cpp_register_pragma (pfile, "GCC", "poison", do_pragma_poison);
01083 cpp_register_pragma (pfile, "GCC", "system_header", do_pragma_system_header);
01084 cpp_register_pragma (pfile, "GCC", "dependency", do_pragma_dependency);
01085 }
01086
01087
01088
01089
01090
01091
01092 static void
01093 do_pragma (pfile)
01094 cpp_reader *pfile;
01095 {
01096 const struct pragma_entry *p = NULL;
01097 const cpp_token *token;
01098 unsigned int count = 1;
01099
01100 pfile->state.prevent_expansion++;
01101
01102 token = cpp_get_token (pfile);
01103 if (token->type == CPP_NAME)
01104 {
01105 p = lookup_pragma_entry (pfile->pragmas, token->val.node);
01106 if (p && p->is_nspace)
01107 {
01108 count = 2;
01109 token = cpp_get_token (pfile);
01110 if (token->type == CPP_NAME)
01111 p = lookup_pragma_entry (p->u.space, token->val.node);
01112 else
01113 p = NULL;
01114 }
01115 }
01116
01117 if (p)
01118 (*p->u.handler) (pfile);
01119 else if (pfile->cb.def_pragma)
01120 {
01121 _cpp_backup_tokens (pfile, count);
01122 (*pfile->cb.def_pragma) (pfile, pfile->directive_line);
01123 }
01124
01125 pfile->state.prevent_expansion--;
01126 }
01127
01128
01129 static void
01130 do_pragma_once (pfile)
01131 cpp_reader *pfile;
01132 {
01133 if (CPP_OPTION (pfile, warn_deprecated))
01134 cpp_error (pfile, DL_WARNING, "#pragma once is obsolete");
01135
01136 if (pfile->buffer->prev == NULL)
01137 cpp_error (pfile, DL_WARNING, "#pragma once in main file");
01138 else
01139 _cpp_never_reread (pfile->buffer->inc);
01140
01141 check_eol (pfile);
01142 }
01143
01144
01145
01146 static void
01147 do_pragma_poison (pfile)
01148 cpp_reader *pfile;
01149 {
01150 const cpp_token *tok;
01151 cpp_hashnode *hp;
01152
01153 pfile->state.poisoned_ok = 1;
01154 for (;;)
01155 {
01156 tok = _cpp_lex_token (pfile);
01157 if (tok->type == CPP_EOF)
01158 break;
01159 if (tok->type != CPP_NAME)
01160 {
01161 cpp_error (pfile, DL_ERROR, "invalid #pragma GCC poison directive");
01162 break;
01163 }
01164
01165 hp = tok->val.node;
01166 if (hp->flags & NODE_POISONED)
01167 continue;
01168
01169 if (hp->type == NT_MACRO)
01170 cpp_error (pfile, DL_WARNING, "poisoning existing macro \"%s\"",
01171 NODE_NAME (hp));
01172 _cpp_free_definition (hp);
01173 hp->flags |= NODE_POISONED | NODE_DIAGNOSTIC;
01174 }
01175 pfile->state.poisoned_ok = 0;
01176 }
01177
01178
01179
01180
01181
01182
01183
01184 static void
01185 do_pragma_system_header (pfile)
01186 cpp_reader *pfile;
01187 {
01188 cpp_buffer *buffer = pfile->buffer;
01189
01190 if (buffer->prev == 0)
01191 cpp_error (pfile, DL_WARNING,
01192 "#pragma system_header ignored outside include file");
01193 else
01194 {
01195 check_eol (pfile);
01196 skip_rest_of_line (pfile);
01197 cpp_make_system_header (pfile, 1, 0);
01198 }
01199 }
01200
01201
01202
01203
01204 static void
01205 do_pragma_dependency (pfile)
01206 cpp_reader *pfile;
01207 {
01208 const cpp_token *header;
01209 int ordering;
01210
01211 header = parse_include (pfile);
01212 if (!header)
01213 return;
01214
01215 ordering = _cpp_compare_file_date (pfile, header);
01216 if (ordering < 0)
01217 cpp_error (pfile, DL_WARNING, "cannot find source %s",
01218 cpp_token_as_text (pfile, header));
01219 else if (ordering > 0)
01220 {
01221 cpp_error (pfile, DL_WARNING, "current file is older than %s",
01222 cpp_token_as_text (pfile, header));
01223 if (cpp_get_token (pfile)->type != CPP_EOF)
01224 {
01225 _cpp_backup_tokens (pfile, 1);
01226 do_diagnostic (pfile, DL_WARNING, 0);
01227 }
01228 }
01229 }
01230
01231
01232 static const cpp_token *
01233 get_token_no_padding (pfile)
01234 cpp_reader *pfile;
01235 {
01236 for (;;)
01237 {
01238 const cpp_token *result = cpp_get_token (pfile);
01239 if (result->type != CPP_PADDING)
01240 return result;
01241 }
01242 }
01243
01244
01245
01246 static const cpp_token *
01247 get__Pragma_string (pfile)
01248 cpp_reader *pfile;
01249 {
01250 const cpp_token *string;
01251
01252 if (get_token_no_padding (pfile)->type != CPP_OPEN_PAREN)
01253 return NULL;
01254
01255 string = get_token_no_padding (pfile);
01256 if (string->type != CPP_STRING && string->type != CPP_WSTRING)
01257 return NULL;
01258
01259 if (get_token_no_padding (pfile)->type != CPP_CLOSE_PAREN)
01260 return NULL;
01261
01262 return string;
01263 }
01264
01265
01266
01267 static void
01268 destringize_and_run (pfile, in)
01269 cpp_reader *pfile;
01270 const cpp_string *in;
01271 {
01272 const unsigned char *src, *limit;
01273 char *dest, *result;
01274
01275 dest = result = alloca (in->len + 1);
01276 for (src = in->text, limit = src + in->len; src < limit;)
01277 {
01278
01279 if (*src == '\\' && (src[1] == '\\' || src[1] == '"'))
01280 src++;
01281 *dest++ = *src++;
01282 }
01283 *dest = '\0';
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293 {
01294 cpp_context *saved_context = pfile->context;
01295 cpp_token *saved_cur_token = pfile->cur_token;
01296 tokenrun *saved_cur_run = pfile->cur_run;
01297
01298 pfile->context = xnew (cpp_context);
01299 pfile->context->macro = 0;
01300 pfile->context->prev = 0;
01301 run_directive (pfile, T_PRAGMA, result, dest - result);
01302 free (pfile->context);
01303 pfile->context = saved_context;
01304 pfile->cur_token = saved_cur_token;
01305 pfile->cur_run = saved_cur_run;
01306 pfile->line--;
01307 }
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322 if (pfile->cb.line_change)
01323 (*pfile->cb.line_change) (pfile, pfile->cur_token, false);
01324 }
01325
01326
01327 void
01328 _cpp_do__Pragma (pfile)
01329 cpp_reader *pfile;
01330 {
01331 const cpp_token *string = get__Pragma_string (pfile);
01332
01333 if (string)
01334 destringize_and_run (pfile, &string->val.str);
01335 else
01336 cpp_error (pfile, DL_ERROR,
01337 "_Pragma takes a parenthesized string literal");
01338 }
01339
01340
01341 static void
01342 do_sccs (pfile)
01343 cpp_reader *pfile ATTRIBUTE_UNUSED;
01344 {
01345 }
01346
01347
01348 static void
01349 do_ifdef (pfile)
01350 cpp_reader *pfile;
01351 {
01352 int skip = 1;
01353
01354 if (! pfile->state.skipping)
01355 {
01356 const cpp_hashnode *node = lex_macro_node (pfile);
01357
01358 if (node)
01359 {
01360 skip = node->type != NT_MACRO;
01361 _cpp_mark_macro_used (node);
01362 check_eol (pfile);
01363 }
01364 }
01365
01366 push_conditional (pfile, skip, T_IFDEF, 0);
01367 }
01368
01369
01370 static void
01371 do_ifndef (pfile)
01372 cpp_reader *pfile;
01373 {
01374 int skip = 1;
01375 const cpp_hashnode *node = 0;
01376
01377 if (! pfile->state.skipping)
01378 {
01379 node = lex_macro_node (pfile);
01380
01381 if (node)
01382 {
01383 skip = node->type == NT_MACRO;
01384 _cpp_mark_macro_used (node);
01385 check_eol (pfile);
01386 }
01387 }
01388
01389 push_conditional (pfile, skip, T_IFNDEF, node);
01390 }
01391
01392
01393
01394
01395
01396
01397 static void
01398 do_if (pfile)
01399 cpp_reader *pfile;
01400 {
01401 int skip = 1;
01402
01403 if (! pfile->state.skipping)
01404 skip = _cpp_parse_expr (pfile) == false;
01405
01406 push_conditional (pfile, skip, T_IF, pfile->mi_ind_cmacro);
01407 }
01408
01409
01410
01411
01412 static void
01413 do_else (pfile)
01414 cpp_reader *pfile;
01415 {
01416 cpp_buffer *buffer = pfile->buffer;
01417 struct if_stack *ifs = buffer->if_stack;
01418
01419 if (ifs == NULL)
01420 cpp_error (pfile, DL_ERROR, "#else without #if");
01421 else
01422 {
01423 if (ifs->type == T_ELSE)
01424 {
01425 cpp_error (pfile, DL_ERROR, "#else after #else");
01426 cpp_error_with_line (pfile, DL_ERROR, ifs->line, 0,
01427 "the conditional began here");
01428 }
01429 ifs->type = T_ELSE;
01430
01431
01432 pfile->state.skipping = ifs->skip_elses;
01433 ifs->skip_elses = true;
01434
01435
01436 ifs->mi_cmacro = 0;
01437
01438
01439 if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels))
01440 check_eol (pfile);
01441 }
01442 }
01443
01444
01445
01446 static void
01447 do_elif (pfile)
01448 cpp_reader *pfile;
01449 {
01450 cpp_buffer *buffer = pfile->buffer;
01451 struct if_stack *ifs = buffer->if_stack;
01452
01453 if (ifs == NULL)
01454 cpp_error (pfile, DL_ERROR, "#elif without #if");
01455 else
01456 {
01457 if (ifs->type == T_ELSE)
01458 {
01459 cpp_error (pfile, DL_ERROR, "#elif after #else");
01460 cpp_error_with_line (pfile, DL_ERROR, ifs->line, 0,
01461 "the conditional began here");
01462 }
01463 ifs->type = T_ELIF;
01464
01465
01466
01467 if (ifs->skip_elses)
01468 pfile->state.skipping = 1;
01469 else
01470 {
01471 pfile->state.skipping = 0;
01472 pfile->state.skipping = ! _cpp_parse_expr (pfile);
01473 ifs->skip_elses = ! pfile->state.skipping;
01474 }
01475
01476
01477 ifs->mi_cmacro = 0;
01478 }
01479 }
01480
01481
01482 static void
01483 do_endif (pfile)
01484 cpp_reader *pfile;
01485 {
01486 cpp_buffer *buffer = pfile->buffer;
01487 struct if_stack *ifs = buffer->if_stack;
01488
01489 if (ifs == NULL)
01490 cpp_error (pfile, DL_ERROR, "#endif without #if");
01491 else
01492 {
01493
01494 if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels))
01495 check_eol (pfile);
01496
01497
01498 if (ifs->next == 0 && ifs->mi_cmacro)
01499 {
01500 pfile->mi_valid = true;
01501 pfile->mi_cmacro = ifs->mi_cmacro;
01502 }
01503
01504 buffer->if_stack = ifs->next;
01505 pfile->state.skipping = ifs->was_skipping;
01506 obstack_free (&pfile->buffer_ob, ifs);
01507 }
01508 }
01509
01510
01511
01512
01513
01514 static void
01515 push_conditional (pfile, skip, type, cmacro)
01516 cpp_reader *pfile;
01517 int skip;
01518 int type;
01519 const cpp_hashnode *cmacro;
01520 {
01521 struct if_stack *ifs;
01522 cpp_buffer *buffer = pfile->buffer;
01523
01524 ifs = xobnew (&pfile->buffer_ob, struct if_stack);
01525 ifs->line = pfile->directive_line;
01526 ifs->next = buffer->if_stack;
01527 ifs->skip_elses = pfile->state.skipping || !skip;
01528 ifs->was_skipping = pfile->state.skipping;
01529 ifs->type = type;
01530
01531 if (pfile->mi_valid && pfile->mi_cmacro == 0)
01532 ifs->mi_cmacro = cmacro;
01533 else
01534 ifs->mi_cmacro = 0;
01535
01536 pfile->state.skipping = skip;
01537 buffer->if_stack = ifs;
01538 }
01539
01540
01541
01542
01543
01544 static int
01545 parse_answer (pfile, answerp, type)
01546 cpp_reader *pfile;
01547 struct answer **answerp;
01548 int type;
01549 {
01550 const cpp_token *paren;
01551 struct answer *answer;
01552 unsigned int acount;
01553
01554
01555
01556 paren = cpp_get_token (pfile);
01557
01558
01559 if (paren->type != CPP_OPEN_PAREN)
01560 {
01561
01562
01563 if (type == T_IF)
01564 {
01565 _cpp_backup_tokens (pfile, 1);
01566 return 0;
01567 }
01568
01569
01570 if (type == T_UNASSERT && paren->type == CPP_EOF)
01571 return 0;
01572
01573 cpp_error (pfile, DL_ERROR, "missing '(' after predicate");
01574 return 1;
01575 }
01576
01577 for (acount = 0;; acount++)
01578 {
01579 size_t room_needed;
01580 const cpp_token *token = cpp_get_token (pfile);
01581 cpp_token *dest;
01582
01583 if (token->type == CPP_CLOSE_PAREN)
01584 break;
01585
01586 if (token->type == CPP_EOF)
01587 {
01588 cpp_error (pfile, DL_ERROR, "missing ')' to complete answer");
01589 return 1;
01590 }
01591
01592
01593 room_needed = (sizeof (struct answer) + acount * sizeof (cpp_token));
01594
01595 if (BUFF_ROOM (pfile->a_buff) < room_needed)
01596 _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (struct answer));
01597
01598 dest = &((struct answer *) BUFF_FRONT (pfile->a_buff))->first[acount];
01599 *dest = *token;
01600
01601
01602 if (acount == 0)
01603 dest->flags &= ~PREV_WHITE;
01604 }
01605
01606 if (acount == 0)
01607 {
01608 cpp_error (pfile, DL_ERROR, "predicate's answer is empty");
01609 return 1;
01610 }
01611
01612 answer = (struct answer *) BUFF_FRONT (pfile->a_buff);
01613 answer->count = acount;
01614 answer->next = NULL;
01615 *answerp = answer;
01616
01617 return 0;
01618 }
01619
01620
01621
01622
01623 static cpp_hashnode *
01624 parse_assertion (pfile, answerp, type)
01625 cpp_reader *pfile;
01626 struct answer **answerp;
01627 int type;
01628 {
01629 cpp_hashnode *result = 0;
01630 const cpp_token *predicate;
01631
01632
01633 pfile->state.prevent_expansion++;
01634
01635 *answerp = 0;
01636 predicate = cpp_get_token (pfile);
01637 if (predicate->type == CPP_EOF)
01638 cpp_error (pfile, DL_ERROR, "assertion without predicate");
01639 else if (predicate->type != CPP_NAME)
01640 cpp_error (pfile, DL_ERROR, "predicate must be an identifier");
01641 else if (parse_answer (pfile, answerp, type) == 0)
01642 {
01643 unsigned int len = NODE_LEN (predicate->val.node);
01644 unsigned char *sym = alloca (len + 1);
01645
01646
01647 sym[0] = '#';
01648 memcpy (sym + 1, NODE_NAME (predicate->val.node), len);
01649 result = cpp_lookup (pfile, sym, len + 1);
01650 }
01651
01652 pfile->state.prevent_expansion--;
01653 return result;
01654 }
01655
01656
01657
01658 static struct answer **
01659 find_answer (node, candidate)
01660 cpp_hashnode *node;
01661 const struct answer *candidate;
01662 {
01663 unsigned int i;
01664 struct answer **result;
01665
01666 for (result = &node->value.answers; *result; result = &(*result)->next)
01667 {
01668 struct answer *answer = *result;
01669
01670 if (answer->count == candidate->count)
01671 {
01672 for (i = 0; i < answer->count; i++)
01673 if (! _cpp_equiv_tokens (&answer->first[i], &candidate->first[i]))
01674 break;
01675
01676 if (i == answer->count)
01677 break;
01678 }
01679 }
01680
01681 return result;
01682 }
01683
01684
01685
01686
01687 int
01688 _cpp_test_assertion (pfile, value)
01689 cpp_reader *pfile;
01690 unsigned int *value;
01691 {
01692 struct answer *answer;
01693 cpp_hashnode *node;
01694
01695 node = parse_assertion (pfile, &answer, T_IF);
01696
01697
01698
01699 *value = 0;
01700
01701 if (node)
01702 *value = (node->type == NT_ASSERTION &&
01703 (answer == 0 || *find_answer (node, answer) != 0));
01704 else if (pfile->cur_token[-1].type == CPP_EOF)
01705 _cpp_backup_tokens (pfile, 1);
01706
01707
01708 return node == 0;
01709 }
01710
01711
01712 static void
01713 do_assert (pfile)
01714 cpp_reader *pfile;
01715 {
01716 struct answer *new_answer;
01717 cpp_hashnode *node;
01718
01719 node = parse_assertion (pfile, &new_answer, T_ASSERT);
01720 if (node)
01721 {
01722
01723
01724 new_answer->next = 0;
01725 if (node->type == NT_ASSERTION)
01726 {
01727 if (*find_answer (node, new_answer))
01728 {
01729 cpp_error (pfile, DL_WARNING, "\"%s\" re-asserted",
01730 NODE_NAME (node) + 1);
01731 return;
01732 }
01733 new_answer->next = node->value.answers;
01734 }
01735
01736 node->type = NT_ASSERTION;
01737 node->value.answers = new_answer;
01738 BUFF_FRONT (pfile->a_buff) += (sizeof (struct answer)
01739 + (new_answer->count - 1)
01740 * sizeof (cpp_token));
01741 check_eol (pfile);
01742 }
01743 }
01744
01745
01746 static void
01747 do_unassert (pfile)
01748 cpp_reader *pfile;
01749 {
01750 cpp_hashnode *node;
01751 struct answer *answer;
01752
01753 node = parse_assertion (pfile, &answer, T_UNASSERT);
01754
01755 if (node && node->type == NT_ASSERTION)
01756 {
01757 if (answer)
01758 {
01759 struct answer **p = find_answer (node, answer), *temp;
01760
01761
01762 temp = *p;
01763 if (temp)
01764 *p = temp->next;
01765
01766
01767 if (node->value.answers == 0)
01768 node->type = NT_VOID;
01769
01770 check_eol (pfile);
01771 }
01772 else
01773 _cpp_free_definition (node);
01774 }
01775
01776
01777 }
01778
01779
01780
01781
01782
01783
01784
01785 void
01786 cpp_define (pfile, str)
01787 cpp_reader *pfile;
01788 const char *str;
01789 {
01790 char *buf, *p;
01791 size_t count;
01792
01793
01794
01795
01796
01797 count = strlen (str);
01798 buf = (char *) alloca (count + 3);
01799 memcpy (buf, str, count);
01800
01801 p = strchr (str, '=');
01802 if (p)
01803 buf[p - str] = ' ';
01804 else
01805 {
01806 buf[count++] = ' ';
01807 buf[count++] = '1';
01808 }
01809 buf[count] = '\0';
01810
01811 run_directive (pfile, T_DEFINE, buf, count);
01812 }
01813
01814
01815 void
01816 _cpp_define_builtin (pfile, str)
01817 cpp_reader *pfile;
01818 const char *str;
01819 {
01820 run_directive (pfile, T_DEFINE, str, strlen (str));
01821 }
01822
01823
01824 void
01825 cpp_undef (pfile, macro)
01826 cpp_reader *pfile;
01827 const char *macro;
01828 {
01829 run_directive (pfile, T_UNDEF, macro, strlen (macro));
01830 }
01831
01832
01833 void
01834 cpp_assert (pfile, str)
01835 cpp_reader *pfile;
01836 const char *str;
01837 {
01838 handle_assertion (pfile, str, T_ASSERT);
01839 }
01840
01841
01842 void
01843 cpp_unassert (pfile, str)
01844 cpp_reader *pfile;
01845 const char *str;
01846 {
01847 handle_assertion (pfile, str, T_UNASSERT);
01848 }
01849
01850
01851 static void
01852 handle_assertion (pfile, str, type)
01853 cpp_reader *pfile;
01854 const char *str;
01855 int type;
01856 {
01857 size_t count = strlen (str);
01858 const char *p = strchr (str, '=');
01859
01860 if (p)
01861 {
01862
01863
01864 char *buf = (char *) alloca (count + 2);
01865
01866 memcpy (buf, str, count);
01867 buf[p - str] = '(';
01868 buf[count++] = ')';
01869 buf[count] = '\0';
01870 str = buf;
01871 }
01872
01873 run_directive (pfile, type, str, count);
01874 }
01875
01876
01877 unsigned int
01878 cpp_errors (pfile)
01879 cpp_reader *pfile;
01880 {
01881 return pfile->errors;
01882 }
01883
01884
01885 cpp_options *
01886 cpp_get_options (pfile)
01887 cpp_reader *pfile;
01888 {
01889 return &pfile->opts;
01890 }
01891
01892
01893 cpp_callbacks *
01894 cpp_get_callbacks (pfile)
01895 cpp_reader *pfile;
01896 {
01897 return &pfile->cb;
01898 }
01899
01900
01901 const struct line_maps *
01902 cpp_get_line_maps (pfile)
01903 cpp_reader *pfile;
01904 {
01905 return &pfile->line_maps;
01906 }
01907
01908
01909 void
01910 cpp_set_callbacks (pfile, cb)
01911 cpp_reader *pfile;
01912 cpp_callbacks *cb;
01913 {
01914 pfile->cb = *cb;
01915 }
01916
01917
01918
01919
01920 cpp_buffer *
01921 cpp_push_buffer (pfile, buffer, len, from_stage3, return_at_eof)
01922 cpp_reader *pfile;
01923 const uchar *buffer;
01924 size_t len;
01925 int from_stage3;
01926 int return_at_eof;
01927 {
01928 cpp_buffer *new = xobnew (&pfile->buffer_ob, cpp_buffer);
01929
01930
01931 memset (new, 0, sizeof (cpp_buffer));
01932
01933 new->line_base = new->buf = new->cur = buffer;
01934 new->rlimit = buffer + len;
01935 new->from_stage3 = from_stage3 || CPP_OPTION (pfile, traditional);
01936 new->prev = pfile->buffer;
01937 new->return_at_eof = return_at_eof;
01938 new->saved_flags = BOL;
01939
01940 pfile->buffer = new;
01941
01942 return new;
01943 }
01944
01945
01946
01947 void
01948 _cpp_pop_buffer (pfile)
01949 cpp_reader *pfile;
01950 {
01951 cpp_buffer *buffer = pfile->buffer;
01952 struct include_file *inc = buffer->inc;
01953 struct if_stack *ifs;
01954
01955
01956
01957 for (ifs = buffer->if_stack; ifs; ifs = ifs->next)
01958 cpp_error_with_line (pfile, DL_ERROR, ifs->line, 0,
01959 "unterminated #%s", dtable[ifs->type].name);
01960
01961
01962 pfile->state.skipping = 0;
01963
01964
01965 pfile->buffer = buffer->prev;
01966
01967
01968
01969 obstack_free (&pfile->buffer_ob, buffer);
01970
01971 if (inc)
01972 {
01973 _cpp_pop_file_buffer (pfile, inc);
01974
01975
01976 if (pfile->buffer)
01977 {
01978 _cpp_do_file_change (pfile, LC_LEAVE, 0, 0, 0);
01979
01980
01981
01982 if (!pfile->buffer->prev)
01983 _cpp_maybe_push_include_file (pfile);
01984 }
01985 }
01986 }
01987
01988
01989 void
01990 _cpp_init_directives (pfile)
01991 cpp_reader *pfile;
01992 {
01993 unsigned int i;
01994 cpp_hashnode *node;
01995
01996 for (i = 0; i < (unsigned int) N_DIRECTIVES; i++)
01997 {
01998 node = cpp_lookup (pfile, dtable[i].name, dtable[i].length);
01999 node->directive_index = i + 1;
02000 }
02001 }