fpdoc.pp 10 KB

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