fpdoc.pp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  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. Writeln(SUsageOption200);
  77. L:=TStringList.Create;
  78. Try
  79. Backend:=FProject.OPtions.Backend;
  80. If (Backend='') then
  81. begin
  82. Writeln;
  83. Writeln(SUsageFormats);
  84. EnumWriters(L);
  85. For I:=0 to L.Count-1 do
  86. begin
  87. S:=L[i];
  88. P:=Pos('=',S);
  89. Writeln(Format(' %s - %s',[Copy(S,1,P-1)+Space(10-p),Copy(S,P+1,Length(S))]));
  90. end;
  91. Writeln(SUsageBackendHelp);
  92. end
  93. else
  94. begin
  95. Writeln;
  96. Writeln(Format(SUsageFormatSpecific,[Lowercase(backend)]));
  97. C:=GetWriterClass(Backend);
  98. C.Usage(L);
  99. If L.Count>0 then
  100. For I:=0 to (L.Count-1) div 2 do
  101. begin
  102. S:=L[i*2];
  103. Writeln(Format('%s %s',[S+Space(30-Length(S)),L[(i*2)+1]]));
  104. end;
  105. end;
  106. Finally
  107. L.Free;
  108. end;
  109. Halt(AnExitCode);
  110. end;
  111. destructor TFPDocAplication.Destroy;
  112. begin
  113. FreeAndNil(FProject);
  114. Inherited;
  115. end;
  116. function TFPDocAplication.SelectedPackage: TFPDocPackage;
  117. begin
  118. Result:=FPackage;
  119. if (FPackage=Nil) or (FPackage.Name='') then
  120. begin
  121. Writeln(SNeedPackageName);
  122. Usage(1);
  123. end;
  124. end;
  125. procedure TFPDocAplication.ParseCommandLine;
  126. Function ProjectOpt(Const s : string) : boolean;
  127. begin
  128. Result:=(Copy(s,1,3)='-p=') or (Copy(s,1,10)='--project=');
  129. end;
  130. Function PackageOpt(Const s : string) : boolean;
  131. begin
  132. Result:=((Copy(s,1,3)='-a=') or (Copy(s,1,10)='--package='));
  133. end;
  134. var
  135. i : Integer;
  136. s : string;
  137. begin
  138. // Check project
  139. for i := 1 to ParamCount do
  140. begin
  141. s:=ParamStr(I);
  142. If ProjectOpt(S) then
  143. ParseOption(s);
  144. If (FProject.Packages.Count=1) then
  145. FPackage:=FProject.Packages[0]
  146. else if (FProject.Options.DefaultPackageName<>'') then
  147. Fpackage:=FProject.Packages.FindPackage(FProject.Options.DefaultPackageName);
  148. end;
  149. If FProject.Packages.Count=0 then
  150. begin
  151. FPackage:=FProject.Packages.Add as TFPDocPackage;
  152. end;
  153. // Check package
  154. for i := 1 to ParamCount do
  155. begin
  156. s:=ParamStr(I);
  157. If PackageOpt(S) then
  158. ParseOption(s);
  159. end;
  160. for i := 1 to ParamCount do
  161. begin
  162. s:=ParamStr(I);
  163. If Not (ProjectOpt(s) or PackageOpt(S)) then
  164. ParseOption(s);
  165. end;
  166. if (FPackage=Nil) or (FPackage.Name='') then
  167. begin
  168. Writeln(SNeedPackageName);
  169. Usage(1);
  170. end;
  171. end;
  172. procedure TFPDocAplication.Parseoption(Const S : String);
  173. procedure AddToFileList(List: TStrings; const FileName: String);
  174. var
  175. f: Text;
  176. s: String;
  177. begin
  178. if Copy(FileName, 1, 1) = '@' then
  179. begin
  180. AssignFile(f, Copy(FileName, 2, Length(FileName)));
  181. Reset(f);
  182. while not EOF(f) do
  183. begin
  184. ReadLn(f, s);
  185. List.Add(s);
  186. end;
  187. Close(f);
  188. end else
  189. List.Add(FileName);
  190. end;
  191. var
  192. i: Integer;
  193. Cmd, Arg: String;
  194. begin
  195. if (s = '-h') or (s = '--help') then
  196. Usage(0)
  197. else if s = '--hide-protected' then
  198. FProject.Options.HideProtected := True
  199. else if s = '--warn-no-node' then
  200. FProject.Options.WarnNoNode := True
  201. else if s = '--show-private' then
  202. FProject.Options.ShowPrivate := False
  203. else if s = '--stop-on-parser-error' then
  204. FProject.Options.StopOnParseError := True
  205. else if s = '--dont-trim' then
  206. FProject.Options.donttrim := True
  207. else
  208. begin
  209. i := Pos('=', s);
  210. if i > 0 then
  211. begin
  212. Cmd := Copy(s, 1, i - 1);
  213. Arg := Copy(s, i + 1, Length(s));
  214. end
  215. else
  216. begin
  217. Cmd := s;
  218. SetLength(Arg, 0);
  219. end;
  220. if (Cmd = '--project') or (Cmd='-p') then
  221. begin
  222. FProjectFile:=True;
  223. With TXMLFPDocOptions.Create(self) do
  224. try
  225. LoadOptionsFromFile(FProject,Arg);
  226. finally
  227. Free;
  228. end;
  229. end
  230. else if (Cmd = '--descr') then
  231. AddToFileList(SelectedPackage.Descriptions, Arg)
  232. else if (Cmd = '-f') or (Cmd = '--format') then
  233. begin
  234. Arg:=UpperCase(Arg);
  235. If FindWriterClass(Arg)=-1 then
  236. WriteLn(StdErr, Format(SCmdLineInvalidFormat, [Arg]))
  237. else
  238. FProject.Options.BackEnd:=Arg;
  239. end
  240. else if (Cmd = '-l') or (Cmd = '--lang') then
  241. FProject.Options.Language := Arg
  242. else if (Cmd = '-i') or (Cmd = '--input') then
  243. AddToFileList(SelectedPackage.Inputs, Arg)
  244. else if (Cmd = '-o') or (Cmd = '--output') then
  245. SelectedPackage.Output := Arg
  246. else if Cmd = '--content' then
  247. SelectedPackage.ContentFile := Arg
  248. else if Cmd = '--import' then
  249. SelectedPackage.Imports.Add(Arg)
  250. else if Cmd = '--package' then
  251. begin
  252. If FProjectFile then
  253. FPackage:=FProject.Packages.FindPackage(Arg)
  254. else
  255. FPackage.Name:=Arg;
  256. end
  257. else if Cmd = '--ostarget' then
  258. FProject.Options.OSTarget := Arg
  259. else if Cmd = '--cputarget' then
  260. FProject.Options.CPUTarget := Arg
  261. else if Cmd = '--mo-dir' then
  262. FProject.Options.modir := Arg
  263. else if Cmd = '--parse-impl' then
  264. FProject.Options.InterfaceOnly:=false
  265. else
  266. begin
  267. FProject.Options.BackendOptions.Add(Cmd);
  268. FProject.Options.BackendOptions.Add(Arg);
  269. end;
  270. end;
  271. end;
  272. procedure TFPDocAplication.CreateDocumentation(APackage : TFPDocPackage; Options : TEngineOptions);
  273. var
  274. i,j: Integer;
  275. WriterClass : TFPDocWriterClass;
  276. Writer : TFPDocWriter;
  277. Engine : TFPDocEngine;
  278. Cmd,Arg : String;
  279. begin
  280. Engine:=TFPDocEngine.Create;
  281. try
  282. For J:=0 to Apackage.Imports.Count-1 do
  283. begin
  284. Arg:=Apackage.Imports[j];
  285. i := Pos(',', Arg);
  286. Engine.ReadContentFile(Copy(Arg,1,i-1),Copy(Arg,i+1,Length(Arg)));
  287. end;
  288. for i := 0 to APackage.Descriptions.Count - 1 do
  289. Engine.AddDocFile(APackage.Descriptions[i],Options.donttrim);
  290. Engine.SetPackageName(APackage.Name);
  291. Engine.Output:=APackage.Output;
  292. Engine.HideProtected:=Options.HideProtected;
  293. Engine.HidePrivate:=Not Options.ShowPrivate;
  294. if Length(Options.Language) > 0 then
  295. TranslateDocStrings(Options.Language);
  296. for i := 0 to Fpackage.Inputs.Count - 1 do
  297. try
  298. ParseSource(Engine, APackage.Inputs[i], Options.OSTarget, Options.CPUTarget);
  299. except
  300. on e: EParserError do
  301. If Options.StopOnParseError then
  302. Raise
  303. else
  304. WriteLn(StdErr, Format('%s(%d,%d): %s',
  305. [e.Filename, e.Row, e.Column, e.Message]));
  306. end;
  307. WriterClass:=GetWriterClass(Options.Backend);
  308. Writer:=WriterClass.Create(Engine.Package,Engine);
  309. Writeln('Writing doc');
  310. With Writer do
  311. Try
  312. If Options.BackendOptions.Count>0 then
  313. for I:=0 to ((Options.BackendOptions.Count-1) div 2) do
  314. begin
  315. Cmd:=Options.BackendOptions[I*2];
  316. Arg:=Options.BackendOptions[I*2+1];
  317. If not InterPretOption(Cmd,Arg) then
  318. WriteLn(StdErr, Format(SCmdLineInvalidOption,[Cmd+'='+Arg]));
  319. end;
  320. WriteDoc;
  321. Finally
  322. Free;
  323. end;
  324. if Length(FPackage.ContentFile) > 0 then
  325. Engine.WriteContentFile(FPackage.ContentFile);
  326. finally
  327. FreeAndNil(Engine);
  328. end;
  329. end;
  330. Procedure TFPDocAplication.DoRun;
  331. begin
  332. {$IFDEF Unix}
  333. gettext.TranslateResourceStrings('/usr/local/share/locale/%s/LC_MESSAGES/fpdoc.mo');
  334. {$ELSE}
  335. gettext.TranslateResourceStrings('intl/fpdoc.%s.mo');
  336. {$ENDIF}
  337. WriteLn(STitle);
  338. WriteLn(Format(SVersion, [DefFPCVersion, DefFPCDate]));
  339. WriteLn(SCopyright);
  340. WriteLn;
  341. ParseCommandLine;
  342. CreateDocumentation(FPackage,FProject.Options);
  343. WriteLn(SDone);
  344. Terminate;
  345. end;
  346. constructor TFPDocAplication.Create(AOwner: TComponent);
  347. begin
  348. inherited Create(AOwner);
  349. StopOnException:=true;
  350. FProject:=TFPDOCproject.Create(Nil);
  351. FProject.Options.StopOnParseError:=False;
  352. FProject.Options.CPUTarget:=DefCPUTarget;
  353. FProject.Options.OSTarget:=DefOSTarget;
  354. end;
  355. begin
  356. With TFPDocAplication.Create(Nil) do
  357. try
  358. Run;
  359. finally
  360. Free;
  361. end;
  362. end.