1
program FreePasResourcePreprocessor;
5
{$ifndef fpc}{$N+}{$endif}
16
function SearchPath(path,name,ext:pchar;size:longint;buf:pchar;var x:pointer):longint;stdcall;
17
external 'kernel32.dll' name 'SearchPathA';
18
function FSearch(s,path:str255):Str255;
21
procedure zeroterm(var s:str255);
34
i:=SearchPath(pchar(@path),pchar(@s),nil,255,pchar(@buf[1]),aPtr);
45
PReplaceRec=^TReplaceRec;
48
CaseSentitive:longbool;
49
oldvalue,newvalue:pstring;
51
chars=array[1..2]of char;
54
Chain:PReplaceRec=nil;
55
ChainHdr:PReplaceRec=nil;
63
function Entry(buf:pchars;Size,fromPos:longint;const sample:str255;casesent:longbool):longbool;
69
if(fromPos>1)and(buf^[pred(frompos)]>#32)then
71
if fromPos+length(sample)-1>=size then
73
if buf^[fromPos+length(sample)]>#32 then
76
for i:=1 to length(sample)do
78
if pred(fromPos+i)>size then
83
c:=buf^[pred(fromPos+i)];
93
function GetWord(buf:pchars;Size,fromPos:longint;var EndPos:longint):str255;
104
if not word_begin then
105
word_begin:=(buf^[i]>#32)and(buf^[i]<>';')and(buf^[i]<>'=');
108
if not(buf^[i]in[#0..#32,';','='])then
120
procedure excludeComments(buf:pchars;size:longint);
126
for i:=1 to pred(size)do
128
if(buf^[i]='/')and(buf^[succ(i)]='*')then
132
if(buf^[i]='*')and(buf^[succ(i)]='/')then
141
for i:=1 to pred(size)do
143
if(buf^[i]='/')and(buf^[succ(i)]='/')then
147
if buf^[i]in[#10,#13]then
153
function IsSwitch(const switch:str255):longbool;
158
for i:=1 to ParamCount do
159
if paramstr(i)='-'+switch then
165
function GetSwitch(const switch:str255):str255;
170
for i:=1 to paramcount do
171
if paramstr(i)='-'+switch then
172
GetSwitch:=paramstr(succ(i));
174
procedure saveproc(const key,value:str255;CaseSent:longbool);{$ifndef fpc}far;{$endif}
180
c^.CaseSentitive:=CaseSent;
181
getmem(c^.oldvalue,succ(length(key)));
183
getmem(c^.newvalue,succ(length(value)));
199
Tlanguage=(L_C,L_Pascal);
200
function Language(s:str255):tLanguage;
211
default:array[1..7]of TLD=(
212
(x:'PAS';l:L_PASCAL),
215
(x:'DPR';l:L_PASCAL),
216
(x:'IN?';l:L_PASCAL),
220
Lstr:=GetSwitch('l');
222
Lstr:=GetSwitch('-language');
223
for i:=1 to length(Lstr)do
224
Lstr[i]:=UpCase(Lstr[i]);
230
else if(Lstr='PASCAL')or(Lstr='DELPHI')then
235
else if (Lstr<>'')then
236
writeln('Warning: unknown language ',Lstr);
238
for i:=length(s)downto 1 do
247
for j:=1 to length(s1)do
248
if s1[j]<>default[i].x[j]then
249
case default[i].x[j] of
255
if(found)and(s1<>'')then
257
Language:=default[i].l;
263
function Up(const s:str255):str255;
269
for i:=1 to length(s)do
273
procedure do_C(buf:pchars;size:longint;proc:pointer);
275
Tpushfunc=procedure(const key,value:str255;CaseSent:longBool);
278
charconst,stringconst:longbool;
280
afunc:Tpushfunc absolute proc;
281
procedure read(var s:str255;toEOL:longbool);
283
i:longint absolute position;
284
function EndOfWord:longbool;
287
EndOfWord:=buf^[i]in[#10,#13]
289
EndOfWord:=buf^[i]<=#32;
295
while buf^[i]<=#32 do
304
if not stringConst then
306
charconst:=not charconst;
307
if not charConst then
309
stringconst:=not stringconst;
310
if(not charconst)and(not stringconst)and EndOfWord then
318
ExcludeComments(buf,size);
324
if Up(s)='#DEFINE' then
328
Tpushfunc(afunc)(s,s0,true);
330
until position>=size;
332
procedure expandname(var s:str255;path:str255);
336
astr:=fsearch(s,path);
338
s:={$ifndef Win32}FExpand{$endif}(astr);
340
function do_include(name:str255):longbool;
352
if (name[1]='"')and(name[length(name)]='"')then
354
else if (name[1]='<')and(name[length(name)]='>')then
359
s1:=GetSwitch('-path');
366
blockread(f,buf^,size);
368
case Language(name)of
370
do_C(buf,size,@saveProc);
372
do_pascal(buf,size,@saveProc);
377
function CheckRight(const s:str255;pos:longint):longbool;
383
CheckRight:=not(s[succ(pos)]in['a'..'z','A'..'Z','0'..'9','_']);
385
function CheckLeft(const s:str255;pos:longint):longbool;
393
CheckLeft:=not(s[pred(pos)]in['a'..'z','A'..'Z','0'..'9','_']);
396
function Evaluate(Equation:Str255):Str255;
401
Eval(Equation,x,Err);
402
if(Err=0)and(frac(x)=0)then
409
taccel=array[1..100]of pReplaceRec;
415
MustBeReplaced:longbool;
417
if(paramcount=0)or isSwitch('h')or isSwitch('-help')or((paramcount>1)and(GetSwitch('i')=''))then
419
writeln('FPC CONSTANTS EXTRACTOR for resource scripts preprocessing');
420
writeln('version 0.01');
421
writeln('Usage: fprcp <file_name>');
423
writeln('fprcp -i <file_name> [-n] [-C] [-l PASCAL|C] [-p <include_path>]');
424
writeln(' -C type C header instead preprocessed resource script');
425
writeln(' -l set programming language for include files');
426
writeln(' -p set path to include files');
427
writeln(' -n disable support of pascal comments nesting');
431
assign(f,paramstr(1))
433
assign(f,GetSwitch('i'));
437
blockread(f,buf^,size);
441
if isSwitch('-disable-nested-pascal-comments')then
443
excludeComments(buf,size);
446
if entry(buf,size,i,'#include',true)then
447
do_include(GetWord(buf,size,i+length('#include'),nextpos));
450
getmem(Accel,sizeof(pReplaceRec)*ChainLen);
459
for i:=1 to pred(Chainlen)do
460
for j:=succ(i)to Chainlen do
461
if length(Accel^[j]^.newvalue^)>=length(Accel^[i]^.oldvalue^)then
463
MustBeReplaced:=false;
464
for kk:=1 to length(Accel^[j]^.newvalue^)do
466
sss:=copy(Accel^[j]^.newvalue^,kk,length(Accel^[i]^.oldvalue^));
467
if length(sss)<>length(Accel^[i]^.oldvalue^)then
469
else if sss=Accel^[i]^.oldvalue^ then
471
MustBeReplaced:=(CheckLeft(Accel^[j]^.newvalue^,kk)and CheckRight(Accel^[j]^.newvalue^,kk-1+
472
length(Accel^[i]^.oldvalue^)));
473
if MustBeReplaced then
477
if MustBeReplaced then
479
sss:=Accel^[j]^.newvalue^;
480
delete(sss,kk,length(Accel^[i]^.oldvalue^));
481
insert(Accel^[i]^.newvalue^,sss,kk);
482
freemem(Accel^[j]^.newvalue,length(Accel^[j]^.newvalue^));
483
getmem(Accel^[j]^.newvalue,length(sss));
484
Accel^[j]^.newvalue^:=sss;
486
until not MustBeReplaced;
487
for j:=1 to Chainlen do
489
sss:=Evaluate(Accel^[j]^.newvalue^);
490
freemem(Accel^[j]^.newvalue,length(Accel^[j]^.newvalue^));
491
getmem(Accel^[j]^.newvalue,length(sss));
492
Accel^[j]^.newvalue^:=sss;
494
if isSwitch('C')or isSwitch('-Cheader')then
495
for i:=1 to Chainlen do
497
if Accel^[i]^.newvalue^<>''then
498
writeln('#define ',Accel^[i]^.oldvalue^,' ',Accel^[i]^.newvalue^)
511
while(sss<>'')and(sss[1]<=#32)do
514
for j:=1 to length(sst)do
515
sst[j]:=upcase(sst[j]);
516
if pos('#INCLUDE',sst)=0 then
519
for kk:=1 to length(sss)do
525
for j:=1 to ChainLen do
527
if accel^[j]^.casesentitive then
529
if(accel^[j]^.oldvalue^=s)and(accel^[j]^.newvalue^<>'')then
531
s:=accel^[j]^.newvalue^;
537
if(accel^[j]^.oldvalue^=Up(s))and(accel^[j]^.newvalue^<>'')then
539
s:=accel^[j]^.newvalue^;
557
freemem(Accel,sizeof(pReplaceRec)*ChainLen);
563
if c^.oldvalue<>nil then
564
freemem(c^.oldvalue,succ(length(c^.oldvalue^)));
565
if c^.newvalue<>nil then
566
freemem(c^.newvalue,succ(length(c^.newvalue^)));