fpdoc.pp 10 KB

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