00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "config.h"
00027 #include "system.h"
00028 #include "cpplib.h"
00029 #include "internal.h"
00030
00031 typedef struct macro_arg macro_arg;
00032 struct macro_arg
00033 {
00034 const cpp_token **first;
00035 const cpp_token **expanded;
00036 const cpp_token *stringified;
00037 unsigned int count;
00038 unsigned int expanded_count;
00039 };
00040
00041
00042
00043 static int enter_macro_context (cpp_reader *, cpp_hashnode *);
00044 static int builtin_macro (cpp_reader *, cpp_hashnode *);
00045 static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *,
00046 const cpp_token **, unsigned int);
00047 static _cpp_buff *collect_args (cpp_reader *, const cpp_hashnode *);
00048 static cpp_context *next_context (cpp_reader *);
00049 static const cpp_token *padding_token (cpp_reader *, const cpp_token *);
00050 static void expand_arg (cpp_reader *, macro_arg *);
00051 static const cpp_token *new_string_token (cpp_reader *, uchar *, unsigned int);
00052 static const cpp_token *stringify_arg (cpp_reader *, macro_arg *);
00053 static void paste_all_tokens (cpp_reader *, const cpp_token *);
00054 static bool paste_tokens (cpp_reader *, const cpp_token **, const cpp_token *);
00055 static void replace_args (cpp_reader *, cpp_hashnode *, cpp_macro *,
00056 macro_arg *);
00057 static _cpp_buff *funlike_invocation_p (cpp_reader *, cpp_hashnode *);
00058 static bool create_iso_definition (cpp_reader *, cpp_macro *);
00059
00060
00061
00062 static cpp_token *alloc_expansion_token (cpp_reader *, cpp_macro *);
00063 static cpp_token *lex_expansion_token (cpp_reader *, cpp_macro *);
00064 static bool warn_of_redefinition (cpp_reader *, const cpp_hashnode *,
00065 const cpp_macro *);
00066 static bool parse_params (cpp_reader *, cpp_macro *);
00067 static void check_trad_stringification (cpp_reader *, const cpp_macro *,
00068 const cpp_string *);
00069
00070
00071
00072 int
00073 _cpp_warn_if_unused_macro (cpp_reader *pfile, cpp_hashnode *node,
00074 void *v ATTRIBUTE_UNUSED)
00075 {
00076 if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
00077 {
00078 cpp_macro *macro = node->value.macro;
00079
00080 if (!macro->used
00081 && MAIN_FILE_P (linemap_lookup (pfile->line_table, macro->line)))
00082 cpp_error_with_line (pfile, CPP_DL_WARNING, macro->line, 0,
00083 "macro \"%s\" is not used", NODE_NAME (node));
00084 }
00085
00086 return 1;
00087 }
00088
00089
00090
00091 static const cpp_token *
00092 new_string_token (cpp_reader *pfile, unsigned char *text, unsigned int len)
00093 {
00094 cpp_token *token = _cpp_temp_token (pfile);
00095
00096 text[len] = '\0';
00097 token->type = CPP_STRING;
00098 token->val.str.len = len;
00099 token->val.str.text = text;
00100 token->flags = 0;
00101 return token;
00102 }
00103
00104 static const char * const monthnames[] =
00105 {
00106 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
00107 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
00108 };
00109
00110
00111
00112 const uchar *
00113 _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
00114 {
00115 const struct line_map *map;
00116 const uchar *result = NULL;
00117 unsigned int number = 1;
00118
00119 switch (node->value.builtin)
00120 {
00121 default:
00122 cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"",
00123 NODE_NAME (node));
00124 break;
00125
00126 case BT_TIMESTAMP:
00127 {
00128 cpp_buffer *pbuffer = cpp_get_buffer (pfile);
00129 if (pbuffer->timestamp == NULL)
00130 {
00131
00132 struct _cpp_file *file = cpp_get_file (pbuffer);
00133 if (file)
00134 {
00135
00136
00137
00138
00139 struct tm *tb = NULL;
00140 struct stat *st = _cpp_get_file_stat (file);
00141 if (st)
00142 tb = localtime (&st->st_mtime);
00143 if (tb)
00144 {
00145 char *str = asctime (tb);
00146 size_t len = strlen (str);
00147 unsigned char *buf = _cpp_unaligned_alloc (pfile, len + 2);
00148 buf[0] = '"';
00149 strcpy ((char *) buf + 1, str);
00150 buf[len] = '"';
00151 pbuffer->timestamp = buf;
00152 }
00153 else
00154 {
00155 cpp_errno (pfile, CPP_DL_WARNING,
00156 "could not determine file timestamp");
00157 pbuffer->timestamp = U"\"??? ??? ?? ??:??:?? ????\"";
00158 }
00159 }
00160 }
00161 result = pbuffer->timestamp;
00162 }
00163 break;
00164 case BT_FILE:
00165 case BT_BASE_FILE:
00166 {
00167 unsigned int len;
00168 const char *name;
00169 uchar *buf;
00170 map = linemap_lookup (pfile->line_table, pfile->line_table->highest_line);
00171
00172 if (node->value.builtin == BT_BASE_FILE)
00173 while (! MAIN_FILE_P (map))
00174 map = INCLUDED_FROM (pfile->line_table, map);
00175
00176 name = map->to_file;
00177 len = strlen (name);
00178 buf = _cpp_unaligned_alloc (pfile, len * 2 + 3);
00179 result = buf;
00180 *buf = '"';
00181 buf = cpp_quote_string (buf + 1, (const unsigned char *) name, len);
00182 *buf++ = '"';
00183 *buf = '\0';
00184 }
00185 break;
00186
00187 case BT_INCLUDE_LEVEL:
00188
00189
00190
00191 number = pfile->line_table->depth - 1;
00192 break;
00193
00194 case BT_SPECLINE:
00195 map = &pfile->line_table->maps[pfile->line_table->used-1];
00196
00197
00198
00199 if (CPP_OPTION (pfile, traditional))
00200 number = pfile->line_table->highest_line;
00201 else
00202 number = pfile->cur_token[-1].src_loc;
00203 number = SOURCE_LINE (map, number);
00204 break;
00205
00206
00207
00208
00209
00210
00211 case BT_STDC:
00212 if (cpp_in_system_header (pfile))
00213 number = 0;
00214 else
00215 number = 1;
00216 break;
00217
00218 case BT_DATE:
00219 case BT_TIME:
00220 if (pfile->date == NULL)
00221 {
00222
00223
00224
00225
00226 time_t tt;
00227 struct tm *tb = NULL;
00228
00229
00230
00231
00232 errno = 0;
00233 tt = time(NULL);
00234 if (tt != (time_t)-1 || errno == 0)
00235 tb = localtime (&tt);
00236
00237 if (tb)
00238 {
00239 pfile->date = _cpp_unaligned_alloc (pfile,
00240 sizeof ("\"Oct 11 1347\""));
00241 sprintf ((char *) pfile->date, "\"%s %2d %4d\"",
00242 monthnames[tb->tm_mon], tb->tm_mday,
00243 tb->tm_year + 1900);
00244
00245 pfile->time = _cpp_unaligned_alloc (pfile,
00246 sizeof ("\"12:34:56\""));
00247 sprintf ((char *) pfile->time, "\"%02d:%02d:%02d\"",
00248 tb->tm_hour, tb->tm_min, tb->tm_sec);
00249 }
00250 else
00251 {
00252 cpp_errno (pfile, CPP_DL_WARNING,
00253 "could not determine date and time");
00254
00255 pfile->date = U"\"??? ?? ????\"";
00256 pfile->time = U"\"??:??:??\"";
00257 }
00258 }
00259
00260 if (node->value.builtin == BT_DATE)
00261 result = pfile->date;
00262 else
00263 result = pfile->time;
00264 break;
00265 }
00266
00267 if (result == NULL)
00268 {
00269
00270 result = _cpp_unaligned_alloc (pfile, 21);
00271 sprintf ((char *) result, "%u", number);
00272 }
00273
00274 return result;
00275 }
00276
00277
00278
00279
00280
00281 static int
00282 builtin_macro (cpp_reader *pfile, cpp_hashnode *node)
00283 {
00284 const uchar *buf;
00285 size_t len;
00286 char *nbuf;
00287
00288 if (node->value.builtin == BT_PRAGMA)
00289 {
00290
00291
00292 if (pfile->state.in_directive)
00293 return 0;
00294
00295 _cpp_do__Pragma (pfile);
00296 return 1;
00297 }
00298
00299 buf = _cpp_builtin_macro_text (pfile, node);
00300 len = ustrlen (buf);
00301 nbuf = (char *) alloca (len + 1);
00302 memcpy (nbuf, buf, len);
00303 nbuf[len]='\n';
00304
00305 cpp_push_buffer (pfile, (uchar *) nbuf, len, true);
00306 _cpp_clean_line (pfile);
00307
00308
00309 pfile->cur_token = _cpp_temp_token (pfile);
00310 _cpp_push_token_context (pfile, NULL, _cpp_lex_direct (pfile), 1);
00311 if (pfile->buffer->cur != pfile->buffer->rlimit)
00312 cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"",
00313 NODE_NAME (node));
00314 _cpp_pop_buffer (pfile);
00315
00316 return 1;
00317 }
00318
00319
00320
00321
00322 uchar *
00323 cpp_quote_string (uchar *dest, const uchar *src, unsigned int len)
00324 {
00325 while (len--)
00326 {
00327 uchar c = *src++;
00328
00329 if (c == '\\' || c == '"')
00330 {
00331 *dest++ = '\\';
00332 *dest++ = c;
00333 }
00334 else
00335 *dest++ = c;
00336 }
00337
00338 return dest;
00339 }
00340
00341
00342
00343 static const cpp_token *
00344 stringify_arg (cpp_reader *pfile, macro_arg *arg)
00345 {
00346 unsigned char *dest;
00347 unsigned int i, escape_it, backslash_count = 0;
00348 const cpp_token *source = NULL;
00349 size_t len;
00350
00351 if (BUFF_ROOM (pfile->u_buff) < 3)
00352 _cpp_extend_buff (pfile, &pfile->u_buff, 3);
00353 dest = BUFF_FRONT (pfile->u_buff);
00354 *dest++ = '"';
00355
00356
00357 for (i = 0; i < arg->count; i++)
00358 {
00359 const cpp_token *token = arg->first[i];
00360
00361 if (token->type == CPP_PADDING)
00362 {
00363 if (source == NULL)
00364 source = token->val.source;
00365 continue;
00366 }
00367
00368 escape_it = (token->type == CPP_STRING || token->type == CPP_WSTRING
00369 || token->type == CPP_CHAR || token->type == CPP_WCHAR);
00370
00371
00372
00373 len = cpp_token_len (token);
00374 if (escape_it)
00375 len *= 4;
00376 len += 3;
00377
00378 if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < len)
00379 {
00380 size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff);
00381 _cpp_extend_buff (pfile, &pfile->u_buff, len);
00382 dest = BUFF_FRONT (pfile->u_buff) + len_so_far;
00383 }
00384
00385
00386 if (dest - 1 != BUFF_FRONT (pfile->u_buff))
00387 {
00388 if (source == NULL)
00389 source = token;
00390 if (source->flags & PREV_WHITE)
00391 *dest++ = ' ';
00392 }
00393 source = NULL;
00394
00395 if (escape_it)
00396 {
00397 _cpp_buff *buff = _cpp_get_buff (pfile, len);
00398 unsigned char *buf = BUFF_FRONT (buff);
00399 len = cpp_spell_token (pfile, token, buf, true) - buf;
00400 dest = cpp_quote_string (dest, buf, len);
00401 _cpp_release_buff (pfile, buff);
00402 }
00403 else
00404 dest = cpp_spell_token (pfile, token, dest, true);
00405
00406 if (token->type == CPP_OTHER && token->val.str.text[0] == '\\')
00407 backslash_count++;
00408 else
00409 backslash_count = 0;
00410 }
00411
00412
00413 if (backslash_count & 1)
00414 {
00415 cpp_error (pfile, CPP_DL_WARNING,
00416 "invalid string literal, ignoring final '\\'");
00417 dest--;
00418 }
00419
00420
00421 *dest++ = '"';
00422 len = dest - BUFF_FRONT (pfile->u_buff);
00423 BUFF_FRONT (pfile->u_buff) = dest + 1;
00424 return new_string_token (pfile, dest - len, len);
00425 }
00426
00427
00428
00429
00430 static bool
00431 paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs)
00432 {
00433 unsigned char *buf, *end, *lhsend;
00434 const cpp_token *lhs;
00435 unsigned int len;
00436
00437 lhs = *plhs;
00438 len = cpp_token_len (lhs) + cpp_token_len (rhs) + 1;
00439 buf = (unsigned char *) alloca (len);
00440 end = lhsend = cpp_spell_token (pfile, lhs, buf, false);
00441
00442
00443
00444
00445
00446 if (lhs->type == CPP_DIV && rhs->type != CPP_EQ)
00447 *end++ = ' ';
00448 end = cpp_spell_token (pfile, rhs, end, false);
00449 *end = '\n';
00450
00451 cpp_push_buffer (pfile, buf, end - buf, true);
00452 _cpp_clean_line (pfile);
00453
00454
00455 pfile->cur_token = _cpp_temp_token (pfile);
00456 *plhs = _cpp_lex_direct (pfile);
00457 if (pfile->buffer->cur != pfile->buffer->rlimit)
00458 {
00459 _cpp_pop_buffer (pfile);
00460 _cpp_backup_tokens (pfile, 1);
00461 *lhsend = '\0';
00462
00463
00464 if (CPP_OPTION (pfile, lang) != CLK_ASM)
00465 cpp_error (pfile, CPP_DL_ERROR,
00466 "pasting \"%s\" and \"%s\" does not give a valid preprocessing token",
00467 buf, cpp_token_as_text (pfile, rhs));
00468 return false;
00469 }
00470
00471 _cpp_pop_buffer (pfile);
00472 return true;
00473 }
00474
00475
00476
00477
00478
00479
00480
00481
00482 static void
00483 paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs)
00484 {
00485 const cpp_token *rhs;
00486 cpp_context *context = pfile->context;
00487
00488 do
00489 {
00490
00491
00492
00493
00494
00495 if (context->direct_p)
00496 rhs = FIRST (context).token++;
00497 else
00498 rhs = *FIRST (context).ptoken++;
00499
00500 if (rhs->type == CPP_PADDING)
00501 abort ();
00502
00503 if (!paste_tokens (pfile, &lhs, rhs))
00504 break;
00505 }
00506 while (rhs->flags & PASTE_LEFT);
00507
00508
00509 _cpp_push_token_context (pfile, NULL, lhs, 1);
00510 }
00511
00512
00513
00514
00515
00516
00517
00518 bool
00519 _cpp_arguments_ok (cpp_reader *pfile, cpp_macro *macro, const cpp_hashnode *node, unsigned int argc)
00520 {
00521 if (argc == macro->paramc)
00522 return true;
00523
00524 if (argc < macro->paramc)
00525 {
00526
00527
00528
00529
00530
00531
00532
00533
00534 if (argc + 1 == macro->paramc && macro->variadic)
00535 {
00536 if (CPP_PEDANTIC (pfile) && ! macro->syshdr)
00537 cpp_error (pfile, CPP_DL_PEDWARN,
00538 "ISO C99 requires rest arguments to be used");
00539 return true;
00540 }
00541
00542 cpp_error (pfile, CPP_DL_ERROR,
00543 "macro \"%s\" requires %u arguments, but only %u given",
00544 NODE_NAME (node), macro->paramc, argc);
00545 }
00546 else
00547 cpp_error (pfile, CPP_DL_ERROR,
00548 "macro \"%s\" passed %u arguments, but takes just %u",
00549 NODE_NAME (node), argc, macro->paramc);
00550
00551 return false;
00552 }
00553
00554
00555
00556
00557
00558
00559 static _cpp_buff *
00560 collect_args (cpp_reader *pfile, const cpp_hashnode *node)
00561 {
00562 _cpp_buff *buff, *base_buff;
00563 cpp_macro *macro;
00564 macro_arg *args, *arg;
00565 const cpp_token *token;
00566 unsigned int argc;
00567
00568 macro = node->value.macro;
00569 if (macro->paramc)
00570 argc = macro->paramc;
00571 else
00572 argc = 1;
00573 buff = _cpp_get_buff (pfile, argc * (50 * sizeof (cpp_token *)
00574 + sizeof (macro_arg)));
00575 base_buff = buff;
00576 args = (macro_arg *) buff->base;
00577 memset (args, 0, argc * sizeof (macro_arg));
00578 buff->cur = (unsigned char *) &args[argc];
00579 arg = args, argc = 0;
00580
00581
00582
00583
00584 do
00585 {
00586 unsigned int paren_depth = 0;
00587 unsigned int ntokens = 0;
00588
00589 argc++;
00590 arg->first = (const cpp_token **) buff->cur;
00591
00592 for (;;)
00593 {
00594
00595 if ((unsigned char *) &arg->first[ntokens + 2] > buff->limit)
00596 {
00597 buff = _cpp_append_extend_buff (pfile, buff,
00598 1000 * sizeof (cpp_token *));
00599 arg->first = (const cpp_token **) buff->cur;
00600 }
00601
00602 token = cpp_get_token (pfile);
00603
00604 if (token->type == CPP_PADDING)
00605 {
00606
00607 if (ntokens == 0)
00608 continue;
00609 }
00610 else if (token->type == CPP_OPEN_PAREN)
00611 paren_depth++;
00612 else if (token->type == CPP_CLOSE_PAREN)
00613 {
00614 if (paren_depth-- == 0)
00615 break;
00616 }
00617 else if (token->type == CPP_COMMA)
00618 {
00619
00620
00621 if (paren_depth == 0
00622 && ! (macro->variadic && argc == macro->paramc))
00623 break;
00624 }
00625 else if (token->type == CPP_EOF
00626 || (token->type == CPP_HASH && token->flags & BOL))
00627 break;
00628
00629 arg->first[ntokens++] = token;
00630 }
00631
00632
00633 while (ntokens > 0 && arg->first[ntokens - 1]->type == CPP_PADDING)
00634 ntokens--;
00635
00636 arg->count = ntokens;
00637 arg->first[ntokens] = &pfile->eof;
00638
00639
00640
00641 if (argc <= macro->paramc)
00642 {
00643 buff->cur = (unsigned char *) &arg->first[ntokens + 1];
00644 if (argc != macro->paramc)
00645 arg++;
00646 }
00647 }
00648 while (token->type != CPP_CLOSE_PAREN && token->type != CPP_EOF);
00649
00650 if (token->type == CPP_EOF)
00651 {
00652
00653
00654
00655
00656 if (pfile->context->prev || pfile->state.in_directive)
00657 _cpp_backup_tokens (pfile, 1);
00658 cpp_error (pfile, CPP_DL_ERROR,
00659 "unterminated argument list invoking macro \"%s\"",
00660 NODE_NAME (node));
00661 }
00662 else
00663 {
00664
00665 if (argc == 1 && macro->paramc == 0 && args[0].count == 0)
00666 argc = 0;
00667 if (_cpp_arguments_ok (pfile, macro, node, argc))
00668 {
00669
00670
00671
00672
00673
00674
00675
00676 if (macro->variadic && (argc < macro->paramc
00677 || (argc == 1 && args[0].count == 0
00678 && !CPP_OPTION (pfile, std))))
00679 args[macro->paramc - 1].first = NULL;
00680 return base_buff;
00681 }
00682 }
00683
00684
00685 _cpp_release_buff (pfile, base_buff);
00686 return NULL;
00687 }
00688
00689
00690
00691
00692
00693 static _cpp_buff *
00694 funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node)
00695 {
00696 const cpp_token *token, *padding = NULL;
00697
00698 for (;;)
00699 {
00700 token = cpp_get_token (pfile);
00701 if (token->type != CPP_PADDING)
00702 break;
00703 if (padding == NULL
00704 || (!(padding->flags & PREV_WHITE) && token->val.source == NULL))
00705 padding = token;
00706 }
00707
00708 if (token->type == CPP_OPEN_PAREN)
00709 {
00710 pfile->state.parsing_args = 2;
00711 return collect_args (pfile, node);
00712 }
00713
00714
00715
00716 if (token->type != CPP_EOF || token == &pfile->eof)
00717 {
00718
00719
00720
00721 _cpp_backup_tokens (pfile, 1);
00722 if (padding)
00723 _cpp_push_token_context (pfile, NULL, padding, 1);
00724 }
00725
00726 return NULL;
00727 }
00728
00729
00730
00731
00732
00733 static int
00734 enter_macro_context (cpp_reader *pfile, cpp_hashnode *node)
00735 {
00736
00737 pfile->mi_valid = false;
00738
00739 pfile->state.angled_headers = false;
00740
00741
00742 if (! (node->flags & NODE_BUILTIN))
00743 {
00744 cpp_macro *macro = node->value.macro;
00745
00746 if (macro->fun_like)
00747 {
00748 _cpp_buff *buff;
00749
00750 pfile->state.prevent_expansion++;
00751 pfile->keep_tokens++;
00752 pfile->state.parsing_args = 1;
00753 buff = funlike_invocation_p (pfile, node);
00754 pfile->state.parsing_args = 0;
00755 pfile->keep_tokens--;
00756 pfile->state.prevent_expansion--;
00757
00758 if (buff == NULL)
00759 {
00760 if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr)
00761 cpp_error (pfile, CPP_DL_WARNING,
00762 "function-like macro \"%s\" must be used with arguments in traditional C",
00763 NODE_NAME (node));
00764
00765 return 0;
00766 }
00767
00768 if (macro->paramc > 0)
00769 replace_args (pfile, node, macro, (macro_arg *) buff->base);
00770 _cpp_release_buff (pfile, buff);
00771 }
00772
00773
00774 node->flags |= NODE_DISABLED;
00775
00776 macro->used = 1;
00777
00778 if (macro->paramc == 0)
00779 _cpp_push_token_context (pfile, node, macro->exp.tokens, macro->count);
00780
00781 return 1;
00782 }
00783
00784
00785 return builtin_macro (pfile, node);
00786 }
00787
00788
00789
00790
00791
00792 static void
00793 replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg *args)
00794 {
00795 unsigned int i, total;
00796 const cpp_token *src, *limit;
00797 const cpp_token **dest, **first;
00798 macro_arg *arg;
00799 _cpp_buff *buff;
00800
00801
00802
00803
00804
00805 total = macro->count;
00806 limit = macro->exp.tokens + macro->count;
00807
00808 for (src = macro->exp.tokens; src < limit; src++)
00809 if (src->type == CPP_MACRO_ARG)
00810 {
00811
00812 total += 2;
00813
00814
00815
00816 arg = &args[src->val.arg_no - 1];
00817
00818 if (src->flags & STRINGIFY_ARG)
00819 {
00820 if (!arg->stringified)
00821 arg->stringified = stringify_arg (pfile, arg);
00822 }
00823 else if ((src->flags & PASTE_LEFT)
00824 || (src > macro->exp.tokens && (src[-1].flags & PASTE_LEFT)))
00825 total += arg->count - 1;
00826 else
00827 {
00828 if (!arg->expanded)
00829 expand_arg (pfile, arg);
00830 total += arg->expanded_count - 1;
00831 }
00832 }
00833
00834
00835
00836 buff = _cpp_get_buff (pfile, total * sizeof (cpp_token *));
00837 first = (const cpp_token **) buff->base;
00838 dest = first;
00839
00840 for (src = macro->exp.tokens; src < limit; src++)
00841 {
00842 unsigned int count;
00843 const cpp_token **from, **paste_flag;
00844
00845 if (src->type != CPP_MACRO_ARG)
00846 {
00847 *dest++ = src;
00848 continue;
00849 }
00850
00851 paste_flag = 0;
00852 arg = &args[src->val.arg_no - 1];
00853 if (src->flags & STRINGIFY_ARG)
00854 count = 1, from = &arg->stringified;
00855 else if (src->flags & PASTE_LEFT)
00856 count = arg->count, from = arg->first;
00857 else if (src != macro->exp.tokens && (src[-1].flags & PASTE_LEFT))
00858 {
00859 count = arg->count, from = arg->first;
00860 if (dest != first)
00861 {
00862 if (dest[-1]->type == CPP_COMMA
00863 && macro->variadic
00864 && src->val.arg_no == macro->paramc)
00865 {
00866
00867
00868 if (from == NULL)
00869 dest--;
00870 else
00871 paste_flag = dest - 1;
00872 }
00873
00874 else if (count == 0)
00875 paste_flag = dest - 1;
00876 }
00877 }
00878 else
00879 count = arg->expanded_count, from = arg->expanded;
00880
00881
00882 if ((!pfile->state.in_directive || pfile->state.directive_wants_padding)
00883 && src != macro->exp.tokens && !(src[-1].flags & PASTE_LEFT))
00884 *dest++ = padding_token (pfile, src);
00885
00886 if (count)
00887 {
00888 memcpy (dest, from, count * sizeof (cpp_token *));
00889 dest += count;
00890
00891
00892
00893 if (src->flags & PASTE_LEFT)
00894 paste_flag = dest - 1;
00895 }
00896
00897
00898 if (!pfile->state.in_directive && !(src->flags & PASTE_LEFT))
00899 *dest++ = &pfile->avoid_paste;
00900
00901
00902 if (paste_flag)
00903 {
00904 cpp_token *token = _cpp_temp_token (pfile);
00905 token->type = (*paste_flag)->type;
00906 token->val = (*paste_flag)->val;
00907 if (src->flags & PASTE_LEFT)
00908 token->flags = (*paste_flag)->flags | PASTE_LEFT;
00909 else
00910 token->flags = (*paste_flag)->flags & ~PASTE_LEFT;
00911 *paste_flag = token;
00912 }
00913 }
00914
00915
00916 for (i = 0; i < macro->paramc; i++)
00917 if (args[i].expanded)
00918 free (args[i].expanded);
00919
00920 push_ptoken_context (pfile, node, buff, first, dest - first);
00921 }
00922
00923
00924 static const cpp_token *
00925 padding_token (cpp_reader *pfile, const cpp_token *source)
00926 {
00927 cpp_token *result = _cpp_temp_token (pfile);
00928
00929 result->type = CPP_PADDING;
00930
00931
00932
00933 result->val.source = (cpp_token *) source;
00934 result->flags = 0;
00935 return result;
00936 }
00937
00938
00939
00940 static cpp_context *
00941 next_context (cpp_reader *pfile)
00942 {
00943 cpp_context *result = pfile->context->next;
00944
00945 if (result == 0)
00946 {
00947 result = XNEW (cpp_context);
00948 result->prev = pfile->context;
00949 result->next = 0;
00950 pfile->context->next = result;
00951 }
00952
00953 pfile->context = result;
00954 return result;
00955 }
00956
00957
00958 static void
00959 push_ptoken_context (cpp_reader *pfile, cpp_hashnode *macro, _cpp_buff *buff,
00960 const cpp_token **first, unsigned int count)
00961 {
00962 cpp_context *context = next_context (pfile);
00963
00964 context->direct_p = false;
00965 context->macro = macro;
00966 context->buff = buff;
00967 FIRST (context).ptoken = first;
00968 LAST (context).ptoken = first + count;
00969 }
00970
00971
00972 void
00973 _cpp_push_token_context (cpp_reader *pfile, cpp_hashnode *macro,
00974 const cpp_token *first, unsigned int count)
00975 {
00976 cpp_context *context = next_context (pfile);
00977
00978 context->direct_p = true;
00979 context->macro = macro;
00980 context->buff = NULL;
00981 FIRST (context).token = first;
00982 LAST (context).token = first + count;
00983 }
00984
00985
00986 void
00987 _cpp_push_text_context (cpp_reader *pfile, cpp_hashnode *macro,
00988 const uchar *start, size_t len)
00989 {
00990 cpp_context *context = next_context (pfile);
00991
00992 context->direct_p = true;
00993 context->macro = macro;
00994 context->buff = NULL;
00995 CUR (context) = start;
00996 RLIMIT (context) = start + len;
00997 macro->flags |= NODE_DISABLED;
00998 }
00999
01000
01001
01002
01003
01004
01005
01006 static void
01007 expand_arg (cpp_reader *pfile, macro_arg *arg)
01008 {
01009 unsigned int capacity;
01010 bool saved_warn_trad;
01011
01012 if (arg->count == 0)
01013 return;
01014
01015
01016 saved_warn_trad = CPP_WTRADITIONAL (pfile);
01017 CPP_WTRADITIONAL (pfile) = 0;
01018
01019
01020 capacity = 256;
01021 arg->expanded = XNEWVEC (const cpp_token *, capacity);
01022
01023 push_ptoken_context (pfile, NULL, NULL, arg->first, arg->count + 1);
01024 for (;;)
01025 {
01026 const cpp_token *token;
01027
01028 if (arg->expanded_count + 1 >= capacity)
01029 {
01030 capacity *= 2;
01031 arg->expanded = XRESIZEVEC (const cpp_token *, arg->expanded,
01032 capacity);
01033 }
01034
01035 token = cpp_get_token (pfile);
01036
01037 if (token->type == CPP_EOF)
01038 break;
01039
01040 arg->expanded[arg->expanded_count++] = token;
01041 }
01042
01043 _cpp_pop_context (pfile);
01044
01045 CPP_WTRADITIONAL (pfile) = saved_warn_trad;
01046 }
01047
01048
01049
01050
01051 void
01052 _cpp_pop_context (cpp_reader *pfile)
01053 {
01054 cpp_context *context = pfile->context;
01055
01056 if (context->macro)
01057 context->macro->flags &= ~NODE_DISABLED;
01058
01059 if (context->buff)
01060 _cpp_release_buff (pfile, context->buff);
01061
01062 pfile->context = context->prev;
01063 }
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076 const cpp_token *
01077 cpp_get_token (cpp_reader *pfile)
01078 {
01079 const cpp_token *result;
01080
01081 for (;;)
01082 {
01083 cpp_hashnode *node;
01084 cpp_context *context = pfile->context;
01085
01086
01087 if (!context->prev)
01088 result = _cpp_lex_token (pfile);
01089 else if (FIRST (context).token != LAST (context).token)
01090 {
01091 if (context->direct_p)
01092 result = FIRST (context).token++;
01093 else
01094 result = *FIRST (context).ptoken++;
01095
01096 if (result->flags & PASTE_LEFT)
01097 {
01098 paste_all_tokens (pfile, result);
01099 if (pfile->state.in_directive)
01100 continue;
01101 return padding_token (pfile, result);
01102 }
01103 }
01104 else
01105 {
01106 _cpp_pop_context (pfile);
01107 if (pfile->state.in_directive)
01108 continue;
01109 return &pfile->avoid_paste;
01110 }
01111
01112 if (pfile->state.in_directive && result->type == CPP_COMMENT)
01113 continue;
01114
01115 if (result->type != CPP_NAME)
01116 break;
01117
01118 node = result->val.node;
01119
01120 if (node->type != NT_MACRO || (result->flags & NO_EXPAND))
01121 break;
01122
01123 if (!(node->flags & NODE_DISABLED))
01124 {
01125 if (!pfile->state.prevent_expansion
01126 && enter_macro_context (pfile, node))
01127 {
01128 if (pfile->state.in_directive)
01129 continue;
01130 return padding_token (pfile, result);
01131 }
01132 }
01133 else
01134 {
01135
01136
01137 cpp_token *t = _cpp_temp_token (pfile);
01138 t->type = result->type;
01139 t->flags = result->flags | NO_EXPAND;
01140 t->val = result->val;
01141 result = t;
01142 }
01143
01144 break;
01145 }
01146
01147 return result;
01148 }
01149
01150
01151
01152
01153 int
01154 cpp_sys_macro_p (cpp_reader *pfile)
01155 {
01156 cpp_hashnode *node = pfile->context->macro;
01157
01158 return node && node->value.macro && node->value.macro->syshdr;
01159 }
01160
01161
01162
01163 void
01164 cpp_scan_nooutput (cpp_reader *pfile)
01165 {
01166
01167
01168 pfile->buffer->return_at_eof = true;
01169
01170 pfile->state.discarding_output++;
01171 pfile->state.prevent_expansion++;
01172
01173 if (CPP_OPTION (pfile, traditional))
01174 while (_cpp_read_logical_line_trad (pfile))
01175 ;
01176 else
01177 while (cpp_get_token (pfile)->type != CPP_EOF)
01178 ;
01179
01180 pfile->state.discarding_output--;
01181 pfile->state.prevent_expansion--;
01182 }
01183
01184
01185
01186 void
01187 _cpp_backup_tokens (cpp_reader *pfile, unsigned int count)
01188 {
01189 if (pfile->context->prev == NULL)
01190 {
01191 pfile->lookaheads += count;
01192 while (count--)
01193 {
01194 pfile->cur_token--;
01195 if (pfile->cur_token == pfile->cur_run->base
01196
01197 && pfile->cur_run->prev != NULL)
01198 {
01199 pfile->cur_run = pfile->cur_run->prev;
01200 pfile->cur_token = pfile->cur_run->limit;
01201 }
01202 }
01203 }
01204 else
01205 {
01206 if (count != 1)
01207 abort ();
01208 if (pfile->context->direct_p)
01209 FIRST (pfile->context).token--;
01210 else
01211 FIRST (pfile->context).ptoken--;
01212 }
01213 }
01214
01215
01216
01217
01218 static bool
01219 warn_of_redefinition (cpp_reader *pfile, const cpp_hashnode *node,
01220 const cpp_macro *macro2)
01221 {
01222 const cpp_macro *macro1;
01223 unsigned int i;
01224
01225
01226 if (node->flags & NODE_WARN)
01227 return true;
01228
01229
01230
01231 macro1 = node->value.macro;
01232
01233
01234
01235 if (macro1->paramc != macro2->paramc
01236 || macro1->fun_like != macro2->fun_like
01237 || macro1->variadic != macro2->variadic)
01238 return true;
01239
01240
01241 for (i = 0; i < macro1->paramc; i++)
01242 if (macro1->params[i] != macro2->params[i])
01243 return true;
01244
01245
01246 if (CPP_OPTION (pfile, traditional))
01247 return _cpp_expansions_different_trad (macro1, macro2);
01248
01249 if (macro1->count != macro2->count)
01250 return true;
01251
01252 for (i = 0; i < macro1->count; i++)
01253 if (!_cpp_equiv_tokens (¯o1->exp.tokens[i], ¯o2->exp.tokens[i]))
01254 return true;
01255
01256 return false;
01257 }
01258
01259
01260 void
01261 _cpp_free_definition (cpp_hashnode *h)
01262 {
01263
01264 h->type = NT_VOID;
01265
01266 h->flags &= ~(NODE_BUILTIN | NODE_DISABLED);
01267 }
01268
01269
01270
01271 bool
01272 _cpp_save_parameter (cpp_reader *pfile, cpp_macro *macro, cpp_hashnode *node)
01273 {
01274 unsigned int len;
01275
01276 if (node->flags & NODE_MACRO_ARG)
01277 {
01278 cpp_error (pfile, CPP_DL_ERROR, "duplicate macro parameter \"%s\"",
01279 NODE_NAME (node));
01280 return true;
01281 }
01282
01283 if (BUFF_ROOM (pfile->a_buff)
01284 < (macro->paramc + 1) * sizeof (cpp_hashnode *))
01285 _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_hashnode *));
01286
01287 ((cpp_hashnode **) BUFF_FRONT (pfile->a_buff))[macro->paramc++] = node;
01288 node->flags |= NODE_MACRO_ARG;
01289 len = macro->paramc * sizeof (union _cpp_hashnode_value);
01290 if (len > pfile->macro_buffer_len)
01291 {
01292 pfile->macro_buffer = XRESIZEVEC (unsigned char, pfile->macro_buffer,
01293 len);
01294 pfile->macro_buffer_len = len;
01295 }
01296 ((union _cpp_hashnode_value *) pfile->macro_buffer)[macro->paramc - 1]
01297 = node->value;
01298
01299 node->value.arg_index = macro->paramc;
01300 return false;
01301 }
01302
01303
01304
01305 static bool
01306 parse_params (cpp_reader *pfile, cpp_macro *macro)
01307 {
01308 unsigned int prev_ident = 0;
01309
01310 for (;;)
01311 {
01312 const cpp_token *token = _cpp_lex_token (pfile);
01313
01314 switch (token->type)
01315 {
01316 default:
01317
01318
01319 if (token->type == CPP_COMMENT
01320 && ! CPP_OPTION (pfile, discard_comments_in_macro_exp))
01321 continue;
01322
01323 cpp_error (pfile, CPP_DL_ERROR,
01324 "\"%s\" may not appear in macro parameter list",
01325 cpp_token_as_text (pfile, token));
01326 return false;
01327
01328 case CPP_NAME:
01329 if (prev_ident)
01330 {
01331 cpp_error (pfile, CPP_DL_ERROR,
01332 "macro parameters must be comma-separated");
01333 return false;
01334 }
01335 prev_ident = 1;
01336
01337 if (_cpp_save_parameter (pfile, macro, token->val.node))
01338 return false;
01339 continue;
01340
01341 case CPP_CLOSE_PAREN:
01342 if (prev_ident || macro->paramc == 0)
01343 return true;
01344
01345
01346 case CPP_COMMA:
01347 if (!prev_ident)
01348 {
01349 cpp_error (pfile, CPP_DL_ERROR, "parameter name missing");
01350 return false;
01351 }
01352 prev_ident = 0;
01353 continue;
01354
01355 case CPP_ELLIPSIS:
01356 macro->variadic = 1;
01357 if (!prev_ident)
01358 {
01359 _cpp_save_parameter (pfile, macro,
01360 pfile->spec_nodes.n__VA_ARGS__);
01361 pfile->state.va_args_ok = 1;
01362 if (! CPP_OPTION (pfile, c99)
01363 && CPP_OPTION (pfile, pedantic)
01364 && CPP_OPTION (pfile, warn_variadic_macros))
01365 cpp_error (pfile, CPP_DL_PEDWARN,
01366 "anonymous variadic macros were introduced in C99");
01367 }
01368 else if (CPP_OPTION (pfile, pedantic)
01369 && CPP_OPTION (pfile, warn_variadic_macros))
01370 cpp_error (pfile, CPP_DL_PEDWARN,
01371 "ISO C does not permit named variadic macros");
01372
01373
01374 token = _cpp_lex_token (pfile);
01375 if (token->type == CPP_CLOSE_PAREN)
01376 return true;
01377
01378
01379 case CPP_EOF:
01380 cpp_error (pfile, CPP_DL_ERROR, "missing ')' in macro parameter list");
01381 return false;
01382 }
01383 }
01384 }
01385
01386
01387 static cpp_token *
01388 alloc_expansion_token (cpp_reader *pfile, cpp_macro *macro)
01389 {
01390 if (BUFF_ROOM (pfile->a_buff) < (macro->count + 1) * sizeof (cpp_token))
01391 _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_token));
01392
01393 return &((cpp_token *) BUFF_FRONT (pfile->a_buff))[macro->count++];
01394 }
01395
01396
01397
01398 static cpp_token *
01399 lex_expansion_token (cpp_reader *pfile, cpp_macro *macro)
01400 {
01401 cpp_token *token;
01402
01403 pfile->cur_token = alloc_expansion_token (pfile, macro);
01404 token = _cpp_lex_direct (pfile);
01405
01406
01407 if (token->type == CPP_NAME
01408 && (token->val.node->flags & NODE_MACRO_ARG) != 0)
01409 {
01410 token->type = CPP_MACRO_ARG;
01411 token->val.arg_no = token->val.node->value.arg_index;
01412 }
01413 else if (CPP_WTRADITIONAL (pfile) && macro->paramc > 0
01414 && (token->type == CPP_STRING || token->type == CPP_CHAR))
01415 check_trad_stringification (pfile, macro, &token->val.str);
01416
01417 return token;
01418 }
01419
01420 static bool
01421 create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
01422 {
01423 cpp_token *token;
01424 const cpp_token *ctoken;
01425
01426
01427
01428 ctoken = _cpp_lex_token (pfile);
01429
01430 if (ctoken->type == CPP_OPEN_PAREN && !(ctoken->flags & PREV_WHITE))
01431 {
01432 bool ok = parse_params (pfile, macro);
01433 macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);
01434 if (!ok)
01435 return false;
01436
01437
01438 if (pfile->hash_table->alloc_subobject)
01439 {
01440 cpp_hashnode **params =
01441 (cpp_hashnode **) pfile->hash_table->alloc_subobject
01442 (sizeof (cpp_hashnode *) * macro->paramc);
01443 memcpy (params, macro->params,
01444 sizeof (cpp_hashnode *) * macro->paramc);
01445 macro->params = params;
01446 }
01447 else
01448 BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->params[macro->paramc];
01449 macro->fun_like = 1;
01450 }
01451 else if (ctoken->type != CPP_EOF && !(ctoken->flags & PREV_WHITE))
01452 {
01453
01454
01455
01456 if (CPP_OPTION (pfile, c99))
01457 cpp_error (pfile, CPP_DL_PEDWARN,
01458 "ISO C99 requires whitespace after the macro name");
01459 else
01460 {
01461 int warntype = CPP_DL_WARNING;
01462 switch (ctoken->type)
01463 {
01464 case CPP_ATSIGN:
01465 case CPP_AT_NAME:
01466 case CPP_OBJC_STRING:
01467
01468 warntype = CPP_DL_PEDWARN;
01469 break;
01470 case CPP_OTHER:
01471
01472 if (strchr ("!\"#%&'()*+,-./:;<=>?[\\]^{|}~",
01473 ctoken->val.str.text[0]) == NULL)
01474 warntype = CPP_DL_PEDWARN;
01475 break;
01476 default:
01477
01478
01479 break;
01480 }
01481 cpp_error (pfile, warntype,
01482 "missing whitespace after the macro name");
01483 }
01484 }
01485
01486 if (macro->fun_like)
01487 token = lex_expansion_token (pfile, macro);
01488 else
01489 {
01490 token = alloc_expansion_token (pfile, macro);
01491 *token = *ctoken;
01492 }
01493
01494 for (;;)
01495 {
01496
01497
01498 if (macro->count > 1 && token[-1].type == CPP_HASH && macro->fun_like)
01499 {
01500 if (token->type == CPP_MACRO_ARG)
01501 {
01502 token->flags &= ~PREV_WHITE;
01503 token->flags |= STRINGIFY_ARG;
01504 token->flags |= token[-1].flags & PREV_WHITE;
01505 token[-1] = token[0];
01506 macro->count--;
01507 }
01508
01509 else if (CPP_OPTION (pfile, lang) != CLK_ASM)
01510 {
01511 cpp_error (pfile, CPP_DL_ERROR,
01512 "'#' is not followed by a macro parameter");
01513 return false;
01514 }
01515 }
01516
01517 if (token->type == CPP_EOF)
01518 break;
01519
01520
01521 if (token->type == CPP_PASTE)
01522 {
01523
01524
01525 if (--macro->count > 0)
01526 token = lex_expansion_token (pfile, macro);
01527
01528 if (macro->count == 0 || token->type == CPP_EOF)
01529 {
01530 cpp_error (pfile, CPP_DL_ERROR,
01531 "'##' cannot appear at either end of a macro expansion");
01532 return false;
01533 }
01534
01535 token[-1].flags |= PASTE_LEFT;
01536 }
01537
01538 token = lex_expansion_token (pfile, macro);
01539 }
01540
01541 macro->exp.tokens = (cpp_token *) BUFF_FRONT (pfile->a_buff);
01542 macro->traditional = 0;
01543
01544
01545 macro->count--;
01546
01547
01548 if (macro->count)
01549 macro->exp.tokens[0].flags &= ~PREV_WHITE;
01550
01551
01552 if (pfile->hash_table->alloc_subobject)
01553 {
01554 cpp_token *tokns =
01555 (cpp_token *) pfile->hash_table->alloc_subobject (sizeof (cpp_token)
01556 * macro->count);
01557 memcpy (tokns, macro->exp.tokens, sizeof (cpp_token) * macro->count);
01558 macro->exp.tokens = tokns;
01559 }
01560 else
01561 BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->exp.tokens[macro->count];
01562
01563 return true;
01564 }
01565
01566
01567 bool
01568 _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
01569 {
01570 cpp_macro *macro;
01571 unsigned int i;
01572 bool ok;
01573
01574 if (pfile->hash_table->alloc_subobject)
01575 macro = (cpp_macro *) pfile->hash_table->alloc_subobject
01576 (sizeof (cpp_macro));
01577 else
01578 macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro));
01579 macro->line = pfile->directive_line;
01580 macro->params = 0;
01581 macro->paramc = 0;
01582 macro->variadic = 0;
01583 macro->used = !CPP_OPTION (pfile, warn_unused_macros);
01584 macro->count = 0;
01585 macro->fun_like = 0;
01586
01587 macro->syshdr = pfile->buffer && pfile->buffer->sysp != 0;
01588
01589 if (CPP_OPTION (pfile, traditional))
01590 ok = _cpp_create_trad_definition (pfile, macro);
01591 else
01592 {
01593 cpp_token *saved_cur_token = pfile->cur_token;
01594
01595 ok = create_iso_definition (pfile, macro);
01596
01597
01598
01599
01600
01601
01602
01603 saved_cur_token[-1].type = pfile->cur_token[-1].type;
01604 pfile->cur_token = saved_cur_token;
01605
01606
01607 pfile->state.va_args_ok = 0;
01608 }
01609
01610
01611 for (i = macro->paramc; i-- > 0; )
01612 {
01613 struct cpp_hashnode *node = macro->params[i];
01614 node->flags &= ~ NODE_MACRO_ARG;
01615 node->value = ((union _cpp_hashnode_value *) pfile->macro_buffer)[i];
01616 }
01617
01618 if (!ok)
01619 return ok;
01620
01621 if (node->type == NT_MACRO)
01622 {
01623 if (CPP_OPTION (pfile, warn_unused_macros))
01624 _cpp_warn_if_unused_macro (pfile, node, NULL);
01625
01626 if (warn_of_redefinition (pfile, node, macro))
01627 {
01628 cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->directive_line, 0,
01629 "\"%s\" redefined", NODE_NAME (node));
01630
01631 if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
01632 cpp_error_with_line (pfile, CPP_DL_PEDWARN,
01633 node->value.macro->line, 0,
01634 "this is the location of the previous definition");
01635 }
01636 }
01637
01638 if (node->type != NT_VOID)
01639 _cpp_free_definition (node);
01640
01641
01642 node->type = NT_MACRO;
01643 node->value.macro = macro;
01644 if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_")))
01645 node->flags |= NODE_WARN;
01646
01647 return ok;
01648 }
01649
01650
01651
01652 static void
01653 check_trad_stringification (cpp_reader *pfile, const cpp_macro *macro,
01654 const cpp_string *string)
01655 {
01656 unsigned int i, len;
01657 const uchar *p, *q, *limit;
01658
01659
01660 limit = string->text + string->len - 1;
01661 for (p = string->text + 1; p < limit; p = q)
01662 {
01663
01664 while (p < limit && !is_idstart (*p))
01665 p++;
01666
01667
01668 q = p;
01669 while (q < limit && is_idchar (*q))
01670 q++;
01671
01672 len = q - p;
01673
01674
01675
01676 for (i = 0; i < macro->paramc; i++)
01677 {
01678 const cpp_hashnode *node = macro->params[i];
01679
01680 if (NODE_LEN (node) == len
01681 && !memcmp (p, NODE_NAME (node), len))
01682 {
01683 cpp_error (pfile, CPP_DL_WARNING,
01684 "macro argument \"%s\" would be stringified in traditional C",
01685 NODE_NAME (node));
01686 break;
01687 }
01688 }
01689 }
01690 }
01691
01692
01693
01694
01695
01696
01697 const unsigned char *
01698 cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node)
01699 {
01700 unsigned int i, len;
01701 const cpp_macro *macro = node->value.macro;
01702 unsigned char *buffer;
01703
01704 if (node->type != NT_MACRO || (node->flags & NODE_BUILTIN))
01705 {
01706 cpp_error (pfile, CPP_DL_ICE,
01707 "invalid hash type %d in cpp_macro_definition", node->type);
01708 return 0;
01709 }
01710
01711
01712 len = NODE_LEN (node) + 2;
01713 if (macro->fun_like)
01714 {
01715 len += 4;
01716
01717 for (i = 0; i < macro->paramc; i++)
01718 len += NODE_LEN (macro->params[i]) + 1;
01719 }
01720
01721
01722 if (CPP_OPTION (pfile, traditional))
01723 len += _cpp_replacement_text_len (macro);
01724 else
01725 {
01726 for (i = 0; i < macro->count; i++)
01727 {
01728 cpp_token *token = ¯o->exp.tokens[i];
01729
01730 if (token->type == CPP_MACRO_ARG)
01731 len += NODE_LEN (macro->params[token->val.arg_no - 1]);
01732 else
01733 len += cpp_token_len (token);
01734
01735 if (token->flags & STRINGIFY_ARG)
01736 len++;
01737 if (token->flags & PASTE_LEFT)
01738 len += 3;
01739 if (token->flags & PREV_WHITE)
01740 len++;
01741 }
01742 }
01743
01744 if (len > pfile->macro_buffer_len)
01745 {
01746 pfile->macro_buffer = XRESIZEVEC (unsigned char,
01747 pfile->macro_buffer, len);
01748 pfile->macro_buffer_len = len;
01749 }
01750
01751
01752 buffer = pfile->macro_buffer;
01753 memcpy (buffer, NODE_NAME (node), NODE_LEN (node));
01754 buffer += NODE_LEN (node);
01755
01756
01757 if (macro->fun_like)
01758 {
01759 *buffer++ = '(';
01760 for (i = 0; i < macro->paramc; i++)
01761 {
01762 cpp_hashnode *param = macro->params[i];
01763
01764 if (param != pfile->spec_nodes.n__VA_ARGS__)
01765 {
01766 memcpy (buffer, NODE_NAME (param), NODE_LEN (param));
01767 buffer += NODE_LEN (param);
01768 }
01769
01770 if (i + 1 < macro->paramc)
01771
01772
01773
01774 *buffer++ = ',';
01775 else if (macro->variadic)
01776 *buffer++ = '.', *buffer++ = '.', *buffer++ = '.';
01777 }
01778 *buffer++ = ')';
01779 }
01780
01781
01782
01783 *buffer++ = ' ';
01784
01785 if (CPP_OPTION (pfile, traditional))
01786 buffer = _cpp_copy_replacement_text (macro, buffer);
01787 else if (macro->count)
01788
01789 {
01790 for (i = 0; i < macro->count; i++)
01791 {
01792 cpp_token *token = ¯o->exp.tokens[i];
01793
01794 if (token->flags & PREV_WHITE)
01795 *buffer++ = ' ';
01796 if (token->flags & STRINGIFY_ARG)
01797 *buffer++ = '#';
01798
01799 if (token->type == CPP_MACRO_ARG)
01800 {
01801 memcpy (buffer,
01802 NODE_NAME (macro->params[token->val.arg_no - 1]),
01803 NODE_LEN (macro->params[token->val.arg_no - 1]));
01804 buffer += NODE_LEN (macro->params[token->val.arg_no - 1]);
01805 }
01806 else
01807 buffer = cpp_spell_token (pfile, token, buffer, false);
01808
01809 if (token->flags & PASTE_LEFT)
01810 {
01811 *buffer++ = ' ';
01812 *buffer++ = '#';
01813 *buffer++ = '#';
01814
01815 }
01816 }
01817 }
01818
01819 *buffer = '\0';
01820 return pfile->macro_buffer;
01821 }