Last active
April 8, 2021 22:19
-
-
Save fuzzy/6c117ad488bef2789dba to your computer and use it in GitHub Desktop.
parses config files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import re | |
import json | |
import shlex | |
import types | |
import ConfigParser | |
_tokens = [] | |
data = {'global': {}} | |
regex = { | |
'section': re.compile('^\[[a-zA-Z0-9_]+\]$'), | |
'string': re.compile('^(\'.*\'|\".*\")$'), | |
'key': re.compile('^[a-zA-Z_]+:$'), | |
'macro': re.compile('^\$\{.*\}$') | |
} | |
def loadConfig(cfgfile): | |
global _tokens, data, regex | |
if not cfgfile: | |
raise ValueError, 'You must specify a path+filename.' | |
# We have a 3 pass parser here. | |
# first pass, pull in the file and parse out comments | |
_slurpFile(cfgfile) | |
# second pass, actually parse the file into the data structure | |
_parseFile() | |
# and third pass, ensure all macro interpolation is handled | |
tmp = _interpolate(data) | |
data = tmp | |
from pprint import pprint as pp | |
pp(data) | |
def _interpolate(node): | |
global _tokens, data, regex | |
for key in node.keys(): | |
if type(node[key]) == types.DictType: | |
t = _interpolate(node[key]) | |
node[key] = t | |
else: | |
if regex['macro'].match(node[key]): | |
if node[key][2:-1].find(':') != -1: | |
k,v = node[key][2:-1].split(':') | |
node[key] = data[k][v] | |
else: | |
node[key] = node[node[key][2:-1]] | |
return node | |
def _parseFile(): | |
global _tokens, data, regex | |
section = 'global' | |
for idx in range(0, len(_tokens)): | |
if not regex['string'].match(_tokens[idx]): | |
if regex['section'].match(_tokens[idx]): | |
if _tokens[idx][1:-1] not in data.keys(): | |
section = _tokens[idx][1:-1] | |
data[section] = {} | |
elif regex['key'].match(_tokens[idx]): | |
try: | |
if regex['string'].match(_tokens[idx+1]): | |
data[section][_tokens[idx][0:-1]] = json.loads(_tokens[idx+1][1:-1]) | |
else: | |
data[section][_tokens[idx][0:-1]] = json.loads(_tokens[idx+1]) | |
except ValueError: | |
print section, idx, _tokens[idx] | |
data[section][_tokens[idx][0:-1]] = _tokens[idx+1] | |
def _slurpFile(cfgfile): | |
global _tokens, data, regex | |
if not os.path.isfile(cfgfile): | |
raise ValueError, '%s: no such file' % cfgfile | |
_cfgfp = open(cfgfile) | |
buff = [] | |
tbuf = _cfgfp.readline() | |
# make sure we don't keep comments around | |
# TODO: support end of line comments | |
while tbuf: | |
if tbuf[0] != '#': | |
buff.append(tbuf) | |
tbuf = _cfgfp.readline() | |
# Hand off a shlex parsed set of tokens for pass 2 | |
_tokens = shlex.split(''.join(buff)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment