makeskel.pp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. {
  2. $Id$
  3. FPDoc - Free Pascal Documentation Tool
  4. Copyright (C) 2000 - 2003 by
  5. Areca Systems GmbH / Sebastian Guenther, [email protected]
  6. * Skeleton XML description file generator
  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 MakeSkel;
  14. uses
  15. SysUtils, Classes, Gettext,
  16. dGlobals, PasTree, PParser,PScanner;
  17. resourcestring
  18. STitle = 'MakeSkel - FPDoc skeleton XML description file generator';
  19. SCopyright = '(c) 2000 - 2003 Areca Systems GmbH / Sebastian Guenther, [email protected]';
  20. SCmdLineHelp = 'See documentation for usage.';
  21. SCmdLineInvalidOption = 'Ignoring unknown option "%s"';
  22. SNoPackageNameProvided = 'Please specify a package name with --package=<name>';
  23. SDone = 'Done.';
  24. type
  25. TCmdLineAction = (actionHelp, actionConvert);
  26. TSkelEngine = class(TFPDocEngine)
  27. public
  28. function CreateElement(AClass: TPTreeElement; const AName: String;
  29. AParent: TPasElement; AVisibility :TPasMemberVisibility;
  30. const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement; override;
  31. end;
  32. const
  33. CmdLineAction: TCmdLineAction = actionConvert;
  34. OSTarget: String = {$I %FPCTARGETOS%};
  35. CPUTarget: String = {$I %FPCTARGETCPU%};
  36. var
  37. InputFiles, DescrFiles: TStringList;
  38. DocLang: String;
  39. Engine: TSkelEngine;
  40. DisableErrors,
  41. DisableSeealso,
  42. DisableArguments,
  43. DisableProtected,
  44. DisablePrivate,
  45. DisableFunctionResults: Boolean;
  46. EmitClassSeparator: Boolean;
  47. PackageName, OutputName: String;
  48. f: Text;
  49. function TSkelEngine.CreateElement(AClass: TPTreeElement; const AName: String;
  50. AParent: TPasElement; AVisibility : TPasMemberVisibility;
  51. const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement;
  52. begin
  53. Result := AClass.Create(AName, AParent);
  54. if AClass.InheritsFrom(TPasModule) then
  55. CurModule := TPasModule(Result);
  56. if Result.ClassType = TPasModule then
  57. begin
  58. WriteLn(f);
  59. WriteLn(f, '<!--');
  60. WriteLn(f, ' ====================================================================');
  61. WriteLn(f, ' ', Result.Name);
  62. WriteLn(f, ' ====================================================================');
  63. WriteLn(f, '-->');
  64. WriteLn(f);
  65. WriteLn(f, '<module name="', Result.Name, '">');
  66. WriteLn(f, '<short></short>');
  67. WriteLn(f, '<descr>');
  68. WriteLn(f, '</descr>');
  69. end else if Assigned(AParent) and (Length(AName) > 0) and
  70. (not DisableArguments or (Result.ClassType <> TPasArgument)) and
  71. (not DisableFunctionResults or (Result.ClassType <> TPasResultElement)) and
  72. (not DisablePrivate or (AVisibility<>visPrivate)) and
  73. (not DisableProtected or (AVisibility<>visProtected)) then
  74. begin
  75. WriteLn(f);
  76. if EmitClassSeparator and (Result.ClassType = TPasClassType) then
  77. begin
  78. WriteLn(f, '<!--');
  79. WriteLn(f, ' ********************************************************************');
  80. WriteLn(f, ' ', Result.PathName);
  81. WriteLn(f, ' ********************************************************************');
  82. WriteLn(f, '-->');
  83. WriteLn(f);
  84. end;
  85. Writeln(F,'<!-- ', Result.ElementTypeName,' Visibility: ',VisibilityNames[AVisibility], ' -->');
  86. WriteLn(f,'<element name="', Result.FullName, '">');
  87. WriteLn(f, '<short></short>');
  88. WriteLn(f, '<descr>');
  89. WriteLn(f, '</descr>');
  90. if not DisableErrors then
  91. begin
  92. WriteLn(f, '<errors>');
  93. WriteLn(f, '</errors>');
  94. end;
  95. if not DisableSeealso then
  96. begin
  97. WriteLn(f, '<seealso>');
  98. WriteLn(f, '</seealso>');
  99. end;
  100. WriteLn(f, '</element>');
  101. end;
  102. end;
  103. procedure InitOptions;
  104. begin
  105. InputFiles := TStringList.Create;
  106. DescrFiles := TStringList.Create;
  107. end;
  108. procedure FreeOptions;
  109. begin
  110. DescrFiles.Free;
  111. InputFiles.Free;
  112. end;
  113. procedure ParseOption(const s: String);
  114. procedure AddToFileList(List: TStringList; const FileName: String);
  115. var
  116. f: Text;
  117. s: String;
  118. begin
  119. if Copy(FileName, 1, 1) = '@' then
  120. begin
  121. Assign(f, Copy(FileName, 2, Length(FileName)));
  122. Reset(f);
  123. while not EOF(f) do
  124. begin
  125. ReadLn(f, s);
  126. List.Add(s);
  127. end;
  128. Close(f);
  129. end else
  130. List.Add(FileName);
  131. end;
  132. var
  133. i: Integer;
  134. Cmd, Arg: String;
  135. begin
  136. if (s = '-h') or (s = '--help') then
  137. CmdLineAction := actionHelp
  138. else if s = '--disable-arguments' then
  139. DisableArguments := True
  140. else if s = '--disable-errors' then
  141. DisableErrors := True
  142. else if s = '--disable-function-results' then
  143. DisableFunctionResults := True
  144. else if s = '--disable-seealso' then
  145. DisableSeealso := True
  146. else if s = '--disable-private' then
  147. DisablePrivate := True
  148. else if s = '--disable-protected' then
  149. begin
  150. DisableProtected := True;
  151. DisablePrivate :=True;
  152. end
  153. else if s = '--emitclassseparator' then
  154. EmitClassSeparator := True
  155. else
  156. begin
  157. i := Pos('=', s);
  158. if i > 0 then
  159. begin
  160. Cmd := Copy(s, 1, i - 1);
  161. Arg := Copy(s, i + 1, Length(s));
  162. end else
  163. begin
  164. Cmd := s;
  165. SetLength(Arg, 0);
  166. end;
  167. if (Cmd = '-i') or (Cmd = '--input') then
  168. AddToFileList(InputFiles, Arg)
  169. else if (Cmd = '-l') or (Cmd = '--lang') then
  170. DocLang := Arg
  171. else if (Cmd = '-o') or (Cmd = '--output') then
  172. OutputName := Arg
  173. else if Cmd = '--package' then
  174. PackageName := Arg
  175. else
  176. WriteLn(StdErr, Format(SCmdLineInvalidOption, [s]));
  177. end;
  178. end;
  179. procedure ParseCommandLine;
  180. Const
  181. {$IFDEF Unix}
  182. MoFileTemplate = '/usr/local/share/locale/%s/LC_MESSAGES/makeskel.mo';
  183. {$ELSE}
  184. MoFileTemplate ='intl/makeskel.%s.mo';
  185. {$ENDIF}
  186. var
  187. MOFilename: string;
  188. i: Integer;
  189. begin
  190. DocLang:='';
  191. for i := 1 to ParamCount do
  192. ParseOption(ParamStr(i));
  193. If (DocLang<>'') then
  194. begin
  195. MOFilename:=Format(MOFileTemplate,[DocLang]);
  196. if FileExists(MOFilename) then
  197. gettext.TranslateResourceStrings(MoFileName)
  198. else
  199. writeln('NOTE: unable to find tranlation file ',MOFilename);
  200. // Translate internal documentation strings
  201. TranslateDocStrings(DocLang);
  202. end;
  203. end;
  204. var
  205. i: Integer;
  206. Module: TPasModule;
  207. begin
  208. InitOptions;
  209. ParseCommandLine;
  210. WriteLn(STitle);
  211. WriteLn(SCopyright);
  212. WriteLn;
  213. if CmdLineAction = actionHelp then
  214. WriteLn(SCmdLineHelp)
  215. else
  216. begin
  217. // Action is to create the XML skeleton
  218. if Length(PackageName) = 0 then
  219. begin
  220. WriteLn(SNoPackageNameProvided);
  221. Halt(2);
  222. end;
  223. Assign(f, OutputName);
  224. Rewrite(f);
  225. WriteLn(f, '<?xml version="1.0" encoding="ISO8859-1"?>');
  226. WriteLn(f, '<fpdoc-descriptions>');
  227. WriteLn(f, '<package name="', PackageName, '">');
  228. // Process all source files
  229. for i := 0 to InputFiles.Count - 1 do
  230. begin
  231. Engine := TSkelEngine.Create;
  232. try
  233. try
  234. Engine.SetPackageName(PackageName);
  235. Module := ParseSource(Engine, InputFiles[i], OSTarget, CPUTarget);
  236. WriteLn(f, '</module> <!-- ', Module.Name, ' -->');
  237. except
  238. on e:EFileNotFoundError do
  239. begin
  240. Writeln(StdErr,' file ', e.message, ' not found');
  241. close(f);
  242. Halt(1);
  243. end;
  244. end;
  245. finally
  246. Engine.Free;
  247. end;
  248. end;
  249. WriteLn(f, '</package>');
  250. WriteLn(f, '</fpdoc-descriptions>');
  251. Close(f);
  252. end;
  253. FreeOptions;
  254. WriteLn(SDone);
  255. end.
  256. {
  257. $Log$
  258. Revision 1.8 2004-08-25 07:16:43 michael
  259. + Improved translation handling
  260. Revision 1.7 2004/08/24 14:48:25 michael
  261. + Translate now called correctly...
  262. Revision 1.6 2004/05/01 20:13:40 marco
  263. * got fed up with exceptions on file not found. Fileresolver now raises a
  264. EFileNotFound error, and makeskel catches and exists gracefully
  265. Revision 1.5 2003/11/28 12:51:37 sg
  266. * Added support for source references
  267. Revision 1.4 2003/09/02 13:26:47 mattias
  268. MG: makeskel now ignores missing translation file
  269. Revision 1.3 2003/05/07 16:31:32 sg
  270. * Fixed a severe memory corruption problem on termination
  271. Revision 1.2 2003/03/28 13:01:36 michael
  272. + Patch from Charlie/iNQ to work with new scanner/parser
  273. Revision 1.1 2003/03/17 23:03:20 michael
  274. + Initial import in CVS
  275. }