adding the breathe files
This commit is contained in:
306
doc/breathe/project.py
Normal file
306
doc/breathe/project.py
Normal file
@@ -0,0 +1,306 @@
|
||||
|
||||
from .exception import BreatheError
|
||||
|
||||
import os
|
||||
|
||||
|
||||
class ProjectError(BreatheError):
|
||||
pass
|
||||
|
||||
|
||||
class NoDefaultProjectError(ProjectError):
|
||||
pass
|
||||
|
||||
|
||||
class AutoProjectInfo(object):
|
||||
"""Created as a temporary step in the automatic xml generation process"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
source_path,
|
||||
build_dir,
|
||||
reference,
|
||||
source_dir,
|
||||
config_dir,
|
||||
domain_by_extension,
|
||||
domain_by_file_pattern,
|
||||
match
|
||||
):
|
||||
|
||||
self._name = name
|
||||
self._source_path = source_path
|
||||
self._build_dir = build_dir
|
||||
self._reference = reference
|
||||
self._source_dir = source_dir
|
||||
self._config_dir = config_dir
|
||||
self._domain_by_extension = domain_by_extension
|
||||
self._domain_by_file_pattern = domain_by_file_pattern
|
||||
self._match = match
|
||||
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
def build_dir(self):
|
||||
return self._build_dir
|
||||
|
||||
def abs_path_to_source_file(self, file_):
|
||||
"""
|
||||
Returns full path to the provide file assuming that the provided path is relative to the
|
||||
projects conf.py directory as specified in the breathe_projects_source config variable.
|
||||
"""
|
||||
|
||||
# os.path.join does the appropriate handling if _source_path is an absolute path
|
||||
return os.path.join(self._config_dir, self._source_path, file_)
|
||||
|
||||
def create_project_info(self, project_path):
|
||||
"""Creates a proper ProjectInfo object based on the information in this AutoProjectInfo"""
|
||||
|
||||
return ProjectInfo(
|
||||
self._name,
|
||||
project_path,
|
||||
self._source_path,
|
||||
self._reference,
|
||||
self._source_dir,
|
||||
self._config_dir,
|
||||
self._domain_by_extension,
|
||||
self._domain_by_file_pattern,
|
||||
self._match
|
||||
)
|
||||
|
||||
|
||||
class ProjectInfo(object):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
path,
|
||||
source_path,
|
||||
reference,
|
||||
source_dir,
|
||||
config_dir,
|
||||
domain_by_extension,
|
||||
domain_by_file_pattern,
|
||||
match
|
||||
):
|
||||
|
||||
self._name = name
|
||||
self._project_path = path
|
||||
self._source_path = source_path
|
||||
self._reference = reference
|
||||
self._source_dir = source_dir
|
||||
self._config_dir = config_dir
|
||||
self._domain_by_extension = domain_by_extension
|
||||
self._domain_by_file_pattern = domain_by_file_pattern
|
||||
self._match = match
|
||||
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
def project_path(self):
|
||||
return self._project_path
|
||||
|
||||
def source_path(self):
|
||||
return self._source_path
|
||||
|
||||
def relative_path_to_xml_file(self, file_):
|
||||
"""
|
||||
Returns relative path from Sphinx documentation top-level source directory to the specified
|
||||
file assuming that the specified file is a path relative to the doxygen xml output
|
||||
directory.
|
||||
"""
|
||||
|
||||
# os.path.join does the appropriate handling if _project_path is an absolute path
|
||||
full_xml_project_path = os.path.join(self._config_dir, self._project_path, file_)
|
||||
|
||||
return os.path.relpath(
|
||||
full_xml_project_path,
|
||||
self._source_dir
|
||||
)
|
||||
|
||||
def sphinx_abs_path_to_file(self, file_):
|
||||
"""
|
||||
Prepends os.path.sep to the value returned by relative_path_to_file.
|
||||
|
||||
This is to match Sphinx's concept of an absolute path which starts from the top-level source
|
||||
directory of the project.
|
||||
"""
|
||||
return os.path.sep + self.relative_path_to_xml_file(file_)
|
||||
|
||||
def reference(self):
|
||||
return self._reference
|
||||
|
||||
def domain_for_file(self, file_):
|
||||
|
||||
domain = ""
|
||||
extension = file_.split(".")[-1]
|
||||
|
||||
try:
|
||||
domain = self._domain_by_extension[extension]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
for pattern, pattern_domain in self._domain_by_file_pattern.items():
|
||||
if self._match(file_, pattern):
|
||||
domain = pattern_domain
|
||||
|
||||
return domain
|
||||
|
||||
|
||||
class ProjectInfoFactory(object):
|
||||
|
||||
def __init__(self, source_dir, build_dir, config_dir, match):
|
||||
|
||||
self.source_dir = source_dir
|
||||
self.build_dir = build_dir
|
||||
self.config_dir = config_dir
|
||||
self.match = match
|
||||
|
||||
self.projects = {}
|
||||
self.default_project = None
|
||||
self.domain_by_extension = {}
|
||||
self.domain_by_file_pattern = {}
|
||||
|
||||
self.project_count = 0
|
||||
self.project_info_store = {}
|
||||
self.project_info_for_auto_store = {}
|
||||
self.auto_project_info_store = {}
|
||||
|
||||
def update(
|
||||
self,
|
||||
projects,
|
||||
default_project,
|
||||
domain_by_extension,
|
||||
domain_by_file_pattern,
|
||||
projects_source,
|
||||
build_dir
|
||||
):
|
||||
|
||||
self.projects = projects
|
||||
self.default_project = default_project
|
||||
self.domain_by_extension = domain_by_extension
|
||||
self.domain_by_file_pattern = domain_by_file_pattern
|
||||
self.projects_source = projects_source
|
||||
|
||||
# If the breathe config values has a non-empty value for build_dir then use that otherwise
|
||||
# stick with the default
|
||||
if build_dir:
|
||||
self.build_dir = build_dir
|
||||
|
||||
def default_path(self):
|
||||
|
||||
if not self.default_project:
|
||||
raise NoDefaultProjectError(
|
||||
"No breathe_default_project config setting to fall back on "
|
||||
"for directive with no 'project' or 'path' specified."
|
||||
)
|
||||
|
||||
try:
|
||||
return self.projects[self.default_project]
|
||||
except KeyError:
|
||||
raise ProjectError(
|
||||
("breathe_default_project value '%s' does not seem to be a valid key for the "
|
||||
"breathe_projects dictionary") % self.default_project
|
||||
)
|
||||
|
||||
def create_project_info(self, options):
|
||||
|
||||
name = ""
|
||||
|
||||
if "project" in options:
|
||||
try:
|
||||
path = self.projects[options["project"]]
|
||||
name = options["project"]
|
||||
except KeyError:
|
||||
raise ProjectError("Unable to find project '%s' in breathe_projects dictionary"
|
||||
% options["project"])
|
||||
|
||||
elif "path" in options:
|
||||
path = options["path"]
|
||||
|
||||
else:
|
||||
path = self.default_path()
|
||||
|
||||
try:
|
||||
return self.project_info_store[path]
|
||||
except KeyError:
|
||||
|
||||
reference = name
|
||||
|
||||
if not name:
|
||||
name = "project%s" % self.project_count
|
||||
reference = path
|
||||
self.project_count += 1
|
||||
|
||||
project_info = ProjectInfo(
|
||||
name,
|
||||
path,
|
||||
"NoSourcePath",
|
||||
reference,
|
||||
self.source_dir,
|
||||
self.config_dir,
|
||||
self.domain_by_extension,
|
||||
self.domain_by_file_pattern,
|
||||
self.match
|
||||
)
|
||||
|
||||
self.project_info_store[path] = project_info
|
||||
|
||||
return project_info
|
||||
|
||||
def store_project_info_for_auto(self, name, project_info):
|
||||
"""Stores the project info by name for later extraction by the auto directives.
|
||||
|
||||
Stored separately to the non-auto project info objects as they should never overlap.
|
||||
"""
|
||||
|
||||
self.project_info_for_auto_store[name] = project_info
|
||||
|
||||
def retrieve_project_info_for_auto(self, options):
|
||||
"""Retrieves the project info by name for later extraction by the auto directives.
|
||||
|
||||
Looks for the 'project' entry in the options dictionary. This is a less than ideal API but
|
||||
it is designed to match the use of 'create_project_info' above for which it makes much more
|
||||
sense.
|
||||
"""
|
||||
|
||||
name = options.get('project', self.default_project)
|
||||
|
||||
if name is None:
|
||||
raise NoDefaultProjectError(
|
||||
"No breathe_default_project config setting to fall back on "
|
||||
"for directive with no 'project' or 'path' specified."
|
||||
)
|
||||
|
||||
return self.project_info_for_auto_store[name]
|
||||
|
||||
def create_auto_project_info(self, name, source_path):
|
||||
|
||||
key = source_path
|
||||
|
||||
try:
|
||||
return self.auto_project_info_store[key]
|
||||
except KeyError:
|
||||
|
||||
reference = name
|
||||
|
||||
if not name:
|
||||
name = "project%s" % self.project_count
|
||||
reference = source_path
|
||||
self.project_count += 1
|
||||
|
||||
auto_project_info = AutoProjectInfo(
|
||||
name,
|
||||
source_path,
|
||||
self.build_dir,
|
||||
reference,
|
||||
self.source_dir,
|
||||
self.config_dir,
|
||||
self.domain_by_extension,
|
||||
self.domain_by_file_pattern,
|
||||
self.match
|
||||
)
|
||||
|
||||
self.auto_project_info_store[key] = auto_project_info
|
||||
|
||||
return auto_project_info
|
Reference in New Issue
Block a user