5d827ad6 |
1 | #! /usr/bin/python |
2 | |
3 | import sre as re |
4 | import os |
5 | from sys import argv, stderr |
6 | |
7 | class struct (object): |
8 | def __init__(me, **kw): |
9 | me.__dict__.update(kw) |
10 | def __repr__(me): |
11 | r = '%s(' % me.__class__.__name__ |
12 | sep = '' |
13 | for k in me.__dict__: |
14 | r += sep + '%s=%r' % (k, me.__dict__[k]) |
15 | sep = ', ' |
16 | r += ')' |
17 | return r |
18 | |
19 | class service (struct): |
20 | def __str__(me): |
21 | return '%(name)s:%(port)d/%(proto)s' % me.__dict__ |
22 | def key(me): |
23 | return me.port, me.proto, me.name |
24 | def parse(string): |
25 | m = re.match(r'''^ (\S+) \s+ (\d+)/(\S+) \s* |
26 | ([^#\s] [^#]* [^#\s] | [^#\s])? \s* |
27 | (?: \# \s* (\S .* \S | \S |) )? \s* $''', |
28 | string, re.VERBOSE) |
29 | if not m: |
30 | raise 'Bad service line %r' % string |
31 | me = service(name = m.group(1), |
32 | port = int(m.group(2)), |
33 | proto = m.group(3), |
34 | aliases = m.group(4) and m.group(4).split() or [], |
35 | comment = m.group(5)) |
36 | return me |
37 | parse = staticmethod(parse) |
38 | |
39 | class servicetab (object): |
40 | def __init__(me): |
41 | me.tab = {} |
42 | def _insert(me, serv): |
43 | tab = me.tab |
44 | changep = False |
45 | if serv.key() not in tab: |
46 | tab[serv.key()] = serv |
47 | changep = True |
48 | else: |
49 | s = tab[serv.key()] |
50 | d = {} |
51 | for a in s.aliases: |
52 | d[a] = 1 |
53 | #warnp = True |
54 | dd = {} |
55 | for a in serv.aliases: |
56 | dd[a] = 1 |
57 | if a not in d: |
58 | #if warnp: |
59 | # print >>stderr, 'Merging aliases for %s' % s |
60 | # warnp = False |
61 | s.aliases += [a] |
62 | changep = True |
63 | #for a in s.aliases: |
64 | # if a not in dd: |
65 | # if warnp: |
66 | # print >>stderr, 'Merging aliases for %s' % s |
67 | # warnp = False |
68 | return changep |
69 | def scan(me, file): |
70 | changep = False |
71 | for l in open(file): |
72 | if re.match(r'^\s*(\#.*)?$', l): |
73 | continue |
74 | serv = service.parse(l) |
75 | if me._insert(serv): |
76 | changep = True |
77 | if not changep: |
78 | print >>stderr, 'File `%s\' redundant' % file |
79 | return changep |
80 | def write(me): |
81 | kk = me.tab.values() |
82 | kk.sort(lambda x, y: cmp(x.key(), y.key())) |
83 | print '## services file [generated]' |
84 | print |
85 | for s in kk: |
86 | print '%-20s %9s %s' % (s.name, |
87 | '%d/%s' % (s.port, s.proto), |
88 | ' '.join(s.aliases)) |
89 | |
90 | if 'running_under_emacs_p' not in globals(): |
91 | t = servicetab() |
92 | for f in argv[1:]: |
93 | t.scan(f) |
f463c0f4 |
94 | t.write() |