progs/perftest.c: Use from Glibc syscall numbers.
[catacomb] / symm / multigen
index f498ce2..8af0f10 100755 (executable)
@@ -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 --------------------------------------------------