From c614e4b06a3e6a3e944b25e803001814bb77b63a Mon Sep 17 00:00:00 2001 From: oysteini Date: Sun, 9 Oct 2011 14:39:07 +0000 Subject: [PATCH] Improved reading in fileformat.py. * Handles comments (lines starting with '#'). * Remembers line numbers, and uses them in error messages. --- cli/fileformat.py | 50 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/cli/fileformat.py b/cli/fileformat.py index 3b89c90..c2d005f 100644 --- a/cli/fileformat.py +++ b/cli/fileformat.py @@ -1,3 +1,4 @@ +import re import types # The possible fields for each type of object. @@ -52,7 +53,9 @@ action_fields = { 'required': ['id'] } } class CommitFormatSyntaxError(Exception): - pass + def __init__(self, msg, linenr): + super(CommitFormatSyntaxError, self).__init__(self, 'Syntax error on line %d: %s' % + (linenr, msg)) def read_field_value_str(val): if val.strip() == '': @@ -79,30 +82,31 @@ def read_field_value_dict(val): def read_field_value_list(val): return val.strip().split(' ') -def read_action(text): +def read_action(lines): ''' Parse text as an action, returning a dictionary. ''' - lines = text.split('\n') print 'reading action' print 'lines:' print lines d = {} lastfield = None - for line in lines: + for (linenr, line) in lines: if len(line) == 0: - raise CommitFormatSyntaxError('Empty line in action') + raise CommitFormatSyntaxError('Empty line in action', linenr) if line[0] in [' ', '\t']: # continuation line if not lastfield: - raise CommitFormatSyntaxError('First line is continuation line: ' + line) + raise CommitFormatSyntaxError('First line is continuation line: ' + line, linenr) d[lastfield] = d[lastfield] + '\n' + line.strip() else: field, value = line.split(':', 1) d[field] = value.strip() lastfield = field + firstlinenr = lines[0][0] + if 'action' not in d: - raise CommitFormatSyntaxError('Missing \'action\' field') + raise CommitFormatSyntaxError('Missing \'action\' field', firstlinenr) action = d['action'] print 'dict:' @@ -110,7 +114,9 @@ def read_action(text): for field in action_fields[action]['required']: if field not in d: - raise CommitFormatSyntaxError('Missing required field \'%s\' in \'%s\' action' % (field, action)) + raise CommitFormatSyntaxError('Missing required field \'%s\' in \'%s\' action' % + (field, action), + firstlinenr) data_type = action_fields[action]['type'] result = { 'action': action } for field, ftype in fields[data_type]: @@ -128,14 +134,38 @@ def read_action(text): return result +def read_paragraphs(text): + lines = text.split('\n') + current_para = [] + paragraphs = [] + comment_re = r'^#.*$' + blank_re = r'^[ \t]*$' + for i in xrange(len(lines)): + l = lines[i] + if re.match(comment_re, l): + print 'comment:', l + continue + elif re.match(blank_re, l): + print 'blank:', l + if len(current_para) > 0: + paragraphs.append(current_para) + current_para = [] + else: + current_para.append((i+1, l)) + if len(current_para) > 0: + paragraphs.append(current_para) + current_para = [] + return paragraphs + def read_actionlist(text): ''' Parse text as a list of actions. The result is a list of dictionaries. ''' - return map(lambda x: read_action(x.strip()), - text.split('\n\n')) + paragraphs = read_paragraphs(text) + print 'paragraphs:', paragraphs + return map(read_action, paragraphs) def write_field_value_str(val): lines = ''