fpdoc.pp 10 KB

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