|
Packit |
971217 |
#!/usr/bin/python
|
|
Packit |
971217 |
# -*- Mode: Python -*-
|
|
Packit |
971217 |
# vi:si:et:sw=4:sts=4:ts=4
|
|
Packit |
971217 |
|
|
Packit |
971217 |
"""
|
|
Packit |
971217 |
parse, merge and write gstdoc-scanobj files
|
|
Packit |
971217 |
"""
|
|
Packit |
971217 |
|
|
Packit |
971217 |
from __future__ import print_function, unicode_literals
|
|
Packit |
971217 |
|
|
Packit |
971217 |
import codecs
|
|
Packit |
971217 |
import os
|
|
Packit |
971217 |
import sys
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def debug(*args):
|
|
Packit |
971217 |
pass
|
|
Packit |
971217 |
|
|
Packit |
971217 |
# OrderedDict class based on
|
|
Packit |
971217 |
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/107747
|
|
Packit |
971217 |
# Licensed under the Python License
|
|
Packit |
971217 |
class OrderedDict(dict):
|
|
Packit |
971217 |
def __init__(self):
|
|
Packit |
971217 |
self._keys = []
|
|
Packit |
971217 |
dict.__init__(self)
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def __delitem__(self, key):
|
|
Packit |
971217 |
dict.__delitem__(self, key)
|
|
Packit |
971217 |
self._keys.remove(key)
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def __setitem__(self, key, item):
|
|
Packit |
971217 |
dict.__setitem__(self, key, item)
|
|
Packit |
971217 |
if key not in self._keys: self._keys.append(key)
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def clear(self):
|
|
Packit |
971217 |
dict.clear(self)
|
|
Packit |
971217 |
self._keys = []
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def copy(self):
|
|
Packit |
971217 |
dict = dict.copy(self)
|
|
Packit |
971217 |
dict._keys = self._keys[:]
|
|
Packit |
971217 |
return dict
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def items(self):
|
|
Packit |
971217 |
return zip(self._keys, self.values())
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def keys(self):
|
|
Packit |
971217 |
return self._keys
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def popitem(self):
|
|
Packit |
971217 |
try:
|
|
Packit |
971217 |
key = self._keys[-1]
|
|
Packit |
971217 |
except IndexError:
|
|
Packit |
971217 |
raise KeyError('dictionary is empty')
|
|
Packit |
971217 |
|
|
Packit |
971217 |
val = self[key]
|
|
Packit |
971217 |
del self[key]
|
|
Packit |
971217 |
|
|
Packit |
971217 |
return (key, val)
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def setdefault(self, key, failobj = None):
|
|
Packit |
971217 |
dict.setdefault(self, key, failobj)
|
|
Packit |
971217 |
if key not in self._keys: self._keys.append(key)
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def update(self, dict):
|
|
Packit |
971217 |
dict.update(self, dict)
|
|
Packit |
971217 |
for key in dict.keys():
|
|
Packit |
971217 |
if key not in self._keys: self._keys.append(key)
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def values(self):
|
|
Packit |
971217 |
return map(self.get, self._keys)
|
|
Packit |
971217 |
|
|
Packit |
971217 |
class Object:
|
|
Packit |
971217 |
def __init__(self, name):
|
|
Packit |
971217 |
self._signals = OrderedDict()
|
|
Packit |
971217 |
self._args = OrderedDict()
|
|
Packit |
971217 |
self.name = name
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def __repr__(self):
|
|
Packit |
971217 |
return "<Object %s>" % self.name
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def add_signal(self, signal, overwrite=True):
|
|
Packit |
971217 |
if not overwrite and signal.name in self._signals:
|
|
Packit |
971217 |
raise IndexError("signal %s already in %r" % (signal.name, self))
|
|
Packit |
971217 |
self._signals[signal.name] = signal
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def add_arg(self, arg, overwrite=True):
|
|
Packit |
971217 |
if not overwrite and arg.name in self._args:
|
|
Packit |
971217 |
raise IndexError("arg %s already in %r" % (arg.name, self))
|
|
Packit |
971217 |
self._args[arg.name] = arg
|
|
Packit |
971217 |
|
|
Packit |
971217 |
class Docable:
|
|
Packit |
971217 |
def __init__(self, **kwargs):
|
|
Packit |
971217 |
for key in self.attrs:
|
|
Packit |
971217 |
setattr(self, key, kwargs[key])
|
|
Packit |
971217 |
self.dict = kwargs
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def __repr__(self):
|
|
Packit |
971217 |
return "<%r %s>" % (str(self.__class__), self.name)
|
|
Packit |
971217 |
|
|
Packit |
971217 |
class Signal(Docable):
|
|
Packit |
971217 |
attrs = ['name', 'returns', 'args']
|
|
Packit |
971217 |
|
|
Packit |
971217 |
class Arg(Docable):
|
|
Packit |
971217 |
attrs = ['name', 'type', 'range', 'flags', 'nick', 'blurb', 'default']
|
|
Packit |
971217 |
|
|
Packit |
971217 |
class GDoc:
|
|
Packit |
971217 |
def load_file(self, filename):
|
|
Packit |
971217 |
try:
|
|
Packit |
971217 |
lines = codecs.open(filename, encoding='utf-8').readlines()
|
|
Packit |
971217 |
self.load_data("".join(lines))
|
|
Packit |
971217 |
except IOError:
|
|
Packit |
971217 |
print ("WARNING - could not read from %s" % filename)
|
|
Packit |
971217 |
except UnicodeDecodeError as e:
|
|
Packit |
971217 |
print ("WARNING - could not parse %s: %s" % (filename, e))
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def save_file(self, filename, backup=False):
|
|
Packit |
971217 |
"""
|
|
Packit |
971217 |
Save the information to the given file if the file content changed.
|
|
Packit |
971217 |
"""
|
|
Packit |
971217 |
olddata = None
|
|
Packit |
971217 |
try:
|
|
Packit |
971217 |
lines = codecs.open(filename, encoding='utf-8').readlines()
|
|
Packit |
971217 |
olddata = "".join(lines)
|
|
Packit |
971217 |
except IOError:
|
|
Packit |
971217 |
print ("WARNING - could not read from %s" % filename)
|
|
Packit |
971217 |
newdata = self.get_data()
|
|
Packit |
971217 |
if olddata and olddata == newdata:
|
|
Packit |
971217 |
return
|
|
Packit |
971217 |
|
|
Packit |
971217 |
if olddata:
|
|
Packit |
971217 |
if backup:
|
|
Packit |
971217 |
os.rename(filename, filename + '.bak')
|
|
Packit |
971217 |
|
|
Packit |
971217 |
handle = codecs.open(filename, "w", encoding='utf-8')
|
|
Packit |
971217 |
handle.write(newdata)
|
|
Packit |
971217 |
handle.close()
|
|
Packit |
971217 |
|
|
Packit |
971217 |
class Signals(GDoc):
|
|
Packit |
971217 |
def __init__(self):
|
|
Packit |
971217 |
self._objects = OrderedDict()
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def load_data(self, data):
|
|
Packit |
971217 |
"""
|
|
Packit |
971217 |
Load the .signals lines, creating our list of objects and signals.
|
|
Packit |
971217 |
"""
|
|
Packit |
971217 |
import re
|
|
Packit |
971217 |
smatcher = re.compile(
|
|
Packit |
971217 |
'(?s)' # make . match \n
|
|
Packit |
971217 |
'<SIGNAL>\n(.*?)</SIGNAL>\n'
|
|
Packit |
971217 |
)
|
|
Packit |
971217 |
nmatcher = re.compile(
|
|
Packit |
971217 |
'<NAME>'
|
|
Packit |
971217 |
'(?P<object>\S*)' # store object
|
|
Packit |
971217 |
'::'
|
|
Packit |
971217 |
'(?P<signal>\S*)' # store signal
|
|
Packit |
971217 |
'</NAME>'
|
|
Packit |
971217 |
)
|
|
Packit |
971217 |
rmatcher = re.compile(
|
|
Packit |
971217 |
'(?s)' # make . match \n
|
|
Packit |
971217 |
'<RETURNS>(?P<returns>\S*)</RETURNS>\n' # store returns
|
|
Packit |
971217 |
'(?P<args>.*)' # store args
|
|
Packit |
971217 |
)
|
|
Packit |
971217 |
for block in smatcher.findall(data):
|
|
Packit |
971217 |
nmatch = nmatcher.search(block)
|
|
Packit |
971217 |
if nmatch:
|
|
Packit |
971217 |
o = nmatch.group('object')
|
|
Packit |
971217 |
debug("Found object", o)
|
|
Packit |
971217 |
debug("Found signal", nmatch.group('signal'))
|
|
Packit |
971217 |
if o not in self._objects:
|
|
Packit |
971217 |
object = Object(o)
|
|
Packit |
971217 |
self._objects[o] = object
|
|
Packit |
971217 |
|
|
Packit |
971217 |
rmatch = rmatcher.search(block)
|
|
Packit |
971217 |
if rmatch:
|
|
Packit |
971217 |
dict = rmatch.groupdict().copy()
|
|
Packit |
971217 |
dict['name'] = nmatch.group('signal')
|
|
Packit |
971217 |
signal = Signal(**dict)
|
|
Packit |
971217 |
self._objects[o].add_signal(signal)
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def get_data(self):
|
|
Packit |
971217 |
lines = []
|
|
Packit |
971217 |
for o in self._objects.values():
|
|
Packit |
971217 |
for s in o._signals.values():
|
|
Packit |
971217 |
block = """<SIGNAL>
|
|
Packit |
971217 |
<NAME>%(object)s::%(name)s</NAME>
|
|
Packit |
971217 |
<RETURNS>%(returns)s</RETURNS>
|
|
Packit |
971217 |
%(args)s</SIGNAL>
|
|
Packit |
971217 |
"""
|
|
Packit |
971217 |
d = s.dict.copy()
|
|
Packit |
971217 |
d['object'] = o.name
|
|
Packit |
971217 |
lines.append(block % d)
|
|
Packit |
971217 |
|
|
Packit |
971217 |
return "\n".join(lines) + '\n'
|
|
Packit |
971217 |
|
|
Packit |
971217 |
class Args(GDoc):
|
|
Packit |
971217 |
def __init__(self):
|
|
Packit |
971217 |
self._objects = OrderedDict()
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def load_data(self, data):
|
|
Packit |
971217 |
"""
|
|
Packit |
971217 |
Load the .args lines, creating our list of objects and args.
|
|
Packit |
971217 |
"""
|
|
Packit |
971217 |
import re
|
|
Packit |
971217 |
amatcher = re.compile(
|
|
Packit |
971217 |
'(?s)' # make . match \n
|
|
Packit |
971217 |
'<ARG>\n(.*?)</ARG>\n'
|
|
Packit |
971217 |
)
|
|
Packit |
971217 |
nmatcher = re.compile(
|
|
Packit |
971217 |
'<NAME>'
|
|
Packit |
971217 |
'(?P<object>\S*)' # store object
|
|
Packit |
971217 |
'::'
|
|
Packit |
971217 |
'(?P<arg>\S*)' # store arg
|
|
Packit |
971217 |
'</NAME>'
|
|
Packit |
971217 |
)
|
|
Packit |
971217 |
rmatcher = re.compile(
|
|
Packit |
971217 |
'(?s)' # make . match \n
|
|
Packit |
971217 |
'<TYPE>(?P<type>\S*)</TYPE>\n' # store type
|
|
Packit |
971217 |
'<RANGE>(?P<range>.*?)</RANGE>\n' # store range
|
|
Packit |
971217 |
'<FLAGS>(?P<flags>\S*)</FLAGS>\n' # store flags
|
|
Packit |
971217 |
'<NICK>(?P<nick>.*?)</NICK>\n' # store nick
|
|
Packit |
971217 |
'<BLURB>(?P<blurb>.*?)</BLURB>\n' # store blurb
|
|
Packit |
971217 |
'<DEFAULT>(?P<default>.*?)</DEFAULT>\n' # store default
|
|
Packit |
971217 |
)
|
|
Packit |
971217 |
for block in amatcher.findall(data):
|
|
Packit |
971217 |
nmatch = nmatcher.search(block)
|
|
Packit |
971217 |
if nmatch:
|
|
Packit |
971217 |
o = nmatch.group('object')
|
|
Packit |
971217 |
debug("Found object", o)
|
|
Packit |
971217 |
debug("Found arg", nmatch.group('arg'))
|
|
Packit |
971217 |
if o not in self._objects:
|
|
Packit |
971217 |
object = Object(o)
|
|
Packit |
971217 |
self._objects[o] = object
|
|
Packit |
971217 |
|
|
Packit |
971217 |
rmatch = rmatcher.search(block)
|
|
Packit |
971217 |
if rmatch:
|
|
Packit |
971217 |
dict = rmatch.groupdict().copy()
|
|
Packit |
971217 |
dict['name'] = nmatch.group('arg')
|
|
Packit |
971217 |
arg = Arg(**dict)
|
|
Packit |
971217 |
self._objects[o].add_arg(arg)
|
|
Packit |
971217 |
else:
|
|
Packit |
971217 |
print ("ERROR: could not match arg from block %s" % block)
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def get_data(self):
|
|
Packit |
971217 |
lines = []
|
|
Packit |
971217 |
for o in self._objects.values():
|
|
Packit |
971217 |
for a in o._args.values():
|
|
Packit |
971217 |
block = """<ARG>
|
|
Packit |
971217 |
<NAME>%(object)s::%(name)s</NAME>
|
|
Packit |
971217 |
<TYPE>%(type)s</TYPE>
|
|
Packit |
971217 |
<RANGE>%(range)s</RANGE>
|
|
Packit |
971217 |
<FLAGS>%(flags)s</FLAGS>
|
|
Packit |
971217 |
<NICK>%(nick)s</NICK>
|
|
Packit |
971217 |
<BLURB>%(blurb)s</BLURB>
|
|
Packit |
971217 |
<DEFAULT>%(default)s</DEFAULT>
|
|
Packit |
971217 |
</ARG>
|
|
Packit |
971217 |
"""
|
|
Packit |
971217 |
d = a.dict.copy()
|
|
Packit |
971217 |
d['object'] = o.name
|
|
Packit |
971217 |
lines.append(block % d)
|
|
Packit |
971217 |
|
|
Packit |
971217 |
return "\n".join(lines) + '\n'
|
|
Packit |
971217 |
|
|
Packit |
971217 |
class SingleLine(GDoc):
|
|
Packit |
971217 |
def __init__(self):
|
|
Packit |
971217 |
self._objects = []
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def load_data(self, data):
|
|
Packit |
971217 |
"""
|
|
Packit |
971217 |
Load the .interfaces/.prerequisites lines, merge duplicates
|
|
Packit |
971217 |
"""
|
|
Packit |
971217 |
# split data on '\n'
|
|
Packit |
971217 |
lines = data.splitlines();
|
|
Packit |
971217 |
# merge them into self._objects
|
|
Packit |
971217 |
for line in lines:
|
|
Packit |
971217 |
if line not in self._objects:
|
|
Packit |
971217 |
self._objects.append(line)
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def get_data(self):
|
|
Packit |
971217 |
lines = sorted(self._objects)
|
|
Packit |
971217 |
return "\n".join(lines) + '\n'
|
|
Packit |
971217 |
|
|
Packit |
971217 |
def main(argv):
|
|
Packit |
971217 |
modulename = None
|
|
Packit |
971217 |
try:
|
|
Packit |
971217 |
modulename = argv[1]
|
|
Packit |
971217 |
except IndexError:
|
|
Packit |
971217 |
sys.stderr.write('Please provide a documentation module name\n')
|
|
Packit |
971217 |
sys.exit(1)
|
|
Packit |
971217 |
|
|
Packit |
971217 |
signals = Signals()
|
|
Packit |
971217 |
signals.load_file(modulename + '.signals')
|
|
Packit |
971217 |
signals.load_file(modulename + '.signals.new')
|
|
Packit |
971217 |
signals.save_file(modulename + '.signals', backup=True)
|
|
Packit |
971217 |
os.unlink(modulename + '.signals.new')
|
|
Packit |
971217 |
|
|
Packit |
971217 |
args = Args()
|
|
Packit |
971217 |
args.load_file(modulename + '.args')
|
|
Packit |
971217 |
args.load_file(modulename + '.args.new')
|
|
Packit |
971217 |
args.save_file(modulename + '.args', backup=True)
|
|
Packit |
971217 |
os.unlink(modulename + '.args.new')
|
|
Packit |
971217 |
|
|
Packit |
971217 |
ifaces = SingleLine()
|
|
Packit |
971217 |
ifaces.load_file(modulename + '.interfaces')
|
|
Packit |
971217 |
ifaces.load_file(modulename + '.interfaces.new')
|
|
Packit |
971217 |
ifaces.save_file(modulename + '.interfaces', backup=True)
|
|
Packit |
971217 |
os.unlink(modulename + '.interfaces.new')
|
|
Packit |
971217 |
|
|
Packit |
971217 |
prereq = SingleLine()
|
|
Packit |
971217 |
prereq.load_file(modulename + '.prerequisites')
|
|
Packit |
971217 |
prereq.load_file(modulename + '.prerequisites.new')
|
|
Packit |
971217 |
prereq.save_file(modulename + '.prerequisites', backup=True)
|
|
Packit |
971217 |
os.unlink(modulename + '.prerequisites.new')
|
|
Packit |
971217 |
|
|
Packit |
971217 |
main(sys.argv)
|