+ } else if (SkipWhitespace (1)) {
+ /* Squeeze runs of blanks within an arg */
+ if (SB_NotEmpty (&Arg)) {
+ SB_AppendChar (&Arg, ' ');
+ }
+ } else if (CurC == '/' && NextC == '*') {
+ if (SB_NotEmpty (&Arg)) {
+ SB_AppendChar (&Arg, ' ');
+ }
+ OldStyleComment ();
+ } else if (IS_Get (&Standard) >= STD_C99 && CurC == '/' && NextC == '/') {
+ if (SB_NotEmpty (&Arg)) {
+ SB_AppendChar (&Arg, ' ');
+ }
+ NewStyleComment ();
+ } else if (CurC == '\0') {
+ /* End of input inside macro argument list */
+ PPError ("Unterminated argument list invoking macro `%s'", E->M->Name);
+
+ ClearLine ();
+ break;
+ } else {
+ /* Just copy the character */
+ SB_AppendChar (&Arg, CurC);
+ NextChar ();
+ }
+ }
+
+ /* Deallocate string buf resources */
+ SB_Done (&Arg);
+}
+
+
+
+static void MacroArgSubst (MacroExp* E)
+/* Argument substitution according to ISO/IEC 9899:1999 (E), 6.10.3.1ff */
+{
+ ident Ident;
+ int ArgIdx;
+ StrBuf* OldSource;
+ StrBuf* Arg;
+ int HaveSpace;
+
+
+ /* Remember the current input and switch to the macro replacement. */
+ int OldIndex = SB_GetIndex (&E->M->Replacement);
+ SB_Reset (&E->M->Replacement);
+ OldSource = InitLine (&E->M->Replacement);
+
+ /* Argument handling loop */
+ while (CurC != '\0') {
+
+ /* If we have an identifier, check if it's a macro */
+ if (IsSym (Ident)) {
+
+ /* Check if it's a macro argument */
+ if ((ArgIdx = FindMacroArg (E->M, Ident)) >= 0) {
+
+ /* A macro argument. Get the corresponding actual argument. */
+ Arg = ME_GetActual (E, ArgIdx);
+
+ /* Copy any following whitespace */
+ HaveSpace = SkipWhitespace (0);
+
+ /* If a ## operator follows, we have to insert the actual
+ * argument as is, otherwise it must be macro replaced.