aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xmlGenerator/PFWScriptGenerator.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/xmlGenerator/PFWScriptGenerator.py')
-rwxr-xr-xtools/xmlGenerator/PFWScriptGenerator.py1269
1 files changed, 98 insertions, 1171 deletions
diff --git a/tools/xmlGenerator/PFWScriptGenerator.py b/tools/xmlGenerator/PFWScriptGenerator.py
index 3e9eb74..d1996d1 100755
--- a/tools/xmlGenerator/PFWScriptGenerator.py
+++ b/tools/xmlGenerator/PFWScriptGenerator.py
@@ -1,7 +1,6 @@
#!/usr/bin/python2
-# -*-coding:utf-8 -*
-# Copyright (c) 2011-2014, Intel Corporation
+# Copyright (c) 2015, Intel Corporation
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@@ -29,1061 +28,73 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import EddParser
+from PfwBaseTranslator import PfwBaseTranslator
-
-import re
+import argparse
import sys
-import copy
-import imp
-from itertools import izip
-from itertools import imap
-
-try:
- import argparse
-except ImportError:
- import optparse
-
-# =====================================================================
-""" Context classes, used during propagation and the "to PFW script" step """
-# =====================================================================
-
-class PropagationContextItem(list) :
- """Handle an item during the propagation step"""
- def __copy__(self):
- """C.__copy__() -> a shallow copy of C"""
- return self.__class__(self)
-
-class PropagationContextElement(PropagationContextItem) :
- """Handle an Element during the propagation step"""
- def getElementsFromName(self, name):
- matchingElements = []
- for element in self :
- if element.getName() == name :
- matchingElements.append(element)
- return matchingElements
-
-
-class PropagationContextOption(PropagationContextItem) :
- """Handle an Option during the propagation step"""
- def getOptionItems (self, itemName):
- items = []
- for options in self :
- items.append(options.getOption(itemName))
- return items
-
-
-class PropagationContext() :
- """Handle the context during the propagation step"""
- def __init__(self, propagationContext=None) :
-
- if propagationContext == None :
- self._context = {
- "DomainOptions" : PropagationContextOption() ,
- "Configurations" : PropagationContextElement() ,
- "ConfigurationOptions" : PropagationContextOption() ,
- "Rules" : PropagationContextElement() ,
- "PathOptions" : PropagationContextOption() ,
- }
- else :
- self._context = propagationContext
-
- def copy(self):
- """return a copy of the context"""
- contextCopy = self._context.copy()
-
- for key in iter(self._context) :
- contextCopy[key] = contextCopy[key].__copy__()
-
- return self.__class__(contextCopy)
-
- def getDomainOptions (self):
- return self._context["DomainOptions"]
-
- def getConfigurations (self):
- return self._context["Configurations"]
-
- def getConfigurationOptions (self):
- return self._context["ConfigurationOptions"]
-
- def getRules (self):
- return self._context["Rules"]
-
- def getPathOptions (self):
- return self._context["PathOptions"]
-
-# ---------------------------------------------------------------------------
-
-class PFWScriptContext ():
- """handle the context during the PFW script generation"""
-
- def __init__(self, prefixIncrease=" ") :
- self._context = {
- "Prefix" : "" ,
- "DomainName" : "" ,
- "ConfigurationName" : "" ,
- "SequenceAwareness" : False ,
- }
- self._prefixIncrease = prefixIncrease
-
- def increasePrefix(self) :
- self._context["Prefix"] = self._prefixIncrease + self._context["Prefix"]
-
- def getNewLinePrefix(self) :
- """return a prefix with decorative new line
-
- return r"\"+"\n"+" "*increased prefix length"""
- return "\\\n" + self._prefixIncrease + " "* len(self.getPrefix())
-
- def copy(self) :
- copy = PFWScriptContext ()
- copy._context = self._context.copy()
- return copy
-
- def setDomainName (self, name) :
- self._context["DomainName"] = name
-
- def setConfigurationName (self, name) :
- self._context["ConfigurationName"] = name
-
- def setSequenceAwareness (self, sequenceAwareness) :
- self._context["SequenceAwareness"] = sequenceAwareness
-
- def getPrefix(self):
- return self._context["Prefix"]
-
- def getDomainName (self):
- return self._context["DomainName"]
-
- def getConfigurationName(self):
- return self._context["ConfigurationName"]
-
- def getSequenceAwareness(self):
- return self._context["SequenceAwareness"]
-
-# =====================================================
-"""Element option container"""
-# =====================================================
-
-class Options () :
- """handle element options"""
- def __init__(self, options=[], optionNames=[]) :
- self.options = dict(izip(optionNames, options))
- # print(options,optionNames,self.options)
-
-
- def __str__(self) :
- ops2str = []
- for name, argument in self.options.items() :
- ops2str.append(str(name) + "=\"" + str(argument) + "\"")
-
- return " ".join(ops2str)
-
- def getOption(self, name):
- """get option by its name, if it does not exist return empty string"""
- return self.options.get(name, "")
-
- def setOption(self, name, newOption):
- """set option by its name"""
- self.options[name] = newOption
-
- def copy (self):
- """D.copy() -> a shallow copy of D"""
- copy = Options()
- copy.options = self.options.copy()
- return copy
-
-# ====================================================
-"""Definition of all element class"""
-# ====================================================
-
-class Element(object):
- """ implement a basic element
-
- It is the class base for all other elements as Domain, Configuration..."""
- tag = "unknown"
- optionNames = ["Name"]
- childWhiteList = []
- optionDelimiter = " "
-
- def __init__(self, line=None) :
-
- if line == None :
- self.option = Options([], self.optionNames)
- else :
- self.option = self.optionFromLine(line)
-
- self.children = []
-
- def optionFromLine(self, line) :
- # get ride of spaces
- line = line.strip()
-
- options = self.extractOptions(line)
-
- return Options(options, self.optionNames)
-
- def extractOptions(self, line) :
- """return the line splited by the optionDelimiter atribute
-
- Option list length is less or equal to the optionNames list length
- """
- options = line.split(self.optionDelimiter, len(self.optionNames) - 1)
-
- # get ride of leftover spaces
- optionsStrip = list(imap(str.strip, options))
-
- return optionsStrip
-
- def addChild(self, child, append=True) :
- """ A.addChid(B) -> add B to A child list if B class name is in A white List"""
- try:
- # Will raise an exception if this child is not in the white list
- self.childWhiteList.index(child.__class__.__name__)
- # If no exception was raised, add child to child list
-
- if append :
- self.children.append(child)
- else :
- self.children.insert(0, child)
-
- except ValueError:
- # the child class is not in the white list
- raise ChildNotPermitedError("", self, child)
-
- def addChildren(self, children, append=True) :
- """Add a list of child"""
- if append:
- # Add children at the end of the child list
- self.children.extend(children)
- else:
- # Add children at the begining of the child list
- self.children = children + self.children
-
- def childrenToString(self, prefix=""):
- """return raw printed children """
- body = ""
- for child in self.children :
- body = body + child.__str__(prefix)
-
- return body
-
- def __str__(self, prefix="") :
- """return raw printed element"""
- selfToString = prefix + " " + self.tag + " " + str(self.option)
- return selfToString + "\n" + self.childrenToString(prefix + "\t")
-
- def extractChildrenByClass(self, classTypeList) :
- """return all children whose class is in the list argument
-
- return a list of all children whose class in the list "classTypeList" (second arguments)"""
- selectedChildren = []
-
- for child in self.children :
- for classtype in classTypeList :
- if child.__class__ == classtype :
- selectedChildren.append(child)
- break
- return selectedChildren
-
- def propagate (self, context=PropagationContext()):
- """call the propagate method of all children"""
- for child in self.children :
- child.propagate(context)
-
- def getName(self):
- """return name option value. If none return "" """
- return self.option.getOption("Name")
-
- def setName(self, name):
- self.option.setOption("Name", name)
-
- def toPFWScript (self, context=PFWScriptContext()) :
- script = ""
- for child in self.children :
- script += child.toPFWScript(context)
- return script
-
-
-# ----------------------------------------------------------
-
-class ElementWithTag (Element):
- """Element of this class are declared with a tag => line == "tag: .*" """
- def extractOptions(self, line) :
- lineWithoutTag = line.split(":", 1)[-1].strip()
- options = super(ElementWithTag, self).extractOptions(lineWithoutTag)
- return options
-
-# ----------------------------------------------------------
-
-class ElementWithInheritance(Element):
- def propagate (self, context=PropagationContext) :
- """propagate some proprieties to children"""
-
- # copy the context so that everything that hapend next will only affect
- # children
- contextCopy = context.copy()
-
- # check for inheritance
- self.Inheritance(contextCopy)
-
- # call the propagate method of all children
- super(ElementWithInheritance, self).propagate(contextCopy)
-
-
-class ElementWithRuleInheritance(ElementWithInheritance):
- """class that will give to its children its rules"""
- def ruleInheritance(self, context):
- """Add its rules to the context and get context rules"""
-
- # extract all children rule and operator
- childRules = self.extractChildrenByClass([Operator, Rule])
-
- # get context rules
- contextRules = context.getRules()
-
- # adopt rules of the beginning of the context
- self.addChildren(contextRules, append=False)
-
- # add previously extract rules to the context
- contextRules += childRules
-
-
-# ----------------------------------------------------------
-
-class EmptyLine (Element) :
- """This class represents an empty line.
-
- Will raise "EmptyLineWarning" exception at instanciation."""
-
- tag = "emptyLine"
- match = re.compile(r"[ \t]*\n?$").match
- def __init__ (self, line):
- raise EmptyLineWarning(line)
-
-# ----------------------------------------------------------
-
-class Commentary(Element):
- """This class represents a commentary.
-
- Will raise "CommentWarning" exception at instanciation."""
-
- tag = "commentary"
- optionNames = ["comment"]
- match = re.compile(r"#").match
- def __init__ (self, line):
- raise CommentWarning(line)
-
-# ----------------------------------------------------------
-
-class Path (ElementWithInheritance) :
- """class implementing the "path = value" concept"""
- tag = "path"
- optionNames = ["Name", "value"]
- match = re.compile(r".+=").match
- optionDelimiter = "="
- PFWCommandParameter = "setParameter"
-
- def toPFWScript (self, context=PFWScriptContext()) :
-
- return context.getPrefix() + \
- self.PFWCommandParameter + " " + \
- self.getName() + " '" + \
- self.option.getOption("value") + "'\n"
-
- def Inheritance (self, context) :
- """check for path name inheritance"""
- self.OptionsInheritance(context)
-
- def OptionsInheritance (self, context) :
- """make configuration name inheritance """
-
- context.getPathOptions().append(self.option.copy())
- self.setName("/".join(context.getPathOptions().getOptionItems("Name")))
-
-
-class GroupPath (Path, ElementWithTag) :
- tag = "component"
- match = re.compile(tag + r" *:").match
- optionNames = ["Name"]
- childWhiteList = ["Path", "GroupPath"]
-
- def toPFWScript (self, pfwScriptContext) :
- script = ""
-
- configurationChildren = self.extractChildrenByClass([GroupPath, Path])
-
- for configurationChild in configurationChildren :
- # add configuration settings
- script += configurationChild.toPFWScript(pfwScriptContext)
-
- return script
-
- def getPathNames (self) :
- """Return the list of all path child name"""
-
- pathNames = []
-
- paths = self.extractChildrenByClass([Path])
- for path in paths :
- pathNames.append(path.getName())
-
- groupPaths = self.extractChildrenByClass([GroupPath])
- for groupPath in groupPaths :
- pathNames += groupPath.getPathNames()
-
- return pathNames
-
-# ----------------------------------------------------------
-
-class Rule (Element) :
- """class implementing the rule concept
-
- A rule is composed of a criterion, a rule type and an criterion state.
- It should not have any child and is propagated to all configuration in parent descendants.
- """
-
- tag = "rule"
- optionNames = ["criterion", "type", "element"]
- match = re.compile(r"[a-zA-Z0-9_.]+ +(Is|IsNot|Includes|Excludes) +[a-zA-Z0-9_.]+").match
- childWhiteList = []
-
- def PFWSyntax (self, prefix=""):
-
- script = prefix + \
- self.option.getOption("criterion") + " " + \
- self.option.getOption("type") + " " + \
- self.option.getOption("element")
-
- return script
-
-
-class Operator (Rule) :
- """class implementing the operator concept
-
- An operator contains rules and other operators
- It is as rules propagated to all configuration children in parent descendants.
- It should only have the name ANY or ALL to be understood by PFW.
- """
-
- tag = "operator"
- optionNames = ["Name"]
- match = re.compile(r"ANY|ALL").match
- childWhiteList = ["Rule", "Operator"]
-
- PFWCommandRule = "setRule"
- syntax = { "ANY" : "Any" , "ALL" : "All"}
-
- def toPFWScript (self, context) :
- """ return a pfw commands generated from him and its child options"""
- script = ""
-
- # add the command name (setRule)
- script += context.getPrefix() + \
- self.PFWCommandRule + " " + \
- context.getDomainName() + " " + \
- context.getConfigurationName() + " "
-
- # add the rule
- script += self.PFWSyntax (context.getNewLinePrefix())
-
- script += "\n"
-
- return script
-
- def PFWSyntax (self, prefix=""):
- """ return a pfw rule (ex : "Any{criterion1 is state1}") generated from "self" and its children options"""
- script = ""
-
- script += prefix + \
- self.syntax[self.getName()] + "{ "
-
- rules = self.extractChildrenByClass([Rule, Operator])
-
- PFWRules = []
- for rule in rules :
- PFWRules.append(rule.PFWSyntax(prefix + " "))
-
- script += (" , ").join(PFWRules)
-
- script += prefix + " }"
-
- return script
-
-# ----------------------------------------------------------
-
-class Configuration (ElementWithRuleInheritance, ElementWithTag) :
- tag = "configuration"
- optionNames = ["Name"]
- match = re.compile(r"conf *:").match
- childWhiteList = ["Rule", "Operator", "Path", "GroupPath"]
-
- PFWCommandConfiguration = "createConfiguration"
- PFWCommandElementSequence = "setElementSequence"
- PFWCommandSequenceAware = "setSequenceAwareness"
-
- PFWCommandRestoreConfiguration = "restoreConfiguration"
- PFWCommandSaveConfiguration = "saveConfiguration"
-
- def composition (self, context):
- """make all needed composition
-
- Composition is the fact that group configuration with the same name defined
- in a parent will give their rule children to this configuration
- """
-
- name = self.getName()
- sameNameConf = context.getConfigurations().getElementsFromName(name)
-
- sameNameConf.reverse()
-
- for configuration in sameNameConf :
- # add same name configuration rule children to self child list
- self.addChildren(configuration.extractChildrenByClass([Operator, Rule]), append=False)
-
-
- def propagate (self, context=PropagationContext) :
- """propagate proprieties to children
-
- make needed compositions, join ancestor name to its name,
- and add rules previously defined rules"""
-
- # make all needed composition
- self.composition(context)
-
- super(Configuration, self).propagate(context)
-
- def Inheritance (self, context) :
- """make configuration name and rule inheritance"""
- # check for configuration name inheritance
- self.OptionsInheritance(context)
-
- # check for rule inheritance
- self.ruleInheritance(context)
-
- def OptionsInheritance (self, context) :
- """make configuration name inheritance """
-
- context.getConfigurationOptions().append(self.option.copy())
- self.setName(".".join(context.getConfigurationOptions().getOptionItems("Name")))
-
-
- def getRootPath (self) :
-
- paths = self.extractChildrenByClass([Path, GroupPath])
-
- rootPath = GroupPath()
- rootPath.addChildren(paths)
-
- return rootPath
-
- def getConfigurableElements (self) :
- """return all path name defined in this configuration"""
-
- return self.getRootPath().getPathNames()
-
- def toPFWScript(self, pfwScriptContext) :
- """Output the PFW commands needed to recreate this configuration
-
- The PFW commands outputed will recreate this configuration if run
- on a PFW instance"""
-
- script = ""
-
- # Copy and update pfwScriptContext for this configuration
- pfwScriptContextAux = pfwScriptContext.copy()
- pfwScriptContextAux.setConfigurationName (self.getName())
-
- # Add the command to create the configuration
- script += pfwScriptContextAux.getPrefix() + \
- self.PFWCommandConfiguration + " " + \
- pfwScriptContextAux.getDomainName() + " " + \
- pfwScriptContextAux.getConfigurationName() + "\n"
-
- # encrease prefix
- pfwScriptContextAux.increasePrefix()
- # Create a rootRule
- ruleChildren = self.extractChildrenByClass([Rule, Operator])
+class PfwScriptTranslator(PfwBaseTranslator):
- # Do not create a root rule if there is only one fist level Operator rule
- if len(ruleChildren) == 1 and ruleChildren[0].__class__ == Operator :
- ruleroot = ruleChildren[0]
-
- else :
- ruleroot = Operator()
- ruleroot.setName("ALL")
- ruleroot.addChildren(ruleChildren)
-
-
- # Add the command to create the rules of this configuration
- script += ruleroot.toPFWScript(pfwScriptContextAux)
-
-
- # Add the command to restore this configuration
- script += pfwScriptContextAux.getPrefix() + \
- self.PFWCommandRestoreConfiguration + " " + \
- pfwScriptContextAux.getDomainName() + " " + \
- pfwScriptContextAux.getConfigurationName() + "\n"
-
- # Copy pfwScriptContextAux and increase the prefix
- contextAux = pfwScriptContextAux.copy()
- contextAux.increasePrefix()
-
- # add the parameter settings for this configuration
- paths = self.extractChildrenByClass([Path, GroupPath])
- for path in paths :
- script += path.toPFWScript(contextAux)
-
- script += pfwScriptContextAux.getPrefix() + \
- self.PFWCommandSaveConfiguration + " " + \
- pfwScriptContextAux.getDomainName() + " " + \
- pfwScriptContextAux.getConfigurationName() + "\n"
-
- # if domain is sequence aware
- if pfwScriptContextAux.getSequenceAwareness() :
-
- script += pfwScriptContextAux.getPrefix() + \
- self.PFWCommandElementSequence + " " + \
- pfwScriptContextAux.getDomainName() + " " + \
- pfwScriptContextAux.getConfigurationName() + " "
-
- for path in paths :
- script += pfwScriptContextAux.getNewLinePrefix() + \
- path.getName()
- script += "\n"
-
- script += pfwScriptContextAux.getPrefix() + \
- self.PFWCommandSequenceAware + " "\
- + pfwScriptContextAux.getDomainName() + " true \n"
-
- # for lisibility
- script += "\n"
-
- return script
-
- def copy (self) :
- """return a shallow copy of the configuration"""
-
- # create configuration or subclass copy
- confCopy = self.__class__()
-
- # add children
- confCopy.children = list(self.children)
-
- # add option
- confCopy.option = self.option.copy()
-
- return confCopy
-
-class GroupConfiguration (Configuration) :
- tag = "GroupConfiguration"
- optionNames = ["Name"]
- match = re.compile(r"(supConf|confGroup|confType) *:").match
- childWhiteList = ["Rule", "Operator", "GroupConfiguration", "Configuration", "GroupPath"]
-
- def composition (self, context) :
- """add itself in context for configuration composition
-
- Composition is the fact that group configuration with the same name defined
- in a parent will give their rule children to this configuration
- """
-
- # copyItself
- selfCopy = self.copy()
-
- # make all needed composition
- super(GroupConfiguration, self).composition(context)
-
- # add the copy in context for futur configuration composition
- context.getConfigurations().append(selfCopy)
-
-
- def getConfigurableElements (self) :
- """return a list. Each elements consist of a list of configurable element of a configuration
-
- return a list consisting of all configurable elements for each configuration.
- These configurable elements are organized in a list"""
- configurableElements = []
-
- configurations = self.extractChildrenByClass([Configuration])
- for configuration in configurations :
- configurableElements.append(configuration.getConfigurableElements())
-
- groudeConfigurations = self.extractChildrenByClass([GroupConfiguration])
- for groudeConfiguration in groudeConfigurations :
- configurableElements += groudeConfiguration.getConfigurableElements()
-
- return configurableElements
-
- def toPFWScript (self, pfwScriptContext) :
- script = ""
-
- configurationChildren = self.extractChildrenByClass([Configuration, GroupConfiguration])
-
- for configurationChild in configurationChildren :
- # add configuration settings
- script += configurationChild.toPFWScript(pfwScriptContext)
-
- return script
-
-# ----------------------------------------------------------
-
-class Domain (ElementWithRuleInheritance, ElementWithTag) :
- tag = "domain"
- sequenceAwareKeyword = "sequenceAware"
-
- match = re.compile(r"domain *:").match
- optionNames = ["Name", sequenceAwareKeyword]
- childWhiteList = ["Configuration", "GroupConfiguration", "Rule", "Operator"]
-
- PFWCommandConfigurableElement = "addElement"
- PFWCommandDomain = "createDomain"
-
- def propagate (self, context=PropagationContext) :
- """ propagate name, sequenceAwareness and rule to children"""
-
- # call the propagate method of all children
- super(Domain, self).propagate(context)
-
- self.checkConfigurableElementUnicity()
-
- def Inheritance (self, context) :
- """check for domain name, sequence awarness and rules inheritance"""
- # check for domain name and sequence awarness inheritance
- self.OptionsInheritance(context)
-
- # check for rule inheritance
- self.ruleInheritance(context)
-
- def OptionsInheritance(self, context) :
- """ make domain name and sequence awareness inheritance
-
- join to the domain name all domain names defined in context and
- if any domain in context is sequence aware, set sequenceAwareness to True"""
-
- # add domain options to context
- context.getDomainOptions().append(self.option.copy())
-
- # set name to the junction of all domain name in context
- self.setName(".".join(context.getDomainOptions().getOptionItems("Name")))
-
- # get sequenceAwareness of all domains in context
- sequenceAwareList = context.getDomainOptions().getOptionItems(self.sequenceAwareKeyword)
- # or operation on all booleans in sequenceAwareList
- sequenceAwareness = False
- for sequenceAware in sequenceAwareList :
- sequenceAwareness = sequenceAwareness or sequenceAware
- # current domain sequenceAwareness = sequenceAwareness
- self.option.setOption(self.sequenceAwareKeyword, sequenceAwareness)
-
-
- def extractOptions(self, line) :
- """Extract options from the definition line"""
- options = super(Domain, self).extractOptions(line)
-
- sequenceAwareIndex = self.optionNames.index(self.sequenceAwareKeyword)
-
- # translate the keyword self.sequenceAwareKeyword if specified to boolean True,
- # to False otherwise
- try :
- if options[sequenceAwareIndex] == self.sequenceAwareKeyword :
- options[sequenceAwareIndex] = True
- else:
- options[sequenceAwareIndex] = False
- except IndexError :
- options = options + [None] * (sequenceAwareIndex - len(options)) + [False]
- return options
-
- def getRootConfiguration (self) :
- """return the root configuration group"""
- configurations = self.extractChildrenByClass([Configuration, GroupConfiguration])
-
- configurationRoot = GroupConfiguration()
-
- configurationRoot.addChildren(configurations)
-
- return configurationRoot
-
- def checkConfigurableElementUnicity (self):
- """ check that all configurable elements defined in child configuration are the sames"""
-
- # get a list. Each elements of is the configurable element list of a configuration
- configurableElementsList = self.getRootConfiguration().getConfigurableElements()
-
- # if at least two configurations in the domain
- if len(configurableElementsList) > 1 :
-
- # get first configuration configurable element list sort
- configurableElementsList0 = list(configurableElementsList[0])
- configurableElementsList0.sort()
-
- for configurableElements in configurableElementsList :
- # sort current configurable element list
- auxConfigurableElements = list(configurableElements)
- auxConfigurableElements.sort()
-
- if auxConfigurableElements != configurableElementsList0 :
- # if different, 2 configurations those not have the same configurable element list
- # => one or more configurable element is missing in one of the 2 configuration
- raise UndefinedParameter(self.getName())
-
-
- def toPFWScript (self, pfwScriptContext=PFWScriptContext()):
- script = ""
-
- domainName = self.getName()
-
-
- script += pfwScriptContext.getPrefix() + \
- self.PFWCommandDomain + " " + \
- domainName + "\n"
-
- # get sequenceAwareness of this domain
- sequenceAwareness = self.option.getOption(self.sequenceAwareKeyword)
-
- # Copy and update pfwScriptContext for this domain
- pfwScriptContextAux = pfwScriptContext.copy()
- pfwScriptContextAux.setDomainName(domainName)
- pfwScriptContextAux.setSequenceAwareness(sequenceAwareness)
- pfwScriptContextAux.increasePrefix()
-
- # get configurable elements
- configurationRoot = self.getRootConfiguration()
- configurableElementsList = configurationRoot.getConfigurableElements()
-
- # add configurable elements
- if len(configurableElementsList) != 0 :
-
- for configurableElement in configurableElementsList[0] :
-
- script += pfwScriptContextAux.getPrefix() + \
- self.PFWCommandConfigurableElement + " " + \
- domainName + " " + \
- configurableElement + "\n"
-
- # new line to be more lisible :
- script += "\n"
-
- # add configuration settings
- script += configurationRoot.toPFWScript(pfwScriptContextAux)
-
- # to be more lisible :
- script += "\n"
-
- return script
-
-
-class GroupDomain (Domain) :
- tag = "groupDomain"
- match = re.compile(r"(supDomain|domainGroup) *:").match
- childWhiteList = ["GroupDomain", "Domain", "GroupConfiguration", "Rule", "Operator"]
-
- def toPFWScript (self, context={}):
- script = ""
- children = self.extractChildrenByClass([Domain, GroupDomain])
-
- for child in children :
- script += child.toPFWScript(context)
-
- return script
-
-# ----------------------------------------------------------
-
-class Root(Element):
- tag = "root"
- childWhiteList = ["Domain", "GroupDomain"]
-
-
-# ===========================================
-""" Syntax error Exceptions"""
-# ===========================================
-
-class MySyntaxProblems(SyntaxError) :
- comment = "syntax error in %(line)s "
-
- def __init__(self, line=None, num=None):
- self.setLine(line, num)
-
- def __str__(self):
-
- if self.line :
- self.comment = self.comment % {"line" : repr(self.line)}
- if self.num :
- self.comment = "Line " + str(self.num) + ", " + self.comment
- return self.comment
-
- def setLine (self, line, num):
- self.line = str(line)
- self.num = num
-
-
-# ---------------------------------------------------------
-
-class MyPropagationError(MySyntaxProblems) :
- """ Syntax error Exceptions used in the propagation step"""
- pass
-
-class UndefinedParameter(MyPropagationError) :
- comment = "Configurations in domain '%(domainName)s' do not all set the same parameters "
- def __init__ (self, domainName):
- self.domainName = domainName
- def __str__ (self):
- return self.comment % { "domainName" : self.domainName }
-
-
-# -----------------------------------------------------
-""" Syntax error Exceptions used by parser"""
-
-class MySyntaxError(MySyntaxProblems) :
- """ Syntax error Exceptions used by parser"""
- pass
-
-class MySyntaxWarning(MySyntaxProblems) :
- """ Syntax warning Exceptions used by parser"""
- pass
-
-class IndentationSyntaxError(MySyntaxError) :
- comment = """syntax error in %(line)s has no father element.
- You can only increment indentation by one tabutation per line")"""
-
-class EmptyLineWarning(MySyntaxWarning):
- comment = "warning : %(line)s is an empty line and has been ommited"
-
-class CommentWarning(MySyntaxWarning):
- comment = "warning : %(line)s is a commentary and has been ommited"
-
-class ChildNotPermitedError(MySyntaxError):
- def __init__(self, line, fatherElement, childElement):
- self.comment = "syntax error in %(line)s, " + fatherElement.tag + " should not have a " + childElement.tag + " child."
- super(ChildNotPermitedError, self).__init__(line)
-
-
-class UnknownElementTypeError(MySyntaxError):
- comment = " error in line %(line)s , not known element type were matched "
-
-class SpaceInIndentationError(MySyntaxError):
- comment = " error in ,%(line)s space is not permited in indentation"
-
-
-# ============================================
-"""Class creating the DOM elements from a stream"""
-# ============================================
-
-class ElementsFactory(object) :
- """Element factory, return an instance of the first matching element
-
- Test each element list in elementClass and instanciate it if it's methode match returns True
- The method match is called with input line as argument
- """
- def __init__ (self):
- self.elementClass = [
- EmptyLine ,
- Commentary,
- GroupDomain,
- Domain,
- Path,
- GroupConfiguration,
- Configuration,
- Operator,
- Rule,
- GroupPath
- ]
-
- def createElementFromLine (self, line) :
- """return an instance of the first matching element
-
- Test each element list in elementClass and instanciate it if it's methode match returns True
- The method match is called with the argument line.
- Raise UnknownElementTypeError if no element matched.
- """
- for element in self.elementClass :
- if element.match(line) :
- # print (line + element.__class__.__name__)
- return element(line)
- # if we have not find any
- raise UnknownElementTypeError(line)
-
-#------------------------------------------------------
-
-class Parser(object) :
- """Class implementing the parser"""
def __init__(self):
- self.rankPattern = re.compile(r"^([\t ]*)(.*)")
- self.elementFactory = ElementsFactory()
- self.previousRank = 0
-
- def __parseLine__(self, line):
-
- rank, rest = self.__getRank__(line)
-
- # instanciate the coresponding element
- element = self.elementFactory.createElementFromLine(rest)
-
- self.__checkIndentation__(rank)
-
- return rank, element
-
- def __getRank__(self, line):
- """return the rank, the name and the option of the input line
-
-the rank is the number of tabulation (\t) at the line beginning.
-the rest is the rest of the line."""
- # split line in rank and rest
- rank = self.rankPattern.match(line)
- if rank :
- rank, rest = rank.group(1, 2)
- else :
- raise MySyntaxError(line)
-
- # check for empty line
- if rest == "" :
- raise EmptyLineWarning(line)
-
- # check for space in indentation
- if rank.find(" ") > -1 :
- raise SpaceInIndentationError(line)
-
- rank = len (rank) + 1 # rank starts at 1
-
-
- return rank, rest
-
-
- def __checkIndentation__(self, rank):
- """check if indentation > previous indentation + 1. If so, raise IndentationSyntaxError"""
- if (rank > self.previousRank + 1) :
- raise IndentationSyntaxError()
- self.previousRank = rank
-
- def parse(self, stream, verbose=False):
- """parse a stream, usually a opened file"""
- myroot = Root("root")
- context = [myroot] # root is element of rank 0
- warnings = ""
-
- for num, line in enumerate(stream):
- try:
- rank, myelement = self.__parseLine__(line)
-
- while len(context) > rank :
- context.pop()
- context.append(myelement)
- context[-2].addChild(myelement)
-
- except MySyntaxWarning, ex:
- ex.setLine(line, num + 1)
- if verbose :
- print >>sys.stderr, ex
-
- except MySyntaxError, ex :
- ex.setLine(line, num + 1)
- raise
-
- return myroot
-
-# ============================
-# command line argument parser
-# ============================
+ super(PfwScriptTranslator, self).__init__()
+
+ self._script = []
+
+ def getScript(self):
+ return self._script
+
+ def _doCreateDomain(self, name):
+ self._script.append(
+ "{cmd} {domain}".format(
+ cmd="createDomain",
+ domain=name))
+
+ def _doSetSequenceAware(self):
+ self._script.append(
+ "{cmd} {domain} {aware}".format(
+ cmd="setSequenceAwareness",
+ domain=self._ctx_domain,
+ aware="true"))
+
+ def _doAddElement(self, path):
+ self._script.append(
+ "{cmd} {domain} {path}".format(
+ cmd="addElement",
+ domain=self._ctx_domain,
+ path=path))
+
+ def _doCreateConfiguration(self, name):
+ self._script.append(
+ "{cmd} {domain} {config}".format(
+ cmd="createConfiguration",
+ domain=self._ctx_domain,
+ config=name))
+
+ def _doSetElementSequence(self, paths):
+ self._script.append(
+ "{cmd} {domain} {config} {paths}".format(
+ cmd="setElementSequence",
+ domain=self._ctx_domain,
+ config=self._ctx_configuration,
+ paths=" ".join(paths)))
+
+ def _doSetRule(self, rule):
+ self._script.append(
+ "{cmd} {domain} {config} {rule}".format(
+ cmd="setRule",
+ domain=self._ctx_domain,
+ config=self._ctx_configuration,
+ rule=rule))
+
+ def _doSetParameter(self, path, value):
+ self._script.append(
+ "{cmd} {domain} {config} {path} '{value}'".format(
+ cmd="setConfigurationParameter",
+ domain=self._ctx_domain,
+ config=self._ctx_configuration,
+ path=path,
+ value=value))
class ArgparseArgumentParser(object) :
"""class that parse command line arguments with argparse library
@@ -1093,109 +104,35 @@ class ArgparseArgumentParser(object) :
myArgParser = argparse.ArgumentParser(description='Process domain scripts.')
- myArgParser.add_argument('inputFile', nargs='?',
- type=argparse.FileType('r'), default=sys.stdin,
- help="the domain script file, default stdin")
+ myArgParser.add_argument('input', nargs='?',
+ type=argparse.FileType('r'), default=sys.stdin,
+ help="the domain script file, default stdin")
myArgParser.add_argument('-o', '--output',
- dest="outputFile",
- type=argparse.FileType('w'), default=sys.stdout,
- help="the output file, default stdout")
+ type=argparse.FileType('w'), default=sys.stdout,
+ help="the output file, default stdout")
myArgParser.add_argument('-d', '--debug',
- dest="debugFlag",
- action='store_true',
- help="print debug warnings")
-
+ action='store_true',
+ help="print debug warnings")
- outputFormatGroupe = myArgParser.add_mutually_exclusive_group(required=False)
-
- outputFormatGroupe.add_argument('--pfw',
- dest="pfwFlag",
- action='store_true',
- help="output pfw commands (default)")
- outputFormatGroupe.add_argument('--raw',
- dest="rawFlag",
- action='store_true',
- help="output raw domain tree (DEBUG ONLY)")
+ myArgParser.add_argument('--output-kind',
+ choices=['pfw', 'raw'],
+ default='pfw',
+ help="output kind; can be either 'raw' (debug only) or 'pfw' (pfw commands; default choice)")
# process command line arguments
options = myArgParser.parse_args()
# maping to atributs
- self.inputFile = options.inputFile
- self.output = options.outputFile
-
- self.debug = options.debugFlag
+ self.input = options.input
+ self.output = options.output
- if not (options.pfwFlag or options.rawFlag) :
- # --pfw is default if none provided
- self.pfw = True
- else :
- self.pfw = options.pfwFlag
- self.raw = options.rawFlag
-
-
-class OptParseArgumentParser(object) :
- """class that parse command line arguments with optparse library
-
- result of parsing are the class atributs"""
- def __init__(self) :
+ self.debug = options.debug
- myOptParser = optparse.OptionParser(usage="usage: [-h] [-d] [--pfw | --raw] "
- "[-o OUTPUTFILE] [INPUTFILE]",
- description="Process domain scripts")
+ self.output_kind = options.output_kind
- myOptParser.add_option('-o', '--output',
- dest="outputFile", metavar="FILE",
- help="the output file, default stdout")
-
- myOptParser.add_option('-d', '--debug',
- dest="debugFlag",
- action='store_true',
- help="print debug warnings")
-
-
- outputFormatGroupe = optparse.OptionGroup(myOptParser, "output format")
-
- outputFormatGroupe.add_option('--pfw',
- dest="pfwFlag",
- action='store_true',
- help="output pfw commands (default)")
- outputFormatGroupe.add_option('--raw',
- dest="rawFlag",
- action='store_true',
- help="output raw domain tree (DEBUG ONLY)")
-
-
- # process command line arguments
- (options, args) = myOptParser.parse_args()
-
- # If no input file provided, use default one
- if len(args) == 0:
- args = [None]
-
- # mapping to attributes
- self.inputFile = self.open_secured(args[0], 'r') or sys.stdin
- self.output = self.open_secured(options.outputFile, 'w') or sys.stdout
-
- self.debug = options.debugFlag
-
- if not (options.pfwFlag or options.rawFlag) :
- # --pfw is default if none provided
- # TODO: find a way to do that with argparse directly
- self.pfw = True
- else :
- self.pfw = options.pfwFlag
- self.raw = options.rawFlag
-
- @staticmethod
- def open_secured(file, openMode="r"):
- if file:
- return open(file, openMode)
-
- return None
# ==============
# main function
@@ -1203,46 +140,36 @@ class OptParseArgumentParser(object) :
def printE(s):
"""print in stderr"""
- print >>sys.stderr, str(s)
+ sys.stderr.write(str(s))
def main ():
- # Get command line arguments
- try:
- imp.find_module("argparse")
-
- except ImportError:
- printE("Warning: unable to import argparse module, fallback to optparse")
- # Using optparse
- options = OptParseArgumentParser()
+ options = ArgparseArgumentParser()
- else:
- # Using argparse
- options = ArgparseArgumentParser()
-
- myparser = Parser()
+ myparser = EddParser.Parser()
try:
- myroot = myparser.parse(options.inputFile, options.debug)
+ myroot = myparser.parse(options.input, options.debug)
- except MySyntaxError, ex :
+ except EddParser.MySyntaxError as ex:
printE(ex)
printE("EXIT ON FAILURE")
- exit (2)
- else :
- if options.raw :
- options.output.write(str(myroot))
- else :
- try :
- myroot.propagate()
+ exit(2)
+
+ if options.output_kind == 'raw':
+ options.output.write(str(myroot))
+ else:
+ try:
+ myroot.propagate()
- except MyPropagationError, ex :
- printE(ex)
- printE("EXIT ON FAILURE")
- exit(1)
+ except EddParser.MyPropagationError, ex :
+ printE(ex)
+ printE("EXIT ON FAILURE")
+ exit(1)
- else:
- if options.pfw :
- options.output.write(myroot.toPFWScript())
+ if options.output_kind == 'pfw':
+ translator = PfwScriptTranslator()
+ myroot.translate(translator)
+ options.output.write("\n".join(translator.getScript()))
# execute main function if the python interpreter is running this module as the main program
if __name__ == "__main__" :