pyulib: ajouter ShConfig

This commit is contained in:
Jephté Clain 2017-10-16 04:37:26 +04:00
parent f31f5f72ad
commit 9c5b46b372
1 changed files with 69 additions and 3 deletions

View File

@ -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()