fpdoc.pp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  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. Function ProjectOpt(Const s : string) : boolean;
  160. begin
  161. Result:=(Copy(s,1,3)='-p=') or (Copy(s,1,10)='--project=');
  162. end;
  163. Function PackageOpt(Const s : string) : boolean;
  164. begin
  165. Result:=((Copy(s,1,3)='-a=') or (Copy(s,1,10)='--package='));
  166. end;
  167. var
  168. i : Integer;
  169. s : string;
  170. begin
  171. // Check project
  172. for i := 1 to ParamCount do
  173. begin
  174. s:=ParamStr(I);
  175. If ProjectOpt(S) then
  176. ParseOption(s);
  177. If (FCreator.Packages.Count=1) then
  178. FPackage:=FCreator.Packages[0]
  179. else if (FCreator.Options.DefaultPackageName<>'') then
  180. Fpackage:=FCreator.Packages.FindPackage(FCreator.Options.DefaultPackageName);
  181. end;
  182. If FCreator.Project.Packages.Count=0 then
  183. begin // Add default package if none defined
  184. FPackage:=FCreator.Packages.Add as TFPDocPackage;
  185. end;
  186. // Check package
  187. for i := 1 to ParamCount do
  188. begin
  189. s:=ParamStr(I);
  190. If PackageOpt(S) then
  191. ParseOption(s);
  192. end;
  193. for i := 1 to ParamCount do
  194. begin
  195. s:=ParamStr(I);
  196. If Not (ProjectOpt(s) or PackageOpt(S)) then
  197. ParseOption(s);
  198. end;
  199. SelectedPackage; // Will print error if none available.
  200. end;
  201. procedure TFPDocApplication.ParseOption(Const S : String);
  202. procedure AddDirToFileList(List: TStrings; const ADirName, AMask: String);
  203. Var
  204. Info : TSearchRec;
  205. D : String;
  206. begin
  207. if (ADirName<>'') and not DirectoryExists(ADirName) then
  208. OutputLog(Self,'Directory '+ADirName+' does not exist')
  209. else
  210. begin
  211. if (ADirName='.') or (ADirName='') then
  212. D:=''
  213. else
  214. D:=IncludeTrailingPathDelimiter(ADirName);
  215. If (FindFirst(D+AMask,0,Info)=0) then
  216. try
  217. Repeat
  218. If (Info.Attr and faDirectory)=0 then
  219. List.Add(D+Info.name);
  220. Until FindNext(Info)<>0;
  221. finally
  222. FindClose(Info);
  223. end;
  224. end;
  225. end;
  226. procedure AddToFileList(List: TStrings; const FileName: String);
  227. var
  228. f: Text;
  229. s: String;
  230. begin
  231. if Copy(FileName, 1, 1) = '@' then
  232. begin
  233. AssignFile(f, Copy(FileName, 2, Length(FileName)));
  234. Reset(f);
  235. while not EOF(f) do
  236. begin
  237. ReadLn(f, s);
  238. List.Add(s);
  239. end;
  240. Close(f);
  241. end else
  242. List.Add(FileName);
  243. end;
  244. var
  245. i: Integer;
  246. Cmd, Arg: String;
  247. begin
  248. if (s = '-h') or (s = '--help') then
  249. Usage(0)
  250. else if s = '--hide-protected' then
  251. FCreator.Options.HideProtected := True
  252. else if s = '--warn-no-node' then
  253. FCreator.Options.WarnNoNode := True
  254. else if s = '--show-private' then
  255. FCreator.Options.ShowPrivate := False
  256. else if s = '--stop-on-parser-error' then
  257. FCreator.Options.StopOnParseError := True
  258. else if s = '--dont-trim' then
  259. FCreator.Options.DontTrim := True
  260. else
  261. begin
  262. i := Pos('=', s);
  263. if i > 0 then
  264. begin
  265. Cmd := Copy(s, 1, i - 1);
  266. Arg := Copy(s, i + 1, Length(s));
  267. end
  268. else
  269. begin
  270. Cmd := s;
  271. SetLength(Arg, 0);
  272. end;
  273. if (Cmd = '--project') or (Cmd='-p') then
  274. begin
  275. FProjectFile:=True;
  276. FCreator.LoadProjectFile(Arg);
  277. end
  278. else if (Cmd = '--descr') then
  279. AddToFileList(SelectedPackage.Descriptions, Arg)
  280. else if (Cmd = '--descr-dir') then
  281. AddDirToFileList(SelectedPackage.Descriptions, Arg, '*.xml')
  282. else if (Cmd = '-f') or (Cmd = '--format') then
  283. begin
  284. Arg:=UpperCase(Arg);
  285. If FindWriterClass(Arg)=-1 then
  286. WriteLn(StdErr, Format(SCmdLineInvalidFormat, [Arg]))
  287. else
  288. FCreator.Options.BackEnd:=Arg;
  289. end
  290. else if (Cmd = '-l') or (Cmd = '--lang') then
  291. FCreator.Options.Language := Arg
  292. else if (Cmd = '-i') or (Cmd = '--input') then
  293. AddToFileList(SelectedPackage.Inputs, Arg)
  294. else if (Cmd = '--input-dir') then
  295. begin
  296. AddDirToFileList(SelectedPackage.Inputs, Arg,'*.pp');
  297. AddDirToFileList(SelectedPackage.Inputs, Arg,'*.pas');
  298. end
  299. else if (Cmd = '-o') or (Cmd = '--output') then
  300. SelectedPackage.Output := Arg
  301. else if (Cmd = '-v') or (Cmd = '--verbose') then
  302. FCreator.Verbose:=true
  303. else if (Cmd = '-n') or (Cmd = '--dry-run') then
  304. FDryRun:=True
  305. else if (Cmd = '-t') or (Cmd = '--emit-notes') then
  306. FCreator.Options.EmitNotes := True
  307. else if Cmd = '--content' then
  308. SelectedPackage.ContentFile := Arg
  309. else if Cmd = '--import' then
  310. SelectedPackage.Imports.Add(Arg)
  311. else if Cmd = '--package' then
  312. begin
  313. If FProjectFile then
  314. FPackage:=FCreator.Packages.FindPackage(Arg)
  315. else
  316. FPackage.Name:=Arg;
  317. end
  318. else if Cmd = '--ostarget' then
  319. FCreator.Options.OSTarget := Arg
  320. else if Cmd = '--cputarget' then
  321. FCreator.Options.CPUTarget := Arg
  322. else if Cmd = '--mo-dir' then
  323. FCreator.Options.modir := Arg
  324. else if Cmd = '--parse-impl' then
  325. FCreator.Options.InterfaceOnly:=false
  326. else if Cmd = '--write-project' then
  327. FWriteProjectFile:=Arg
  328. else
  329. begin
  330. FCreator.Options.BackendOptions.Add(Cmd);
  331. FCreator.Options.BackendOptions.Add(Arg);
  332. end;
  333. end;
  334. end;
  335. Procedure TFPDocApplication.DoRun;
  336. begin
  337. {$IFDEF Unix}
  338. gettext.TranslateResourceStrings('/usr/local/share/locale/%s/LC_MESSAGES/fpdoc.mo');
  339. {$ELSE}
  340. gettext.TranslateResourceStrings('intl/fpdoc.%s.mo');
  341. {$ENDIF}
  342. WriteLn(STitle);
  343. WriteLn(Format(SVersion, [DefFPCVersion, DefFPCDate]));
  344. WriteLn(SCopyright1);
  345. WriteLn(SCopyright2);
  346. WriteLn;
  347. ParseCommandLine;
  348. if (FWriteProjectFile<>'') then
  349. FCreator.CreateProjectFile(FWriteProjectFile)
  350. else
  351. FCreator.CreateDocumentation(FPackage,FDryRun);
  352. WriteLn(SDone);
  353. Terminate;
  354. end;
  355. constructor TFPDocApplication.Create(AOwner: TComponent);
  356. begin
  357. inherited Create(AOwner);
  358. StopOnException:=true;
  359. FCreator:=TFPDocCreator.Create(Self);
  360. FCreator.OnLog:=@OutputLog;
  361. end;
  362. begin
  363. With TFPDocApplication.Create(Nil) do
  364. try
  365. Run;
  366. finally
  367. Free;
  368. end;
  369. end.