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