354
354
void PreMacroExpander::replaceUnchangedArg (int index, Unit* argUnit,
355
355
PreArgDesc &args, Unit* unit, Token *token, bool varnargs) const
357
Token* prev = (Token*) unit->prev (token);
358
Token* next = (Token*) unit->next (token);
357
Token* prev = prevPreprocessingToken (token, unit);
358
Token* next = nextPreprocessingToken (token, unit);
360
// It's not an empty argument or an argument too much.
360
// It's not an empty argument or an additional argument.
361
361
if (index <= args.numArgs ()-1)
363
MacroUnit& arg = args.getArg (index);
363
365
// If no concatenation operator was found the argument has
364
366
// to be prescanned before it will be inserted into the unit.
365
367
// During prescan all macros in the argument will be expanded.
368
if (prev->is_macro_op () && prev->type () == TOK_MO_HASHHASH)
370
// The argument has to be inserted in unit as it is.
371
*argUnit += args.getArg (index);
376
if (next->is_macro_op () && next->type () == TOK_MO_HASHHASH)
378
// The argument has to be inserted in unit as it is.
379
*argUnit += args.getArg (index);
383
// Concatenation operator not found. Prescan the argument.
384
Unit* unit = &prescanArgument (&args.getArg (index));
385
argUnit->move ((Token*)argUnit->last (), *unit);
369
if (prev && prev->is_macro_op () && prev->type () == TOK_MO_HASHHASH)
371
// The argument has to be inserted in unit as it is.
374
// If the argument consists only of spaces and comments,
375
// then the concat operator can be deleted. Concating X
376
// with spaces and comments results in X.
377
if (onlySpacesAndComments (arg))
379
unit->kill (prev); // Delete the concat operator.
381
// The concat operator has a special meaning when placed
382
// between a comma and a variable argument (see below).
383
else if (index == args.numArgs ()-1)
386
Token* comma = prevPreprocessingToken (prev, unit);
387
if (comma && comma->type () == TOK_COMMA)
389
unit->kill (prev); // Delete the concat operator.
393
else if (next && next->is_macro_op () && next->type () == TOK_MO_HASHHASH)
395
// The argument has to be inserted in unit as it is.
398
// If the argument consists only of spaces and comments,
399
// then the concat operator can be deleted. Concating X
400
// with spaces and comments results in X.
401
if (onlySpacesAndComments (args.getArg (index)))
403
unit->kill (next); // Delete the concat operator.
408
// Concatenation operator not found. Prescan the argument.
409
Unit* unit = &prescanArgument (&arg);
410
argUnit->move ((Token*)argUnit->last (), *unit);
414
// Rest argument of a variadic macro.
415
else if (varnargs && prev)
390
for (; prev; prev = (Token*) unit->prev (prev))
391
if (! prev->is_whitespace () && ! prev->is_comment ())
395
if (prev->is_macro_op () && prev->type () == TOK_MO_HASHHASH)
417
// The concat operator has a special meaning when placed
418
// between a comma and a variable argument. If the variable
419
// argument is left out when the macro is used, then the
420
// comma before the concat operator will be deleted.
421
if (prev->is_macro_op () && prev->type () == TOK_MO_HASHHASH)
424
Token* comma = prevPreprocessingToken (prev, unit);
425
if (comma && comma->type () == TOK_COMMA)
397
for (prev = (Token*) unit->prev (prev); prev;
398
prev = (Token*) unit->prev (prev))
399
if (! prev->is_whitespace () && ! prev->is_comment ())
427
unit->kill (comma); // Delete the comma.
429
unit->kill (prev); // Delete the concat operator.
435
// Get the next non-whitespace non-comment token
436
Token* PreMacroExpander::nextPreprocessingToken (Token* token, Unit* unit) const {
437
for (token = (Token*) unit->next (token); token; token = (Token*) unit->next (token))
438
if (! token->is_whitespace () && ! token->is_comment ())
444
// Get the previous non-whitespace non-comment token
445
Token* PreMacroExpander::prevPreprocessingToken (Token* token, Unit* unit) const {
446
for (token = (Token*) unit->prev (token); token; token = (Token*) unit->prev (token))
447
if (! token->is_whitespace () && ! token->is_comment ())
453
// Check if the given unit contains only spaces and comments.
454
bool PreMacroExpander::onlySpacesAndComments (MacroUnit& unit) const {
455
for (Token* token = (Token*) unit.first (); token; token = (Token*) unit.next (token))
456
if (! token->is_whitespace () && ! token->is_comment ())
409
462
// Stringify and replace an argument.
410
463
void PreMacroExpander::replaceStringifiedArg (int index, Unit* unit,
411
464
PreArgDesc &args) const