Parse command-line macros more consistently with macros in code.

This makes a macro defined on the command line like -Dfoo=-1 consist of two tokens, the same as it would if defined in code. (Previously, it was just one token.)

This also somewhat expands the set of macros accepted on the command line. A prefix of +, -, *, &, ~, or ! (the one-character unary operators) can now be used ahead of any identifier, number, or string. Empty macro definitions like -Dfoo= are also permitted.
This commit is contained in:
Stephen Heumann
2022-06-15 21:51:52 -05:00
parent 161bb952e3
commit 8406921147

View File

@@ -3998,7 +3998,7 @@ var
lch: char; {next command line character}
cp: ptr; {character pointer}
i: 0..hashSize; {loop variable}
negative: boolean; {is a number negative?}
tPtr: tokenListRecordPtr; {for building macros from command line}
mp: macroRecordPtr; {for building the predefined macros}
bp: ^macroRecordPtr;
@@ -4420,21 +4420,35 @@ repeat
bp := pointer(ord4(macros) + hash(mp^.name));
mp^.next := bp^;
bp^ := mp;
new(mp^.tokens);
with mp^.tokens^ do begin
next := nil;
expandEnabled := true;
end; {with}
token.kind := intconst; {create the default value}
token.numString := @oneStr;
token.class := intConstant;
token.ival := 1;
oneStr := '1';
mp^.tokens^.tokenStart := @oneStr[1];
mp^.tokens^.tokenEnd := pointer(ord4(@oneStr[1])+1);
if lch = '=' then begin
mp^.tokens^.tokenStart := cp;
mp^.tokens := nil;
NextCh; {record the value}
if lch in ['+','-','*','&','~','!'] then begin
new(tPtr);
tPtr^.next := mp^.tokens;
mp^.tokens := tPtr;
tPtr^.expandEnabled := true;
tPtr^.tokenStart := ptr(ord4(cp)-1);
tPtr^.tokenEnd := cp;
tPtr^.token.class := reservedSymbol;
tPtr^.token.isDigraph := false;
tPtr^.token.numString := nil;
case lch of
'+': tPtr^.token.kind := plusch;
'-': tPtr^.token.kind := minusch;
'*': tPtr^.token.kind := asteriskch;
'&': tPtr^.token.kind := andch;
'~': tPtr^.token.kind := tildech;
'!': tPtr^.token.kind := excch;
end; {case}
NextCh;
end;
if not (charKinds[ord(lch)] in [ch_white,ch_eol,ch_eof]) then begin
new(tPtr);
tPtr^.next := mp^.tokens;
mp^.tokens := tPtr;
tPtr^.expandEnabled := true;
tPtr^.tokenStart := ptr(ord4(cp)-1);
token.numString := nil;
if charKinds[ord(lch)] = letter then begin
token.kind := ident;
@@ -4442,31 +4456,6 @@ repeat
token.name := GetWord;
token.symbolPtr := nil;
end {if}
else if lch in ['+','-'] then begin
negative := lch = '-';
NextCh;
if lch in ['.','0'..'9'] then begin
token.name := GetWord;
DoNumber(true);
token.numString := @'?';
if negative then
case token.class of
intConstant : token.ival := -token.ival;
longConstant : token.lval := -token.lval;
realConstant : token.rval := -token.rval;
longlongConstant: begin
token.qval.lo := ~token.qval.lo;
token.qval.hi := ~token.qval.hi;
token.qval.lo := token.qval.lo + 1;
if token.qval.lo = 0 then
token.qval.hi := token.qval.hi + 1;
end;
otherwise: Error(108);
end; {case}
end {if}
else
FlagErrorAndSkip;
end {else if}
else if lch in ['.','0'..'9'] then begin
token.name := GetWord;
saveNumber := true;
@@ -4475,11 +4464,27 @@ repeat
end {else if}
else if lch = '"' then
GetString
else
else begin
FlagErrorAndSkip;
mp^.tokens^.tokenEnd := ptr(ord4(cp)-1);
mp^.tokens := tPtr^.next;
end; {else}
tPtr^.token := token;
tPtr^.tokenEnd := ptr(ord4(cp)-1);
end; {if}
mp^.tokens^.token := token; {add the value to the definition}
end {if}
else begin
new(tPtr);
tPtr^.next := nil;
mp^.tokens := tPtr;
tPtr^.expandEnabled := true;
oneStr := '1';
tPtr^.tokenStart := @oneStr[1];
tPtr^.tokenEnd := pointer(ord4(@oneStr[1])+1);
tPtr^.token.kind := intconst;
tPtr^.token.numString := @oneStr;
tPtr^.token.class := intConstant;
tPtr^.token.ival := 1;
end; {else}
end {if}
else if lch in ['i','I'] then begin
NextCh; {get the pathname}