fpdoc.pp 11 KB

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