fpdoc.pp 11 KB

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