fpdoc.pp 10 KB

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