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