doxygen.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. ## @file
  2. #
  3. # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
  4. #
  5. # SPDX-License-Identifier: BSD-2-Clause-Patent
  6. #
  7. from __future__ import print_function
  8. from __future__ import absolute_import
  9. import os
  10. from .message import *
  11. class BaseDoxygeItem:
  12. def __init__(self, name, tag=''):
  13. self.mName = name
  14. self.mTag = tag
  15. self.mDescription = ''
  16. self.mText = []
  17. def AddDescription(self, desc):
  18. self.mDescription = '%s%s' % (self.mDescription, desc)
  19. def __str__(self):
  20. return '\n'.join(self.mText)
  21. def Generate(self):
  22. """This interface need to be override"""
  23. class Section(BaseDoxygeItem):
  24. def Generate(self):
  25. """This interface need to be override"""
  26. if len(self.mTag) != 0:
  27. self.mText.append(' \section %s %s' % (self.mName, self.mTag))
  28. else:
  29. self.mText.append(' \section %s' % self.mName)
  30. self.mText.append(self.mDescription)
  31. return self.mText
  32. class Page(BaseDoxygeItem):
  33. def __init__(self, name, tag=None, isSort=True):
  34. BaseDoxygeItem.__init__(self, name, tag)
  35. self.mSubPages = []
  36. self.mIsMainPage = False
  37. self.mSections = []
  38. self.mIsSort = isSort
  39. def GetSubpageCount(self):
  40. return len(self.mSubPages)
  41. def AddPage(self, subpage):
  42. self.mSubPages.append(subpage)
  43. return subpage
  44. def AddPages(self, pageArray):
  45. if pageArray is None:
  46. return
  47. for page in pageArray:
  48. self.AddPage(page)
  49. def AddSection(self, section):
  50. self.mSections.append(section)
  51. self.mSections.sort(key=lambda x: x.mName.lower())
  52. def Generate(self):
  53. if self.mIsMainPage:
  54. self.mText.append('/** \mainpage %s' % self.mName)
  55. self.mIsSort = False
  56. else:
  57. self.mText.append('/** \page %s %s' % (self.mTag, self.mName))
  58. if len(self.mDescription) != 0:
  59. self.mText.append(self.mDescription)
  60. endIndex = len(self.mText)
  61. self.mSections.sort(key=lambda x: x.mName.lower())
  62. for sect in self.mSections:
  63. self.mText += sect.Generate()
  64. endIndex = len(self.mText)
  65. if len(self.mSubPages) != 0:
  66. self.mText.insert(endIndex, "<p> \section content_index INDEX")
  67. endIndex = len(self.mText)
  68. self.mText.insert(endIndex, '<ul>')
  69. endIndex += 1
  70. if self.mIsSort:
  71. self.mSubPages.sort(key=lambda x: x.mName.lower())
  72. for page in self.mSubPages:
  73. self.mText.insert(endIndex, '<li>\subpage %s \"%s\" </li>' % (page.mTag, page.mName))
  74. endIndex += 1
  75. self.mText += page.Generate()
  76. self.mText.insert(endIndex, '</ul>')
  77. endIndex += 1
  78. self.mText.insert(endIndex, ' **/')
  79. return self.mText
  80. class DoxygenFile(Page):
  81. def __init__(self, name, file):
  82. Page.__init__(self, name)
  83. self.mFilename = file
  84. self.mIsMainPage = True
  85. def GetFilename(self):
  86. return self.mFilename.replace('/', '\\')
  87. def Save(self):
  88. str = self.Generate()
  89. try:
  90. f = open(self.mFilename, 'w')
  91. f.write('\n'.join(str))
  92. f.close()
  93. except IOError as e:
  94. ErrorMsg ('Fail to write file %s' % self.mFilename)
  95. return False
  96. return True
  97. doxygenConfigTemplate = """
  98. DOXYFILE_ENCODING = UTF-8
  99. PROJECT_NAME = %(ProjectName)s
  100. PROJECT_NUMBER = %(ProjectVersion)s
  101. OUTPUT_DIRECTORY = %(OutputDir)s
  102. CREATE_SUBDIRS = YES
  103. OUTPUT_LANGUAGE = English
  104. BRIEF_MEMBER_DESC = YES
  105. REPEAT_BRIEF = YES
  106. ABBREVIATE_BRIEF = "The $name class " \\
  107. "The $name widget " \\
  108. "The $name file " \\
  109. is \\
  110. provides \\
  111. specifies \\
  112. contains \\
  113. represents \\
  114. a \\
  115. an \\
  116. the
  117. ALWAYS_DETAILED_SEC = NO
  118. INLINE_INHERITED_MEMB = NO
  119. FULL_PATH_NAMES = YES
  120. STRIP_FROM_PATH = %(StripPath)s
  121. STRIP_FROM_INC_PATH =
  122. SHORT_NAMES = YES
  123. JAVADOC_AUTOBRIEF = NO
  124. QT_AUTOBRIEF = NO
  125. MULTILINE_CPP_IS_BRIEF = NO
  126. DETAILS_AT_TOP = YES
  127. INHERIT_DOCS = YES
  128. SEPARATE_MEMBER_PAGES = NO
  129. TAB_SIZE = 1
  130. ALIASES =
  131. OPTIMIZE_OUTPUT_FOR_C = YES
  132. OPTIMIZE_OUTPUT_JAVA = NO
  133. BUILTIN_STL_SUPPORT = NO
  134. CPP_CLI_SUPPORT = NO
  135. SIP_SUPPORT = NO
  136. DISTRIBUTE_GROUP_DOC = YES
  137. SUBGROUPING = YES
  138. TYPEDEF_HIDES_STRUCT = NO
  139. EXTRACT_ALL = YES
  140. EXTRACT_PRIVATE = NO
  141. EXTRACT_STATIC = NO
  142. EXTRACT_LOCAL_CLASSES = NO
  143. EXTRACT_LOCAL_METHODS = NO
  144. EXTRACT_ANON_NSPACES = NO
  145. HIDE_UNDOC_MEMBERS = NO
  146. HIDE_UNDOC_CLASSES = NO
  147. HIDE_FRIEND_COMPOUNDS = NO
  148. HIDE_IN_BODY_DOCS = NO
  149. INTERNAL_DOCS = NO
  150. CASE_SENSE_NAMES = NO
  151. HIDE_SCOPE_NAMES = NO
  152. SHOW_INCLUDE_FILES = NO
  153. INLINE_INFO = YES
  154. SORT_MEMBER_DOCS = YES
  155. SORT_BRIEF_DOCS = NO
  156. SORT_BY_SCOPE_NAME = YES
  157. GENERATE_TODOLIST = YES
  158. GENERATE_TESTLIST = YES
  159. GENERATE_BUGLIST = YES
  160. GENERATE_DEPRECATEDLIST= YES
  161. ENABLED_SECTIONS =
  162. MAX_INITIALIZER_LINES = 30
  163. SHOW_USED_FILES = NO
  164. SHOW_DIRECTORIES = NO
  165. FILE_VERSION_FILTER =
  166. QUIET = NO
  167. WARNINGS = YES
  168. WARN_IF_UNDOCUMENTED = YES
  169. WARN_IF_DOC_ERROR = YES
  170. WARN_NO_PARAMDOC = YES
  171. WARN_FORMAT = "$file:$line: $text "
  172. WARN_LOGFILE = %(WarningFile)s
  173. INPUT = %(FileList)s
  174. INPUT_ENCODING = UTF-8
  175. FILE_PATTERNS = %(Pattern)s
  176. RECURSIVE = NO
  177. EXCLUDE = *.svn
  178. EXCLUDE_SYMLINKS = NO
  179. EXCLUDE_PATTERNS = .svn
  180. EXCLUDE_SYMBOLS =
  181. EXAMPLE_PATH = %(ExamplePath)s
  182. EXAMPLE_PATTERNS = *
  183. EXAMPLE_RECURSIVE = NO
  184. IMAGE_PATH =
  185. INPUT_FILTER =
  186. FILTER_PATTERNS =
  187. FILTER_SOURCE_FILES = NO
  188. SOURCE_BROWSER = NO
  189. INLINE_SOURCES = NO
  190. STRIP_CODE_COMMENTS = YES
  191. REFERENCED_BY_RELATION = YES
  192. REFERENCES_RELATION = YES
  193. REFERENCES_LINK_SOURCE = NO
  194. USE_HTAGS = NO
  195. VERBATIM_HEADERS = NO
  196. ALPHABETICAL_INDEX = NO
  197. COLS_IN_ALPHA_INDEX = 5
  198. IGNORE_PREFIX =
  199. GENERATE_HTML = YES
  200. HTML_OUTPUT = html
  201. HTML_FILE_EXTENSION = .html
  202. HTML_HEADER =
  203. HTML_FOOTER =
  204. HTML_STYLESHEET =
  205. HTML_ALIGN_MEMBERS = YES
  206. GENERATE_HTMLHELP = %(WhetherGenerateHtmlHelp)s
  207. HTML_DYNAMIC_SECTIONS = NO
  208. CHM_FILE = index.chm
  209. HHC_LOCATION =
  210. GENERATE_CHI = NO
  211. BINARY_TOC = NO
  212. TOC_EXPAND = NO
  213. DISABLE_INDEX = NO
  214. ENUM_VALUES_PER_LINE = 4
  215. GENERATE_TREEVIEW = %(WhetherGenerateTreeView)s
  216. TREEVIEW_WIDTH = 250
  217. GENERATE_LATEX = NO
  218. LATEX_OUTPUT = latex
  219. LATEX_CMD_NAME = latex
  220. MAKEINDEX_CMD_NAME = makeindex
  221. COMPACT_LATEX = NO
  222. PAPER_TYPE = a4wide
  223. EXTRA_PACKAGES =
  224. LATEX_HEADER =
  225. PDF_HYPERLINKS = YES
  226. USE_PDFLATEX = YES
  227. LATEX_BATCHMODE = NO
  228. LATEX_HIDE_INDICES = NO
  229. GENERATE_RTF = NO
  230. RTF_OUTPUT = rtf
  231. COMPACT_RTF = NO
  232. RTF_HYPERLINKS = NO
  233. RTF_STYLESHEET_FILE =
  234. RTF_EXTENSIONS_FILE =
  235. GENERATE_MAN = NO
  236. MAN_OUTPUT = man
  237. MAN_EXTENSION = .3
  238. MAN_LINKS = NO
  239. GENERATE_XML = NO
  240. XML_OUTPUT = xml
  241. XML_SCHEMA =
  242. XML_DTD =
  243. XML_PROGRAMLISTING = YES
  244. GENERATE_AUTOGEN_DEF = NO
  245. GENERATE_PERLMOD = NO
  246. PERLMOD_LATEX = NO
  247. PERLMOD_PRETTY = YES
  248. PERLMOD_MAKEVAR_PREFIX =
  249. ENABLE_PREPROCESSING = YES
  250. MACRO_EXPANSION = YES
  251. EXPAND_ONLY_PREDEF = YES
  252. SEARCH_INCLUDES = YES
  253. INCLUDE_PATH = %(IncludePath)s
  254. INCLUDE_FILE_PATTERNS = *.h
  255. PREDEFINED = %(PreDefined)s
  256. EXPAND_AS_DEFINED =
  257. SKIP_FUNCTION_MACROS = NO
  258. TAGFILES =
  259. GENERATE_TAGFILE =
  260. ALLEXTERNALS = NO
  261. EXTERNAL_GROUPS = YES
  262. PERL_PATH = /usr/bin/perl
  263. CLASS_DIAGRAMS = NO
  264. MSCGEN_PATH =
  265. HIDE_UNDOC_RELATIONS = YES
  266. HAVE_DOT = NO
  267. CLASS_GRAPH = YES
  268. COLLABORATION_GRAPH = YES
  269. GROUP_GRAPHS = YES
  270. UML_LOOK = NO
  271. TEMPLATE_RELATIONS = NO
  272. INCLUDE_GRAPH = YES
  273. INCLUDED_BY_GRAPH = YES
  274. CALL_GRAPH = NO
  275. CALLER_GRAPH = NO
  276. GRAPHICAL_HIERARCHY = YES
  277. DIRECTORY_GRAPH = YES
  278. DOT_IMAGE_FORMAT = png
  279. DOT_PATH =
  280. DOTFILE_DIRS =
  281. DOT_GRAPH_MAX_NODES = 50
  282. MAX_DOT_GRAPH_DEPTH = 1000
  283. DOT_TRANSPARENT = YES
  284. DOT_MULTI_TARGETS = NO
  285. GENERATE_LEGEND = YES
  286. DOT_CLEANUP = YES
  287. SEARCHENGINE = NO
  288. """
  289. class DoxygenConfigFile:
  290. def __init__(self):
  291. self.mProjectName = ''
  292. self.mOutputDir = ''
  293. self.mFileList = []
  294. self.mIncludeList = []
  295. self.mStripPath = ''
  296. self.mExamplePath = ''
  297. self.mPattern = ['*.c', '*.h',
  298. '*.asm', '*.s', '.nasm', '*.html', '*.dox']
  299. self.mMode = 'HTML'
  300. self.mWarningFile = ''
  301. self.mPreDefined = []
  302. self.mProjectVersion = 0.1
  303. def SetChmMode(self):
  304. self.mMode = 'CHM'
  305. def SetHtmlMode(self):
  306. self.mMode = 'HTML'
  307. def SetProjectName(self, str):
  308. self.mProjectName = str
  309. def SetProjectVersion(self, str):
  310. self.mProjectVersion = str
  311. def SetOutputDir(self, str):
  312. self.mOutputDir = str
  313. def SetStripPath(self, str):
  314. self.mStripPath = str
  315. def SetExamplePath(self, str):
  316. self.mExamplePath = str
  317. def SetWarningFilePath(self, str):
  318. self.mWarningFile = str.replace('\\', '/')
  319. def FileExists(self, path):
  320. if path is None:
  321. return False
  322. if len(path) == 0:
  323. return False
  324. for p in self.mFileList:
  325. if path.lower() == p.lower():
  326. return True
  327. return False
  328. def AddFile(self, path):
  329. if path is None:
  330. return
  331. if len(path) == 0:
  332. return
  333. path = path.replace('\\', '/')
  334. if not self.FileExists(path):
  335. self.mFileList.append(path)
  336. def AddIncludePath(self, path):
  337. path = path.replace('\\', '/')
  338. if path not in self.mIncludeList:
  339. self.mIncludeList.append(path)
  340. def AddPattern(self, pattern):
  341. self.mPattern.append(pattern)
  342. def AddPreDefined(self, macro):
  343. self.mPreDefined.append(macro)
  344. def Generate(self, path):
  345. files = ' \\\n'.join(self.mFileList)
  346. includes = ' \\\n'.join(self.mIncludeList)
  347. patterns = ' \\\n'.join(self.mPattern)
  348. if self.mMode.lower() == 'html':
  349. sHtmlHelp = 'NO'
  350. sTreeView = 'YES'
  351. else:
  352. sHtmlHelp = 'YES'
  353. sTreeView = 'NO'
  354. text = doxygenConfigTemplate % {'ProjectName':self.mProjectName,
  355. 'OutputDir':self.mOutputDir,
  356. 'StripPath':self.mStripPath,
  357. 'ExamplePath':self.mExamplePath,
  358. 'FileList':files,
  359. 'Pattern':patterns,
  360. 'WhetherGenerateHtmlHelp':sHtmlHelp,
  361. 'WhetherGenerateTreeView':sTreeView,
  362. 'IncludePath':includes,
  363. 'WarningFile':self.mWarningFile,
  364. 'PreDefined':' '.join(self.mPreDefined),
  365. 'ProjectVersion':self.mProjectVersion}
  366. try:
  367. f = open(path, 'w')
  368. f.write(text)
  369. f.close()
  370. except IOError as e:
  371. ErrorMsg ('Fail to generate doxygen config file %s' % path)
  372. return False
  373. return True
  374. ########################################################################
  375. # TEST CODE
  376. ########################################################################
  377. if __name__== '__main__':
  378. df = DoxygenFile('Platform Document', 'm:\tree')
  379. df.AddPage(Page('Module', 'module'))
  380. p = df.AddPage(Page('Library', 'library'))
  381. p.AddDescription(desc)
  382. p.AddPage(Page('PCD', 'pcds'))
  383. df.Generate()
  384. print(df)