parse_subst
index
/home/pfeiffer/project-shared/publicize/bii_scripts-top/bii_scripts/lib/python/bii_scripts3/parse_subst.py

===========
parse_subst
===========
 
Preface
=======
 
This module contains a parser function for epics substitution-files. The
contents of the db-file are returned in a python dictionary or list structure
that can then be used for further evaluation.
 
Implemented Functions
---------------------
 
parse
+++++
 
Definition::
 
  parse(data, mode= "dict", errmsg_prefix= None)
 
This function parses a given string variable that must contain a complete
substitution-file. It returns a data structure where the parsed data is
stored.
 
The new "global" statement in substitution files is also supported. Globals are
resolved, meaning that definitions of global values are merged in the local
per-file definitions. Applications that use parse_subst do not have to be
aware of the global statement.
 
parameters:
 
- data          : The string containing the substitution data.
- mode          : Either "dict" or "list". This determines the format of the
                  returned data structure, see examples below.
- errmsg_prefix : This message is prepended to possible parse error messages
 
parse_file
++++++++++
 
Definition::
 
  parse_file(filename, mode= "dict", encoding= None)
 
This function parses the contents of a file specified by a filename. If the
parameter "filename" is "-", it reads from STDIN. It returns a data structure
where the parsed data is stored.
 
parameters:
 
- filename : The name of the file.
- mode     : Either "dict" or "list". This determines the format of the
             returned data structure, see examples below.
- encoding : The encoding of the file, the default is your system's encoding
             default, which usually is UTF-8. A list of valid encodings can be
             found at:
             https://docs.python.org/3/library/codecs.html#standard-encodings.
 
json_str
++++++++
 
Definition::
 
  json_str(var, ensure_ascii= True)
 
This function converts a python data structure to a JSON string. It uses the
standard JSON module from python with some useful defaults.
 
parameters:
 
- var          : The data structure.
- ensure_ascii : If True, ensure that the JSON string contains only ASCII
                 characters, all other characters are converted to JSON escape
                 codes. If False, leave non-ASCII characters in the string.
 
json_print
++++++++++
 
Definition::
 
  json_print(var, ensure_ascii= True)
 
This function converts a python data structure to a JSON string and prints it
to the console. It uses the standard JSON module from python with some useful
defaults.
 
parameters:
 
- var          : The data structure.
- ensure_ascii : If True, ensure that the JSON string contains only ASCII
                 characters, all other characters are converted to JSON escape
                 codes. If False, leave non-ASCII characters in the string.
 
data structures
---------------
 
In all the examples below, this is the substitution data parsed::
 
  file adimogbl.template
    {
      {
        GBASE="U3IV:",
        TRIG1="U3IV:AdiMoVGblTrg.PROC",
      }
    }
  file adimovhgbl.template
    {
      {
        GBASE="U3IV:",
        DRV="V",
        AdiMopVer="9",
        TRIG1="U3IV:AdiVGblPvr.PROC",
      }
      {
        GBASE="U3IV:",
        DRV="H",
        AdiMopVer="9",
        TRIG1="U3IV:AdiHGblPvr.PROC",
      }
    }
 
dict structure
++++++++++++++
 
When the "mode" parameter of the parse function is not given or set to 'dict',
the parse function returns a dict structure.
 
Each template-name is a key in the dictionary. It's value is a list that
contains the data for that template.
 
The list contains dictionary for each instantiation of that template.
 
Each instantiation dictionary contains a key-value pair for each field name
value.  Note that undefined fields-values are empty strings ("").
 
Example of a dictionary that parse() returns::
 
  {
    'adimovhgbl.template' : [
                               {
                                 'TRIG1' : 'U3IV:AdiVGblPvr.PROC',
                                 'DRV' : 'V',
                                 'GBASE' : 'U3IV:',
                                 'AdiMopVer' : '9'
                               },
                               {
                                 'TRIG1' : 'U3IV:AdiHGblPvr.PROC',
                                 'DRV' : 'H',
                                 'GBASE' : 'U3IV:',
                                 'AdiMopVer' : '9'
                               }
                             ],
    'adimogbl.template' : [
                             {
                               'TRIG1' : 'U3IV:AdiMoVGblTrg.PROC',
                               'GBASE' : 'U3IV:'
                             }
                           ]
  }
 
list structure
++++++++++++++
 
When the "mode" parameter of the parse function is set to 'list', the parse
function returns a list structure.
 
The list contains a list for each template-name. Within these lists, the first
element is the template-name, all following elements are dictionaries, one for
each instantiation of that template.
 
Each instantiation dictionary contains a key-value pair for each field name
value.  Note that undefined fields-values are empty strings ("").
 
Example of a dictionary that parse() returns::
 
  [
    [
      'adimogbl.template',
      {
        'TRIG1' : 'U3IV:AdiMoVGblTrg.PROC',
        'GBASE' : 'U3IV:'
      }
    ],
    [
      'adimovhgbl.template',
      {
        'TRIG1' : 'U3IV:AdiVGblPvr.PROC',
        'DRV' : 'V',
        'GBASE' : 'U3IV:',
        'AdiMopVer' : '9'
      },
      {
        'TRIG1' : 'U3IV:AdiHGblPvr.PROC',
        'DRV' : 'H',
        'GBASE' : 'U3IV:',
        'AdiMopVer' : '9'
      }
    ]
  ]

 
Modules
       
bisect
json
locale
re
sys
textwrap

 
Classes
       
builtins.Exception(builtins.BaseException)
ParseException
builtins.object
IndexedString

 
class IndexedString(builtins.object)
    IndexedString(st)
 
a string together with row column information.
 
Here is an example:
 
>>> txt='''01234
... 67
... 9abcd'''
>>> l=IndexedString(txt)
>>> l.rowcol(0)
(1, 1)
>>> l.rowcol(1)
(1, 2)
>>> l.rowcol(4)
(1, 5)
>>> l.rowcol(5)
(1, 6)
>>> l.rowcol(6)
(2, 1)
>>> l.rowcol(7)
(2, 2)
>>> l.rowcol(8)
(2, 3)
>>> l.rowcol(9)
(3, 1)
>>> l.rowcol(13)
(3, 5)
>>> l.rowcol(14)
(3, 6)
>>> l.rowcol(16)
(3, 8)
 
  Methods defined here:
__init__(self, st)
Initialize self.  See help(type(self)) for accurate signature.
__repr__(self)
Return repr(self).
__str__(self)
Return str(self).
line(self, pos)
return the line that contains the position.
rowcol(self, pos)
calculate (row,column) from a string position.
st(self)
return the raw string.

Data descriptors defined here:
__dict__
dictionary for instance variables
__weakref__
list of weak references to the object

 
class ParseException(builtins.Exception)
    ParseException(value, str_=None, pos=None)
 
used for Exceptions in this module.
 
 
Method resolution order:
ParseException
builtins.Exception
builtins.BaseException
builtins.object

Methods defined here:
__init__(self, value, str_=None, pos=None)
Initialize self.  See help(type(self)) for accurate signature.
__str__(self)
Return str(self).

Data descriptors defined here:
__weakref__
list of weak references to the object

Static methods inherited from builtins.Exception:
__new__(*args, **kwargs) class method of builtins.Exception
Create and return a new object.  See help(type) for accurate signature.

Methods inherited from builtins.BaseException:
__getattribute__(self, name, /)
Return getattr(self, name).
__reduce__(...)
Helper for pickle.
__repr__(self, /)
Return repr(self).
__setstate__(...)
add_note(...)
Exception.add_note(note) --
add a note to the exception
with_traceback(...)
Exception.with_traceback(tb) --
set self.__traceback__ to tb and return self.

Data descriptors inherited from builtins.BaseException:
__cause__
exception cause
__context__
exception context
__dict__
__suppress_context__
__traceback__
args

 
Functions
       
create(data, use_pattern=False, maxlen=None)
create substitution data from structure.
create_print(data, use_pattern=False, maxlen=None)
print data returned by create.
json_print(var, ensure_ascii=True)
print as JSON to the console.
json_str(var, ensure_ascii=True)
convert a variable to JSON format.
 
Here is an example:
 
>>> var= {"key":[1,2,3], "key2":"val", "key3":{"A":1,"B":2}}
>>> print(json_str(var))
{
    "key": [
        1,
        2,
        3
    ],
    "key2": "val",
    "key3": {
        "A": 1,
        "B": 2
    }
}
<BLANKLINE>
parse(data, mode='dict', errmsg_prefix=None)
convert a single string.
parse_file(filename, mode='dict', encoding=None)
parse a file.
quote(st)
always return a quoted string.
 
Here are some examples:
>>> quote('')
'""'
>>> quote('a')
'"a"'
>>> quote('"a"')
'"a"'
>>> quote('"a')
'"a"'
>>> quote('a"')
'"a"'
test_encoding(encoding)
test if an encoding is known.
 
raises (by encode() method) a LookupError exception in case of an error.
unquote(st)
removes quotes around a string.
 
Here are some examples:
>>> unquote("")
''
>>> unquote('"')
''
>>> unquote('""')
''
>>> unquote('"x"')
'x'
>>> unquote('"x')
'x'
>>> unquote('x"')
'x'
warning(msg)
warning to stderr.

 
Data
        LINESEP = '\n'
LINESEP_LEN = 1
MODES = {'dict', 'list'}
PERMISSIVE = True
SYS_DEFAULT_ENCODING = 'UTF-8'
WARNINGS = True
rx_bracket1 = re.compile('(\\s*(?:\\s*(?:|\\#[^\\r\\n]*)[\\r\\n]+)*\\s*)\\{', re.MULTILINE)
rx_bracket2 = re.compile('(\\s*(?:\\s*(?:|\\#[^\\r\\n]*)[\\r\\n]+)*\\s*)\\}', re.MULTILINE)
rx_comma = re.compile('\\s*,', re.MULTILINE)
rx_complete_unquoted_value = re.compile('(?:[^"\\s\\{\\},]+)$')
rx_complete_unquoted_word = re.compile('(?:\\w+)$')
rx_def = re.compile('(\\s*(?:\\s*(?:|\\#[^\\r\\n]*)[\\r\\...\\s*)(,?)(\\s*(?:\\s*(?:|\\#[^\\r\, re.MULTILINE)
rx_file_head = re.compile('(\\s*(?:\\s*(?:|\\#[^\\r\\n]*)[\\r\\...:|\\#[^\\r\\n]*)[\\r\\n]+)*\\s*){', re.MULTILINE)
rx_pattern = re.compile('(\\s*(?:\\s*(?:|\\#[^\\r\\n]*)[\\r\\n]+)*\\s*)pattern', re.MULTILINE)
rx_top = re.compile('(\\s*(?:\\s*(?:|\\#[^\\r\\n]*)[\\r\\n]+)*\\s*)(file|global|)', re.MULTILINE)
rx_unquoted_filename = re.compile('(?:[^\\/\\s\\{\\}]+)', re.MULTILINE)
rx_val = re.compile('(\\s*(?:\\s*(?:|\\#[^\\r\\n]*)[\\r\\..."|(?:[^"\\s\\{\\},]+))\\s*(,|\\})', re.MULTILINE)
st_bracket1 = r'(\s*(?:\s*(?:|\#[^\r\n]*)[\r\n]+)*\s*)\{'
st_bracket2 = r'(\s*(?:\s*(?:|\#[^\r\n]*)[\r\n]+)*\s*)\}'
st_comma = r'\s*,'
st_def = r'(\s*(?:\s*(?:|\#[^\r\n]*)[\r\n]+)*\s*)(\"(?:\w+)...*)(,?)(\s*(?:\s*(?:|\#[^\r\n]*)[\r\n]+)*\s*)(\}?)'
st_file_head = r'(\s*(?:\s*(?:|\#[^\r\n]*)[\r\n]+)*\s*)(\"(?:.*?)...\s\{\}]+))(\s*(?:\s*(?:|\#[^\r\n]*)[\r\n]+)*\s*){'
st_pattern = r'(\s*(?:\s*(?:|\#[^\r\n]*)[\r\n]+)*\s*)pattern'
st_quoted = r'\"(?:.*?)(?<!\\)\"'
st_quoted_word = r'\"(?:\w+)\"'
st_space_or_comment = r'\s*(?:\s*(?:|\#[^\r\n]*)[\r\n]+)*\s*'
st_top = r'(\s*(?:\s*(?:|\#[^\r\n]*)[\r\n]+)*\s*)(file|global|)'
st_unquoted_filename = r'(?:[^\/\s\{\}]+)'
st_unquoted_value = r'(?:[^"\s\{\},]+)'
st_unquoted_word = r'(?:\w+)'
st_val = r'(\s*(?:\s*(?:|\#[^\r\n]*)[\r\n]+)*\s*)(\"(?:.*?)(?<!\\)\"|(?:[^"\s\{\},]+))\s*(,|\})'