def __GetExternalLibraryDependencies(self, package: Package) -> List[Tuple[str, str]]:
        libsAndPaths = []  # type: List[Tuple[str, str]]
        buildOrder = list(package.ResolvedBuildOrder)
        for entry in buildOrder:
            depList = Util.FilterByType(entry.ResolvedDirectExternalDependencies, ExternalDependencyType.StaticLib)
            for dep in depList:
                libName = dep.Name
                libPath = dep.Location
                libsAndPaths.append((libName, libPath))

        return libsAndPaths
Exemplo n.º 2
0
 def __ParseCMakeVersionString(self,
                               versionStr: Optional[str]) -> CMakeVersion:
     toolMin = CMakeUtil.GetMinimumVersion()
     if versionStr is None:
         return toolMin
     parsedMinVersion = Util.ParseVersionString(versionStr, maxValues=3)
     while len(parsedMinVersion) < 3:
         parsedMinVersion.append(0)
     projectMin = CMakeVersion(parsedMinVersion[0], parsedMinVersion[1],
                               parsedMinVersion[2])
     return projectMin if projectMin >= toolMin else toolMin
Exemplo n.º 3
0
 def __ValidateName(self) -> None:
     name = self.Name
     trimmed = name.strip()
     if trimmed != name:
         raise Exception("Name contained leading or ending whitespaces'{0}'".format(name))
     if len(name) <= 0:
         raise Exception("Name length must be greater than zero")
     if not Util.IsValidComamndName(name):
         raise Exception("Name must start with a a-z or A-Z and can only contain a-z,A-Z,0-9,_ and - '{0}'".format(name))
     if name.lower() in g_bannedCommands:
         raise Exception("The command '{0}' is banned".format(name))
Exemplo n.º 4
0
 def PrintExecutableSkipReason(log: Log, fullPackageList: List[Package],
                               filteredPackageList: List[Package]) -> None:
     for package in fullPackageList:
         if package.Type == PackageType.Executable:
             if package.ResolvedPlatformNotSupported:
                 notSupported = LocalUtil.BuildListOfDirectlyNotSupported(
                     package)
                 notSupportedNames = Util.ExtractNames(notSupported)
                 log.DoPrint(
                     "{0} was marked as not supported on this platform by package: {1}"
                     .format(package.Name, notSupportedNames))
Exemplo n.º 5
0
    def __TryValidateCommandVersion(self, cmd: str, versionCommand: str, versionRegEx: str, minVersion: Optional[str],
                                    addOnErrorWarning: List[XmlRecipeValidateCommandFindExecutableFileInPathAddOnErrorWarning]) -> List[int]:
        output = ""
        try:
            runCmd = [cmd, versionCommand]
            with subprocess.Popen(runCmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, universal_newlines=True) as proc:
                output = proc.stdout.read().strip()
                proc.stdout.close()
                result = proc.wait()
                if result != 0:
                    self.__BasicConfig.LogPrintWarning("The command '{0}' failed with '{1}'".format(" ".join(runCmd), result))
                    return []
        except FileNotFoundError:
                self.__BasicConfig.DoPrintWarning("The command '{0}' failed with 'file not found'.".format(" ".join(runCmd)))
                return []

        match = re.search(versionRegEx, output)
        if match is None:
            self.__BasicConfig.DoPrintWarning("The regex '{0}' did not capture the version".format(versionRegEx))
            return []
        if len(match.groups()) > 1:
            self.__BasicConfig.DoPrintWarning("The regex '{0}' captured more than one group: {1}".format(versionRegEx, match.groups))
        if len(match.groups()) != 1:
            self.__BasicConfig.DoPrintWarning("The regex '{0}' did not capture a group with version information".format(versionRegEx))
        matchResult = match.group(1)
        try:
            # time to parse the version string
            foundVersionList = Util.ParseVersionString(matchResult, maxValues=4)
            if minVersion is not None:
                minVersionList = Util.ParseVersionString(minVersion, maxValues=4)
                if len(minVersionList) > len(foundVersionList):
                    self.__BasicConfig.DoPrintWarning("The regex '{0}' did not capture the enough version number elements to compare against the min version '{1}'".format(versionRegEx, minVersion))
                    return []
                self.__BasicConfig.LogPrint("  Found version {0} expected minVersion {1}".format(matchResult, minVersion))
                if not self.__CheckVersion(minVersionList, foundVersionList):
                    return []
            self.__CheckOnErrorWarnings(foundVersionList, versionRegEx, addOnErrorWarning)
            return foundVersionList
        except Exception as ex:
            self.__BasicConfig.DoPrintWarning("Failed to parse version string: {0}".format(str(ex)))
            return []
Exemplo n.º 6
0
def __ValidateRequirementList(requirementNameList: List[str],
                              strHelpListName: str,
                              strHelpEntryName: str) -> None:
    if len(requirementNameList) <= 0 or requirementNameList[0] == '*':
        return

    for entry in requirementNameList:
        if not Util.IsValidRequirementName(entry):
            raise Exception(
                "The {0} must be valid, the {1} name '{2}' is not a valid {1} name in list {3}"
                .format(strHelpListName, strHelpEntryName, entry,
                        requirementNameList))
Exemplo n.º 7
0
 def __FiltersPackagesBySupported(log: Log, packages: Union[List[Package], List[AppInfoPackage]]) -> List[T]:
     """ Remove packages that are marked as not supported by the platform
     """
     packageList = []
     for package in packages:
         if not package.ResolvedPlatformNotSupported:
             packageList.append(package)
         elif not package.Type == PackageType.TopLevel and log.IsVerbose and isinstance(package, Package):
             notSupported = LocalUtil.BuildListOfDirectlyNotSupported(package)
             notSupportedNames = Util.ExtractNames(notSupported)
             log.DoPrint("Skipping {0} since its marked as not supported on this platform by package: {1}".format(package.Name, notSupportedNames))
     return cast(List[T], packageList)
Exemplo n.º 8
0
    def __init__(self, log: Log, requirementTypes: List[str],
                 xmlElement: ET.Element) -> None:
        super().__init__(log, xmlElement)
        self.Name = self._ReadAttrib(xmlElement, 'Name')  # type: str
        self.Type = self._ReadAttrib(xmlElement, 'Type')  # type: str
        self.Extends = self._ReadAttrib(xmlElement, 'Extends', '')  # type: str
        self.Version = self._ReadAttrib(xmlElement, 'Version', '')  # type: str

        if not Util.IsValidRequirementName(self.Name):
            raise XmlRequirementNameException(xmlElement, self.Name)
        if not self.Type in requirementTypes:
            raise XmlRequirementTypeException(xmlElement, self.Name, self.Type,
                                              self.Extends, requirementTypes)

        if len(self.Extends) > 0 and not Util.IsValidRequirementName(
                self.Extends):
            raise XmlRequirementStringException(xmlElement, "extends",
                                                self.Extends)
        if self.Type == PackageRequirementTypeString.Extension and len(
                self.Extends) == 0:
            raise XmlRequirementTypeExtensionRequiresAValidExtendFieldException(
                xmlElement, self.Name)
Exemplo n.º 9
0
 def ToBashPath(self, path: str) -> str:
     if path.find("\\") >= 0:
         raise UsageErrorException(
             "Backslash found in the supplied path '{0}'".format(path))
     for rootDir in self.RootDirectories:
         if path.startswith(rootDir.ResolvedPathEx):
             lenRootPath = len(rootDir.ResolvedPathEx)
             path = path[lenRootPath:]
             return rootDir.BashName + "/" + Util.UTF8ToAscii(path)
         elif path == rootDir.ResolvedPath:
             return rootDir.Name + "/"
     raise UsageErrorException(
         "the folder '{0}' does not reside inside one of the root dirs".
         format(path))
Exemplo n.º 10
0
 def ToPath(rootDirectories: List[ToolConfigRootDirectory], path: str) -> str:
     """
     convert to a path that we know reside in one of the package roots
     """
     if path.find("\\") >= 0:
         raise UsageErrorException("Backslash found in the supplied path '{0}'".format(path))
     for rootDir in rootDirectories:
         if path.startswith(rootDir.ResolvedPathEx):
             lenRootPath = len(rootDir.ResolvedPathEx)
             path = path[lenRootPath:]
             return rootDir.Name + "/" + Util.UTF8ToAscii(path)
         elif path == rootDir.ResolvedPath:
             return rootDir.Name + "/"
     raise UsageErrorException("the folder '{0}' does not reside inside one of the root dirs".format(path))
Exemplo n.º 11
0
    def AddNew(self, packageName: str, packageProjectId: str) -> None:
        if not Util.IsValidPackageName(packageName):
            raise InvalidPackageNameException(packageName)

        if packageProjectId in self.__projectIdToNameDict:
            raise Exception(
                "Package '{0}' uses project id '{1}' already used by package: '{2}'"
                .format(packageName, packageProjectId,
                        self.__projectIdToNameDict[packageProjectId]))
        if packageName in self.__projectIdCache.ProjectIdDict:
            raise Exception("Package '{0}' already added".format(packageName))

        self.__projectIdCache.Add(packageName, packageProjectId)
        self.__projectIdToNameDict[packageProjectId] = packageName
def BuildTargetLinkLibrariesForDirectDependencies(
        config: Config,
        package: Package,
        templatePackageDependencyTargetLinkLibraries: str,
        ignoreLibs: Optional[List[str]] = None) -> str:
    if ignoreLibs is None:
        ignoreLibs = []

    if package.ResolvedDirectDependencies is None:
        raise Exception("Invalid package")

    isExternalLibrary = package.Type == PackageType.ExternalLibrary

    deps = ""
    for entry1 in package.ResolvedDirectDependencies:
        if entry1.Package.Type != PackageType.ToolRecipe:
            deps += "\n  {0} {1}".format(
                GetAccessTypeString(package, entry1.Access, False),
                GetPackageName(entry1.Package))


#           deps += "\n  {0} {1}".format(GetAccessTypeString(package, entry1.Access), GetAliasPackageName(entry1.Package))

# FIX: handle debug libraries
    for entry2 in package.ResolvedDirectExternalDependencies:
        libraryName = LibUtil.ToUnixLibName(entry2.Name)
        if libraryName not in ignoreLibs:
            if entry2.Type == ExternalDependencyType.StaticLib:
                location = entry2.Location if entry2.Location and not isExternalLibrary else ""
                fullPathLinkDir = Util.ChangeToCMakeEnvVariables(
                    IOUtil.Join(location, libraryName))
                deps += "\n  {0} {1}".format(
                    GetAccessTypeString(package, entry2.Access, False),
                    fullPathLinkDir)
            if entry2.Type == ExternalDependencyType.Find:
                linkName = "${%s_LIBRARY}" % (libraryName)
                deps += "\n  {0} {1}".format(
                    GetAccessTypeString(package, entry2.Access, False),
                    linkName)
        else:
            config.LogPrintVerbose(
                2, "INFO: Force ignored '{0}'".format(libraryName))

    if len(deps) <= 0:
        return ""

    content = templatePackageDependencyTargetLinkLibraries
    content = content.replace("##PACKAGE_DIRECT_DEPENDENCIES##", deps)
    return content
Exemplo n.º 13
0
 def __CheckOnErrorWarning(
     self, foundVersionList: List[int], versionRegEx: str, warning:
     XmlRecipeValidateCommandFindExecutableFileInPathAddOnErrorWarning
 ) -> None:
     startVersionList = Util.ParseVersionString(warning.StartVersion,
                                                maxValues=4)
     if len(startVersionList) > len(foundVersionList):
         self.__Log.DoPrintWarning(
             "The regex '{0}' did not capture the enough version number elements to compare against the start version '{1}'"
             .format(versionRegEx, warning.StartVersion))
         return  # Its just a warning hint we can't display, so we log it and skip it for now
     if self.__CheckVersion(startVersionList, foundVersionList):
         # ok we passed the start version check for this warning hint
         if warning.EndVersion is not None:
             endVersionList = Util.ParseVersionString(warning.EndVersion,
                                                      maxValues=4)
             if len(endVersionList) > len(foundVersionList):
                 self.__Log.DoPrintWarning(
                     "The regex '{0}' did not capture the enough version number elements to compare against the end version '{1}'"
                     .format(versionRegEx, warning.EndVersion))
                 return  # Its just a warning hint we can't display, so we log it and skip it for now
             if self.__CheckVersion(endVersionList, foundVersionList):
                 return
         self.__ErrorHelpManager.AddOnErrorWarningHint(warning.Help)
Exemplo n.º 14
0
    def __init__(self, base: Union[UnresolvedPackageDefine, 'PackageDefine'],
                 introducedByPackageName: str,
                 fromPackageAccess: AccessType) -> None:
        super().__init__(base.Name)
        self.IntroducedByPackageName = introducedByPackageName  # type: str
        self.Value = base.Value  # type: Optional[str]
        self.Access = base.Access  # type: AccessType
        self.IsFirstActualUse = False  # type: bool
        self.ConsumedBy = base.ConsumedBy if isinstance(
            base, PackageDefine) else None  # type: Optional[Package]
        # the access to the package this was received from
        self.FromPackageAccess = fromPackageAccess  # type: AccessType

        if self.Value is not None and not Util.IsValidDefineValue(self.Value):
            raise InvalidDefineValueException(self.Name, self.Value)
Exemplo n.º 15
0
    def __TryParseFlavor(self, flavor: Optional[str]) -> Dict[str, str]:
        if flavor is None or len(flavor) <= 0:
            return {}
        uniqueIds = {}  # type: Dict[str, str]
        resDict = {}  # type: Dict[str, str]
        entries = flavor.split(',')
        for entry in entries:
            parts = entry.split('=')
            if len(parts) != 2:
                raise XmlFormatException(
                    "Dependency flavor constraint '{0}' not in the expected format 'flavor1=option, flavor2=option'"
                    .format(flavor))
            key = parts[0].strip()
            value = parts[1].strip()
            if key in resDict:
                raise XmlFormatException(
                    "Dependency flavor constraint key '{0}' already defined to '{1}'"
                    .format(key, resDict[key]))
            keyId = key.upper()
            if keyId in uniqueIds:
                raise XmlFormatException(
                    "Dependency flavor constraint key '{0}' already collides with '{1}'"
                    .format(key, uniqueIds[keyId]))

            if not Util.IsValidFlavorName(key):
                raise XmlFormatException(
                    "Dependency flavor name '{0}' is invalid".format(key))

            if not Util.IsValidFlavorOptionName(value):
                raise XmlFormatException(
                    "Dependency flavor option '{1}' is invalid in {0}={1}".
                    format(key, value))

            uniqueIds[keyId] = key
            resDict[key] = value
        return resDict
Exemplo n.º 16
0
def ParseExtensionList(strExtensionList: str) -> ExtensionListManager:
    parsedList = ParseList(strExtensionList, "extension", True)
    if not '*' in parsedList:
        newParsedList = []
        for entry in parsedList:
            # Do some minimal basic validation of the input
            # All extensions has to be qualified with a feature "featureName:extensionName
            values = entry.split(':')
            if not len(values) == 2:
                raise Exception(
                    "The extension list must be valid, the extension '{0}' did not follow the expected '<FeatureName>:<ExtensionName>' format"
                    .format(entry))
            if not Util.IsValidRequirementName(values[0]):
                raise Exception(
                    "The extension list must be valid, the extension '{0}' did not contain a valid feature name '{1}'"
                    .format(entry, values[0]))
            if not Util.IsValidRequirementName(values[1]):
                raise Exception(
                    "The extension list must be valid, the extension '{0}' did not contain a valid extension name '{1}'"
                    .format(entry, values[1]))
            newParsedList.append(
                QualifiedRequirementExtensionName(values[0], values[1]))
        return ExtensionListManager(False, newParsedList)
    return ExtensionListManager(True, [])
Exemplo n.º 17
0
    def __init__(self, projectIdDict: Dict[str, str]) -> None:
        super().__init__()
        self.Version = JsonProjectIdCache.CURRENT_VERSION
        self.ProjectIdDict = projectIdDict

        projectIdToNameDict = {}  # type: Dict[str, str]
        for packageName, packageProjectId in projectIdToNameDict.items():
            if not Util.IsValidPackageName(packageName):
                raise InvalidPackageNameException(packageName)
            if packageProjectId in projectIdDict:
                raise Exception(
                    "The package project id '{0}' is registered for multiple package names. First '{1}' Second '{2}'"
                    .format(packageProjectId, projectIdToNameDict[packageName],
                            packageName))
            projectIdToNameDict[packageProjectId] = packageName
Exemplo n.º 18
0
 def __ValidateOptionNames(self) -> None:
     if self.Type == VariantType.Normal:
         for option in self.Options:
             if not Util.IsValidName(option.Name):
                 raise XmlUnsupportedVariantOptionNameException(
                     option.XMLElement, option.Name)
     elif self.Type == VariantType.Virtual:
         if len(self.Options) != 1:
             raise XmlInvalidVirtualVariantOptionException(
                 self.XMLElement, self.Name)
         if not self.Options[0].Name == self.Name:
             raise XmlUnsupportedVirtualVariantOptionNameException(
                 self.Options[0].XMLElement, self.Options[0].Name,
                 self.Name)
     else:
         raise XmlException(self.XMLElement, "Unknown variant type")
Exemplo n.º 19
0
def __ResolveAndGenerate(config: Config, platformGeneratorPlugin: GeneratorPlugin, packageLoader: PackageLoader,
                         packageFilters: PackageFilters, isSDKBuild: bool) -> List[Package]:
    generatorContext = GeneratorContext(config, config.ToolConfig.Experimental, platformGeneratorPlugin)


    process = PackageLoadAndResolveProcess(config, packageLoader, platformGeneratorPlugin)
    process.Resolve(generatorContext, packageFilters)

    if not isSDKBuild:
        for package in process.Packages:
            if package.ResolvedPlatformNotSupported and package.Type != PackageType.TopLevel:
                notSupported = LocalUtil.BuildListOfDirectlyNotSupported(package)
                notSupportedNames = Util.ExtractNames(notSupported)
                config.DoPrintWarning("{0} was marked as not supported on this platform by package: {1}".format(package.Name, notSupportedNames))

    return platformGeneratorPlugin.Generate(generatorContext, config, process.Packages)
 def __GetExternalLibraryPaths(
         self, package: Package,
         dependencyTypeFilter: List[int]) -> List[str]:
     # GCC apparently needs the list to be in reverse order
     buildOrder = list(package.ResolvedBuildOrder)
     buildOrder.reverse()
     additionalLibraryDirectories = set()  # type: Set[str]
     for currentPackage in buildOrder:
         extDeps = Util.FilterByType(
             currentPackage.ResolvedDirectExternalDependencies,
             dependencyTypeFilter)  # type: List[PackageExternalDependency]
         for entry in extDeps:
             if entry.Location is not None:
                 additionalLibraryDirectories.add(entry.Location)
     result = list(additionalLibraryDirectories)
     result.sort()
     return result
Exemplo n.º 21
0
    def __init__(self, genFileName: str, template: XmlNewTemplateFile,
                 projectPath: str, projectName: str, packageName: str) -> None:
        self.Template = template
        self.ProjectName = projectName
        self.ProjectPath = projectPath
        self.PrefixedProjectName = template.Prefix + projectName

        self.PackageName = packageName
        self.PackageShortName, self.PackageNamespace = Util.GetPackageNames(
            packageName)
        self.PackageTargetName = packageName

        self.ProjectPrefix = template.Prefix
        self.ProjectPathInclude = os.path.join(projectPath, g_projectInclude)
        self.ProjectPathSource = os.path.join(projectPath, g_projectSource)
        self.TemplatePathCode = os.path.join(template.Path, g_templatePathCode)
        self.TemplatePathFslGen = os.path.join(template.Path,
                                               g_templatePathFslGen)
        self.ConfigCode = ConfigCode(self.TemplatePathCode, projectPath,
                                     projectName, self.PrefixedProjectName)
        self.ConfigFslGen = ConfigFslGen(genFileName, self.TemplatePathFslGen,
                                         projectPath, projectName,
                                         self.PrefixedProjectName)
Exemplo n.º 22
0
    def __init__(self, name: str) -> None:
        super().__init__()
        if not Util.IsValidFlavorOptionName(name):
            raise InvalidPackageFlavorOptionNameException(name)

        self.Value = name
Exemplo n.º 23
0
    def __init__(self, name: str, allowInternalNames: bool = False) -> None:
        super().__init__()
        if (not allowInternalNames and not Util.IsValidUnresolvedPackageName(name)) or (allowInternalNames and not Util.IsValidPackageInstanceName(name)):
            raise InvalidUnresolvedPackageNameException(name)

        self.Value = name
def BuildTargetIncludeDirectories(
        config: Config,
        package: Package,
        templatePackageTargetIncludeDirectories: str,
        templatePackageTargetIncludeDirEntry: str,
        pathType: int = CMakePathType.Relative) -> str:
    isExternalLibrary = package.Type == PackageType.ExternalLibrary
    publicIncludeDir = ""
    if package.AbsoluteIncludePath:
        pubIncPath = __GetPackageIncludePath(config, package,
                                             package.AbsoluteIncludePath,
                                             pathType)
        accessString = "PUBLIC" if not package.IsVirtual else "INTERFACE"
        publicIncludeDir = "\n" + __GenerateDirEntryString(
            accessString, pubIncPath, templatePackageTargetIncludeDirEntry)
    privateIncludeDir = ""
    if package.AbsoluteSourcePath:
        priIncPath = __GetPackageIncludePath(config, package,
                                             package.AbsoluteSourcePath,
                                             pathType)
        accessString = "PRIVATE" if not package.IsVirtual else "INTERFACE"
        privateIncludeDir = "\n" + __GenerateDirEntryString(
            accessString, priIncPath, templatePackageTargetIncludeDirEntry)

    for directExternalDeps in package.ResolvedDirectExternalDependencies:
        if directExternalDeps.Type != ExternalDependencyType.Find:
            currentIncDir = directExternalDeps.Include
            if currentIncDir is not None:
                if package.AbsolutePath is None:
                    raise Exception("Invalid package")
                packageRootPath = config.ToPath(package.AbsolutePath)
                if currentIncDir.startswith(packageRootPath):
                    relativeCurrentIncDir = currentIncDir[
                        len(packageRootPath) +
                        1:] if pathType == CMakePathType.LocalRelative else Util.ChangeToCMakeVariables(
                            currentIncDir)
                    add = "\n" + __GenerateDirEntryString(
                        GetAccessTypeString(package,
                                            directExternalDeps.Access),
                        relativeCurrentIncDir,
                        templatePackageTargetIncludeDirEntry)
                else:
                    relativeCurrentIncDir = config.ToPath(currentIncDir)
                    if relativeCurrentIncDir is None:
                        add = "\n  {0} {1}".format(
                            GetAccessTypeString(package,
                                                directExternalDeps.Access),
                            Util.ChangeToCMakeEnvVariables(currentIncDir))
                    else:
                        if pathType != CMakePathType.LocalRelative:
                            relativeCurrentIncDir = Util.ChangeToCMakeVariables(
                                relativeCurrentIncDir)
                        add = "\n" + __GenerateDirEntryString(
                            GetAccessTypeString(package,
                                                directExternalDeps.Access),
                            relativeCurrentIncDir,
                            templatePackageTargetIncludeDirEntry)
                if directExternalDeps.Access == AccessType.Public:
                    publicIncludeDir += add
                else:
                    privateIncludeDir += add
        else:
            add = "\n  %s ${%s_INCLUDE_DIRS}" % (GetAccessTypeString(
                package, directExternalDeps.Access), directExternalDeps.Name)
            if directExternalDeps.Access == AccessType.Public:
                publicIncludeDir += add
            else:
                privateIncludeDir += add

    if len(publicIncludeDir) <= 0 and len(privateIncludeDir) <= 0:
        return ""

    content = templatePackageTargetIncludeDirectories
    content = content.replace("##PACKAGE_PUBLIC_INCLUDE_DIRECTORIES##",
                              publicIncludeDir)
    content = content.replace("##PACKAGE_PRIVATE_INCLUDE_DIRECTORIES##",
                              privateIncludeDir)
    return content
Exemplo n.º 25
0
 def __ValidateFlavorName(self) -> None:
     if not Util.IsValidName(self.Name):
         raise XmlUnsupportedFlavorNameException(self.XMLElement, self.Name)
Exemplo n.º 26
0
 def Add(self, packageName: str, packageProjectId: str) -> None:
     if not Util.IsValidPackageName(packageName):
         raise InvalidPackageNameException(packageName)
     self.ProjectIdDict[packageName] = packageProjectId
Exemplo n.º 27
0
 def __ValidateOptionNames(self) -> None:
     for option in self.Options:
         if not Util.IsValidName(option.Name):
             raise XmlUnsupportedFlavorOptionNameException(
                 option.XMLElement, option.Name)
Exemplo n.º 28
0
    def __init__(self,
                 source: str,
                 variableDict: Optional[VariableDict],
                 environmentVariableResolver: Optional[
                     FormatStringEnvironmentVariableResolver] = None,
                 noVariableResolve: bool = False,
                 noEnvVariableResolve: bool = False) -> None:
        super().__init__()
        self.SplitList = []  # type: List[str]
        self.VarCommandList = []  # type: List[LookupVariableCommand]
        self.EnvCommandList = [
        ]  # type: List[LookupEnvironmentVariableCommand]

        if source == "":
            self.SplitList.append("")
            return

        state = ParseState.Scanning
        startSplitIndex = 0
        blockStartIndex = 0
        for index, ch in enumerate(source):
            if state == ParseState.Scanning:
                if ch == '$':
                    state = ParseState.CommandStart
            elif state == ParseState.CommandStart:
                if ch == '{':
                    state = ParseState.VariableBlock
                    if startSplitIndex < index - 1:
                        self.SplitList.append(source[startSplitIndex:index -
                                                     1])
                    startSplitIndex = index - 1
                    blockStartIndex = index + 1
                elif ch == '(':
                    state = ParseState.EnvBlock
                    if startSplitIndex < index - 1:
                        self.SplitList.append(source[startSplitIndex:index -
                                                     1])
                    startSplitIndex = index - 1
                    blockStartIndex = index + 1
                    #stringEndSplitIndex = blockStartIndex-2
            elif state == ParseState.VariableBlock:
                if ch == '}':
                    state = ParseState.Scanning
                    self.SplitList.append(source[startSplitIndex:index + 1])
                    startSplitIndex = index + 1
                    # Do the report lookup
                    variableName = (source[blockStartIndex:index])
                    if not Util.IsValidCStyleName(variableName):
                        raise FormatStringInvalidVariableNameException(
                            variableName)

                    if noVariableResolve:
                        variableValue = VariableReport(
                            "*NotDefined*", ["*NotDefined*"],
                            None)  # type: Optional[VariableReport]
                    else:
                        variableValue = variableDict.TryGetVariableReport(
                            variableName) if variableDict is not None else None
                    if variableValue is None:
                        raise FormatStringUndefinedVariableNameException(
                            variableName)

                    self.VarCommandList.append(
                        LookupVariableCommand(variableName, variableValue,
                                              len(self.SplitList) - 1))
                    #stringEndSplitIndex = blockStartIndex
            elif state == ParseState.EnvBlock:
                if ch == ')':
                    state = ParseState.Scanning
                    self.SplitList.append(source[startSplitIndex:index + 1])
                    startSplitIndex = index + 1

                    envName = source[blockStartIndex:index]
                    if not Util.IsValidCStyleName(envName):
                        raise FormatStringInvalidVariableNameException(envName)

                    if noEnvVariableResolve:
                        envValue = "*NotDefined*"  # type: Optional[str]
                    elif environmentVariableResolver is None:
                        envValue = IOUtil.TryGetEnvironmentVariable(envName)
                    else:
                        envValue = environmentVariableResolver(envName)

                    if envValue is None:
                        raise FormatStringUndefinedEnvironmentVariableNameException(
                            envName)

                    self.EnvCommandList.append(
                        LookupEnvironmentVariableCommand(
                            envName, envValue,
                            len(self.SplitList) - 1))

        if startSplitIndex < len(source):
            self.SplitList.append(source[startSplitIndex:])

        if state != ParseState.Scanning and state != ParseState.CommandStart:
            if state == ParseState.VariableBlock:
                raise FormatStringVariableMissingTerminationException(
                    "The string '{0}' is missing a terminating '}}' ".format(
                        source))
            elif state == ParseState.EnvBlock:
                raise FormatStringEnvironmentVariableMissingTerminationException(
                    "The string '{0}' is missing a terminating ')' ".format(
                        source))
            raise FormatStringInvalidException(
                "The string '{0}' contained invalid format codes".format(
                    source))
Exemplo n.º 29
0
 def __PurifyName(self, variantType: int, variantName: str) -> str:
     if variantType == VariantType.Virtual:
         variantName = Util.RemoveEnvironmentVariablePadding(variantName)
     return variantName
    def __GenerateBuildFile(self, config: Config, generatorName: str,
                            package: Package, template: str,
                            dstMakeFilename: str) -> None:
        if package.ShortName is None or package.Namespace is None or package.ResolvedMakeObjectPath is None or package.AbsolutePath is None:
            raise Exception("Invalid Package")
        name = GeneratorGNUmakefileUtil.GetTargetName(package)
        installPath = package.Namespace
        if package.Type == PackageType.Library:
            name = "lib" + name

        if package.ResolvedBuildSourceFiles is None or package.ResolvedBuildAllIncludeDirs is None or package.ResolvedBuildAllPrivateDefines is None or package.ResolvedBuildAllPublicDefines is None:
            raise Exception("Invalid Package")

        files = MakeFileHelper.CreateList(package.ResolvedBuildSourceFiles)
        includeDirs = MakeFileHelper.CreateList(
            package.ResolvedBuildAllIncludeDirs)

        localDefines = Util.ExtractNames(
            package.ResolvedBuildAllPrivateDefines)
        localDefines += Util.ExtractNames(
            package.ResolvedBuildAllPublicDefines)
        localDefineNames = MakeFileHelper.CreateList(localDefines)

        variantSection = self.__GetVariantSection(package)

        if package.ResolvedMakeVariantNameHint is None:
            raise InternalErrorException(
                "Package '{0}' ResolvedMakeVariantNameHint can not be None".
                format(package.Name))

        variantName = package.ResolvedMakeVariantNameHint
        build = template
        build = build.replace("##PACKAGE_TARGET_NAME##", name)
        build = build.replace("##PACKAGE_TARGET_INSTALL_PATH##", installPath)
        build = build.replace("##PACKAGE_SOURCE_FILES##", files)
        build = build.replace("##PACKAGE_INCLUDE_DIRS##", includeDirs)
        build = build.replace("##PACKAGE_DEFINES##", localDefineNames)
        build = build.replace("##PACKAGE_VARIANT_SECTION##", variantSection)
        build = build.replace("##PACKAGE_OBJECT_PATH##",
                              package.ResolvedMakeObjectPath)
        build = build.replace("##PACKAGE_VARIANT_NAME##", variantName)

        if package.Type == PackageType.Executable:
            libraryDependencies = self.__GetLibraryDependencies(
                config, package)
            strLibraryDependencies = MakeFileHelper.CreateList(
                libraryDependencies)
            build = build.replace("##PACKAGE_LIBRARY_DEPENDENCIES##",
                                  strLibraryDependencies)
            extLibraryDependencies = self.__GetExternalLibraryDependencies(
                package)
            strExtLibraryDependencies = MakeFileHelper.CreateList(
                extLibraryDependencies)
            build = build.replace("##PACKAGE_EXTERNAL_LIBRARY_DEPENDENCIES##",
                                  strExtLibraryDependencies)
            extLibraryPaths = self.__GetExternalLibraryPaths(
                package,
                [ExternalDependencyType.StaticLib, ExternalDependencyType.DLL])
            strExtLibraryPaths = MakeFileHelper.CreateList(extLibraryPaths)
            build = build.replace("##PACKAGE_EXTERNAL_LIBRARY_PATHS##",
                                  strExtLibraryPaths)
            extDllPaths = self.__GetExternalLibraryPaths(
                package, [ExternalDependencyType.DLL])
            strExtDllPaths = MakeFileHelper.CreateList(extDllPaths)
            build = build.replace("##PACKAGE_EXTERNAL_DLL_PATHS##",
                                  strExtDllPaths)
            executableReport = GeneratorGNUmakefileUtil.TryGenerateExecutableReport(
                config, generatorName, package)
            if executableReport is not None:
                variableReport = GeneratorGNUmakefileUtil.GenerateVariableReport(
                    config, generatorName, package, self.ConfigVariantOptions)
                GitIgnoreHelper.AddFromBuildReport(self.GitIgnoreDict, package,
                                                   executableReport,
                                                   variableReport)

        dstFile = IOUtil.Join(package.AbsolutePath, dstMakeFilename)
        if not config.DisableWrite:
            IOUtil.WriteFileIfChanged(dstFile, build)
            GitIgnoreHelper.AddPathIfInPackageRoot(self.GitIgnoreDict, package,
                                                   dstFile)