def Configure(self, config): self.path = config.sourcePath # os.path.abspath() call prefixes the path with a drive letter. # os.path.isabs() does not check for the drive letter so cannot be used as a normalization check. self.path = os.path.abspath(self.path) self.path = os.path.normpath(self.path) sectionName = "JSONObjects" self.jsonObjectStrings = OrderedDict(config.parser.items(sectionName)) self.jsonObjects = OrderedDict() for p in self.jsonObjectStrings: try: if p in self._jsonObjectHooks: self.jsonObjects[p] = json.loads(self.jsonObjectStrings[p], object_hook=self._jsonObjectHooks[p]) else: self.jsonObjects[p] = json.loads(self.jsonObjectStrings[p]) except Exception as e: config.messagePrinter.error("The [{0}] option in the [{1}] section has an invalid JSON object!".format(p, sectionName)) config.messagePrinter.dbg("Exception message: {0}".format(e)) config.messagePrinter.error("Exiting.") sys.exit(1) self.projectList = OrderedDict() self.jsonObjects["ProjectGroupsList"] for group in self.jsonObjects["ProjectGroupsList"]: if config.sourcePath is not None: if group.pathPrefix is not None: groupPathPrefix = group.pathPrefix = toPosixPath(os.path.normpath(os.path.join(config.sourcePath, group.pathPrefix))) else: groupPathPrefix = config.sourcePath else: groupPathPrefix = None for project in group.projects: # Add the project reverse link back to group. project.groupName = group.name # Apply the group's path-prefix property to each project path. if groupPathPrefix is not None: project.path = toPosixPath(os.path.normpath(os.path.join(groupPathPrefix, project.path))) if project.includePath is not None and len(project.includePath) > 0: project.includePath = toPosixPath(os.path.normpath(os.path.join(groupPathPrefix, project.includePath))) if group.pathPrefix is not None and not os.path.isdir(group.pathPrefix): config.messagePrinter.error("The group \"{0}\" path-prefix \"{1}\" does not exist.".format(group.name, group.pathPrefix)) if not os.path.isdir(project.path): config.messagePrinter.error("The project \"{0}\" path \"{1}\" does not exist.".format(project.name, project.path)) if project.includePath is not None and not os.path.isdir(project.includePath): config.messagePrinter.error("The project \"{0}\" include-path \"{1}\" does not exist.".format(project.name, project.includePath)) # Add the project to the dictionary self.projectList[project.name] = project
def Configure(self, argv): self.args = argv self.messagePrinter = Logger() self.scriptPath, self.scriptExtension = os.path.splitext(argv[0]) self.scriptPath, self.scriptName = os.path.split(self.scriptPath) self.argparser.parse_args(args=argv[1:], namespace=self) self.messagePrinter.isDbgEnabled = self.debugMessages self.messagePrinter.isInfoEnabled = self.verbose self.messagePrinter.isErrEnabled = not self.silenceErrors if self.scriptIni is None: iniPath = '' if self.scriptPath is not None: iniPath = self.scriptPath self.scriptIni = toPosixPath(os.path.join(iniPath, '{0}.ini'.format(self.scriptName))) self.parser = configparser.ConfigParser(allow_no_value = True) # see https://docs.python.org/2/library/configparser.html self.parser.optionxform = str # make case-sensitive as per https://docs.python.org/2/library/configparser.html self.isConfigured = True if os.path.exists(self.scriptIni): self.parser.read(self.scriptIni) elif os.path.exists(os.path.join(self.scriptPath, self.scriptIni)): self.parser.read(os.path.join(self.scriptPath, self.scriptIni)) else: msg = "No configuration file found. Searched, current directory and script directory directory for {0}.".format(self.scriptIni) self.messagePrinter.error(msg) self.isConfigured = False self.databaseFilename = ':memory:' self.sourcePath = './' return try: if self.databaseFilename is None: self.databaseFilename = self.parser.get("Output", "DatabaseFilename") except: self.databaseFilename = ':memory:' try: if self.sourcePath is None: self.sourcePath = self.parser.get("Paths","SourceRoot") # Make the read SourceRoot path relative to the INI file's path. if self.isConfigured: iniPath, iniFilename = os.path.split(self.scriptIni) self.sourcePath = toPosixPath(os.path.normpath(os.path.join(iniPath, self.sourcePath))) print('source-path: {0}'.format(self.sourcePath)) except: self.sourcePath = './'
def GetIncludeFileAbsolutePath(self, absoluteFilepath, includetext, isLocalInclude = True): filepath, filename = os.path.split(absoluteFilepath) localFilePath = os.path.join(filepath, includetext) solFilePath = os.path.join(self.solutionInfo.path, includetext) if os.path.isfile(localFilePath): # This is a local include file return os.path.abspath(localFilePath) elif os.path.isfile(solFilePath): # Solution path relative include return os.path.abspath(solFilePath) else: # Try one of the projects paths potentials = [] for project in self.solutionInfo.projectList: proj = self.solutionInfo.projectList[project] if proj.includePath is not None: projFilePath = toPosixPath(os.path.join(proj.includePath, includetext)) if os.path.isfile(projFilePath): potentials.append(projFilePath) if len(potentials) == 1: return os.path.abspath(potentials[0]) elif len(potentials) > 1: self.config.messagePrinter.error('include text "{0}" in {1} matches multiple files:'.format(includetext, absoluteFilepath)) formatStr = ' {0} (selected)' for p in potentials: self.config.messagePrinter.error(formatStr.format(p)) formatStr = ' {0}' return os.path.abspath(potentials[0]) # Don't know where this file is... return None
def GetPathRelativeToSolution(self, filepath): if not os.path.isabs(filepath): filepath = os.path.abspath(filepath) filepath = os.path.normpath(filepath) filepath = os.path.relpath(filepath, self.path) return toPosixPath(filepath)
def AddFile(self, filename, project, solutionPath, exists): solutionPath = toPosixPath(solutionPath) # normpath doesn't normalize to posix slashes. try: self.cur.execute("INSERT INTO CodeFile (SolutionPath, Project, Filename) VALUES (?, ?, ?);", (solutionPath, project, filename)) except: self.cur.execute("UPDATE CodeFile SET Project = ?, Filename = ? WHERE SolutionPath = ?;", (project, filename, solutionPath)) return self.cur.lastrowid
def AddProject(self, projectName, solutionPath, hierarchyLevel): solutionPath = toPosixPath(solutionPath) # normpath doesn't normalize to posix slashes. try: self.cur.execute("INSERT INTO Project (SolutionPath, Name, HierarchyLevel) VALUES (?, ?, ?);", (solutionPath, projectName, hierarchyLevel)) except: self.cur.execute("UPDATE CodeFile SET Name = ?, HierarchyLevel = ? WHERE SolutionPath = ?;", (projectName, hierarchyLevel, solutionPath)) return self.cur.lastrowid
def AddInclude(self, solutionPath, includeText, includeType, includeFilename, includeProject, includeSolutionPath, lineNumber): solutionPath = toPosixPath(solutionPath) # normpath doesn't normalize to posix slashes. normIncludeText = toPosixPath(includeText) # normpath doesn't normalize to posix slashes. if includeSolutionPath: includeSolutionPath = toPosixPath(includeSolutionPath) # normpath doesn't normalize to posix slashes if normIncludeText != includeText: if self.errorLogger: self.errorLogger.write("Error, #include directive with non-posix path!" + includeText + " included in " + solutionPath + "\n") includeText = normIncludeText try: self.cur.execute("INSERT INTO IncludeDirective (CodeFileSolutionPath, IncludeText, IncludeType, IncludeFilename, IncludeProject, IncludeSolutionPath, LineNumber) VALUES (?, ?, ?, ?, ?, ?, ?);", (solutionPath, includeText, includeType, includeFilename, includeProject, includeSolutionPath, lineNumber)) except: if self.messagePrinter: msg = "Unknown exception for: INSERT INTO IncludeDirective (CodeFileSolutionPath, IncludeText, IncludeType, IncludeFilename, IncludeProject, IncludeSolutionPath) VALUES (" + repr(solutionPath) + "," + repr(includeText) + "," + repr(includeType) + "," + repr(includeFilename) + "," + repr(includeProject) + "," + repr(includeSolutionPath) + "," + repr(lineNumber) + ");" self.messagePrinter.info(msg) return self.cur.lastrowid
def GetProjectName(self, filepath): if not os.path.isabs(filepath): filepath = os.path.abspath(filepath) filepath = os.path.normpath(filepath) filepath = toPosixPath(filepath) # Standardise the slashes. if filepath[-1] != '/': # Ensure that the path is slash terminated otherwise we might # end up including projects which start with the same name... filepath += '/' rv = None # Project name rvLen = 0 # Lenght of the matched path # Project paths are either absolute or relative to the solution path. for project in self.projectList: projectPath = self.projectList[project].path if not os.path.isabs(projectPath): projectPath = os.path.abspath(projectPath) projectPath = os.path.normpath(projectPath) projectPath = toPosixPath(projectPath) # Standardise the slashes. if projectPath[-1] != '/': # Ensure that the path is slash terminated otherwise we might # end up including projects which start with the same name... projectPath += '/' # Check all projects in the list and return the one with the longest matching path. if filepath.startswith(projectPath): if not rv: rv = project rvLen = len(projectPath) else: if rvLen < len(projectPath): rv = project rvLen = len(projectPath) return rv