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