|
@@ -16,7 +16,7 @@
|
|
|
program FPDoc;
|
|
|
|
|
|
uses
|
|
|
- SysUtils, Classes, Gettext, DOM, XMLWrite, PasTree, PParser,
|
|
|
+ SysUtils, Classes, Gettext, DOM, XMLWrite, PasTree, PParser, custapp,
|
|
|
dGlobals, // GLobal definitions, constants.
|
|
|
dwriter, // TFPDocWriter definition.
|
|
|
dwlinear, // Linear (abstract) writer
|
|
@@ -27,29 +27,44 @@ uses
|
|
|
dw_ipflin, // IPF writer (new linear output)
|
|
|
dw_man, // Man page writer
|
|
|
dw_linrtf, // linear RTF writer
|
|
|
- dw_txt; // TXT writer
|
|
|
+ dw_txt, fpdocproj, fpdocxmlopts; // TXT writer
|
|
|
|
|
|
const
|
|
|
- OSTarget: String = {$I %FPCTARGETOS%};
|
|
|
- CPUTarget: String = {$I %FPCTARGETCPU%};
|
|
|
- FPCVersion: String = {$I %FPCVERSION%};
|
|
|
- FPCDate: String = {$I %FPCDATE%};
|
|
|
+ DefOSTarget = {$I %FPCTARGETOS%};
|
|
|
+ DefCPUTarget = {$I %FPCTARGETCPU%};
|
|
|
+ DefFPCVersion = {$I %FPCVERSION%};
|
|
|
+ DefFPCDate = {$I %FPCDATE%};
|
|
|
|
|
|
-var
|
|
|
- Backend : String;
|
|
|
- BackendOptions : TStrings;
|
|
|
- InputFiles, DescrFiles: TStringList;
|
|
|
- PackageName, DocLang, ContentFile : String;
|
|
|
- Engine: TFPDocEngine;
|
|
|
- StopOnParserError : Boolean;
|
|
|
+Type
|
|
|
+
|
|
|
+ { TFPDocAplication }
|
|
|
+
|
|
|
+ TFPDocAplication = Class(TCustomApplication)
|
|
|
+ private
|
|
|
+ FProject : TFPDocProject;
|
|
|
+ FProjectFile : Boolean;
|
|
|
+ FPackage : TFPDocPackage;
|
|
|
+ Protected
|
|
|
+ procedure ParseCommandLine;
|
|
|
+ procedure Parseoption(const S: String);
|
|
|
+ Procedure Usage(AnExitCode : Byte);
|
|
|
+ procedure CreateDocumentation(APackage : TFPDocPackage; Options : TEngineOptions);
|
|
|
+ Procedure DoRun; override;
|
|
|
+ Public
|
|
|
+ Constructor Create(AOwner : TComponent); override;
|
|
|
+ Destructor Destroy; override;
|
|
|
+ Function SelectedPackage : TFPDocPackage;
|
|
|
+ end;
|
|
|
|
|
|
-Procedure Usage(AnExitCode : Byte);
|
|
|
+
|
|
|
+Procedure TFPDocAplication.Usage(AnExitCode : Byte);
|
|
|
|
|
|
Var
|
|
|
I,P : Integer;
|
|
|
S : String;
|
|
|
L : TStringList;
|
|
|
C : TFPDocWriterClass;
|
|
|
+ Backend : String;
|
|
|
|
|
|
begin
|
|
|
Writeln(Format(SCmdLineHelp,[ExtractFileName(Paramstr(0))]));
|
|
@@ -74,6 +89,7 @@ begin
|
|
|
Writeln(SUsageOption190);
|
|
|
L:=TStringList.Create;
|
|
|
Try
|
|
|
+ Backend:=FProject.OPtions.Backend;
|
|
|
If (Backend='') then
|
|
|
begin
|
|
|
Writeln;
|
|
@@ -90,8 +106,8 @@ begin
|
|
|
else
|
|
|
begin
|
|
|
Writeln;
|
|
|
- Writeln(Format(SUsageFormatSpecific,[Lowercase(Backend)]));
|
|
|
- C:=GetWriterClass(backend);
|
|
|
+ Writeln(Format(SUsageFormatSpecific,[Lowercase(backend)]));
|
|
|
+ C:=GetWriterClass(Backend);
|
|
|
C.Usage(L);
|
|
|
If L.Count>0 then
|
|
|
For I:=0 to (L.Count-1) div 2 do
|
|
@@ -106,42 +122,88 @@ begin
|
|
|
Halt(AnExitCode);
|
|
|
end;
|
|
|
|
|
|
-procedure InitOptions;
|
|
|
+destructor TFPDocAplication.Destroy;
|
|
|
+
|
|
|
begin
|
|
|
- InputFiles := TStringList.Create;
|
|
|
- DescrFiles := TStringList.Create;
|
|
|
- BackendOptions := TStringList.Create;
|
|
|
- Engine := TFPDocEngine.Create;
|
|
|
- StopOnParserError:=False;
|
|
|
+ FreeAndNil(FProject);
|
|
|
+ Inherited;
|
|
|
end;
|
|
|
|
|
|
-procedure FreeOptions;
|
|
|
+function TFPDocAplication.SelectedPackage: TFPDocPackage;
|
|
|
begin
|
|
|
- Engine.Free;
|
|
|
- BackendOptions.Free;
|
|
|
- DescrFiles.Free;
|
|
|
- InputFiles.Free;
|
|
|
+ Result:=FPackage;
|
|
|
+ if (FPackage=Nil) or (FPackage.Name='') then
|
|
|
+ begin
|
|
|
+ Writeln(SNeedPackageName);
|
|
|
+ Usage(1);
|
|
|
+ end;
|
|
|
end;
|
|
|
|
|
|
-procedure ReadContentFile(const AParams: String);
|
|
|
+
|
|
|
+procedure TFPDocAplication.ParseCommandLine;
|
|
|
+
|
|
|
+ Function ProjectOpt(Const s : string) : boolean;
|
|
|
+
|
|
|
+ begin
|
|
|
+ Result:=(Copy(s,1,3)='-p=') or (Copy(s,1,10)='--project=');
|
|
|
+ end;
|
|
|
+
|
|
|
+ Function PackageOpt(Const s : string) : boolean;
|
|
|
+
|
|
|
+ begin
|
|
|
+ Result:=((Copy(s,1,3)='-a=') or (Copy(s,1,10)='--package='));
|
|
|
+ end;
|
|
|
+
|
|
|
var
|
|
|
- i: Integer;
|
|
|
+ i : Integer;
|
|
|
+ s : string;
|
|
|
+
|
|
|
begin
|
|
|
- i := Pos(',', AParams);
|
|
|
- Engine.ReadContentFile(Copy(AParams, 1, i - 1),
|
|
|
- Copy(AParams, i + 1, Length(AParams)));
|
|
|
+ // Check project
|
|
|
+ for i := 1 to ParamCount do
|
|
|
+ begin
|
|
|
+ s:=ParamStr(I);
|
|
|
+ If ProjectOpt(S) then
|
|
|
+ ParseOption(s);
|
|
|
+ If (FProject.Packages.Count=1) then
|
|
|
+ FPackage:=FProject.Packages[0]
|
|
|
+ else if (FProject.Options.DefaultPackageName<>'') then
|
|
|
+ Fpackage:=FProject.Packages.FindPackage(FProject.Options.DefaultPackageName);
|
|
|
+ end;
|
|
|
+ If FProject.Packages.Count=0 then
|
|
|
+ begin
|
|
|
+ FPackage:=FProject.Packages.Add as TFPDocPackage;
|
|
|
+ end;
|
|
|
+ // Check package
|
|
|
+ for i := 1 to ParamCount do
|
|
|
+ begin
|
|
|
+ s:=ParamStr(I);
|
|
|
+ If PackageOpt(S) then
|
|
|
+ ParseOption(s);
|
|
|
+ end;
|
|
|
+ for i := 1 to ParamCount do
|
|
|
+ begin
|
|
|
+ s:=ParamStr(I);
|
|
|
+ If Not (ProjectOpt(s) or PackageOpt(S)) then
|
|
|
+ ParseOption(s);
|
|
|
+ end;
|
|
|
+ if (FPackage=Nil) or (FPackage.Name='') then
|
|
|
+ begin
|
|
|
+ Writeln(SNeedPackageName);
|
|
|
+ Usage(1);
|
|
|
+ end;
|
|
|
end;
|
|
|
|
|
|
-procedure ParseOption(const s: String);
|
|
|
+procedure TFPDocAplication.Parseoption(Const S : String);
|
|
|
|
|
|
- procedure AddToFileList(List: TStringList; const FileName: String);
|
|
|
+ procedure AddToFileList(List: TStrings; const FileName: String);
|
|
|
var
|
|
|
f: Text;
|
|
|
s: String;
|
|
|
begin
|
|
|
if Copy(FileName, 1, 1) = '@' then
|
|
|
begin
|
|
|
- Assign(f, Copy(FileName, 2, Length(FileName)));
|
|
|
+ AssignFile(f, Copy(FileName, 2, Length(FileName)));
|
|
|
Reset(f);
|
|
|
while not EOF(f) do
|
|
|
begin
|
|
@@ -161,13 +223,13 @@ begin
|
|
|
if (s = '-h') or (s = '--help') then
|
|
|
Usage(0)
|
|
|
else if s = '--hide-protected' then
|
|
|
- Engine.HideProtected := True
|
|
|
+ FProject.Options.HideProtected := True
|
|
|
else if s = '--warn-no-node' then
|
|
|
- Engine.WarnNoNode := True
|
|
|
+ FProject.Options.WarnNoNode := True
|
|
|
else if s = '--show-private' then
|
|
|
- Engine.HidePrivate := False
|
|
|
+ FProject.Options.ShowPrivate := False
|
|
|
else if s = '--stop-on-parser-error' then
|
|
|
- StopOnParserError := True
|
|
|
+ FProject.Options.StopOnParseError := True
|
|
|
else
|
|
|
begin
|
|
|
i := Pos('=', s);
|
|
@@ -181,102 +243,122 @@ begin
|
|
|
Cmd := s;
|
|
|
SetLength(Arg, 0);
|
|
|
end;
|
|
|
- if Cmd = '--descr' then
|
|
|
- AddToFileList(DescrFiles, Arg)
|
|
|
+ if (Cmd = '--project') or (Cmd='-p') then
|
|
|
+ begin
|
|
|
+ FProjectFile:=True;
|
|
|
+ With TXMLFPDocOptions.Create(self) do
|
|
|
+ try
|
|
|
+ LoadOptionsFromFile(FProject,Arg);
|
|
|
+ finally
|
|
|
+ Free;
|
|
|
+ end;
|
|
|
+ end
|
|
|
+ else if (Cmd = '--descr') then
|
|
|
+ AddToFileList(SelectedPackage.Descriptions, Arg)
|
|
|
else if (Cmd = '-f') or (Cmd = '--format') then
|
|
|
begin
|
|
|
Arg:=UpperCase(Arg);
|
|
|
If FindWriterClass(Arg)=-1 then
|
|
|
WriteLn(StdErr, Format(SCmdLineInvalidFormat, [Arg]))
|
|
|
else
|
|
|
- BackEnd:=Arg;
|
|
|
+ FProject.Options.BackEnd:=Arg;
|
|
|
end
|
|
|
else if (Cmd = '-l') or (Cmd = '--lang') then
|
|
|
- DocLang := Arg
|
|
|
+ FProject.Options.Language := Arg
|
|
|
else if (Cmd = '-i') or (Cmd = '--input') then
|
|
|
- AddToFileList(InputFiles, Arg)
|
|
|
+ AddToFileList(SelectedPackage.Inputs, Arg)
|
|
|
else if (Cmd = '-o') or (Cmd = '--output') then
|
|
|
- Engine.Output := Arg
|
|
|
+ SelectedPackage.Output := Arg
|
|
|
else if Cmd = '--content' then
|
|
|
- ContentFile := Arg
|
|
|
+ SelectedPackage.ContentFile := Arg
|
|
|
else if Cmd = '--import' then
|
|
|
- ReadContentFile(Arg)
|
|
|
+ SelectedPackage.Imports.Add(Arg)
|
|
|
else if Cmd = '--package' then
|
|
|
- PackageName := Arg
|
|
|
+ begin
|
|
|
+ If FProjectFile then
|
|
|
+ FPackage:=FProject.Packages.FindPackage(Arg)
|
|
|
+ else
|
|
|
+ FPackage.Name:=Arg;
|
|
|
+ end
|
|
|
else if Cmd = '--ostarget' then
|
|
|
- OSTarget := Arg
|
|
|
+ FProject.Options.OSTarget := Arg
|
|
|
else if Cmd = '--cputarget' then
|
|
|
- CPUTarget := Arg
|
|
|
+ FProject.Options.CPUTarget := Arg
|
|
|
else if Cmd = '--mo-dir' then
|
|
|
- modir := Arg
|
|
|
+ FProject.Options.modir := Arg
|
|
|
else if Cmd = '--parse-impl' then
|
|
|
- Engine.InterfaceOnly:=false
|
|
|
+ FProject.Options.InterfaceOnly:=false
|
|
|
else
|
|
|
begin
|
|
|
- BackendOptions.Add(Cmd);
|
|
|
- BackendOptions.Add(Arg);
|
|
|
+ FProject.Options.BackendOptions.Add(Cmd);
|
|
|
+ FProject.Options.BackendOptions.Add(Arg);
|
|
|
end;
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-procedure ParseCommandLine;
|
|
|
-
|
|
|
-var
|
|
|
- i: Integer;
|
|
|
-
|
|
|
-begin
|
|
|
- for i := 1 to ParamCount do
|
|
|
- ParseOption(ParamStr(i));
|
|
|
- If (BackEnd='') then
|
|
|
- BackEnd:='html';
|
|
|
- if (PackageName='') then
|
|
|
- begin
|
|
|
- Writeln(SNeedPackageName);
|
|
|
- Usage(1);
|
|
|
- end;
|
|
|
-end;
|
|
|
|
|
|
-procedure CreateDocumentation;
|
|
|
+procedure TFPDocAplication.CreateDocumentation(APackage : TFPDocPackage; Options : TEngineOptions);
|
|
|
|
|
|
var
|
|
|
- i: Integer;
|
|
|
+ i,j: Integer;
|
|
|
WriterClass : TFPDocWriterClass;
|
|
|
Writer : TFPDocWriter;
|
|
|
+ Engine : TFPDocEngine;
|
|
|
+ Cmd,Arg : String;
|
|
|
|
|
|
begin
|
|
|
- for i := 0 to DescrFiles.Count - 1 do
|
|
|
- Engine.AddDocFile(DescrFiles[i]);
|
|
|
- Engine.SetPackageName(PackageName);
|
|
|
- if Length(DocLang) > 0 then
|
|
|
- TranslateDocStrings(DocLang);
|
|
|
- for i := 0 to InputFiles.Count - 1 do
|
|
|
- try
|
|
|
- ParseSource(Engine, InputFiles[i], OSTarget, CPUTarget);
|
|
|
- except
|
|
|
- on e: EParserError do
|
|
|
- If StopOnParserError then
|
|
|
- Raise
|
|
|
- else
|
|
|
- WriteLn(StdErr, Format('%s(%d,%d): %s',
|
|
|
- [e.Filename, e.Row, e.Column, e.Message]));
|
|
|
- end;
|
|
|
- WriterClass:=GetWriterClass(Backend);
|
|
|
- Writer:=WriterClass.Create(Engine.Package,Engine);
|
|
|
- With Writer do
|
|
|
- Try
|
|
|
- If BackendOptions.Count>0 then
|
|
|
- for I:=0 to ((BackendOptions.Count-1) div 2) do
|
|
|
- If not InterPretOption(BackendOptions[I*2],BackendOptions[I*2+1]) then
|
|
|
- WriteLn(StdErr, Format(SCmdLineInvalidOption,[BackendOptions[I*2]+' '+BackendOptions[I*2+1]]));
|
|
|
- WriteDoc;
|
|
|
- Finally
|
|
|
- Free;
|
|
|
- end;
|
|
|
- if Length(ContentFile) > 0 then
|
|
|
- Engine.WriteContentFile(ContentFile);
|
|
|
+ Engine:=TFPDocEngine.Create;
|
|
|
+ try
|
|
|
+ For J:=0 to Apackage.Imports.Count-1 do
|
|
|
+ begin
|
|
|
+ Arg:=Apackage.Imports[j];
|
|
|
+ i := Pos(',', Arg);
|
|
|
+ Engine.ReadContentFile(Copy(Arg,1,i-1),Copy(Arg,i+1,Length(Arg)));
|
|
|
+ end;
|
|
|
+ for i := 0 to APackage.Descriptions.Count - 1 do
|
|
|
+ Engine.AddDocFile(APackage.Descriptions[i]);
|
|
|
+ Engine.SetPackageName(APackage.Name);
|
|
|
+ Engine.Output:=APackage.Output;
|
|
|
+ Engine.HideProtected:=Options.HideProtected;
|
|
|
+ Engine.HidePrivate:=Not Options.ShowPrivate;
|
|
|
+ if Length(Options.Language) > 0 then
|
|
|
+ TranslateDocStrings(Options.Language);
|
|
|
+ for i := 0 to Fpackage.Inputs.Count - 1 do
|
|
|
+ try
|
|
|
+ ParseSource(Engine, APackage.Inputs[i], Options.OSTarget, Options.CPUTarget);
|
|
|
+ except
|
|
|
+ on e: EParserError do
|
|
|
+ If Options.StopOnParseError then
|
|
|
+ Raise
|
|
|
+ else
|
|
|
+ WriteLn(StdErr, Format('%s(%d,%d): %s',
|
|
|
+ [e.Filename, e.Row, e.Column, e.Message]));
|
|
|
+ end;
|
|
|
+ WriterClass:=GetWriterClass(Options.Backend);
|
|
|
+ Writer:=WriterClass.Create(Engine.Package,Engine);
|
|
|
+ With Writer do
|
|
|
+ Try
|
|
|
+ If Options.BackendOptions.Count>0 then
|
|
|
+ for I:=0 to ((Options.BackendOptions.Count-1) div 2) do
|
|
|
+ begin
|
|
|
+ Cmd:=Options.BackendOptions[I*2];
|
|
|
+ Arg:=Options.BackendOptions[I*2+1];
|
|
|
+ If not InterPretOption(Cmd,Arg) then
|
|
|
+ WriteLn(StdErr, Format(SCmdLineInvalidOption,[Cmd+'='+Arg]));
|
|
|
+ end;
|
|
|
+ WriteDoc;
|
|
|
+ Finally
|
|
|
+ Free;
|
|
|
+ end;
|
|
|
+ if Length(FPackage.ContentFile) > 0 then
|
|
|
+ Engine.WriteContentFile(FPackage.ContentFile);
|
|
|
+ finally
|
|
|
+ FreeAndNil(Engine);
|
|
|
+ end;
|
|
|
end;
|
|
|
|
|
|
|
|
|
+Procedure TFPDocAplication.DoRun;
|
|
|
|
|
|
begin
|
|
|
{$IFDEF Unix}
|
|
@@ -285,15 +367,30 @@ begin
|
|
|
gettext.TranslateResourceStrings('intl/fpdoc.%s.mo');
|
|
|
{$ENDIF}
|
|
|
WriteLn(STitle);
|
|
|
- WriteLn(Format(SVersion, [FPCVersion, FPCDate]));
|
|
|
+ WriteLn(Format(SVersion, [DefFPCVersion, DefFPCDate]));
|
|
|
WriteLn(SCopyright);
|
|
|
WriteLn;
|
|
|
- InitOptions;
|
|
|
- Try
|
|
|
- ParseCommandLine;
|
|
|
- CreateDocumentation;
|
|
|
- WriteLn(SDone);
|
|
|
- Finally
|
|
|
- FreeOptions;
|
|
|
- end;
|
|
|
+ ParseCommandLine;
|
|
|
+ CreateDocumentation(FPackage,FProject.Options);
|
|
|
+ WriteLn(SDone);
|
|
|
+ Terminate;
|
|
|
+end;
|
|
|
+
|
|
|
+constructor TFPDocAplication.Create(AOwner: TComponent);
|
|
|
+begin
|
|
|
+ inherited Create(AOwner);
|
|
|
+ StopOnException:=true;
|
|
|
+ FProject:=TFPDOCproject.Create(Nil);
|
|
|
+ FProject.Options.StopOnParseError:=False;
|
|
|
+ FProject.Options.CPUTarget:=DefCPUTarget;
|
|
|
+ FProject.Options.OSTarget:=DefOSTarget;
|
|
|
+end;
|
|
|
+
|
|
|
+begin
|
|
|
+ With TFPDocAplication.Create(Nil) do
|
|
|
+ try
|
|
|
+ Run;
|
|
|
+ finally
|
|
|
+ Free;
|
|
|
+ end;
|
|
|
end.
|