From 9c5b46b372584edfbf854a78cb87d50bbcb59349 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Mon, 16 Oct 2017 04:37:26 +0400 Subject: [PATCH] pyulib: ajouter ShConfig --- lib/pyulib/src/ulib/base/config.py | 72 ++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/lib/pyulib/src/ulib/base/config.py b/lib/pyulib/src/ulib/base/config.py index 3c63f2b..5d04774 100644 --- a/lib/pyulib/src/ulib/base/config.py +++ b/lib/pyulib/src/ulib/base/config.py @@ -11,14 +11,18 @@ value peut être placé entre double quotes ou simple quotes. Elle peut s'étend plusieurs lignes si elle est mise entre quotes, ou si elle se termine par \ """ -__all__ = ('ConfigFile', 'ShConfigFile', 'PListFile') +__all__ = ( + 'ConfigFile', 'ShConfigFile', 'PListFile', + 'ShConfig', +) -import os, string, re, types +import os, string, re, types, shlex from os import path -from base import make_prop, isseq, seqof, firstof +from base import odict, make_prop, isseq, seqof, firstof from uio import _s, _u from files import TextFile +from ulib.formats import unicodeF #################### # gestion des commentaires @@ -806,6 +810,68 @@ class PListFile(TextFile): _print_debug("XXX string=%s" % string) return string +################################################################################ +# classes utilisant shlex et l'interface odict + +class ShConfig(odict): + _formats = None + def __init__(self, config, formats=None): + super(ShConfig, self).__init__() + if formats is None: formats = {} + else: formats = dict(formats) + self.__dict__['_formats'] = formats + for name in self._formats.keys(): + self[name] = None + + inf = open(config, 'rb') + try: s = inf.read() + finally: inf.close() + parts = shlex.split(s, True) + self.parse(parts) + + def get_format(self, name): + format = None + if format is None: format = self._formats.get(name, None) + if format is None: format = self._formats.get(None, None) + if format is None: format = unicodeF + return format + + RE_ARRAY = re.compile(r'([^=]+)=\((.*)') + RE_ARRAY_LAST = re.compile(r'(.*)\)$') + RE_SCALAR = re.compile(r'([^=]+)=(.*)') + def parse(self, parts): + i = 0 + while i < len(parts): + part = parts[i] + i += 1 + amo = self.RE_ARRAY.match(part) + smo = self.RE_SCALAR.match(part) + if amo is not None: + array = [] + name, value = amo.groups() + format = self.get_format(name) + if value != '': array.append(format.parse(value)) + while i < len(parts): + value = parts[i] + i += 1 + mo = self.RE_ARRAY_LAST.match(value) + if mo is not None: + value = mo.group(1) + if value != '': array.append(format.parse(value)) + break + else: + array.append(format.parse(value)) + self[name] = array + elif smo is not None: + name, value = smo.groups() + format = self.get_format(name) + self[name] = format.parse(value) + else: + continue # ignorer l'erreur pour le moment + raise ValueError("%s: not a variable" % part) + +################################################################################ + if __name__ == '__main__': import doctest doctest.testmod()