fpdoc.pp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. {
  2. FPDoc - Free Pascal Documentation Tool
  3. Copyright (C) 2000 - 2003 by
  4. Areca Systems GmbH / Sebastian Guenther, [email protected]
  5. 2005-2012 by
  6. various FPC contributors
  7. See the file COPYING, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. }
  13. program FPDoc;
  14. uses
  15. {$ifdef Unix}
  16. CThreads,
  17. cwstring,
  18. {$endif}
  19. SysUtils, Classes, Gettext, custapp,
  20. dGlobals, // Global definitions, constants.
  21. fpdocclasstree, // Class tree builder
  22. dwriter, // TFPDocWriter definition.
  23. dwlinear, // Linear (abstract) writer
  24. dw_LaTeX, // TLaTex writer
  25. dw_XML, // XML writer
  26. dw_dxml, // Delphi XML doc.
  27. dw_HTML, // HTML writer
  28. dw_chm, // CHM Writer
  29. dw_markdown, // Markdown writer
  30. dw_ipflin, // IPF writer (new linear output)
  31. dw_man, // Man page writer
  32. dw_linrtf, // linear RTF writer
  33. dw_txt, // TXT writer
  34. fpdocproj, mkfpdoc, dw_basemd, dw_basehtml, fpdocstrs;
  35. Type
  36. { TFPDocApplication }
  37. TFPDocApplication = Class(TCustomApplication)
  38. private
  39. FCreator : TFPDocCreator;
  40. FPackage : TFPDocPackage;
  41. FDryRun,
  42. FProjectFile : Boolean;
  43. FWriteProjectFile : String;
  44. Protected
  45. procedure OutputLog(Sender: TObject; const Msg: String);
  46. procedure ParseCommandLine;
  47. procedure ParseOption(const S: String);
  48. procedure Usage(AnExitCode : Byte);
  49. procedure ExceptProc(Sender: TObject; E: Exception);
  50. procedure DoRun; override;
  51. Public
  52. Constructor Create(AOwner : TComponent); override;
  53. Destructor Destroy; override;
  54. Function SelectedPackage : TFPDocPackage;
  55. end;
  56. procedure TFPDocApplication.Usage(AnExitCode: Byte);
  57. Var
  58. I,P : Integer;
  59. S : String;
  60. L : TStringList;
  61. C : TFPDocWriterClass;
  62. Backend : String;
  63. begin
  64. Writeln(Format(SCmdLineHelp,[ExtractFileName(Paramstr(0))]));
  65. Writeln(SUsageOption008);
  66. Writeln(SUsageOption009);
  67. Writeln(SUsageOption010);
  68. Writeln(SUsageOption020);
  69. Writeln(SUsageOption030);
  70. Writeln(SUsageOption035);
  71. Writeln(SUsageOption040);
  72. Writeln(SUsageOption050);
  73. Writeln(SUsageOption060);
  74. Writeln(SUsageOption070);
  75. Writeln(SUsageOption080);
  76. Writeln(SUsageOption090);
  77. Writeln(SUsageOption100);
  78. Writeln(SUsageOption110);
  79. Writeln(SUsageOption120);
  80. Writeln(SUsageOption130);
  81. Writeln(SUsageOption140);
  82. Writeln(SUsageOption145);
  83. Writeln(SUsageOption150);
  84. Writeln(SUsageOption160);
  85. Writeln(SUsageOption170);
  86. Writeln(SUsageOption180);
  87. Writeln(SUsageOption190);
  88. Writeln(SUsageOption200);
  89. Writeln(SUsageOption210);
  90. Writeln(SUsageOption215);
  91. Writeln(SUsageOption215A);
  92. Writeln(SUsageOption220);
  93. Writeln(SUsageOption221);
  94. Writeln(SUsageOption222);
  95. Writeln(SUsageOption223);
  96. Writeln(SUsageOption230);
  97. Writeln(SUsageOption240);
  98. Writeln(SUsageOption250);
  99. Writeln(SUsageOption260);
  100. Writeln(SUsageOption270);
  101. Writeln(SUsageOption280);
  102. Writeln(SUsageOption290);
  103. Writeln(SUsageOption300);
  104. Writeln(SUsageOption310);
  105. Writeln(SUsageOption320);
  106. L:=TStringList.Create;
  107. Try
  108. Backend:=FCreator.OPtions.Backend;
  109. If (Backend='') then
  110. begin
  111. Writeln;
  112. Writeln(SUsageFormats);
  113. EnumWriters(L);
  114. For I:=0 to L.Count-1 do
  115. begin
  116. S:=L[i];
  117. P:=Pos('=',S);
  118. Writeln(Format(' %s - %s',[Copy(S,1,P-1)+Space(10-p),Copy(S,P+1,Length(S))]));
  119. end;
  120. Writeln(SUsageBackendHelp);
  121. end
  122. else
  123. begin
  124. Writeln;
  125. Writeln(Format(SUsageFormatSpecific,[Lowercase(backend)]));
  126. C:=GetWriterClass(Backend);
  127. C.Usage(L);
  128. If L.Count>0 then
  129. For I:=0 to (L.Count-1) div 2 do
  130. begin
  131. S:=L[i*2];
  132. Writeln(Format('%s %s',[S+Space(30-Length(S)),L[(i*2)+1]]));
  133. end;
  134. end;
  135. Finally
  136. L.Free;
  137. end;
  138. Halt(AnExitCode);
  139. end;
  140. procedure TFPDocApplication.ExceptProc(Sender: TObject; E: Exception);
  141. begin
  142. {$IFDEF EXCEPTION_STACK}
  143. OutputLog(Sender, DumpExceptionCallStack(E));
  144. {$ENDIF}
  145. end;
  146. destructor TFPDocApplication.Destroy;
  147. begin
  148. FreeAndNil(FCreator);
  149. Inherited;
  150. end;
  151. function TFPDocApplication.SelectedPackage: TFPDocPackage;
  152. var
  153. i:integer;
  154. begin
  155. Result:=FPackage;
  156. if (FPackage=Nil) or (FPackage.Name='') then
  157. begin
  158. Writeln(SNeedPackageName);
  159. if FCreator.Packages.Count>0 then
  160. begin
  161. if (FCreator.Packages[0].Name<>'') then
  162. Writeln(SAvailablePackages);
  163. for i:=0 to FCreator.Packages.Count-1 do
  164. begin
  165. Writeln(FCreator.Packages[i].Name);
  166. end;
  167. end;
  168. Usage(1);
  169. end;
  170. end;
  171. procedure TFPDocApplication.OutputLog(Sender: TObject; const Msg: String);
  172. begin
  173. Writeln(StdErr,Msg);
  174. end;
  175. procedure TFPDocApplication.ParseCommandLine;
  176. Const
  177. SOptProject = '--project=';
  178. SOptPackage = '--package=';
  179. SOptMacro = '--macro=';
  180. Function ProjectOpt(Const s : string) : boolean;
  181. begin
  182. Result:=(Copy(s,1,3)='-p=') or (Copy(s,1,Length(SOptProject))=SOptProject) or (Copy(s,1,Length(SOptMacro))=SOptMacro);
  183. end;
  184. Function PackageOpt(Const s : string) : boolean;
  185. begin
  186. Result:=((Copy(s,1,3)='-a=') or (Copy(s,1,Length(SOptPackage))=SOptPackage));
  187. end;
  188. var
  189. i : Integer;
  190. s : string;
  191. begin
  192. // Check project
  193. for i := 1 to ParamCount do
  194. begin
  195. s:=ParamStr(I);
  196. If ProjectOpt(S) then
  197. ParseOption(s);
  198. end;
  199. If (FCreator.Packages.Count=1) then
  200. FPackage:=FCreator.Packages[0]
  201. else if (FCreator.Options.DefaultPackageName<>'') then
  202. Fpackage:=FCreator.Packages.FindPackage(FCreator.Options.DefaultPackageName);
  203. If FCreator.Project.Packages.Count=0 then
  204. begin // Add default package if none defined
  205. FPackage:=FCreator.Packages.Add as TFPDocPackage;
  206. end;
  207. // Check package
  208. for i := 1 to ParamCount do
  209. begin
  210. s:=ParamStr(I);
  211. If PackageOpt(S) then
  212. ParseOption(s);
  213. end;
  214. for i := 1 to ParamCount do
  215. begin
  216. s:=ParamStr(I);
  217. If Not (ProjectOpt(s) or PackageOpt(S)) then
  218. ParseOption(s);
  219. end;
  220. SelectedPackage; // Will print error if none available.
  221. // Set defaults
  222. if FCreator.Options.BackEnd='' then
  223. FCreator.Options.BackEnd:='html';
  224. if SelectedPackage.Output='' then
  225. SelectedPackage.Output:=SelectedPackage.Name;
  226. end;
  227. procedure TFPDocApplication.ParseOption(Const S : String);
  228. procedure AddDirToFileList(List: TStrings; const ADirName, AMask: String);
  229. Var
  230. Info : TSearchRec;
  231. D : String;
  232. begin
  233. if (ADirName<>'') and not DirectoryExists(ADirName) then
  234. OutputLog(Self,'Directory '+ADirName+' does not exist')
  235. else
  236. begin
  237. if (ADirName='.') or (ADirName='') then
  238. D:=''
  239. else
  240. D:=IncludeTrailingPathDelimiter(ADirName);
  241. If (FindFirst(D+AMask,0,Info)=0) then
  242. try
  243. Repeat
  244. If (Info.Attr and faDirectory)=0 then
  245. List.Add(D+Info.name);
  246. Until FindNext(Info)<>0;
  247. finally
  248. FindClose(Info);
  249. end;
  250. end;
  251. end;
  252. procedure AddToFileList(List: TStrings; const FileName: String);
  253. var
  254. f: Text;
  255. s: String;
  256. begin
  257. if Copy(FileName, 1, 1) = '@' then
  258. begin
  259. AssignFile(f, Copy(FileName, 2, Length(FileName)));
  260. Reset(f);
  261. while not EOF(f) do
  262. begin
  263. ReadLn(f, s);
  264. List.Add(s);
  265. end;
  266. Close(f);
  267. end else
  268. List.Add(FileName);
  269. end;
  270. var
  271. i: Integer;
  272. Cmd, Arg: String;
  273. begin
  274. if (s = '-h') or (s = '--help') then
  275. Usage(0)
  276. else if s = '--hide-protected' then
  277. FCreator.Options.HideProtected := True
  278. else if s = '--warn-no-node' then
  279. FCreator.Options.WarnNoNode := True
  280. else if s = '--warn-documentation-empty' then
  281. FCreator.Options.WarnDocumentationEmpty := True
  282. else if s = '--warn-used-file' then
  283. FCreator.Options.WarnUsedFile := True
  284. else if s = '--warn-XCT' then
  285. FCreator.Options.WarnXCT := True
  286. else if s = '--show-private' then
  287. FCreator.Options.ShowPrivate := True
  288. else if s = '--stop-on-parser-error' then
  289. FCreator.Options.StopOnParseError := True
  290. else if s = '--dont-trim' then
  291. FCreator.Options.DontTrim := True
  292. else
  293. begin
  294. i := Pos('=', s);
  295. if i > 0 then
  296. begin
  297. Cmd := Copy(s, 1, i - 1);
  298. Arg := Copy(s, i + 1, Length(s));
  299. end
  300. else
  301. begin
  302. Cmd := s;
  303. SetLength(Arg, 0);
  304. end;
  305. if (Cmd = '--project') or (Cmd='-p') then
  306. begin
  307. FProjectFile:=True;
  308. FCreator.LoadProjectFile(Arg);
  309. end
  310. else if (Cmd = '--descr') then
  311. AddToFileList(SelectedPackage.Descriptions, Arg)
  312. else if (Cmd = '--descr-dir') then
  313. AddDirToFileList(SelectedPackage.Descriptions, Arg, '*.xml')
  314. else if (Cmd = '--base-descr-dir') then
  315. FCreator.BaseDescrDir:=Arg
  316. else if (Cmd = '--macro') then
  317. begin
  318. If Pos('=',Arg)=0 then
  319. WriteLn(StdErr, Format(SCmdLineErrInvalidMacro, [Arg]));
  320. FCreator.ProjectMacros.Add(Arg);
  321. end
  322. else if (Cmd = '-f') or (Cmd = '--format') then
  323. begin
  324. Arg:=UpperCase(Arg);
  325. If FindWriterClass(Arg)=-1 then
  326. WriteLn(StdErr, Format(SCmdLineInvalidFormat, [Arg]))
  327. else
  328. FCreator.Options.BackEnd:=Arg;
  329. end
  330. else if (Cmd = '-l') or (Cmd = '--lang') then
  331. FCreator.Options.Language := Arg
  332. else if (Cmd = '-i') or (Cmd = '--input') then
  333. AddToFileList(SelectedPackage.Inputs, Arg)
  334. else if (Cmd = '--base-input-dir') then
  335. FCreator.BaseInputDir:=Arg
  336. else if (Cmd = '--input-dir') then
  337. begin
  338. AddDirToFileList(SelectedPackage.Inputs, Arg,'*.pp');
  339. AddDirToFileList(SelectedPackage.Inputs, Arg,'*.pas');
  340. end
  341. else if (Cmd = '-o') or (Cmd = '--output') then
  342. SelectedPackage.Output := Arg
  343. else if (Cmd = '-v') or (Cmd = '--verbose') then
  344. FCreator.Verbose:=true
  345. else if (Cmd = '-n') or (Cmd = '--dry-run') then
  346. FDryRun:=True
  347. else if (Cmd = '-t') or (Cmd = '--emit-notes') then
  348. FCreator.Options.EmitNotes := True
  349. else if Cmd = '--content' then
  350. SelectedPackage.ContentFile := Arg
  351. else if Cmd = '--import' then
  352. SelectedPackage.Imports.Add(Arg)
  353. else if Cmd = '--package' then
  354. begin
  355. If FProjectFile then
  356. FPackage:=FCreator.Packages.FindPackage(Arg)
  357. else
  358. FPackage.Name:=Arg;
  359. end
  360. else if Cmd = '--ostarget' then
  361. FCreator.Options.OSTarget := Arg
  362. else if Cmd = '--cputarget' then
  363. FCreator.Options.CPUTarget := Arg
  364. else if Cmd = '--mo-dir' then
  365. FCreator.Options.modir := Arg
  366. else if Cmd = '--parse-impl' then
  367. FCreator.Options.InterfaceOnly:=false
  368. else if Cmd = '--write-project' then
  369. FWriteProjectFile:=Arg
  370. else
  371. begin
  372. FCreator.Options.BackendOptions.Add(Cmd);
  373. FCreator.Options.BackendOptions.Add(Arg);
  374. end;
  375. end;
  376. end;
  377. Procedure TFPDocApplication.DoRun;
  378. begin
  379. ExceptionExitCode:=1;
  380. try
  381. {$IFDEF Unix}
  382. gettext.TranslateResourceStrings('/usr/local/share/locale/%s/LC_MESSAGES/fpdoc.mo');
  383. {$ELSE}
  384. gettext.TranslateResourceStrings('intl/fpdoc.%s.mo');
  385. {$ENDIF}
  386. WriteLn(STitle);
  387. WriteLn(Format(SVersion, [DefFPCVersion, DefFPCDate]));
  388. WriteLn(SCopyright1);
  389. WriteLn(SCopyright2);
  390. WriteLn;
  391. ParseCommandLine;
  392. if (FWriteProjectFile<>'') then
  393. FCreator.CreateProjectFile(FWriteProjectFile)
  394. else
  395. FCreator.CreateDocumentation(FPackage,FDryRun);
  396. WriteLn(SDone);
  397. Terminate;
  398. except
  399. ExitCode:=1;
  400. Raise;
  401. end;
  402. end;
  403. constructor TFPDocApplication.Create(AOwner: TComponent);
  404. begin
  405. inherited Create(AOwner);
  406. StopOnException:=true;
  407. FCreator:=TFPDocCreator.Create(Self);
  408. FCreator.OnLog:=@OutputLog;
  409. OnException:= @ExceptProc;
  410. end;
  411. begin
  412. //AssignFile(Output, 'fpdoc.log');
  413. //rewrite(Output);
  414. With TFPDocApplication.Create(Nil) do
  415. try
  416. Run;
  417. finally
  418. Free;
  419. end;
  420. end.