X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/e7abc7ea1c83b671db65884d7f8e4b8c57762083..HEAD:/symm/multigen diff --git a/symm/multigen b/symm/multigen index f498ce2a..8af0f108 100755 --- a/symm/multigen +++ b/symm/multigen @@ -30,7 +30,9 @@ import itertools as IT import optparse as OP import os as OS import re as RX -from cStringIO import StringIO +import sys as SYS +if SYS.version_info >= (3,): from io import StringIO +else: from cStringIO import StringIO from sys import argv, exit, stderr ###-------------------------------------------------------------------------- @@ -49,6 +51,16 @@ def indexed(seq): """ return IT.izip(IT.count(), seq) +if SYS.version_info >= (3,): + def func_name(func): return func.__name__ + IT.izip = zip +else: + def func_name(func): return func.func_name + +try: next +except NameError: + def next(obj): return obj.next() + ###-------------------------------------------------------------------------- ### Reading the input values. @@ -363,7 +375,7 @@ class SequenceTemplate (BasicTemplate): if len(seq) == 1: return seq[0] else: - return super(SequenceTemplate, cls).__new__(cls, seq = seq, **kw) + return super(SequenceTemplate, cls).__new__(cls, **kw) def __init__(me, seq, **kw): """ @@ -461,7 +473,7 @@ class ParseState (object): Sets `curr' to the next line, or to None if the input is exhausted. """ - try: me.curr = me._it.next() + try: me.curr = next(me._it) except StopIteration: me.curr = None else: me._i += 1 @@ -504,7 +516,7 @@ def defop(func): An operator function is given the raw value as an argument and should return the transformed value. """ - name = func.func_name + name = func_name(func) if name.startswith('op_'): name = name[3:] OPMAP[name] = func return func @@ -519,6 +531,11 @@ def op_l(val): """@{COLUMN:l} -- the item in upper case.""" return val.lower() +@defop +def op_f(val): + """@{COLUMN:f} -- the item, with `/' characters replaced by `-'.""" + return val.replace('/', '-') + R_NOTIDENT = RX.compile(r'[^a-zA-Z0-9_]+') @defop def op_c(val): @@ -571,7 +588,7 @@ def parse_text(ps): ## object. l = lit.getvalue() if l: tt.append(LiteralTemplate(l)) - lit.reset() + lit.seek(0) lit.truncate() ## Iterate over the lines of input. @@ -741,17 +758,21 @@ def compile_template(file, text): op = OP.OptionParser( description = 'Generates files by filling in simple templates', - usage = 'usage: %prog [-gl] FILE [COL,...=VAL,... ... | @FILE:COL,...] ...', + usage = 'usage: %prog {-l | -g TMPL} FILE [COL,...=VAL,... ... | @FILE:COL,...] ...', version = 'Catacomb version @VERSION@') +def cb_gen(opt, optstr, arg, op): + op.values.input = arg + op.values.mode = 'gen' for short, long, kw in [ ('-l', '--list', dict( action = 'store_const', const = 'list', dest = 'mode', help = 'list filenames generated')), ('-g', '--generate', dict( - action = 'store', metavar = 'PATH', dest = 'input', - help = 'generate output (default)'))]: + action = 'callback', metavar = 'TEMPLATE', + callback = cb_gen, type = 'string', + help = 'generate file(s) from TEMPLATE file'))]: op.add_option(short, long, **kw) -op.set_defaults(mode = 'gen') +op.set_defaults(mode = 'what?') opts, args = op.parse_args() if len(args) < 1: op.error('missing FILE') @@ -777,7 +798,7 @@ def filenames(filetempl): ## Main dispatch. if opts.mode == 'list': - for file, cs in filenames(filetempl): print file + for file, cs in filenames(filetempl): print(file) elif opts.mode == 'gen': with open(opts.input) as f: templ = RepeatTemplate(compile_template(opts.input, f.read())) @@ -787,6 +808,6 @@ elif opts.mode == 'gen': templ.subst(out, cs) OS.rename(new, file) else: - raise Exception, 'What am I doing here?' + die('What am I doing here?') ###----- That's all, folks --------------------------------------------------