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