Commit 79ea5529 authored by Vincent Michel's avatar Vincent Michel

Add xia ini file parser

parent dcf7592e
Pipeline #941 passed with stages
in 1 minute and 18 seconds
......@@ -22,7 +22,6 @@ Run requirements:
- cffi
- numpy
- configparser
Test requirements:
......
......@@ -3,12 +3,12 @@
from __future__ import absolute_import
import os
import configparser
import numpy
from .error import check_error
from ._cffi import handel, ffi
from .parser import parse_xia_ini_file
__all__ = ['init', 'init_handel', 'exit',
'new_detector', 'get_num_detectors', 'get_detectors',
......@@ -408,13 +408,14 @@ def get_handel_version():
def get_config_files(path):
"""Return all the ini files in path (including subdirectories)."""
ext = b'.ini' if isinstance(path, bytes) else '.ini'
return [os.path.join(dp, f)
for dp, dn, fn in os.walk(path)
for f in fn
if f.endswith('.ini')]
if f.endswith(ext)]
def get_config(filename):
"""Read and return the given config file as a dictionary."""
with open(filename) as f:
return f.read()
return parse_xia_ini_file(f.read())
"""Parser for the specific XIA INI file format."""
from collections import OrderedDict
def parse_xia_ini_file(content):
dct = OrderedDict()
section, item = None, None
# Loop over striped lines
for line in content.splitlines():
line = line.strip()
# Comment
if line.startswith('*'):
pass
# New section
elif line.startswith('[') and line.endswith(']'):
section = line[1:-1].strip()
dct[section] = []
# New item
elif line.startswith('START #'):
item = int(line.split('#')[1])
if item != len(dct[section]):
msg = 'Corrupted start (section {}, {} != {})'
msg = msg.format(section, item, len(dct[section]))
raise ValueError(msg)
if section is None:
msg = 'Item {} outside of section'
raise ValueError(msg.format(item))
dct[section].append(OrderedDict())
# End item
elif line.startswith('END #'):
item = int(line.split('#')[1])
if item != len(dct[section]) - 1:
msg = 'Corrupted end (section {}, {} != {})'
msg = msg.format(section, item, len(dct[section]) - 1)
raise ValueError(msg)
if section is None:
msg = 'Item {} outside of section'
raise ValueError(msg.format(item))
item = None
# New pair
elif '=' in line:
key, value = map(str.strip, line.split('='))
if section is None:
msg = 'Key/value pair {} outside of section'
raise ValueError(msg.format((key, value)))
if item is None:
msg = 'Key/value pair {} outside of item'
raise ValueError(msg.format((key, value)))
dct[section][item][key] = value
# Error
elif line:
raise ValueError('Line not recognized: {!r}'.format(line))
# Return result
return dct
......@@ -11,7 +11,7 @@ setup(
version='0.1.1.dev0',
packages=['handel'],
install_requires=['cffi', 'numpy', 'configparser'],
install_requires=['cffi', 'numpy'],
setup_requires=['pytest-runner', 'pytest'] if TESTING else [],
tests_require=['pytest-cov', 'mock'],
......
......@@ -492,11 +492,12 @@ def test_get_handel_version(interface):
def test_get_config_files(interface):
assert interface.get_config_files('.') == ['./scripts/mercury.ini']
assert interface.get_config_files(b'.') == [b'./scripts/mercury.ini']
def test_get_config(interface):
filename = interface.get_config_files('.')[0]
conf = interface.get_config(filename)
assert 'alias = detector1' in conf
assert conf['detector definitions'][0]['alias'] == 'detector1'
with pytest.raises(IOError):
interface.get_config('i_dont_exist.ini')
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment