fpdoc.pp 10 KB

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