fpdoc.pp 11 KB

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