3 # vi:si:et:sw=4:sts=4:ts=4
6 parse, update and write .signals and .args files
9 from twisted.python import util
18 def __init__(self, name):
19 self._signals = util.OrderedDict()
20 self._args = util.OrderedDict()
24 return "<Object %s>" % self.name
26 def add_signal(self, signal, overwrite=True):
27 if not overwrite and self._signals.has_key(signal.name):
28 raise IndexError, "signal %s already in %r" % (signal.name, self)
29 self._signals[signal.name] = signal
31 def add_arg(self, arg, overwrite=True):
32 if not overwrite and self._args.has_key(arg.name):
33 raise IndexError, "arg %s already in %r" % (arg.name, self)
34 self._args[arg.name] = arg
37 def __init__(self, **kwargs):
38 for key in self.attrs:
39 setattr(self, key, kwargs[key])
43 return "<%r %s>" % (str(self.__class__), self.name)
45 class Signal(Docable):
46 attrs = ['name', 'returns', 'args']
49 attrs = ['name', 'type', 'range', 'flags', 'nick', 'blurb', 'default']
52 def load_file(self, filename):
54 lines = open(filename).readlines()
55 self.load_data("".join(lines))
57 print "WARNING - could not read from %s" % filename
59 def save_file(self, filename, backup=False):
61 Save the signals information to the given .signals file if the
66 lines = open(filename).readlines()
67 olddata = "".join(lines)
69 print "WARNING - could not read from %s" % filename
70 newdata = self.get_data()
71 if olddata and olddata == newdata:
76 os.rename(filename, filename + '.bak')
78 handle = open(filename, "w")
84 self._objects = util.OrderedDict()
86 def load_data(self, data):
88 Load the .signals lines, creating our list of objects and signals.
91 smatcher = re.compile(
92 '(?s)' # make . match \n
93 '<SIGNAL>\n(.*?)</SIGNAL>\n'
95 nmatcher = re.compile(
97 '(?P<object>\S*)' # store object
99 '(?P<signal>\S*)' # store signal
102 rmatcher = re.compile(
103 '(?s)' # make . match \n
104 '<RETURNS>(?P<returns>\S*)</RETURNS>\n' # store returns
105 '(?P<args>.*)' # store args
107 for block in smatcher.findall(data):
108 nmatch = nmatcher.search(block)
110 o = nmatch.group('object')
111 debug("Found object", o)
112 debug("Found signal", nmatch.group('signal'))
113 if not self._objects.has_key(o):
115 self._objects[o] = object
117 rmatch = rmatcher.search(block)
119 dict = rmatch.groupdict().copy()
120 dict['name'] = nmatch.group('signal')
121 signal = Signal(**dict)
122 self._objects[o].add_signal(signal)
126 for o in self._objects.values():
127 for s in o._signals.values():
129 <NAME>%(object)s::%(name)s</NAME>
130 <RETURNS>%(returns)s</RETURNS>
135 lines.append(block % d)
137 return "\n".join(lines) + '\n'
141 self._objects = util.OrderedDict()
143 def load_data(self, data):
145 Load the .args lines, creating our list of objects and args.
148 amatcher = re.compile(
149 '(?s)' # make . match \n
150 '<ARG>\n(.*?)</ARG>\n'
152 nmatcher = re.compile(
154 '(?P<object>\S*)' # store object
156 '(?P<arg>\S*)' # store arg
159 rmatcher = re.compile(
160 '(?s)' # make . match \n
161 '<TYPE>(?P<type>\S*)</TYPE>\n' # store type
162 '<RANGE>(?P<range>.*?)</RANGE>\n' # store range
163 '<FLAGS>(?P<flags>\S*)</FLAGS>\n' # store flags
164 '<NICK>(?P<nick>.*?)</NICK>\n' # store nick
165 '<BLURB>(?P<blurb>.*?)</BLURB>\n' # store blurb
166 '<DEFAULT>(?P<default>.*?)</DEFAULT>\n' # store default
168 for block in amatcher.findall(data):
169 nmatch = nmatcher.search(block)
171 o = nmatch.group('object')
172 debug("Found object", o)
173 debug("Found arg", nmatch.group('arg'))
174 if not self._objects.has_key(o):
176 self._objects[o] = object
178 rmatch = rmatcher.search(block)
180 dict = rmatch.groupdict().copy()
181 dict['name'] = nmatch.group('arg')
183 self._objects[o].add_arg(arg)
185 print "ERROR: could not match arg from block %s" % block
189 for o in self._objects.values():
190 for a in o._args.values():
192 <NAME>%(object)s::%(name)s</NAME>
193 <TYPE>%(type)s</TYPE>
194 <RANGE>%(range)s</RANGE>
195 <FLAGS>%(flags)s</FLAGS>
196 <NICK>%(nick)s</NICK>
197 <BLURB>%(blurb)s</BLURB>
198 <DEFAULT>%(default)s</DEFAULT>
203 lines.append(block % d)
205 return "\n".join(lines) + '\n'
212 sys.stderr.write('Pleae provide a documentation module name\n')
215 print "Merging scangobj output for %s" % modulename
217 signals.load_file(modulename + '.signals')
218 signals.load_file(modulename + '.signals.new')
219 signals.save_file(modulename + '.signals', backup=True)
222 args.load_file(modulename + '.args')
223 args.load_file(modulename + '.args.new')
224 args.save_file(modulename + '.args', backup=True)