mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-05-18 11:22:39 +02:00
303 lines
6.3 KiB
ObjectPascal
303 lines
6.3 KiB
ObjectPascal
{
|
|
Copyright (c) 2000 by Peter Vreman
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
****************************************************************************}
|
|
program h2paspp;
|
|
|
|
type
|
|
PSymbol=^TSymbol;
|
|
TSymbol=record
|
|
name : string[32];
|
|
next : PSymbol;
|
|
end;
|
|
var
|
|
Symbols : PSymbol;
|
|
OutFile : string;
|
|
|
|
|
|
procedure def_symbol(const s:string);
|
|
var
|
|
p : PSymbol;
|
|
begin
|
|
new(p);
|
|
p^.name:=s;
|
|
p^.next:=Symbols;
|
|
Symbols:=p;
|
|
end;
|
|
|
|
procedure undef_symbol(const s:string);
|
|
var
|
|
p,plast : PSymbol;
|
|
begin
|
|
p:=Symbols;
|
|
plast:=nil;
|
|
while assigned(p) do
|
|
begin
|
|
if p^.name=s then
|
|
begin
|
|
if assigned(plast) then
|
|
plast^.next:=p^.next
|
|
else
|
|
Symbols:=p^.next;
|
|
dispose(p);
|
|
exit;
|
|
end;
|
|
p:=p^.next;
|
|
end;
|
|
end;
|
|
|
|
function check_symbol(const s:string):boolean;
|
|
var
|
|
p : PSymbol;
|
|
begin
|
|
check_symbol:=false;
|
|
p:=Symbols;
|
|
while assigned(p) do
|
|
begin
|
|
if p^.name=s then
|
|
begin
|
|
check_symbol:=true;
|
|
exit;
|
|
end;
|
|
p:=p^.next;
|
|
end;
|
|
end;
|
|
|
|
procedure clear_symbols;
|
|
var
|
|
hp : PSymbol;
|
|
begin
|
|
while assigned(Symbols) do
|
|
begin
|
|
hp:=Symbols;
|
|
Symbols:=Symbols^.next;
|
|
dispose(hp);
|
|
end;
|
|
end;
|
|
|
|
function dofile(const filename : string):boolean;
|
|
|
|
procedure RemoveSpace(var fn:string);
|
|
var
|
|
i : longint;
|
|
begin
|
|
i:=0;
|
|
while (i<length(fn)) and (fn[i+1] in [' ',#9]) do
|
|
inc(i);
|
|
Delete(fn,1,i);
|
|
i:=length(fn);
|
|
while (i>0) and (fn[i] in [' ',#9]) do
|
|
dec(i);
|
|
fn:=copy(fn,1,i);
|
|
end;
|
|
|
|
function GetName(var fn:string):string;
|
|
var
|
|
i : longint;
|
|
begin
|
|
i:=0;
|
|
while (i<length(fn)) and (fn[i+1] in ['a'..'z','A'..'Z','0'..'9','_','-']) do
|
|
inc(i);
|
|
GetName:=Copy(fn,1,i);
|
|
Delete(fn,1,i);
|
|
end;
|
|
|
|
const
|
|
maxlevel=16;
|
|
var
|
|
f,g : text;
|
|
s,orgs,
|
|
opts : string;
|
|
skip : array[0..maxlevel-1] of boolean;
|
|
level : longint;
|
|
begin
|
|
dofile:=false;
|
|
{ open file }
|
|
assign(f,filename);
|
|
{$I-}
|
|
reset(f);
|
|
{$I+}
|
|
if ioresult<>0 then
|
|
begin
|
|
Writeln('Unable to open file ',filename);
|
|
exit;
|
|
end;
|
|
if outfile='' then
|
|
assign(g,'h2paspp.tmp')
|
|
else
|
|
assign(g,outfile);
|
|
{$I-}
|
|
rewrite(g);
|
|
{$I+}
|
|
if ioresult<>0 then
|
|
begin
|
|
Writeln('Unable to create file tmp');
|
|
Close(f);
|
|
exit;
|
|
end;
|
|
fillchar(skip,sizeof(skip),0);
|
|
level:=0;
|
|
while not eof(f) do
|
|
begin
|
|
readln(f,orgs);
|
|
opts:=orgs;
|
|
if (opts<>'') and (opts[1]='#') then
|
|
begin
|
|
Delete(opts,1,1);
|
|
RemoveSpace(opts);
|
|
s:=GetName(opts);
|
|
if (s='ifdef') then
|
|
begin
|
|
RemoveSpace(opts);
|
|
if Level>=maxlevel then
|
|
begin
|
|
Writeln('Too many ifdef levels');
|
|
exit;
|
|
end;
|
|
inc(Level);
|
|
skip[level]:=(skip[level-1] or (not check_symbol(GetName(opts))));
|
|
end
|
|
else
|
|
if (s='if') then
|
|
begin
|
|
RemoveSpace(opts);
|
|
if Level>=maxlevel then
|
|
begin
|
|
Writeln('Too many ifdef levels');
|
|
exit;
|
|
end;
|
|
inc(Level);
|
|
skip[level]:=(skip[level-1] or (not check_symbol(GetName(opts))));
|
|
end
|
|
else
|
|
if (s='ifndef') then
|
|
begin
|
|
RemoveSpace(opts);
|
|
if Level>=maxlevel then
|
|
begin
|
|
Writeln('Too many ifdef levels');
|
|
exit;
|
|
end;
|
|
inc(Level);
|
|
skip[level]:=(skip[level-1] or (check_symbol(GetName(opts))));
|
|
end
|
|
else
|
|
if (s='else') then
|
|
skip[level]:=skip[level-1] or (not skip[level])
|
|
else
|
|
if (s='endif') then
|
|
begin
|
|
skip[level]:=false;
|
|
if Level=0 then
|
|
begin
|
|
Writeln('Too many endif found');
|
|
exit;
|
|
end;
|
|
dec(level);
|
|
end
|
|
else
|
|
if (not skip[level]) then
|
|
begin
|
|
if (s='define') then
|
|
begin
|
|
RemoveSpace(opts);
|
|
def_symbol(GetName(opts));
|
|
end
|
|
else
|
|
if (s='undef') then
|
|
begin
|
|
RemoveSpace(opts);
|
|
undef_symbol(GetName(opts));
|
|
end
|
|
else
|
|
if (s='include') then
|
|
begin
|
|
RemoveSpace(opts);
|
|
Writeln('Uses include: ',opts);
|
|
opts:='';
|
|
end;
|
|
{ Add defines also to the output }
|
|
if opts<>'' then
|
|
writeln(g,orgs);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
if (not skip[level]) then
|
|
writeln(g,orgs);
|
|
end;
|
|
end;
|
|
if Level>0 then
|
|
Writeln('Error: too less endif found');
|
|
Close(f);
|
|
Close(g);
|
|
if outfile='' then
|
|
begin
|
|
Erase(f);
|
|
Rename(g,filename);
|
|
end;
|
|
DoFile:=true;
|
|
end;
|
|
|
|
|
|
procedure Usage;
|
|
begin
|
|
writeln('h2paspp [options] <file(s)>');
|
|
writeln('options:');
|
|
writeln(' -d<symbol> define symbol');
|
|
writeln(' -o<outfile> output file');
|
|
writeln(' -i include also includes (default is to remove)');
|
|
writeln(' -h or -? this helpscreen');
|
|
halt(0);
|
|
end;
|
|
|
|
|
|
var
|
|
i,j : longint;
|
|
s : string;
|
|
begin
|
|
{ process options }
|
|
j:=0;
|
|
for i:=1to paramcount do
|
|
begin
|
|
s:=paramstr(i);
|
|
if s[1]='-' then
|
|
begin
|
|
case s[2] of
|
|
'd' :
|
|
def_symbol(Copy(s,3,255));
|
|
'o' :
|
|
outfile:=Copy(s,3,255);
|
|
'h','?' :
|
|
Usage;
|
|
end;
|
|
end
|
|
else
|
|
inc(j);
|
|
end;
|
|
{ no files? }
|
|
if j=0 then
|
|
Usage;
|
|
{ process files }
|
|
for i:=1to paramcount do
|
|
begin
|
|
s:=paramstr(i);
|
|
if s[1]<>'-' then
|
|
dofile(s);
|
|
end;
|
|
end.
|