fpdoc.pp 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. {
  2. FPDoc - Free Pascal Documentation Tool
  3. Copyright (C) 2000 - 2003 by
  4. Areca Systems GmbH / Sebastian Guenther, [email protected]
  5. See the file COPYING, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. }
  11. program FPDoc;
  12. uses
  13. SysUtils, Classes, Gettext, DOM, XMLWrite, PasTree, PParser, custapp,
  14. dGlobals, // GLobal definitions, constants.
  15. dwriter, // TFPDocWriter definition.
  16. dwlinear, // Linear (abstract) writer
  17. dw_LaTeX, // TLaTex writer
  18. dw_XML, // XML writer
  19. dw_dxml, // Delphi XML doc.
  20. dw_HTML, // HTML writer
  21. dw_ipflin, // IPF writer (new linear output)
  22. dw_man, // Man page writer
  23. dw_linrtf, // linear RTF writer
  24. dw_txt, fpdocproj, fpdocxmlopts; // TXT writer
  25. const
  26. DefOSTarget = {$I %FPCTARGETOS%};
  27. DefCPUTarget = {$I %FPCTARGETCPU%};
  28. DefFPCVersion = {$I %FPCVERSION%};
  29. DefFPCDate = {$I %FPCDATE%};
  30. Type
  31. { TFPDocAplication }
  32. TFPDocAplication = Class(TCustomApplication)
  33. private
  34. FProject : TFPDocProject;
  35. FProjectFile : Boolean;
  36. FPackage : TFPDocPackage;
  37. Protected
  38. procedure ParseCommandLine;
  39. procedure Parseoption(const S: String);
  40. Procedure Usage(AnExitCode : Byte);
  41. procedure CreateDocumentation(APackage : TFPDocPackage; Options : TEngineOptions);
  42. Procedure DoRun; override;
  43. Public
  44. Constructor Create(AOwner : TComponent); override;
  45. Destructor Destroy; override;
  46. Function SelectedPackage : TFPDocPackage;
  47. end;
  48. Procedure TFPDocAplication.Usage(AnExitCode : Byte);
  49. Var
  50. I,P : Integer;
  51. S : String;
  52. L : TStringList;
  53. C : TFPDocWriterClass;
  54. Backend : String;
  55. begin
  56. Writeln(Format(SCmdLineHelp,[ExtractFileName(Paramstr(0))]));
  57. Writeln(SUsageOption010);
  58. Writeln(SUsageOption020);
  59. Writeln(SUsageOption030);
  60. Writeln(SUsageOption040);
  61. Writeln(SUsageOption050);
  62. Writeln(SUsageOption060);
  63. Writeln(SUsageOption070);
  64. Writeln(SUsageOption080);
  65. Writeln(SUsageOption090);
  66. Writeln(SUsageOption100);
  67. Writeln(SUsageOption110);
  68. Writeln(SUsageOption120);
  69. Writeln(SUsageOption130);
  70. Writeln(SUsageOption140);
  71. Writeln(SUsageOption150);
  72. Writeln(SUsageOption160);
  73. Writeln(SUsageOption170);
  74. Writeln(SUsageOption180);
  75. Writeln(SUsageOption190);
  76. L:=TStringList.Create;
  77. Try
  78. Backend:=FProject.OPtions.Backend;
  79. If (Backend='') then
  80. begin
  81. Writeln;
  82. Writeln(SUsageFormats);
  83. EnumWriters(L);
  84. For I:=0 to L.Count-1 do
  85. begin
  86. S:=L[i];
  87. P:=Pos('=',S);
  88. Writeln(Format(' %s - %s',[Copy(S,1,P-1)+Space(10-p),Copy(S,P+1,Length(S))]));
  89. end;
  90. Writeln(SUsageBackendHelp);
  91. end
  92. else
  93. begin
  94. Writeln;
  95. Writeln(Format(SUsageFormatSpecific,[Lowercase(backend)]));
  96. C:=GetWriterClass(Backend);
  97. C.Usage(L);
  98. If L.Count>0 then
  99. For I:=0 to (L.Count-1) div 2 do
  100. begin
  101. S:=L[i*2];
  102. Writeln(Format('%s %s',[S+Space(30-Length(S)),L[(i*2)+1]]));
  103. end;
  104. end;
  105. Finally
  106. L.Free;
  107. end;
  108. Halt(AnExitCode);
  109. end;
  110. destructor TFPDocAplication.Destroy;
  111. begin
  112. FreeAndNil(FProject);
  113. Inherited;
  114. end;
  115. function TFPDocAplication.SelectedPackage: TFPDocPackage;
  116. begin
  117. Result:=FPackage;
  118. if (FPackage=Nil) or (FPackage.Name='') then
  119. begin
  120. Writeln(SNeedPackageName);
  121. Usage(1);
  122. end;
  123. end;
  124. procedure TFPDocAplication.ParseCommandLine;
  125. Function ProjectOpt(Const s : string) : boolean;
  126. begin
  127. Result:=(Copy(s,1,3)='-p=') or (Copy(s,1,10)='--project=');
  128. end;
  129. Function PackageOpt(Const s : string) : boolean;
  130. begin
  131. Result:=((Copy(s,1,3)='-a=') or (Copy(s,1,10)='--package='));
  132. end;
  133. var
  134. i : Integer;
  135. s : string;
  136. begin
  137. // Check project
  138. for i := 1 to ParamCount do
  139. begin
  140. s:=ParamStr(I);
  141. If ProjectOpt(S) then
  142. ParseOption(s);
  143. If (FProject.Packages.Count=1) then
  144. FPackage:=FProject.Packages[0]
  145. else if (FProject.Options.DefaultPackageName<>'') then
  146. Fpackage:=FProject.Packages.FindPackage(FProject.Options.DefaultPackageName);
  147. end;
  148. If FProject.Packages.Count=0 then
  149. begin
  150. FPackage:=FProject.Packages.Add as TFPDocPackage;
  151. end;
  152. // Check package
  153. for i := 1 to ParamCount do
  154. begin
  155. s:=ParamStr(I);
  156. If PackageOpt(S) then
  157. ParseOption(s);
  158. end;
  159. for i := 1 to ParamCount do
  160. begin
  161. s:=ParamStr(I);
  162. If Not (ProjectOpt(s) or PackageOpt(S)) then
  163. ParseOption(s);
  164. end;
  165. if (FPackage=Nil) or (FPackage.Name='') then
  166. begin
  167. Writeln(SNeedPackageName);
  168. Usage(1);
  169. end;
  170. end;
  171. procedure TFPDocAplication.Parseoption(Const S : String);
  172. procedure AddToFileList(List: TStrings; const FileName: String);
  173. var
  174. f: Text;
  175. s: String;
  176. begin
  177. if Copy(FileName, 1, 1) = '@' then
  178. begin
  179. AssignFile(f, Copy(FileName, 2, Length(FileName)));
  180. Reset(f);
  181. while not EOF(f) do
  182. begin
  183. ReadLn(f, s);
  184. List.Add(s);
  185. end;
  186. Close(f);
  187. end else
  188. List.Add(FileName);
  189. end;
  190. var
  191. i: Integer;
  192. Cmd, Arg: String;
  193. begin
  194. if (s = '-h') or (s = '--help') then
  195. Usage(0)
  196. else if s = '--hide-protected' then
  197. FProject.Options.HideProtected := True
  198. else if s = '--warn-no-node' then
  199. FProject.Options.WarnNoNode := True
  200. else if s = '--show-private' then
  201. FProject.Options.ShowPrivate := False
  202. else if s = '--stop-on-parser-error' then
  203. FProject.Options.StopOnParseError := True
  204. else
  205. begin
  206. i := Pos('=', s);
  207. if i > 0 then
  208. begin
  209. Cmd := Copy(s, 1, i - 1);
  210. Arg := Copy(s, i + 1, Length(s));
  211. end
  212. else
  213. begin
  214. Cmd := s;
  215. SetLength(Arg, 0);
  216. end;
  217. if (Cmd = '--project') or (Cmd='-p') then
  218. begin
  219. FProjectFile:=True;
  220. With TXMLFPDocOptions.Create(self) do
  221. try
  222. LoadOptionsFromFile(FProject,Arg);
  223. finally
  224. Free;
  225. end;
  226. end
  227. else if (Cmd = '--descr') then
  228. AddToFileList(SelectedPackage.Descriptions, Arg)
  229. else if (Cmd = '-f') or (Cmd = '--format') then
  230. begin
  231. Arg:=UpperCase(Arg);
  232. If FindWriterClass(Arg)=-1 then
  233. WriteLn(StdErr, Format(SCmdLineInvalidFormat, [Arg]))
  234. else
  235. FProject.Options.BackEnd:=Arg;
  236. end
  237. else if (Cmd = '-l') or (Cmd = '--lang') then
  238. FProject.Options.Language := Arg
  239. else if (Cmd = '-i') or (Cmd = '--input') then
  240. AddToFileList(SelectedPackage.Inputs, Arg)
  241. else if (Cmd = '-o') or (Cmd = '--output') then
  242. SelectedPackage.Output := Arg
  243. else if Cmd = '--content' then
  244. SelectedPackage.ContentFile := Arg
  245. else if Cmd = '--import' then
  246. SelectedPackage.Imports.Add(Arg)
  247. else if Cmd = '--package' then
  248. begin
  249. If FProjectFile then
  250. FPackage:=FProject.Packages.FindPackage(Arg)
  251. else
  252. FPackage.Name:=Arg;
  253. end
  254. else if Cmd = '--ostarget' then
  255. FProject.Options.OSTarget := Arg
  256. else if Cmd = '--cputarget' then
  257. FProject.Options.CPUTarget := Arg
  258. else if Cmd = '--mo-dir' then
  259. FProject.Options.modir := Arg
  260. else if Cmd = '--parse-impl' then
  261. FProject.Options.InterfaceOnly:=false
  262. else
  263. begin
  264. FProject.Options.BackendOptions.Add(Cmd);
  265. FProject.Options.BackendOptions.Add(Arg);
  266. end;
  267. end;
  268. end;
  269. procedure TFPDocAplication.CreateDocumentation(APackage : TFPDocPackage; Options : TEngineOptions);
  270. var
  271. i,j: Integer;
  272. WriterClass : TFPDocWriterClass;
  273. Writer : TFPDocWriter;
  274. Engine : TFPDocEngine;
  275. Cmd,Arg : String;
  276. begin
  277. Engine:=TFPDocEngine.Create;
  278. try
  279. For J:=0 to Apackage.Imports.Count-1 do
  280. begin
  281. Arg:=Apackage.Imports[j];
  282. i := Pos(',', Arg);
  283. Engine.ReadContentFile(Copy(Arg,1,i-1),Copy(Arg,i+1,Length(Arg)));
  284. end;
  285. for i := 0 to APackage.Descriptions.Count - 1 do
  286. Engine.AddDocFile(APackage.Descriptions[i]);
  287. Engine.SetPackageName(APackage.Name);
  288. Engine.Output:=APackage.Output;
  289. Engine.HideProtected:=Options.HideProtected;
  290. Engine.HidePrivate:=Not Options.ShowPrivate;
  291. if Length(Options.Language) > 0 then
  292. TranslateDocStrings(Options.Language);
  293. for i := 0 to Fpackage.Inputs.Count - 1 do
  294. try
  295. ParseSource(Engine, APackage.Inputs[i], Options.OSTarget, Options.CPUTarget);
  296. except
  297. on e: EParserError do
  298. If Options.StopOnParseError then
  299. Raise
  300. else
  301. WriteLn(StdErr, Format('%s(%d,%d): %s',
  302. [e.Filename, e.Row, e.Column, e.Message]));
  303. end;
  304. WriterClass:=GetWriterClass(Options.Backend);
  305. Writer:=WriterClass.Create(Engine.Package,Engine);
  306. With Writer do
  307. Try
  308. If Options.BackendOptions.Count>0 then
  309. for I:=0 to ((Options.BackendOptions.Count-1) div 2) do
  310. begin
  311. Cmd:=Options.BackendOptions[I*2];
  312. Arg:=Options.BackendOptions[I*2+1];
  313. If not InterPretOption(Cmd,Arg) then
  314. WriteLn(StdErr, Format(SCmdLineInvalidOption,[Cmd+'='+Arg]));
  315. end;
  316. WriteDoc;
  317. Finally
  318. Free;
  319. end;
  320. if Length(FPackage.ContentFile) > 0 then
  321. Engine.WriteContentFile(FPackage.ContentFile);
  322. finally
  323. FreeAndNil(Engine);
  324. end;
  325. end;
  326. Procedure TFPDocAplication.DoRun;
  327. begin
  328. {$IFDEF Unix}
  329. gettext.TranslateResourceStrings('/usr/local/share/locale/%s/LC_MESSAGES/fpdoc.mo');
  330. {$ELSE}
  331. gettext.TranslateResourceStrings('intl/fpdoc.%s.mo');
  332. {$ENDIF}
  333. WriteLn(STitle);
  334. WriteLn(Format(SVersion, [DefFPCVersion, DefFPCDate]));
  335. WriteLn(SCopyright);
  336. WriteLn;
  337. ParseCommandLine;
  338. CreateDocumentation(FPackage,FProject.Options);
  339. WriteLn(SDone);
  340. Terminate;
  341. end;
  342. constructor TFPDocAplication.Create(AOwner: TComponent);
  343. begin
  344. inherited Create(AOwner);
  345. StopOnException:=true;
  346. FProject:=TFPDOCproject.Create(Nil);
  347. FProject.Options.StopOnParseError:=False;
  348. FProject.Options.CPUTarget:=DefCPUTarget;
  349. FProject.Options.OSTarget:=DefOSTarget;
  350. end;
  351. begin
  352. With TFPDocAplication.Create(Nil) do
  353. try
  354. Run;
  355. finally
  356. Free;
  357. end;
  358. end.