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