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