123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600 |
- {
- unit generation tool
- (C) 2000 Alexander Stohr, [email protected]
- based upon the linux dynamic tool from Sebastian Guenther
- with latest version "1.1 1999/12/23 13:51:50 peter"
- }
- {$MODE objfpc}
- {$H-} { use normal strings }
- (* do not enable! fpc bug with H+ *)
- program c_gen;
- uses
- SysUtils,
- Classes,
- buildgl;
- // =====================================================================
- type
- ptDefFile = ^tDefFile;
- tDefFile = record
- Name : String;
- DefFile : TDefReader;
- pNext : ptDefFile;
- end;
- ptSectionKey = ^tSectionKey;
- tSectionKey = record
- Keyword : String;
- Rule : DWord;
- pDefFile : ptDefFile;
- Option2 : String;
- pNext : ptSectionKey;
- end;
- // =====================================================================
- const
- verbose = 0; // change this for debugging
- const
- ST_NONE = 0;
- ST_COMMON = 1;
- ST_FILE = 2;
- RULE_IG = 0;
- RULE_TX = 1;
- RULE_IF = 2;
- RULE_PD = 3;
- RULE_PL = 4;
- RULE_PS = 5;
- // =====================================================================
- // global vars
- var
- ReturnVal : Word;
- pSectionKey : ptSectionKey;
- pAllDefFile : ptDefFile;
- ToolName : String;
- TargetText : String;
- TargetDir : String;
- SectionType : DWord;
- SectionName : String;
- TemplateName : String;
- // =====================================================================
- procedure StripSpaces(var s : String);
- var
- L : Byte;
- begin
- // strip leading spaces
- while (Pos(' ',s)=1) or (Pos(#8,s)=1) do
- Delete(s,1,1);
- // strip trailing spaces
- L := Length(s);
- while L<>0 do
- begin
- if (s[L]=' ') or (s[L]=#8) then
- begin
- Delete(s,L,1);
- Dec(L);
- end
- else
- L := 0;
- end;
- end;
- function GetName(var s : String) : String;
- var
- Name : String;
- P : Byte;
- begin
- Name := s;
- P := Pos(',',s);
- if p>0 then
- begin
- Delete(s,1,P);
- Delete(Name,P,255);
- end
- else
- s := '';
- StripSpaces(Name);
- { WriteLn('GetName, reminder = ',Name,',',s); }
- GetName := Name;
- end;
- function Name2Rule(Name : String) : DWord;
- begin
- if Name='IG'
- then Name2Rule := RULE_IG
- else
- if Name='TX'
- then Name2Rule := RULE_TX
- else
- if Name='IF'
- then Name2Rule := RULE_IF
- else
- if Name='PD'
- then Name2Rule := RULE_PD
- else
- if Name='PL'
- then Name2Rule := RULE_PL
- else
- if Name='PS'
- then Name2Rule := RULE_PS
- else
- begin
- Name2Rule := RULE_IG;
- WriteLn('error - unknown rule: ',Name);
- ReturnVal := 1;
- end;
- end;
- function AddDefFile(Name : String) : ptDefFile;
- var
- pDefFile : ptDefFile;
- pSearch : ptDefFile;
- begin
- pDefFile := NIL;
- // search if file is already loaded
- if pAllDefFile<>NIL then
- begin
- pSearch := pAllDefFile;
- while pSearch<>NIL do
- begin
- if pSearch^.Name = Name then
- begin
- pDefFile := pSearch;
- pSearch := NIL;
- end
- else
- pSearch := pSearch^.pNext;
- end;
- end;
- // create new file if its not loaded
- if pDefFile = NIL then
- begin
- New(pDefFile);
- pDefFile^.Name := Name;
- pDefFile^.DefFile := TDefReader.Create(Name);
- pDefFile^.pNext := pAllDefFile; // chain in as first member
- pAllDefFile := pDefFile;
- end;
- AddDefFile := pDefFile;
- end;
- procedure AddSectionKey(s : string);
- var
- pKey : ptSectionKey;
- t : string;
- begin
- New(pKey);
- pKey^.Keyword := GetName(s);
- pKey^.Rule := Name2Rule(GetName(s));
- pKey^.pDefFile := AddDefFile(GetName(s));
- t := GetName(s);
- pKey^.Option2 := t;
- pKey^.pNext := pSectionKey; // chain in as first member
- pSectionKey := pKey;
- end;
- function GetSectionKey(s : string) : ptSectionKey;
- var
- pSearch : ptSectionKey;
- begin
- GetSectionKey := NIL;
- pSearch := pSectionKey;
- while pSearch<>NIL do
- begin
- if pSearch^.Keyword = s then
- begin
- GetSectionKey := pSearch;
- pSearch := NIL;
- end
- else pSearch := pSearch^.pNext;
- end;
- end;
- procedure FreeSectionKeys;
- var
- pSearch, pNext : ptSectionKey;
- begin
- pSearch := pSectionKey;
- while pSearch<>NIL do
- begin
- pNext := pSearch^.pNext;
- Dispose(pSearch);
- pSearch := pNext;
- end;
- pSectionKey := pSearch;
- end;
- // =====================================================================
- procedure ResetCommonSecData;
- begin
- ToolName := 'BuildTool';
- TargetText := 'unknown';
- TargetDir := '.\';
- end;
- procedure ResetFileSecData;
- begin
- FreeSectionKeys;
- TemplateName := '';
- end;
- procedure InitGlobals;
- begin
- ReturnVal := 0;
- SectionType := ST_NONE;
- pSectionKey := NIL;
- pAllDefFile := NIL;
- ResetCommonSecData;
- ResetFileSecData;
- end;
- // =====================================================================
- procedure PrintInterface(var dest: Text; lines: TStringList);
- var
- i: Integer;
- begin
- for i := 0 to lines.Count - 1 do
- WriteLn(dest, lines.Strings[i]);
- end;
- procedure PrintProcDecls(var dest: Text; procs: TStringList; const Modifier : String);
- var
- i, j: Integer;
- s: String;
- begin
- for i := 0 to procs.Count - 1 do
- begin
- s := procs.Strings[i];
- j := Pos('//', s);
- if (Length(s) = 0)
- then
- WriteLn(dest)
- else
- if (Pos('{', s) = 1)
- then
- WriteLn(dest,procs.Strings[i])
- else
- if ((j > 0) and (Trim(s)[1] = '/')) then
- WriteLn(dest, s)
- else if j = 0 then
- WriteLn(dest, s, ' ',Modifier)
- else
- WriteLn(dest, TrimRight(Copy(s, 1, j-1)),
- ' ',Modifier,' ', Copy(s, j, Length(s)) );
- end;
- end;
- procedure PrintProcLoaders(var dest: Text; procs: TStringList; const libname: String);
- var
- i, j: Integer;
- s: String;
- begin
- for i := 0 to procs.Count - 1 do
- begin
- s := Trim(procs.Strings[i]);
- if (Pos('//', s) > 0)
- or (Pos('{', s) = 1)
- then
- WriteLn(dest,procs.Strings[i])
- else
- begin
- j := Pos(':', s);
- s := Trim(Copy(s, 1, j - 1));
- if (Length(s) = 0)
- then
- continue
- else
- WriteLn(dest, ' ', s, ' := GetProc(', libname, ', ''', s, ''');');
- end;
- end;
- end;
- procedure PrintProcStatic(var dest: Text; procs: TStringList; const Modifier: String);
- var
- i, j, k: Integer;
- s: String;
- t: String;
- begin
- for i := 0 to procs.Count - 1 do
- begin
- s := procs.Strings[i];
- j := Pos('//', s);
- if (Length(s) = 0) or ((j > 0) and (Trim(s)[1] = '/')) then
- WriteLn(dest, s)
- else
- begin
- // swap order of leading symbols and remove ':'
- t := Trim(procs.Strings[i]);
- j := Pos(':', t);
- t := Trim(Copy(t, 1, j - 1));
- j := Pos(':', s);
- Delete(s,1,j);
- s := Trim(s);
- j := Pos(';', s);
- k := Pos('(', s);
- if k>0 then if j>k then j := k;
- k := Pos(':', s);
- if k>0 then if j>k then j := k;
- Insert(t,s,j);
- Insert(' ',s,j);
- j := Pos('//', s);
- if j = 0 then
- WriteLn(dest, s, ' ',Modifier)
- else
- WriteLn(dest, TrimRight(Copy(s, 1, j-1)),
- ' ',Modifier,' ', Copy(s, j, Length(s)) );
- end;
- end;
- end;
- procedure PrintCVSLogSection(var dest: Text);
- begin
- WriteLn(dest);
- WriteLn(dest);
- WriteLn(dest, '{');
- WriteLn(dest, ' $', 'Log:$'); // needed because _this_ file might be in CVS, too
- WriteLn(dest, '}');
- end;
- // =====================================================================
- procedure ProcessFileSection;
- var
- f : Text;
- tpl : Text;
- s : String;
- { j : Integer; }
- tmp : String;
- pKey : ptSectionKey;
- begin
- WriteLn('Generating "',TargetDir+SectionName,'" ...');
- Assign(f, TargetDir+SectionName);
- Rewrite(f);
- Assign(tpl, TemplateName);
- Reset(tpl);
- while not EOF(tpl) do
- begin
- ReadLn(tpl, s);
- if Copy(s, 1, 1) = '%' then
- begin
- tmp := Copy(s,2,255);
- StripSpaces(tmp);
- pKey := GetSectionKey(tmp);
- if pKey=NIL then
- begin
- WriteLn(f, '// ### ',ToolName,': Don''t know what to insert here!: ', s);
- WriteLn('error - unknown keyword: ',tmp);
- ReturnVal := 1;
- end
- else
- begin
- case pKey^.Rule of
- RULE_IG : { ignore };
- RULE_TX : { todo };
- RULE_IF : PrintInterface(f, pKey^.pDefFile^.DefFile.InterfaceBlock);
- RULE_PD : PrintProcDecls(f, pKey^.pDefFile^.DefFile.Procs,
- pKey^.Option2);
- RULE_PL : PrintProcLoaders(f, pKey^.pDefFile^.DefFile.Procs,
- pKey^.Option2);
- RULE_PS : PrintProcStatic(f, pKey^.pDefFile^.DefFile.Procs,
- pKey^.Option2);
- end;
- end;
- end
- else
- begin
- if Copy(s, 1, 1) <> '#'
- then WriteLn(f, s);
- end;
- end;
- PrintCVSLogSection(f);
- Close(f);
- (*
- if Copy(s, 1, 1) <> '#' then
- begin
- j := Pos('#extdecl', s);
- if j = 0 then
- WriteLn(f, s)
- else
- WriteLn(f, Copy(s, 1, j - 1), 'cdecl', Copy(s, j + 8, Length(s)));
- end;
- *)
- end;
- procedure ProcessCommonSection;
- begin
- if verbose>0 then
- begin
- WriteLn('common section:');
- WriteLn(' ToolName = ',ToolName);
- WriteLn(' TargetText = ',TargetText);
- WriteLn(' TargetDir = ',TargetDir);
- end;
- end;
- // =====================================================================
- procedure SectionComplete;
- begin
- if ReturnVal=0 then { if we are error free }
- case SectionType of
- ST_NONE :
- begin
- // ignore
- end;
- ST_COMMON :
- begin
- ProcessCommonSection;
- end;
- ST_FILE :
- begin
- ProcessFileSection();
- end;
- end;
- end;
- var
- hFGen : Text;
- Line : String;
- KeyName : String;
- KeyValue : String;
- begin
- InitGlobals;
- WriteLn('File Generator Tool for OpenGL related Units');
- if ParamCount<>1 then
- begin
- WriteLn('specify a generator file as parameter 1');
- Halt(1);
- end;
- // Open Generation File
- Assign(hFGen,ParamStr(1));
- Reset(hFGen);
- while Not(EOF(hFGen)) do
- begin
- ReadLn(hFGen,Line);
- if Length(Line)>0 then
- begin
- if Line[1]='[' then
- begin
- // its a new section
- SectionComplete; // close previous section
- Delete(Line,Pos(']',Line),255);
- SectionName := Copy(Line,2,255);
- if verbose>0 then
- WriteLn('SectionName = ',SectionName);
- if SectionName='common' then
- begin
- SectionType := ST_COMMON;
- ResetCommonSecData;
- end
- else
- begin
- SectionType := ST_FILE;
- ResetFileSecData;
- end;
- end
- else
- if Pos(Line[1],'#*;''')<>0 then
- begin
- // just a comment - ignore
- end
- else
- begin
- // its a key in the section
- KeyName := Line;
- KeyValue := Line;
- Delete(KeyName,Pos('=',KeyName),255);
- Delete(KeyValue,1,Pos('=',KeyValue));
- StripSpaces(KeyName);
- StripSpaces(KeyValue);
- // WriteLn('KeyName = ',KeyName);
- // WriteLn('KeyValue = ',KeyValue);
- case SectionType of
- ST_COMMON :
- begin
- if KeyName='TOOL_NAME'
- then ToolName := KeyValue
- else
- if KeyName='TARGET_TEXT'
- then TargetText := KeyValue
- else
- if KeyName='TARGET_DIR'
- then
- begin
- TargetDir := KeyValue;
- end
- else
- begin
- WriteLn('error in script file - inside common section');
- WriteLn('key line: ',Line);
- ReturnVal := 1;
- end;
- end;
- ST_FILE :
- begin
- if KeyName='TEMPLATE'
- then TemplateName := KeyValue
- else
- if KeyName='KEY'
- then AddSectionKey(KeyValue)
- else
- begin
- WriteLn('error in script file - inside file section');
- WriteLn('key line: ',Line);
- ReturnVal := 1;
- end;
- end;
- ELSE
- begin
- WriteLn('error in script file - not in a section');
- WriteLn('key line: ',Line);
- ReturnVal := 1;
- end;
- end;
- end
- end;
- end;
- SectionComplete; // close last section
- Close(hFGen);
- WriteLn('Done...');
- Halt(ReturnVal);
- end.
|