# # # patch "mtn.py" # from [ce95ba92be3d66183fe9170e2885b676e039c404] # to [9aacc29cd3af6277ef411f7e582a450f58c727ee] # ============================================================ --- mtn.py ce95ba92be3d66183fe9170e2885b676e039c404 +++ mtn.py 9aacc29cd3af6277ef411f7e582a450f58c727ee @@ -111,7 +111,7 @@ if code and code > code_max: code_max = code for line in data.split('\n'): - yield line + yield line + '\n' if code_max > 0: raise MonotoneException("error code %d in automate packet." % code_max) self.lock.release() @@ -171,24 +171,65 @@ def choose_consume(line): line = line.lstrip() - if line[0] == '[': + if line == '': + consumer = choose_consume + elif line[0] == '[': consumer = hex_consume - elif line[0] == '\\': + elif line[0] == '"': consumer = string_consume else: consumer = name_consume return None, consumer, line + class StringState: + def __init__(self): + self.in_escape = False + self.has_started = False + self.has_ended = False + self.value = '' + + def string_consume(line, state=None): + if not state: + state = StringState() + + if not state.has_started: + if line[0] != '"': + raise MonotoneException("Not a string: %s" % line) + line = line[1:] + state.has_started = True + + for idx, c in enumerate(line): + if state.in_escape: + if c != '\\' or c != '\"': + raise MonotoneException("Invalid escape code: %s\n" % line) + state.value += c + state.in_escape = False + else: + if c == '\\': + state.in_escape = True + elif c == '"': + state.has_ended = True + break + else: + state.value += c + + if state.has_ended: + return state.value, choose_consume, line[idx+1:] + else: + return (None, + lambda s: string_consume(s, state), + line[idx+1:]) + consumer = choose_consume current_stanza = [] - for line in (t.strip() for t in gen): - print "read line:", line - if line == '' and current_stanza: + for line in gen: +# print "read line:", [line] + if (line == '' or line == '\n') and current_stanza: yield current_stanza current_stanza = [] continue - while line: + while line != '' and line != '\n': new_token, consumer, line = consumer(line) if new_token != None: current_stanza.append(new_token) @@ -214,6 +255,10 @@ for line in self.automate.run('graph', []): yield line - def get_revision(self, id): - for stanza in basic_io_from_stream(self.automate.run('get_revision', [id])): + def get_revision(self, revision): + for stanza in basic_io_from_stream(self.automate.run('get_revision', [revision])): yield stanza + + def certs(self, revision): + for stanza in basic_io_from_stream(self.automate.run('certs', [revision])): + yield stanza