+#! /usr/bin/python
+
+import sre as re
+import os
+from sys import argv, stderr
+
+class struct (object):
+ def __init__(me, **kw):
+ me.__dict__.update(kw)
+ def __repr__(me):
+ r = '%s(' % me.__class__.__name__
+ sep = ''
+ for k in me.__dict__:
+ r += sep + '%s=%r' % (k, me.__dict__[k])
+ sep = ', '
+ r += ')'
+ return r
+
+class service (struct):
+ def __str__(me):
+ return '%(name)s:%(port)d/%(proto)s' % me.__dict__
+ def key(me):
+ return me.port, me.proto, me.name
+ def parse(string):
+ m = re.match(r'''^ (\S+) \s+ (\d+)/(\S+) \s*
+ ([^#\s] [^#]* [^#\s] | [^#\s])? \s*
+ (?: \# \s* (\S .* \S | \S |) )? \s* $''',
+ string, re.VERBOSE)
+ if not m:
+ raise 'Bad service line %r' % string
+ me = service(name = m.group(1),
+ port = int(m.group(2)),
+ proto = m.group(3),
+ aliases = m.group(4) and m.group(4).split() or [],
+ comment = m.group(5))
+ return me
+ parse = staticmethod(parse)
+
+class servicetab (object):
+ def __init__(me):
+ me.tab = {}
+ def _insert(me, serv):
+ tab = me.tab
+ changep = False
+ if serv.key() not in tab:
+ tab[serv.key()] = serv
+ changep = True
+ else:
+ s = tab[serv.key()]
+ d = {}
+ for a in s.aliases:
+ d[a] = 1
+ #warnp = True
+ dd = {}
+ for a in serv.aliases:
+ dd[a] = 1
+ if a not in d:
+ #if warnp:
+ # print >>stderr, 'Merging aliases for %s' % s
+ # warnp = False
+ s.aliases += [a]
+ changep = True
+ #for a in s.aliases:
+ # if a not in dd:
+ # if warnp:
+ # print >>stderr, 'Merging aliases for %s' % s
+ # warnp = False
+ return changep
+ def scan(me, file):
+ changep = False
+ for l in open(file):
+ if re.match(r'^\s*(\#.*)?$', l):
+ continue
+ serv = service.parse(l)
+ if me._insert(serv):
+ changep = True
+ if not changep:
+ print >>stderr, 'File `%s\' redundant' % file
+ return changep
+ def write(me):
+ kk = me.tab.values()
+ kk.sort(lambda x, y: cmp(x.key(), y.key()))
+ print '## services file [generated]'
+ print
+ for s in kk:
+ print '%-20s %9s %s' % (s.name,
+ '%d/%s' % (s.port, s.proto),
+ ' '.join(s.aliases))
+
+if 'running_under_emacs_p' not in globals():
+ t = servicetab()
+ for f in argv[1:]:
+ t.scan(f)
+ t.write()