summaryrefslogtreecommitdiffstats
path: root/docs/release/scripts/minimaws/lib/lxparse.py
diff options
context:
space:
mode:
Diffstat (limited to 'docs/release/scripts/minimaws/lib/lxparse.py')
-rw-r--r--docs/release/scripts/minimaws/lib/lxparse.py471
1 files changed, 471 insertions, 0 deletions
diff --git a/docs/release/scripts/minimaws/lib/lxparse.py b/docs/release/scripts/minimaws/lib/lxparse.py
new file mode 100644
index 00000000000..e773669080d
--- /dev/null
+++ b/docs/release/scripts/minimaws/lib/lxparse.py
@@ -0,0 +1,471 @@
+#!/usr/bin/python
+##
+## license:BSD-3-Clause
+## copyright-holders:Vas Crabb
+
+from . import dbaccess
+
+import os
+import os.path
+import subprocess
+import xml.sax
+import xml.sax.saxutils
+
+
+class ElementHandlerBase(object):
+ def __init__(self, parent, **kwargs):
+ super(ElementHandlerBase, self).__init__(**kwargs)
+ self.dbconn = parent.dbconn if parent is not None else None
+ self.locator = parent.locator if parent is not None else None
+ self.depth = 0
+ self.childhandler = None
+ self.childdepth = 0
+
+ def startMainElement(self, name, attrs):
+ pass
+
+ def endMainElement(self, name):
+ pass
+
+ def mainCharacters(self, content):
+ pass
+
+ def mainIgnorableWitespace(self, whitespace):
+ pass
+
+ def startChildElement(self, name, attrs):
+ pass
+
+ def endChildElement(self, name):
+ pass
+
+ def childCharacters(self, content):
+ pass
+
+ def childIgnorableWitespace(self, whitespace):
+ pass
+
+ def endChildHandler(self, name, handler):
+ pass
+
+ def setChildHandler(self, name, attrs, handler):
+ self.depth -= 1
+ self.childhandler = handler
+ self.childdepth += 1
+ handler.startElement(name, attrs)
+
+ def setDocumentLocator(self, locator):
+ self.locator = locator
+
+ def startElement(self, name, attrs):
+ if self.childhandler is not None:
+ self.childdepth += 1
+ self.childhandler.startElement(name, attrs)
+ else:
+ self.depth += 1
+ if 1 == self.depth:
+ self.startMainElement(name, attrs)
+ else:
+ self.startChildElement(name, attrs)
+
+ def endElement(self, name):
+ if self.childhandler is not None:
+ self.childdepth -= 1
+ self.childhandler.endElement(name)
+ if 0 == self.childdepth:
+ self.endChildHandler(name, self.childhandler)
+ self.childhandler = None
+ else:
+ self.depth -= 1
+ if 0 == self.depth:
+ self.endMainElement(name)
+ else:
+ self.endChildElement(name)
+
+ def characters(self, content):
+ if self.childhandler is not None:
+ self.childhandler.characters(content)
+ elif 1 < self.depth:
+ self.childCharacters(content)
+ else:
+ self.mainCharacters(content)
+
+ def ignorableWhitespace(self, content):
+ if self.childhandler is not None:
+ self.childhandler.ignorableWhitespace(content)
+ elif 1 < self.depth:
+ self.childIgnorableWitespace(content)
+ else:
+ self.mainIgnorableWitespace(content)
+
+
+class ElementHandler(ElementHandlerBase):
+ IGNORE = ElementHandlerBase(parent=None)
+
+
+class TextAccumulator(ElementHandler):
+ def __init__(self, parent, **kwargs):
+ super(TextAccumulator, self).__init__(parent=parent, **kwargs)
+ self.text = ''
+
+ def mainCharacters(self, content):
+ self.text += content
+
+
+class DipSwitchHandler(ElementHandler):
+ def __init__(self, parent, **kwargs):
+ super(DipSwitchHandler, self).__init__(parent=parent, **kwargs)
+ self.dbcurs = parent.dbcurs
+ self.machine = parent.id
+
+ def startMainElement(self, name, attrs):
+ self.mask = int(attrs['mask'])
+ self.bit = 0
+ self.id = self.dbcurs.add_dipswitch(self.machine, name == 'configuration', attrs['name'], attrs['tag'], self.mask)
+
+ def startChildElement(self, name, attrs):
+ if (name == 'diplocation') or (name == 'conflocation'):
+ while (0 != self.mask) and not (self.mask & 1):
+ self.mask >>= 1
+ self.bit += 1
+ self.dbcurs.add_diplocation(self.id, self.bit, attrs['name'], attrs['number'], attrs.get('inverted', 'no') == 'yes')
+ self.mask >>= 1
+ self.bit += 1
+ elif (name == 'dipvalue') or (name == 'confsetting'):
+ self.dbcurs.add_dipvalue(self.id, attrs['name'], attrs['value'], attrs.get('default', 'no') == 'yes')
+ self.setChildHandler(name, attrs, self.IGNORE)
+
+
+class SlotHandler(ElementHandler):
+ def __init__(self, parent, **kwargs):
+ super(SlotHandler, self).__init__(parent=parent, **kwargs)
+ self.dbcurs = parent.dbcurs
+ self.machine = parent.id
+
+ def startMainElement(self, name, attrs):
+ self.id = self.dbcurs.add_slot(self.machine, attrs['name'])
+
+ def startChildElement(self, name, attrs):
+ if name == 'slotoption':
+ option = self.dbcurs.add_slotoption(self.id, attrs['devname'], attrs['name'])
+ if attrs.get('default') == 'yes':
+ self.dbcurs.add_slotdefault(self.id, option)
+ self.setChildHandler(name, attrs, self.IGNORE)
+
+
+class RamOptionHandler(TextAccumulator):
+ def __init__(self, parent, **kwargs):
+ super(RamOptionHandler, self).__init__(parent=parent, **kwargs)
+ self.dbcurs = parent.dbcurs
+ self.machine = parent.id
+
+ def startMainElement(self, name, attrs):
+ self.name = attrs['name']
+ self.default = attrs.get('default', 'no') == 'yes';
+
+ def endMainElement(self, name):
+ self.size = int(self.text)
+ self.dbcurs.add_ramoption(self.machine, self.name, self.size)
+ if self.default:
+ self.dbcurs.add_ramdefault(self.machine, self.size)
+
+
+class MachineHandler(ElementHandler):
+ CHILD_HANDLERS = {
+ 'description': TextAccumulator,
+ 'year': TextAccumulator,
+ 'manufacturer': TextAccumulator,
+ 'dipswitch': DipSwitchHandler,
+ 'configuration': DipSwitchHandler,
+ 'slot': SlotHandler,
+ 'ramoption': RamOptionHandler }
+
+ def __init__(self, parent, **kwargs):
+ super(MachineHandler, self).__init__(parent=parent, **kwargs)
+ self.dbcurs = self.dbconn.cursor()
+
+ def startMainElement(self, name, attrs):
+ self.shortname = attrs['name']
+ self.sourcefile = attrs['sourcefile']
+ self.isdevice = attrs.get('isdevice', 'no') == 'yes'
+ self.runnable = attrs.get('runnable', 'yes') == 'yes'
+ self.cloneof = attrs.get('cloneof')
+ self.romof = attrs.get('romof')
+ self.dbcurs.add_sourcefile(self.sourcefile)
+
+ def endMainElement(self, name):
+ self.dbcurs.close()
+
+ def startChildElement(self, name, attrs):
+ if name in self.CHILD_HANDLERS:
+ self.setChildHandler(name, attrs, self.CHILD_HANDLERS[name](self))
+ else:
+ if name == 'biosset':
+ bios = self.dbcurs.add_biosset(self.id, attrs['name'], attrs['description'])
+ if attrs.get('default', 'no') == 'yes':
+ self.dbcurs.add_biossetdefault(bios)
+ elif name == 'device_ref':
+ self.dbcurs.add_devicereference(self.id, attrs['name'])
+ elif name == 'feature':
+ self.dbcurs.add_featuretype(attrs['type'])
+ status = 0 if 'status' not in attrs else 2 if attrs['status'] == 'unemulated' else 1
+ overall = status if 'overall' not in attrs else 2 if attrs['overall'] == 'unemulated' else 1
+ self.dbcurs.add_feature(self.id, attrs['type'], status, overall)
+ elif name == 'softwarelist':
+ self.dbcurs.add_machinesoftwarelist(self.id, attrs['name'], attrs['tag'], attrs['status'])
+ elif name == 'rom':
+ crc = attrs.get('crc')
+ sha1 = attrs.get('sha1')
+ if (crc is not None) and (sha1 is not None):
+ crc = int(crc, 16)
+ sha1 = sha1.lower()
+ self.dbcurs.add_rom(crc, sha1)
+ status = attrs.get('status', 'good')
+ self.dbcurs.add_romdump(self.id, attrs['name'], crc, sha1, status != 'good')
+ elif name == 'disk':
+ sha1 = attrs.get('sha1')
+ if sha1 is not None:
+ sha1 = sha1.lower()
+ self.dbcurs.add_disk(sha1)
+ status = attrs.get('status', 'good')
+ self.dbcurs.add_diskdump(self.id, attrs['name'], sha1, status != 'good')
+ self.setChildHandler(name, attrs, self.IGNORE)
+
+ def endChildHandler(self, name, handler):
+ if name == 'description':
+ self.description = handler.text
+ self.id = self.dbcurs.add_machine(self.shortname, self.description, self.sourcefile, self.isdevice, self.runnable)
+ if self.cloneof is not None:
+ self.dbcurs.add_cloneof(self.id, self.cloneof)
+ if self.romof is not None:
+ self.dbcurs.add_romof(self.id, self.romof)
+ elif name == 'year':
+ self.year = handler.text
+ elif name == 'manufacturer':
+ self.manufacturer = handler.text
+ self.dbcurs.add_system(self.id, self.year, self.manufacturer)
+
+
+class ListXmlHandler(ElementHandler):
+ def __init__(self, dbconn, **kwargs):
+ super(ListXmlHandler, self).__init__(parent=None, **kwargs)
+ self.dbconn = dbconn
+
+ def startDocument(self):
+ pass
+
+ def endDocument(self):
+ pass
+
+ def startMainElement(self, name, attrs):
+ if name != 'mame':
+ raise xml.sax.SAXParseException(
+ msg=('Expected "mame" element but found "%s"' % (name, )),
+ exception=None,
+ locator=self.locator)
+ self.machines = 0
+
+ def endMainElement(self, name):
+ self.dbconn.commit()
+
+ def startChildElement(self, name, attrs):
+ if name != 'machine':
+ raise xml.sax.SAXParseException(
+ msg=('Expected "machine" element but found "%s"' % (name, )),
+ exception=None,
+ locator=self.locator)
+ self.setChildHandler(name, attrs, MachineHandler(self))
+
+ def endChildHandler(self, name, handler):
+ if name == 'machine':
+ if self.machines >= 1023:
+ self.dbconn.commit()
+ self.machines = 0
+ else:
+ self.machines += 1
+
+ def processingInstruction(self, target, data):
+ pass
+
+
+class DataAreaHandler(ElementHandler):
+ def __init__(self, parent, **kwargs):
+ super(DataAreaHandler, self).__init__(parent=parent, **kwargs)
+ self.dbcurs = parent.dbcurs
+ self.part = parent.id
+
+ def startChildElement(self, name, attrs):
+ if name == 'rom':
+ crc = attrs.get('crc')
+ sha1 = attrs.get('sha1')
+ if ('name' in attrs) and (crc is not None) and (sha1 is not None):
+ crc = int(crc, 16)
+ sha1 = sha1.lower()
+ self.dbcurs.add_rom(crc, sha1)
+ status = attrs.get('status', 'good')
+ self.dbcurs.add_softwareromdump(self.part, attrs['name'], crc, sha1, status != 'good')
+ self.setChildHandler(name, attrs, self.IGNORE)
+
+
+class DiskAreaHandler(ElementHandler):
+ def __init__(self, parent, **kwargs):
+ super(DiskAreaHandler, self).__init__(parent=parent, **kwargs)
+ self.dbcurs = parent.dbcurs
+ self.part = parent.id
+
+ def startChildElement(self, name, attrs):
+ if name == 'disk':
+ sha1 = attrs.get('sha1')
+ if sha1 is not None:
+ sha1 = sha1.lower()
+ self.dbcurs.add_disk(sha1)
+ status = attrs.get('status', 'good')
+ self.dbcurs.add_softwarediskdump(self.part, attrs['name'], sha1, status != 'good')
+ self.setChildHandler(name, attrs, self.IGNORE)
+
+
+class SoftwarePartHandler(ElementHandler):
+ CHILD_HANDLERS = {
+ 'dataarea': DataAreaHandler,
+ 'diskarea': DiskAreaHandler }
+
+ def __init__(self, parent, **kwargs):
+ super(SoftwarePartHandler, self).__init__(parent=parent, **kwargs)
+ self.dbcurs = parent.dbcurs
+ self.software = parent.id
+
+ def startMainElement(self, name, attrs):
+ self.id = self.dbcurs.add_softwarepart(self.software, attrs['name'], attrs['interface'])
+
+ def startChildElement(self, name, attrs):
+ if name in self.CHILD_HANDLERS:
+ self.setChildHandler(name, attrs, self.CHILD_HANDLERS[name](self))
+ else:
+ if name == 'feature':
+ self.dbcurs.add_softwarepartfeaturetype(attrs['name'])
+ self.dbcurs.add_softwarepartfeature(self.id, attrs['name'], attrs['value'])
+ self.setChildHandler(name, attrs, self.IGNORE)
+
+
+class SoftwareHandler(ElementHandler):
+ CHILD_HANDLERS = {
+ 'description': TextAccumulator,
+ 'year': TextAccumulator,
+ 'publisher': TextAccumulator,
+ 'notes': TextAccumulator,
+ 'part': SoftwarePartHandler }
+
+ def __init__(self, parent, **kwargs):
+ super(SoftwareHandler, self).__init__(parent=parent, **kwargs)
+ self.dbcurs = self.dbconn.cursor()
+ self.softwarelist = parent.id
+
+ def startMainElement(self, name, attrs):
+ self.shortname = attrs['name']
+ self.cloneof = attrs.get('cloneof')
+ self.supported = 0 if (attrs.get('supported', 'yes') == 'yes') else 1 if (attrs.get('supported', 'yes') == 'partial') else 2
+
+ def endMainElement(self, name):
+ self.dbcurs.close()
+
+ def startChildElement(self, name, attrs):
+ if name in self.CHILD_HANDLERS:
+ self.setChildHandler(name, attrs, self.CHILD_HANDLERS[name](self))
+ else:
+ if name == 'info':
+ self.dbcurs.add_softwareinfotype(attrs['name'])
+ self.dbcurs.add_softwareinfo(self.id, attrs['name'], attrs['value'])
+ elif name == 'sharedfeat':
+ self.dbcurs.add_softwaresharedfeattype(attrs['name'])
+ self.dbcurs.add_softwaresharedfeat(self.id, attrs['name'], attrs['value'])
+ self.setChildHandler(name, attrs, self.IGNORE)
+
+ def endChildHandler(self, name, handler):
+ if name == 'description':
+ self.description = handler.text
+ elif name == 'year':
+ self.year = handler.text
+ elif name == 'publisher':
+ self.publisher = handler.text
+ self.id = self.dbcurs.add_software(self.softwarelist, self.shortname, self.supported, self.description, self.year, self.publisher)
+ if self.cloneof is not None:
+ self.dbcurs.add_softwarecloneof(self.id, self.cloneof)
+ elif name == 'notes':
+ self.dbcurs.add_softwarenotes(self.id, handler.text)
+
+
+class SoftwareListHandler(ElementHandler):
+ CHILD_HANDLERS = {
+ 'notes': TextAccumulator,
+ 'software': SoftwareHandler }
+
+ def __init__(self, dbconn, **kwargs):
+ super(SoftwareListHandler, self).__init__(parent=None, **kwargs)
+ self.dbconn = dbconn
+
+ def startDocument(self):
+ pass
+
+ def endDocument(self):
+ pass
+
+ def startMainElement(self, name, attrs):
+ if name != 'softwarelist':
+ raise xml.sax.SAXParseException(
+ msg=('Expected "softwarelist" element but found "%s"' % (name, )),
+ exception=None,
+ locator=self.locator)
+ self.shortname = attrs['name']
+ self.description = attrs['description']
+ self.entries = 0
+ dbcurs = self.dbconn.cursor()
+ self.id = dbcurs.add_softwarelist(self.shortname, self.description)
+ dbcurs.close()
+
+ def endMainElement(self, name):
+ self.dbconn.commit()
+
+ def startChildElement(self, name, attrs):
+ if name in self.CHILD_HANDLERS:
+ self.setChildHandler(name, attrs, self.CHILD_HANDLERS[name](self))
+ else:
+ raise xml.sax.SAXParseException(
+ msg=('Found unexpected element "%s"' % (name, )),
+ exception=None,
+ locator=self.locator)
+
+ def endChildHandler(self, name, handler):
+ if name == 'notes':
+ dbcurs = self.dbconn.cursor()
+ dbcurs.add_softwarelistnotes(self.id, handler.text)
+ dbcurs.close()
+ elif name == 'software':
+ if self.entries >= 1023:
+ self.dbconn.commit()
+ self.entries = 0
+ else:
+ self.entries += 1
+
+ def processingInstruction(self, target, data):
+ pass
+
+
+def load_info(options):
+ dbconn = dbaccess.UpdateConnection(options.database)
+ dbconn.prepare_for_load()
+ parser = xml.sax.make_parser()
+
+ parser.setContentHandler(SoftwareListHandler(dbconn))
+ for path in options.softwarepath:
+ files = [os.path.join(path, f) for f in os.listdir(path) if f.endswith('.xml')]
+ for filename in files:
+ parser.parse(filename)
+
+ parser.setContentHandler(ListXmlHandler(dbconn))
+ if options.executable is not None:
+ task = subprocess.Popen([options.executable, '-listxml'], stdout=subprocess.PIPE)
+ parser.parse(task.stdout)
+ else:
+ parser.parse(options.file)
+
+ dbconn.finalise_load()