mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-05 03:29:42 +01:00
+ added flag to TMacro denoting mac style compiler variable
* fixed $DEFINEC * improved robustness of macro facility
This commit is contained in:
parent
f125ee32d1
commit
df2d2a847c
@ -48,9 +48,11 @@ interface
|
|||||||
tscannerfile = class;
|
tscannerfile = class;
|
||||||
|
|
||||||
tmacro = class(TNamedIndexItem)
|
tmacro = class(TNamedIndexItem)
|
||||||
defined,
|
defined : boolean; { normally true, but false when the macro is undef-ed}
|
||||||
defined_at_startup,
|
defined_at_startup : boolean;
|
||||||
is_used : boolean;
|
is_used : boolean;
|
||||||
|
is_compiler_var : boolean; { if this is a mac style compiler variable, in
|
||||||
|
which case no macro substitutions shall be done.}
|
||||||
buftext : pchar;
|
buftext : pchar;
|
||||||
buflen : longint;
|
buflen : longint;
|
||||||
fileinfo : tfileposinfo;
|
fileinfo : tfileposinfo;
|
||||||
@ -379,7 +381,8 @@ implementation
|
|||||||
len : integer;
|
len : integer;
|
||||||
begin
|
begin
|
||||||
result := current_scanner.preproc_pattern;
|
result := current_scanner.preproc_pattern;
|
||||||
{ allow macro support in macro's }
|
{ Substitue macros and compiler variables with their content/value.
|
||||||
|
For real macros also do recursive substitution. }
|
||||||
macrocount:=0;
|
macrocount:=0;
|
||||||
repeat
|
repeat
|
||||||
mac:=tmacro(current_scanner.macros.search(result));
|
mac:=tmacro(current_scanner.macros.search(result));
|
||||||
@ -391,21 +394,30 @@ implementation
|
|||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if assigned(mac) and mac.defined and assigned(mac.buftext) then
|
if assigned(mac) and mac.defined then
|
||||||
begin
|
if assigned(mac.buftext) then
|
||||||
if mac.buflen>255 then
|
begin
|
||||||
begin
|
if mac.buflen>255 then
|
||||||
len:=255;
|
begin
|
||||||
Message(scan_w_macro_cut_after_255_chars);
|
len:=255;
|
||||||
end
|
Message(scan_w_macro_cut_after_255_chars);
|
||||||
else
|
end
|
||||||
len:=mac.buflen;
|
else
|
||||||
hs[0]:=char(len);
|
len:=mac.buflen;
|
||||||
move(mac.buftext^,hs[1],len);
|
hs[0]:=char(len);
|
||||||
result:=upcase(hs);
|
move(mac.buftext^,hs[1],len);
|
||||||
end
|
result:=upcase(hs);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Message1(scan_e_error_macro_lacks_value, result);
|
||||||
|
break;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if mac.is_compiler_var then
|
||||||
|
break;
|
||||||
until false;
|
until false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -421,7 +433,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if current_scanner.preproc_token=_ID then
|
if current_scanner.preproc_token=_ID then
|
||||||
begin
|
begin
|
||||||
if preproc_substitutedtoken='DEFINED' then
|
if current_scanner.preproc_pattern='DEFINED' then
|
||||||
begin
|
begin
|
||||||
preproc_consume(_ID);
|
preproc_consume(_ID);
|
||||||
current_scanner.skipspace;
|
current_scanner.skipspace;
|
||||||
@ -452,7 +464,7 @@ implementation
|
|||||||
Message(scan_e_error_in_preproc_expr);
|
Message(scan_e_error_in_preproc_expr);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if (m_mac in aktmodeswitches) and (preproc_substitutedtoken='UNDEFINED') then
|
if (m_mac in aktmodeswitches) and (current_scanner.preproc_pattern='UNDEFINED') then
|
||||||
begin
|
begin
|
||||||
preproc_consume(_ID);
|
preproc_consume(_ID);
|
||||||
current_scanner.skipspace;
|
current_scanner.skipspace;
|
||||||
@ -472,7 +484,7 @@ implementation
|
|||||||
Message(scan_e_error_in_preproc_expr);
|
Message(scan_e_error_in_preproc_expr);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if (m_mac in aktmodeswitches) and (preproc_substitutedtoken='OPTION') then
|
if (m_mac in aktmodeswitches) and (current_scanner.preproc_pattern='OPTION') then
|
||||||
begin
|
begin
|
||||||
preproc_consume(_ID);
|
preproc_consume(_ID);
|
||||||
current_scanner.skipspace;
|
current_scanner.skipspace;
|
||||||
@ -507,7 +519,7 @@ implementation
|
|||||||
Message(scan_e_error_in_preproc_expr);
|
Message(scan_e_error_in_preproc_expr);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if preproc_substitutedtoken='SIZEOF' then
|
if current_scanner.preproc_pattern='SIZEOF' then
|
||||||
begin
|
begin
|
||||||
preproc_consume(_ID);
|
preproc_consume(_ID);
|
||||||
current_scanner.skipspace;
|
current_scanner.skipspace;
|
||||||
@ -544,7 +556,7 @@ implementation
|
|||||||
Message(scan_e_error_in_preproc_expr);
|
Message(scan_e_error_in_preproc_expr);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if preproc_substitutedtoken='DECLARED' then
|
if current_scanner.preproc_pattern='DECLARED' then
|
||||||
begin
|
begin
|
||||||
preproc_consume(_ID);
|
preproc_consume(_ID);
|
||||||
current_scanner.skipspace;
|
current_scanner.skipspace;
|
||||||
@ -574,7 +586,7 @@ implementation
|
|||||||
Message(scan_e_error_in_preproc_expr);
|
Message(scan_e_error_in_preproc_expr);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if preproc_substitutedtoken='NOT' then
|
if current_scanner.preproc_pattern='NOT' then
|
||||||
begin
|
begin
|
||||||
preproc_consume(_ID);
|
preproc_consume(_ID);
|
||||||
hs:=read_factor();
|
hs:=read_factor();
|
||||||
@ -585,13 +597,13 @@ implementation
|
|||||||
read_factor:='1';
|
read_factor:='1';
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if (m_mac in aktmodeswitches) and (preproc_substitutedtoken='TRUE') then
|
if (m_mac in aktmodeswitches) and (current_scanner.preproc_pattern='TRUE') then
|
||||||
begin
|
begin
|
||||||
preproc_consume(_ID);
|
preproc_consume(_ID);
|
||||||
read_factor:='1';
|
read_factor:='1';
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if (m_mac in aktmodeswitches) and (preproc_substitutedtoken='FALSE') then
|
if (m_mac in aktmodeswitches) and (current_scanner.preproc_pattern='FALSE') then
|
||||||
begin
|
begin
|
||||||
preproc_consume(_ID);
|
preproc_consume(_ID);
|
||||||
read_factor:='0';
|
read_factor:='0';
|
||||||
@ -623,7 +635,7 @@ implementation
|
|||||||
repeat
|
repeat
|
||||||
if (current_scanner.preproc_token<>_ID) then
|
if (current_scanner.preproc_token<>_ID) then
|
||||||
break;
|
break;
|
||||||
if preproc_substitutedtoken<>'AND' then
|
if current_scanner.preproc_pattern<>'AND' then
|
||||||
break;
|
break;
|
||||||
preproc_consume(_ID);
|
preproc_consume(_ID);
|
||||||
hs2:=read_factor;
|
hs2:=read_factor;
|
||||||
@ -648,7 +660,7 @@ implementation
|
|||||||
repeat
|
repeat
|
||||||
if (current_scanner.preproc_token<>_ID) then
|
if (current_scanner.preproc_token<>_ID) then
|
||||||
break;
|
break;
|
||||||
if preproc_substitutedtoken<>'OR' then
|
if current_scanner.preproc_pattern<>'OR' then
|
||||||
break;
|
break;
|
||||||
preproc_consume(_ID);
|
preproc_consume(_ID);
|
||||||
hs2:=read_term;
|
hs2:=read_term;
|
||||||
@ -757,6 +769,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
Message1(parser_c_macro_defined,mac.name);
|
Message1(parser_c_macro_defined,mac.name);
|
||||||
mac.defined:=true;
|
mac.defined:=true;
|
||||||
|
mac.is_compiler_var:=false;
|
||||||
{ delete old definition }
|
{ delete old definition }
|
||||||
if assigned(mac.buftext) then
|
if assigned(mac.buftext) then
|
||||||
begin
|
begin
|
||||||
@ -767,53 +780,59 @@ implementation
|
|||||||
mac.is_used:=true;
|
mac.is_used:=true;
|
||||||
if (cs_support_macro in aktmoduleswitches) then
|
if (cs_support_macro in aktmoduleswitches) then
|
||||||
begin
|
begin
|
||||||
{ key words are never substituted }
|
{ key words are never substituted }
|
||||||
if is_keyword(hs) then
|
if is_keyword(hs) then
|
||||||
Message(scan_e_keyword_cant_be_a_macro);
|
Message(scan_e_keyword_cant_be_a_macro);
|
||||||
{ !!!!!! handle macro params, need we this? }
|
{ !!!!!! handle macro params, need we this? }
|
||||||
current_scanner.skipspace;
|
current_scanner.skipspace;
|
||||||
{ may be a macro? }
|
|
||||||
if c=':' then
|
if not (m_mac in aktmodeswitches) then
|
||||||
begin
|
begin
|
||||||
current_scanner.readchar;
|
{ may be a macro? }
|
||||||
if c='=' then
|
if c <> ':' then
|
||||||
begin
|
exit;
|
||||||
new(macrobuffer);
|
current_scanner.readchar;
|
||||||
macropos:=0;
|
if c <> '=' then
|
||||||
{ parse macro, brackets are counted so it's possible
|
exit;
|
||||||
to have a $ifdef etc. in the macro }
|
current_scanner.readchar;
|
||||||
bracketcount:=0;
|
current_scanner.skipspace;
|
||||||
repeat
|
|
||||||
current_scanner.readchar;
|
|
||||||
case c of
|
|
||||||
'}' :
|
|
||||||
if (bracketcount=0) then
|
|
||||||
break
|
|
||||||
else
|
|
||||||
dec(bracketcount);
|
|
||||||
'{' :
|
|
||||||
inc(bracketcount);
|
|
||||||
#10,#13 :
|
|
||||||
current_scanner.linebreak;
|
|
||||||
#26 :
|
|
||||||
current_scanner.end_of_file;
|
|
||||||
end;
|
|
||||||
macrobuffer^[macropos]:=c;
|
|
||||||
inc(macropos);
|
|
||||||
if macropos>maxmacrolen then
|
|
||||||
Message(scan_f_macro_buffer_overflow);
|
|
||||||
until false;
|
|
||||||
{ free buffer of macro ?}
|
|
||||||
if assigned(mac.buftext) then
|
|
||||||
freemem(mac.buftext,mac.buflen);
|
|
||||||
{ get new mem }
|
|
||||||
getmem(mac.buftext,macropos);
|
|
||||||
mac.buflen:=macropos;
|
|
||||||
{ copy the text }
|
|
||||||
move(macrobuffer^,mac.buftext^,macropos);
|
|
||||||
dispose(macrobuffer);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
new(macrobuffer);
|
||||||
|
macropos:=0;
|
||||||
|
{ parse macro, brackets are counted so it's possible
|
||||||
|
to have a $ifdef etc. in the macro }
|
||||||
|
bracketcount:=0;
|
||||||
|
repeat
|
||||||
|
case c of
|
||||||
|
'}' :
|
||||||
|
if (bracketcount=0) then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
dec(bracketcount);
|
||||||
|
'{' :
|
||||||
|
inc(bracketcount);
|
||||||
|
#10,#13 :
|
||||||
|
current_scanner.linebreak;
|
||||||
|
#26 :
|
||||||
|
current_scanner.end_of_file;
|
||||||
|
end;
|
||||||
|
macrobuffer^[macropos]:=c;
|
||||||
|
inc(macropos);
|
||||||
|
if macropos>maxmacrolen then
|
||||||
|
Message(scan_f_macro_buffer_overflow);
|
||||||
|
current_scanner.readchar;
|
||||||
|
until false;
|
||||||
|
|
||||||
|
{ free buffer of macro ?}
|
||||||
|
if assigned(mac.buftext) then
|
||||||
|
freemem(mac.buftext,mac.buflen);
|
||||||
|
{ get new mem }
|
||||||
|
getmem(mac.buftext,macropos);
|
||||||
|
mac.buflen:=macropos;
|
||||||
|
{ copy the text }
|
||||||
|
move(macrobuffer^,mac.buftext^,macropos);
|
||||||
|
dispose(macrobuffer);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -841,12 +860,14 @@ implementation
|
|||||||
begin
|
begin
|
||||||
mac:=tmacro.create(hs);
|
mac:=tmacro.create(hs);
|
||||||
mac.defined:=true;
|
mac.defined:=true;
|
||||||
|
mac.is_compiler_var:=true;
|
||||||
Message1(parser_c_macro_defined,mac.name);
|
Message1(parser_c_macro_defined,mac.name);
|
||||||
current_scanner.macros.insert(mac);
|
current_scanner.macros.insert(mac);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
mac.defined:=true;
|
mac.defined:=true;
|
||||||
|
mac.is_compiler_var:=true;
|
||||||
{ delete old definition }
|
{ delete old definition }
|
||||||
if assigned(mac.buftext) then
|
if assigned(mac.buftext) then
|
||||||
begin
|
begin
|
||||||
@ -911,6 +932,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
Message1(parser_c_macro_undefined,mac.name);
|
Message1(parser_c_macro_undefined,mac.name);
|
||||||
mac.defined:=false;
|
mac.defined:=false;
|
||||||
|
mac.is_compiler_var:=false;
|
||||||
{ delete old definition }
|
{ delete old definition }
|
||||||
if assigned(mac.buftext) then
|
if assigned(mac.buftext) then
|
||||||
begin
|
begin
|
||||||
@ -1061,6 +1083,7 @@ implementation
|
|||||||
defined_at_startup:=false;
|
defined_at_startup:=false;
|
||||||
fileinfo:=akttokenpos;
|
fileinfo:=akttokenpos;
|
||||||
is_used:=false;
|
is_used:=false;
|
||||||
|
is_compiler_var:= false;
|
||||||
buftext:=nil;
|
buftext:=nil;
|
||||||
buflen:=0;
|
buflen:=0;
|
||||||
end;
|
end;
|
||||||
@ -1242,8 +1265,9 @@ implementation
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
if assigned(mac.buftext) then
|
mac.is_compiler_var:=false;
|
||||||
freemem(mac.buftext,mac.buflen);
|
if assigned(mac.buftext) then
|
||||||
|
freemem(mac.buftext,mac.buflen);
|
||||||
end;
|
end;
|
||||||
Message2(parser_c_macro_set_to,mac.name,value);
|
Message2(parser_c_macro_set_to,mac.name,value);
|
||||||
mac.buflen:=length(value);
|
mac.buflen:=length(value);
|
||||||
@ -2416,7 +2440,7 @@ implementation
|
|||||||
if (cs_support_macro in aktmoduleswitches) then
|
if (cs_support_macro in aktmoduleswitches) then
|
||||||
begin
|
begin
|
||||||
mac:=tmacro(macros.search(pattern));
|
mac:=tmacro(macros.search(pattern));
|
||||||
if assigned(mac) and (assigned(mac.buftext)) then
|
if assigned(mac) and (not mac.is_compiler_var) and (assigned(mac.buftext)) then
|
||||||
begin
|
begin
|
||||||
if yylexcount<max_macro_nesting then
|
if yylexcount<max_macro_nesting then
|
||||||
begin
|
begin
|
||||||
@ -3242,9 +3266,10 @@ exit_label:
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.86 2004-08-22 10:50:19 olle
|
Revision 1.87 2004-08-22 23:16:06 olle
|
||||||
+ added DEFINEC for mode macpas, is equivalent to DEFINE
|
+ added flag to TMacro denoting mac style compiler variable
|
||||||
* fixed bug when macro without value is used in a compile time expr.
|
* fixed $DEFINEC
|
||||||
|
* improved robustness of macro facility
|
||||||
|
|
||||||
Revision 1.85 2004/08/02 20:45:40 florian
|
Revision 1.85 2004/08/02 20:45:40 florian
|
||||||
* sizeof in the preprocessor handles types now as well
|
* sizeof in the preprocessor handles types now as well
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user