1from __future__ import unicode_literals 2 3from breathe.project import ProjectInfoFactory 4 5try: 6 from shlex import quote # py3 7except ImportError: 8 from pipes import quote # py2 9 10import os 11 12 13AUTOCFG_TEMPLATE = r""" 14PROJECT_NAME = "{project_name}" 15OUTPUT_DIRECTORY = {output_dir} 16GENERATE_LATEX = NO 17GENERATE_MAN = NO 18GENERATE_RTF = NO 19CASE_SENSE_NAMES = NO 20INPUT = {input} 21ENABLE_PREPROCESSING = YES 22QUIET = YES 23JAVADOC_AUTOBRIEF = YES 24JAVADOC_AUTOBRIEF = NO 25GENERATE_HTML = NO 26GENERATE_XML = YES 27ALIASES = "rst=\verbatim embed:rst" 28ALIASES += "endrst=\endverbatim" 29ALIASES += "inlinerst=\verbatim embed:rst:inline" 30{extra} 31""".strip() 32 33 34class ProjectData(object): 35 "Simple handler for the files and project_info for each project" 36 37 def __init__(self, auto_project_info, files): 38 39 self.auto_project_info = auto_project_info 40 self.files = files 41 42 43class AutoDoxygenProcessHandle: 44 def __init__(self, run_process, write_file, project_info_factory: ProjectInfoFactory): 45 self.run_process = run_process 46 self.write_file = write_file 47 self.project_info_factory = project_info_factory 48 49 def generate_xml(self, projects_source, doxygen_options): 50 51 project_files = {} 52 53 # First collect together all the files which need to be doxygen processed for each project 54 for project_name, file_structure in projects_source.items(): 55 56 folder = file_structure[0] 57 contents = file_structure[1] 58 59 auto_project_info = self.project_info_factory.create_auto_project_info( 60 project_name, folder) 61 62 project_files[project_name] = ProjectData(auto_project_info, contents) 63 64 # Iterate over the projects and generate doxygen xml output for the files for each one into 65 # a directory in the Sphinx build area 66 for project_name, data in project_files.items(): 67 68 project_path = self.process(data.auto_project_info, data.files, doxygen_options) 69 70 project_info = data.auto_project_info.create_project_info(project_path) 71 72 self.project_info_factory.store_project_info_for_auto(project_name, project_info) 73 74 def process(self, auto_project_info, files, doxygen_options): 75 76 name = auto_project_info.name() 77 cfgfile = "%s.cfg" % name 78 79 full_paths = map(lambda x: auto_project_info.abs_path_to_source_file(x), files) 80 81 cfg = AUTOCFG_TEMPLATE.format( 82 project_name=name, 83 output_dir=name, 84 input=" ".join(full_paths), 85 extra='\n'.join("%s=%s" % pair for pair in doxygen_options.items()) 86 ) 87 88 build_dir = os.path.join( 89 auto_project_info.build_dir(), 90 "breathe", 91 "doxygen" 92 ) 93 94 self.write_file(build_dir, cfgfile, cfg) 95 96 # Shell-escape the cfg file name to try to avoid any issue where the name might include 97 # malicious shell character - We have to use the shell=True option to make it work on 98 # Windows. See issue #271 99 self.run_process('doxygen %s' % quote(cfgfile), cwd=build_dir, shell=True) 100 101 return os.path.join(build_dir, name, "xml") 102