dw_xml.pp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  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. * 'XML struct' output generator
  8. See the file COPYING, included in this distribution,
  9. for details about the copyright.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. }
  14. {$mode objfpc}
  15. {$H+}
  16. unit dw_XML;
  17. interface
  18. uses DOM, PasTree, dGlobals, dwriter, xmlWrite, SysUtils, Classes;
  19. Type
  20. { TXMLWriter }
  21. TXMLWriter = Class(TFPDocWriter)
  22. private
  23. FShowSourceInfo: Boolean;
  24. public
  25. function ModuleToXMLStruct(AModule: TPasModule): TXMLDocument;
  26. Procedure WriteDoc; override;
  27. class procedure Usage(List: TStrings); override;
  28. function InterPretOption(const Cmd,Arg : String): boolean; override;
  29. end;
  30. implementation
  31. const
  32. DefaultVisibility = [visDefault, visPublic, visPublished, visProtected];
  33. function TXMLWriter.ModuleToXMLStruct(AModule: TPasModule): TXMLDocument;
  34. var
  35. ModuleElement: TDOMElement;
  36. Doc: TXMLDocument absolute Result;
  37. function VisibilityToString(vis: TPasMemberVisibility): String;
  38. begin
  39. case vis of
  40. visDefault : Result := '';
  41. visPrivate : Result := 'private';
  42. visProtected : Result := 'protected';
  43. visPublic : Result := 'public';
  44. visPublished : Result := 'published';
  45. visAutomated : Result := 'automated';
  46. visStrictPrivate : Result := 'strictprivate';
  47. visStrictProtected : Result := 'strictprotected';
  48. end;
  49. end;
  50. function Sanitize(AString: String): String;
  51. var
  52. i: Integer;
  53. begin
  54. Result := AString;
  55. for i := 1 to length(Result) do
  56. if Result[i] in [' '] then
  57. Result[i] := '_';
  58. end;
  59. procedure AddSourceInfo(ADecl: TPasElement; AElement: TDOMElement);
  60. var
  61. SourceNode: TDOMElement;
  62. begin
  63. if not FShowSourceInfo then
  64. Exit;
  65. SourceNode := Doc.CreateElement('source');
  66. SourceNode['line'] := UTF8Decode(IntToStr(ADecl.SourceLinenumber));
  67. SourceNode['file'] := UTF8Decode(ADecl.SourceFilename);
  68. AElement.AppendChild(SourceNode);
  69. end;
  70. procedure AddProcedureModifiers(ADecl: TPasProcedure; Node: TDOMElement);
  71. begin
  72. {pmVirtual , pmDynamic, pmAbstract, pmOverride,
  73. pmExport, pmOverload, pmMessage, pmReintroduce,
  74. pmStatic,pmInline,pmAssembler,pmVarargs, pmPublic,
  75. pmCompilerProc,pmExternal,pmForward}
  76. if (pmVirtual in ADecl.Modifiers) or (pmDynamic in ADecl.Modifiers) then
  77. Node['virtual'] := 'true';
  78. if pmAbstract in ADecl.Modifiers then
  79. Node['abstract'] := 'true';
  80. if assigned(ADecl.ProcType) and (ptmStatic in ADecl.ProcType.Modifiers) then
  81. Node['static'] := 'true';
  82. if pmReintroduce in ADecl.Modifiers then
  83. Node['reintroduce'] := 'true';
  84. if pmOverload in ADecl.Modifiers then
  85. Node['overload'] := 'true';
  86. if pmForward in ADecl.Modifiers then
  87. Node['forward'] := 'true';
  88. if pmOverride in ADecl.Modifiers then
  89. Node['override'] := 'true';
  90. end;
  91. procedure AddTypeNode(ToNode: TDOMElement; AType: String);
  92. begin
  93. ToNode.AttribStrings['type'] := UTF8Decode(AType);
  94. end;
  95. function AddTypeNode(ToNode: TDOMElement; AType: TPasType): Boolean;
  96. //var
  97. // TypeNode: TDOMElement;
  98. begin
  99. Result := False;
  100. if not Assigned(AType) then
  101. Exit;
  102. //TypeNode := Doc.CreateElement('type');
  103. //TypeNode.TextContent:=AType.Name;
  104. //ToNode.AppendChild(TypeNode);
  105. AddTypeNode(ToNode, AType.Name);
  106. Result := True;
  107. end;
  108. procedure ProcessArgs(Args: TFPList; ProcNode: TDomElement);
  109. var
  110. i: Integer;
  111. ArgNode: TDOMElement;
  112. Arg: TPasArgument;
  113. begin
  114. for i := 0 to Args.Count-1 do
  115. begin
  116. Arg := TPasArgument(Args.Items[i]);
  117. ArgNode := Doc.CreateElement('argument');
  118. ArgNode.AttribStrings['name'] := UTF8Decode(Arg.Name);
  119. AddTypeNode(ArgNode, Arg.ArgType);
  120. ProcNode.AppendChild(ArgNode);
  121. end;
  122. end;
  123. procedure DoVisibility(PasEl: TPasElement; Element: TDOMElement);
  124. begin
  125. if PasEl.Visibility <> visDefault then
  126. Element['visibility'] := UTF8Decode(VisibilityToString(PasEl.Visibility));
  127. end;
  128. function ProcessProcedure(Proc: TPasProcedure; Element: TDOMElement): TDOMElement;
  129. var
  130. ProcEl: TDOMElement;
  131. ReturnEl: TDOMElement;
  132. begin
  133. Result := nil;
  134. ProcEl := Doc.CreateElement(UTF8Decode(Sanitize(Proc.TypeName)));
  135. Element.AppendChild(ProcEl);
  136. ProcEl['name'] := UTF8Decode(Proc.Name);
  137. DoVisibility(Proc, ProcEl);
  138. AddProcedureModifiers(Proc, ProcEl);
  139. AddSourceInfo(Proc,ProcEl);
  140. if Proc.InheritsFrom(TPasFunction) then
  141. begin
  142. ReturnEl := Doc.CreateElement('return');
  143. ProcEl.AppendChild(ReturnEl);
  144. AddTypeNode(ReturnEl, TPasFunction(Proc).FuncType.ResultEl.ResultType);
  145. end;
  146. ProcessArgs(Proc.ProcType.Args, ProcEl);
  147. Result := ProcEl;
  148. end;
  149. procedure ProcessArrayType(AType: TPasArrayType; Element: TDOMElement);
  150. var
  151. TypeEl: TDOMElement;
  152. begin
  153. TypeEl := Doc.CreateElement('array');
  154. TypeEl['name'] := UTF8Decode(AType.Name);
  155. if not AddTypeNode(TypeEl, AType.ElType) then
  156. TypeEl['const'] := 'true';
  157. TypeEl['range'] := UTF8Decode(AType.IndexRange);
  158. DoVisibility(AType, Element);
  159. AddSourceInfo(AType,Element);
  160. Element.AppendChild(TypeEl);
  161. end;
  162. procedure ProcessPointerType(AType: TPasPointerType; Element: TDOMElement);
  163. var
  164. TypeEl: TDOMElement;
  165. begin
  166. TypeEl := Doc.CreateElement('pointer');
  167. TypeEl['name'] := UTF8Decode(AType.Name);
  168. AddTypeNode(TypeEl, AType.DestType);
  169. DoVisibility(AType, Element);
  170. AddSourceInfo(AType,Element);
  171. Element.AppendChild(TypeEl);
  172. end;
  173. procedure ProcessAliasType(AType: TPasAliasType; Element: TDOMElement);
  174. var
  175. TypeEl: TDOMElement;
  176. begin
  177. TypeEl := Doc.CreateElement('alias');
  178. TypeEl['name'] := UTF8Decode(AType.Name);
  179. AddTypeNode(TypeEl, AType.DestType);
  180. DoVisibility(AType, Element);
  181. AddSourceInfo(AType,Element);
  182. Element.AppendChild(TypeEl);
  183. end;
  184. procedure ProcessVariable(AVar: TPasVariable; Element: TDOMElement);
  185. var
  186. VarEl: TDOMElement;
  187. begin
  188. VarEl := Result.CreateElement('var');
  189. Element.AppendChild(VarEl);
  190. VarEl['name'] := UTF8Decode(AVar.Name);
  191. if not AVar.VarType.InheritsFrom(TPasArrayType) then
  192. AddTypeNode(VarEl, AVar.VarType)
  193. else
  194. begin
  195. VarEl['array'] := 'true';
  196. ProcessArrayType(TPasArrayType(AVar.VarType), VarEl);
  197. end;
  198. DoVisibility(Avar, VarEl);
  199. AddSourceInfo(AVar,VarEl);
  200. end;
  201. procedure ProcessProperty(AProp: TPasProperty; Element: TDOMElement);
  202. var
  203. PropEl: TDOMElement;
  204. begin
  205. PropEl := Doc.CreateElement('property');
  206. Element.AppendChild(PropEl);
  207. PropEl.AttribStrings['name'] := UTF8Decode(AProp.Name);
  208. AddTypeNode(PropEL, AProp.ResolvedType);
  209. if AProp.IndexValue <> '' then
  210. PropEl['index'] := UTF8Decode(AProp.IndexValue);
  211. if AProp.DefaultValue <> '' then
  212. PropEl['default'] := UTF8Decode(AProp.DefaultValue);
  213. if AProp.WriteAccessorName <> '' then
  214. PropEl.AttribStrings['writable'] := 'true';
  215. ProcessArgs(AProp.Args, PropEl);
  216. DoVisibility(AProp, Element);
  217. AddSourceInfo(AProp,PropEl);
  218. // this isn't quite right
  219. //if AProp.ReadAccessorName = '' then
  220. // PropEl.AttribStrings['inherited'] := 'true';
  221. end;
  222. procedure ProcessOverloadedProcedure(AOverload: TPasOverloadedProc; Element: TDOMElement);
  223. var
  224. OverEl: TDOMElement;
  225. i: Integer;
  226. begin
  227. for i := 0 to AOverload.Overloads.Count-1 do
  228. begin
  229. OverEl := ProcessProcedure(TPasProcedure(AOverload.Overloads.Items[i]), Element);
  230. OverEl['overload'] := 'true';
  231. end;
  232. end;
  233. procedure ProcessConst(AConst: TPasConst; Element: TDOMElement);
  234. var
  235. ConstEl: TDOMElement;
  236. begin
  237. ConstEl := Doc.CreateElement('const');
  238. ConstEl['name'] := UTF8Decode(AConst.name);
  239. ConstEl['value'] := UTF8Decode(AConst.Value);
  240. Element.AppendChild(ConstEl);
  241. AddSourceInfo(AConst,ConstEl);
  242. end;
  243. procedure ProcessEnumType(AType: TPasEnumType; Element: TDOMElement);
  244. var
  245. TypeEl: TDOMElement;
  246. ValEl: TDOMELement;
  247. i: Integer;
  248. begin
  249. TypeEl := Doc.CreateElement('enum');
  250. TypeEl['name'] := UTF8Decode(AType.name);
  251. AddSourceInfo(AType,TypeEl);
  252. //ConstEl['value'] := AConst.Value;
  253. for i := 0 to AType.Values.Count-1 do
  254. begin
  255. ValEl := Doc.CreateElement('enumvalue');
  256. ValEl['name'] := UTF8Decode(TPasEnumValue(AType.Values.Items[i]).Name);
  257. AddSourceInfo(TPasEnumValue(AType.Values.Items[i]),ValEl);
  258. TypeEl.AppendChild(ValEl);
  259. end;
  260. Element.AppendChild(TypeEl);
  261. end;
  262. procedure ProcessSetType(AType: TPasSetType; Element: TDOMElement);
  263. var
  264. SetEl: TDOMElement;
  265. begin
  266. SetEl := Doc.CreateElement('set');
  267. SetEl['name'] := UTF8Decode(AType.name);
  268. AddTypeNode(SetEl, AType.EnumType);
  269. AddSourceInfo(AType,SetEl);
  270. Element.AppendChild(SetEl);
  271. end;
  272. procedure ProcessProcedureType(AType: TPasProcedureType; Element: TDOMElement);
  273. var
  274. TypeEl: TDOMElement;
  275. begin
  276. TypeEl := Doc.CreateElement(UTF8Decode(AType.TypeName));
  277. TypeEl['name'] := UTF8Decode(AType.name);
  278. TypeEl['istype'] := 'true';
  279. if AType.IsOfObject then
  280. TypeEl['object'] := 'true';
  281. ProcessArgs(AType.Args, TypeEl);
  282. AddSourceInfo(AType,TypeEl);
  283. Element.AppendChild(TypeEl);
  284. end;
  285. procedure ProcessRecordType(AType: TPasRecordType; Element: TDOMElement);
  286. var
  287. TypeEl: TDOMElement;
  288. Decl: TPasElement;
  289. i: Integer;
  290. begin
  291. TypeEl := Doc.CreateElement('record');
  292. TypeEl['name'] := UTF8Decode(AType.name);
  293. Element.AppendChild(TypeEl);
  294. AddSourceInfo(AType,TypeEl);
  295. if Assigned(AType.Members) then
  296. for i := 0 to AType.Members.Count - 1 do
  297. begin
  298. Decl := TPasElement(AType.Members[i]);
  299. if Decl.InheritsFrom(TPasProcedure)then
  300. ProcessProcedure(TPasProcedure(Decl), TypeEl)
  301. else if Decl.ClassType = TPasVariable then
  302. ProcessVariable(TPasVariable(Decl), TypeEl)
  303. else if Decl.ClassType = TPasProperty then
  304. ProcessProperty(TPasProperty(Decl), TypeEl)
  305. else writeln('Unhandled record member: ', Decl.ClassName, ' ', Decl.Name);
  306. end;
  307. end;
  308. procedure ProcessGenericTypes(AGenericTypes: TFPList; ANode: TDOMElement);
  309. var
  310. i: Integer;
  311. Node: TDOMElement;
  312. begin
  313. for i := 0 to AGenericTypes.Count-1 do
  314. begin
  315. Node := Doc.CreateElement('t');
  316. Node['name'] := UTF8Decode(TPasGenericTemplateType(AGenericTypes.Items[i]).Name);
  317. ANode.AppendChild(Node);
  318. AddSourceInfo(TPasGenericTemplateType(AGenericTypes.Items[i]),Node);
  319. end;
  320. end;
  321. procedure ProcessRangeType(AType: TPasRangeType; Element: TDOMElement);
  322. var
  323. TypeEl: TDOMElement;
  324. begin
  325. TypeEl := Doc.CreateElement('range');
  326. TypeEl['name'] := UTF8Decode(AType.Name);
  327. TypeEl['start'] := UTF8Decode(AType.RangeStart);
  328. TypeEl['end'] := UTF8Decode(AType.RangeEnd);
  329. AddSourceInfo(AType,TypeEl);
  330. Element.AppendChild(TypeEl);
  331. end;
  332. procedure ProcessClassType(AClass: TPasClassType; Element: TDOMElement); forward;
  333. function ProcessType(AType: TPasElement; Element: TDOMElement): Boolean;
  334. begin
  335. Result := True;
  336. if AType.ClassType = TPasVariable then
  337. ProcessVariable(TPasVariable(AType), Element)
  338. else if AType.ClassType = TPasProperty then
  339. ProcessProperty(TPasProperty(AType), Element)
  340. else if AType.InheritsFrom(TPasOverloadedProc) then
  341. ProcessOverloadedProcedure(TPasOverloadedProc(AType), Element)
  342. else if AType.InheritsFrom(TPasConst) then
  343. ProcessConst(TPasConst(AType), Element)
  344. else if AType.InheritsFrom(TPasEnumType) then
  345. ProcessEnumType(TPasEnumType(AType), Element)
  346. else if AType.InheritsFrom(TPasClassType) then
  347. ProcessClassType(TPasClassType(AType), Element)
  348. else if AType.InheritsFrom(TPasAliasType) then
  349. ProcessAliasType(TPasAliasType(AType), Element)
  350. else if AType.InheritsFrom(TPasSetType) then
  351. ProcessSetType(TPasSetType(AType), Element)
  352. else if AType.InheritsFrom(TPasProcedureType) then
  353. ProcessProcedureType(TPasProcedureType(AType), Element)
  354. else if AType.InheritsFrom(TPasRecordType) then
  355. ProcessRecordType(TPasRecordType(AType), Element)
  356. else if AType.InheritsFrom(TPasArrayType) then
  357. ProcessArrayType(TPasArrayType(AType), Element)
  358. else if AType.InheritsFrom(TPasPointerType) then
  359. ProcessPointerType(TPasPointerType(AType), Element)
  360. else if AType.InheritsFrom(TPasRangeType) then
  361. ProcessRangeType(TPasRangeType(AType), Element)
  362. else
  363. Result := False;
  364. end;
  365. procedure ProcessClassType(AClass: TPasClassType; Element: TDOMElement);
  366. var
  367. ClassEl: TDOMElement = nil;
  368. i: Integer;
  369. Decl: TPasElement;
  370. SubNode: TDomElement;
  371. InterfaceEl: TDomElement;
  372. Vis: TPasMemberVisibilities = DefaultVisibility;
  373. begin
  374. if not Engine.HidePrivate then Include(Vis, visPrivate);
  375. if Engine.HideProtected then Exclude(Vis, visProtected);
  376. case AClass.ObjKind of
  377. okClass: ClassEl := Result.CreateElement('class');
  378. okObject: ClassEl := Result.CreateElement('object');
  379. okInterface: ClassEl := Result.CreateElement('interface');
  380. //okGeneric: Result.CreateElement('generic');
  381. //okClassHelper: Result.CreateElement('classhelper');
  382. //okRecordHelper: Result.CreateElement('recordhelper');
  383. //okTypeHelper: Result.CreateElement('typehelper');
  384. else
  385. //raise Exception.Create('ProcessClass: unknown class kind');
  386. WriteLn('Unhandled Class kind: ', AClass.ObjKind);
  387. end;
  388. if Assigned(ClassEl) then
  389. begin
  390. Element.AppendChild(ClassEl);
  391. ClassEl['name'] := UTF8Decode(AClass.Name);
  392. if Assigned(AClass.AncestorType) then
  393. ClassEl['parentclass'] := UTF8Decode(AClass.AncestorType.Name);
  394. AddSourceInfo(AClass,ClassEl);
  395. if Assigned(AClass.Interfaces) then
  396. for i := 0 to AClass.Interfaces.Count-1 do
  397. begin
  398. InterfaceEl := Doc.CreateElement('interface');
  399. ClassEl.AppendChild(InterfaceEl);
  400. InterfaceEl['name'] := UTF8Decode(TPasElement(AClass.Interfaces.Items[i]).Name);
  401. end;
  402. if Assigned(AClass.Members) then
  403. for i := 0 to AClass.Members.Count - 1 do
  404. begin
  405. Decl := TPasElement(AClass.Members[i]);
  406. if not (Decl.Visibility in Vis) then
  407. continue;
  408. if Decl.InheritsFrom(TPasProcedure)then
  409. begin
  410. SubNode := ProcessProcedure(TPasProcedure(Decl), ClassEl);
  411. if Assigned(SubNode) then
  412. begin
  413. if SubNode.InheritsFrom(TPasClassConstructor) then
  414. SubNode.SetAttribute('type', 'constructor')
  415. else if SubNode.InheritsFrom(TPasClassDestructor) then
  416. SubNode.SetAttribute('type', 'destructor');
  417. end;
  418. end
  419. else if not ProcessType(Decl, ClassEl) then
  420. writeln('Unhandled class member: ', Decl.ClassName, ' ', Decl.Name);
  421. end;
  422. end;
  423. end;
  424. function FindInList(AName: String; AList: TFPList): Boolean;
  425. var
  426. El: TPasElement;
  427. I: Integer;
  428. begin
  429. Result := False;
  430. I := 0;
  431. while not Result and (I < AList.Count) do
  432. begin
  433. El := TPasElement(AList[I]);
  434. if El.Name = AName then
  435. Result := True;
  436. Inc(I);
  437. end;
  438. end;
  439. procedure ProcessSection(ASection: TPasSection; const Name: DOMString);
  440. var
  441. Element, UsesElement, UnitElement: TDOMElement;
  442. i: Integer;
  443. Decl: TPasElement;
  444. begin
  445. Element := Result.CreateElement(Name);
  446. ModuleElement.AppendChild(Element);
  447. if ASection.UsesList.Count > 0 then
  448. begin
  449. UsesElement := Result.CreateElement('uses');
  450. Element.AppendChild(UsesElement);
  451. for i := 0 to ASection.UsesList.Count - 1 do
  452. begin
  453. UnitElement := Result.CreateElement('unit-ref');
  454. UnitElement['name'] := UTF8Decode(TPasType(ASection.UsesList[i]).Name);
  455. UsesElement.AppendChild(UnitElement);
  456. end;
  457. end;
  458. for i := 0 to ASection.Classes.Count -1 do
  459. begin
  460. Decl := TPasElement(ASection.Classes[i]);
  461. ProcessClassType(TPasClassType(Decl), Element);
  462. end;
  463. for i := 0 to ASection.Consts.Count - 1 do
  464. begin
  465. Decl := TPasElement(ASection.Consts[i]);
  466. ProcessConst(TPasConst(Decl), Element)
  467. end;
  468. for i := 0 to ASection.Types.Count - 1 do
  469. begin
  470. Decl := TPasElement(ASection.Types[i]);
  471. if not ProcessType(Decl, Element) then
  472. WriteLn('Unhandled type: ',Decl.ClassName, ' ', Decl.Name);
  473. end;
  474. for i := 0 to ASection.Declarations.Count - 1 do
  475. begin
  476. Decl := TPasElement(ASection.Declarations[i]);
  477. if Decl.InheritsFrom(TPasProcedure) then
  478. ProcessProcedure(TPasProcedure(Decl), Element)
  479. else if Decl.ClassType = TPasVariable then
  480. ProcessVariable(TPasVariable(Decl), Element);
  481. end;
  482. for i := 0 to ASection.Functions.Count - 1 do
  483. begin
  484. // many of these (all?) seem to be in ASection.Declarations
  485. Decl := TPasElement(ASection.Functions[i]);
  486. if FindInList(Decl.Name, ASection.Declarations) then
  487. WriteLn('Duplicate proc definition in declarations. Skipping: ', Decl.Name)
  488. else
  489. WriteLn('Unhandled function: ',Decl.ClassName, ' ', Decl.Name);
  490. end;
  491. for i := 0 to ASection.Properties.Count - 1 do
  492. begin
  493. Decl := TPasElement(ASection.Properties[i]);
  494. ProcessProperty(TPasProperty(Decl), Element);
  495. end;
  496. end;
  497. begin
  498. Result := TXMLDocument.Create;
  499. Result.AppendChild(Result.CreateComment(UTF8Decode(SDocGeneratedByComment)));
  500. Result.AppendChild(Result.CreateElement('fp-refdoc'));
  501. ModuleElement := Result.CreateElement('unit');
  502. ModuleElement['name'] := UTF8Decode(AModule.Name);
  503. Result.DocumentElement.AppendChild(ModuleElement);
  504. ProcessSection(AModule.InterfaceSection, 'interface');
  505. end;
  506. { TXMLWriter }
  507. procedure TXMLWriter.WriteDoc;
  508. var
  509. doc: TXMLDocument;
  510. i: Integer;
  511. begin
  512. if Engine.Output <> '' then
  513. Engine.Output := IncludeTrailingBackSlash(Engine.Output);
  514. for i := 0 to Package.Modules.Count - 1 do
  515. begin
  516. doc := ModuleToXMLStruct(TPasModule(Package.Modules[i]));
  517. WriteXMLFile(doc, Engine.Output + TPasModule(Package.Modules[i]).Name + '.xml' );
  518. doc.Free;
  519. end;
  520. end;
  521. class procedure TXMLWriter.Usage(List: TStrings);
  522. begin
  523. List.AddStrings(['--source-info', SXMLUsageSource]);
  524. end;
  525. function TXMLWriter.InterPretOption(const Cmd, Arg: String): boolean;
  526. begin
  527. Result := True;
  528. if Cmd = '--source-info' then
  529. FShowSourceInfo:=True
  530. else
  531. Result:=inherited InterPretOption(Cmd, Arg);
  532. end;
  533. initialization
  534. // Do not localize.
  535. RegisterWriter(TXMLWriter,'xml','fpdoc XML output.');
  536. finalization
  537. UnRegisterWriter('xml');
  538. end.