fpdoc.pp 11 KB

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