from jwutils.stree.StringTree import * from jwutils.log import * def _cleanup_line(line): line = line.strip() r = '' in_quote = None for c in line: # slog(DEBUG, "in_quote = >" + str(in_quote) + "<") if in_quote is not None: if c == in_quote: in_quote = None else: if c in [ '"', "'" ]: in_quote = c elif in_quote is None and c == '#': return r.strip() r += c if len(r) >= 2 and r[0] in [ '"', "'" ] and r[-1] == r[0]: return r[1:-1] return r def parse(s, allow_full_lines=True, root_content='root'): # export slog(DEBUG, "parsing", s) root = StringTree('', content=root_content) sec = '' for line in s.splitlines(): slog(DEBUG, "line=", line) line = _cleanup_line(line) #slog(DEBUG, "cleaned line=", line) if not len(line): continue if line[0] == '[': if line[-1] == ']': sec = line[1:-1] elif line[-1] == '[': if len(sec): sec += '.' sec += line[1:-1] else: raise Exception("failed to parse section line", line) if root.get(sec) is None: root.add(sec) continue elif line[0] == ']': assert(len(sec) > 0) sec = '.'.join(sec.split('.')[0:-1]) continue lhs = '' rhs = None for c in line: if rhs is None: if c == '=': rhs = '' continue lhs += c continue rhs += c split = True if rhs is None: if not allow_full_lines: raise Exception("failed to parse assignment", line) rhs = 'empty' split = False root.add(sec + '.' + cleanup_string(lhs), cleanup_string(rhs), split=split) return root def read(path, root_content='root'): # export with open(path, 'r') as infile: s = infile.read() return parse(s, root_content=root_content)