diff --git a/bcfg2/pygen.py b/bcfg2/pygen.py index dce550c1..ae6bff23 100644 --- a/bcfg2/pygen.py +++ b/bcfg2/pygen.py @@ -35,46 +35,38 @@ def done(): class Environment(dict): '''Environment dans lequel sont éxécuté les scripts''' - # Dernière variable exportée à avoir été définie - last_definition = None - # Le flux de sortie stream = None - # Les variables qui sont partagées entre le script éxécuté - # et le programme appelant - shared = ["out", "exports", "export_definition", - "last_definition", "conv", "tostring"] - def __init__(self): - # Les variables à "exporter" dans le fichier produit - self.exports = {} - # Fonctions de convertions initiales - self.conv = {bool: {True: "yes", False: "no"}, - list: lambda l: ", ".join([str(x) for x in l]), - tuple: lambda l: ", ".join([str(x) for x in l])} # Création de l'environment initial dict.__init__(self, { - # Permet d'accéder aux variables exportées - "exports": self.exports, + # Les variables à "exporter" dans le fichier produit + "exports": set([]), + # Export d'une variable "export": self.export, - # On met a disposition le nécessaire pour surcharger - # la gestion des variables exportée - "last_definition": self.last_definition, + # Dernière variable exportée à avoir été définie + "last_definition": None, + # Écrit: variable keysep tostring(value) "export_definition": self.export_definition, - # La convertion - "conv": self.conv, + # La convertion en chaîne de charactère "tostring": self.tostring, + # Définition des convertions + "conv": {bool: {True: "yes", False: "no"}, + list: lambda l: ", ".join([str(x) for x in l]), + tuple: lambda l: ", ".join([str(x) for x in l])}, # Fonction de base pour imprimer quelque chose "out": self.out, # Arrêt du script - "done": done}) + "done": done, + # Le séparateur pour la forme: variable keysep valeur + "keysep": "=", + # Le charactère de commentaire + "comment_start": "#"}) def __setitem__(self, variable, value): '''Lorsqu'on définie une variable, on "l'exporte" dans le fichier produit''' -# if variable in self.shared: -# self.__setattr__(variable, value) if variable in self["exports"]: self["export_definition"](variable, value) dict.__setitem__(self, "last_definition", variable) @@ -83,7 +75,7 @@ class Environment(dict): def export_definition(self, variable, value): '''Fonction par défaut pour gérée la définition des variables exportée. écrit 'variable = tostring(value)' dans le fichier produit''' - self["out"]("%s = %s\n" % (variable, self["tostring"](value))) + self["out"]("%s%s%s\n" % (variable, self["keysep"], self["tostring"](value))) def out(self, string): '''Fonction de base pour écrire une chaine dans le fichier produit''' @@ -104,9 +96,9 @@ class Environment(dict): # mais elle est pratique donc on la met pour tout le monde def export(variable): '''Exporte une variable''' - self["exports"][variable] = True + self["exports"].add(variable) -__re_special_line = re.compile(r"^([ \t]*)@(.*)$", re.MULTILINE) +__re_special_line = re.compile(r"^([ \t]*)(@|%)(.*)$", re.MULTILINE) def compileSource(source, filename=""): '''Compile un script''' @@ -117,9 +109,34 @@ def compileSource(source, filename=""): for m in __re_special_line.finditer(source): newsource.write(source[start:m.start()]) newsource.write(m.group(1)) - newsource.write('out("') - newsource.write(m.group(2).replace("\\", "\\\\").replace('"', '\\"')) - newsource.write('\\n")') + linetype = m.group(2) + if linetype == "@": + line = m.group(3).replace("\\", "\\\\").replace('"', '\\"') + if line and line[0] == "#": + newsource.write('out(comment_start + "') + line = line[1:] + else: + newsource.write('out("') + newsource.write(line) + newsource.write('\\n")') + elif linetype == "%": + line = m.group(3) + sp = line.split("=", 1) + if len(sp) == 1: + sp = line.split(" ", 1) + newsource.write("export_definition('") + newsource.write(sp[0]) + newsource.write("', tostring(") + newsource.write(sp[1]) + newsource.write("))\n") + varname = sp[0].strip() + else: + newsource.write(line) + newsource.write("; export_definition('") + newsource.write(sp[0]) + newsource.write("', tostring(") + newsource.write(sp[0]) + newsource.write("))\n") start = m.end() newsource.write(source[start:]) return compile(newsource.getvalue(), filename, "exec")