fpdoc.pp 9.5 KB

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