1program fpgmake;
2
3{$mode objfpc}{$H+}
4
5uses
6{$ifdef UNIX}
7  cthreads,
8{$endif UNIX}
9  Classes,
10  sysutils,
11  fpmkunit,
12  fpTemplate,
13  fpmakeParseJSon, fpmakecreatefile;
14
15{
16  data2inc -b -s fpmake.cft fpmake.inc fpmake
17}
18
19{$i fpmake.inc}
20
21Resourcestring
22  SUsage00  = 'Usage: %s [options]';
23  SUsage10  = 'Where options is one or more of';
24  SUSage20  = '  -t filename   Template file name. Default is built-in';
25  SUSage30  = '  -o filename   Set output file. Default is standard output.';
26  SUsage40  = '  -d name=value define name=value pair.';
27  SUsage50  = '  -h            show this help and exit.';
28  SUsage60  = '  -u name       remove name from list of name/value pairs.';
29  SUsage70  = '  -m            show builtin macros and exit.';
30  SUsage80  = '  -b            show builtin template and exit.';
31  SUsage90  = '  -s            skip the creation of a backup-file.';
32  SUsage95  = '  -p            force directory creation.';
33  SError              = 'Error:';
34  SErrUnknownOption   = 'Error: Unknown option (%s).';
35  SErrArgExpected     = 'Error: Option "%s" requires an argument.';
36  SErrIncompletePair  = 'Error: Incomplete name-value pair "%s".';
37  SErrNoSuchFile      = 'Error: File "%s" does not exist.';
38
39  SWarnIgnoringFile   = 'Warning: Ignoring non-existent file: ';
40  SWarnIgnoringPair   = 'Warning: Ignoring wrong name/value pair: ';
41  SWarngccNotFound    = 'Warning: Could not find gcc. Unable to determine the gcclib path.';
42  SWarnCouldNotExecute= 'Warning: Could not execute command ''%s''';
43
44Var
45  SkipBackup : Boolean;
46  CreateDir: Boolean;
47  Cfg : TStringList;
48  TemplateFileName,
49  OutputFileName : String;
50
51const
52  InputFileName = 'fpmake.fpc';
53
54procedure Usage;
55
56begin
57  Writeln(Format(SUsage00,[ExtractFileName(ApplicationName)]));
58  Writeln(SUsage10);
59  Writeln(SUsage20);
60  Writeln(SUsage30);
61  Writeln(SUsage40);
62  Writeln(SUsage50);
63  Writeln(SUsage60);
64  Writeln(SUsage70);
65  Writeln(SUsage80);
66  Writeln(SUsage90);
67  Writeln(SUsage95);
68end;
69
70Procedure UnknownOption(Const S : String);
71
72begin
73  Writeln(Format(SErrUnknownOption,[S]));
74  Usage;
75  Halt(1);
76end;
77
78procedure Init;
79
80begin
81  Cfg:=TStringList.Create;
82  Cfg.Text:=StrPas(Addr(fpmake[0][1]));
83end;
84
85procedure Done;
86
87begin
88  Cfg.Free;
89end;
90
91Procedure ShowBuiltInMacros;
92
93Var
94  I : Integer;
95
96begin
97  For I:=0 to TemplateParser.ValueCount-1 do
98    Writeln(TemplateParser.NamesByIndex[I]+'='+TemplateParser.ValuesByIndex[I]);
99end;
100
101Procedure ShowBuiltIn;
102
103Var
104  I : Integer;
105
106
107begin
108  For I:=0 to Cfg.Count-1 do
109    Writeln(Cfg[I]);
110end;
111
112
113Procedure ProcessCommandline;
114
115Var
116  I : Integer;
117  S : String;
118  ShowBuiltinCommand : boolean;
119
120  Function GetOptArg : String;
121
122  begin
123    If I=ParamCount then
124      begin
125      Writeln(StdErr,Format(SErrArgExpected,[S]));
126      Halt(1);
127      end;
128    inc(I);
129    Result:=ParamStr(I);
130  end;
131
132  procedure AddPair(const Value: String);
133  var P: integer;
134      N,V: String;
135  begin
136    P:=Pos('=',Value);
137    If p=0 then
138      begin
139      Writeln(StdErr,Format(SErrIncompletePair,[Value]));
140      Halt(1);
141      end;
142    V:=Value;
143    N:=Copy(V,1,P-1);
144    Delete(V,1,P);
145    TemplateParser.Values[N] := V;
146  end;
147
148begin
149  I:=1;
150  ShowBuiltinCommand := False;
151  SkipBackup := False;
152  CreateDir := False;
153  While( I<=ParamCount) do
154    begin
155    S:=Paramstr(i);
156    If Length(S)<=1 then
157      UnknownOption(S)
158    else
159      case S[2] of
160        'h' : begin
161              Usage;
162              halt(0);
163              end;
164        'b' : ShowBuiltinCommand := true;
165        'm' : begin
166              ShowBuiltinMacros;
167              halt(0);
168              end;
169        't' : TemplateFileName:=GetOptArg;
170        'd' : AddPair(GetOptArg);
171        'u' : TemplateParser.Values[GetOptArg]:='';
172        'o' : OutputFileName:=GetoptArg;
173        's' : SkipBackup:=True;
174        'p' : CreateDir:=True;
175      else
176        UnknownOption(S);
177      end;
178    Inc(I);
179    end;
180  If (TemplateFileName<>'') then
181    begin
182    If Not FileExists(TemplateFileName) then
183      begin
184      Writeln(StdErr,Format(SErrNoSuchFile,[TemplateFileName]));
185      Halt(1);
186      end;
187    Cfg.LoadFromFile(TemplateFileName);
188    TemplateParser.Values['TEMPLATEFILE'] := TemplateFileName;
189    end;
190  if ShowBuiltinCommand then
191    begin
192    ShowBuiltIn;
193    halt(0);
194    end;
195end;
196
197var
198  APackages: TPackages;
199
200begin
201  Init;
202  Try
203    ProcessCommandLine;
204    APackages := ParseFpmakeFile(InputFileName);
205    if assigned(APackages) then
206      CreateFile(OutputFileName, Cfg, APackages, SkipBackup, CreateDir);
207  Finally
208    APackages.Free;
209    Done;
210  end;
211end.
212