|
@@ -48,9 +48,11 @@ interface
|
|
tscannerfile = class;
|
|
tscannerfile = class;
|
|
|
|
|
|
tmacro = class(TNamedIndexItem)
|
|
tmacro = class(TNamedIndexItem)
|
|
- defined,
|
|
|
|
- defined_at_startup,
|
|
|
|
|
|
+ defined : boolean; { normally true, but false when the macro is undef-ed}
|
|
|
|
+ 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
|
|
|
|
- begin
|
|
|
|
- if mac.buflen>255 then
|
|
|
|
- begin
|
|
|
|
- len:=255;
|
|
|
|
- Message(scan_w_macro_cut_after_255_chars);
|
|
|
|
- end
|
|
|
|
- else
|
|
|
|
- len:=mac.buflen;
|
|
|
|
- hs[0]:=char(len);
|
|
|
|
- move(mac.buftext^,hs[1],len);
|
|
|
|
- result:=upcase(hs);
|
|
|
|
- end
|
|
|
|
|
|
+ if assigned(mac) and mac.defined then
|
|
|
|
+ if assigned(mac.buftext) then
|
|
|
|
+ begin
|
|
|
|
+ if mac.buflen>255 then
|
|
|
|
+ begin
|
|
|
|
+ len:=255;
|
|
|
|
+ Message(scan_w_macro_cut_after_255_chars);
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ len:=mac.buflen;
|
|
|
|
+ hs[0]:=char(len);
|
|
|
|
+ move(mac.buftext^,hs[1],len);
|
|
|
|
+ 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);
|
|
|
|
- { !!!!!! handle macro params, need we this? }
|
|
|
|
|
|
+ Message(scan_e_keyword_cant_be_a_macro);
|
|
|
|
+ { !!!!!! 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;
|
|
|
|
- if c='=' then
|
|
|
|
- begin
|
|
|
|
- new(macrobuffer);
|
|
|
|
- macropos:=0;
|
|
|
|
- { parse macro, brackets are counted so it's possible
|
|
|
|
- to have a $ifdef etc. in the macro }
|
|
|
|
- bracketcount:=0;
|
|
|
|
- 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;
|
|
|
|
|
|
+ { may be a macro? }
|
|
|
|
+ if c <> ':' then
|
|
|
|
+ exit;
|
|
|
|
+ current_scanner.readchar;
|
|
|
|
+ if c <> '=' then
|
|
|
|
+ exit;
|
|
|
|
+ current_scanner.readchar;
|
|
|
|
+ current_scanner.skipspace;
|
|
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
|
|
|
|
- freemem(mac.buftext,mac.buflen);
|
|
|
|
|
|
+ mac.is_compiler_var:=false;
|
|
|
|
+ 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
|
|
|
|
- + added DEFINEC for mode macpas, is equivalent to DEFINE
|
|
|
|
- * fixed bug when macro without value is used in a compile time expr.
|
|
|
|
|
|
+ Revision 1.87 2004-08-22 23:16:06 olle
|
|
|
|
+ + added flag to TMacro denoting mac style compiler variable
|
|
|
|
+ * 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
|