mirror of
https://github.com/mamedev/mame.git
synced 2024-11-16 07:48:32 +01:00
Added CI job to check for likely mame.lst errors.
This commit is contained in:
parent
4a5196149b
commit
6176c84768
2 changed files with 143 additions and 0 deletions
2
.github/workflows/ci-linux.yml
vendored
2
.github/workflows/ci-linux.yml
vendored
|
@ -55,6 +55,8 @@ jobs:
|
|||
run: make -j2
|
||||
- name: Validate
|
||||
run: ./mame -validate
|
||||
- name: Reconcile driver list
|
||||
run: ./mame -listxml | python scripts/build/makedep.py reconcilelist -l src/mame/mame.lst -
|
||||
- name: ORM check
|
||||
run: python scripts/minimaws/minimaws.py load --executable ./mame --softwarepath hash
|
||||
- uses: actions/upload-artifact@master
|
||||
|
|
|
@ -8,6 +8,7 @@ import glob
|
|||
import io
|
||||
import os.path
|
||||
import sys
|
||||
import xml.sax
|
||||
|
||||
|
||||
class ParserBase:
|
||||
|
@ -581,6 +582,128 @@ class DriverCollector(DriverFilter):
|
|||
self.sources = sorted(sources)
|
||||
|
||||
|
||||
class DriverReconciler(DriverFilter):
|
||||
class InfoHandler:
|
||||
def __init__(self, drivers, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.drivers = drivers
|
||||
self.bad = False
|
||||
self.locator = None
|
||||
self.ignored_depth = 0
|
||||
self.in_document = False
|
||||
self.in_mame = False
|
||||
|
||||
def startElement(self, name, attrs):
|
||||
if not self.in_document:
|
||||
raise xml.sax.SAXParseException('Unexpected start of element "%s"' % (name, ), None, self.locator)
|
||||
elif self.ignored_depth > 0:
|
||||
self.ignored_depth += 1
|
||||
elif not self.in_mame:
|
||||
if name != 'mame':
|
||||
raise xml.sax.SAXParseException('Unexpected start of element "%s"' % (name, ), None, self.locator)
|
||||
self.in_mame = True
|
||||
elif name != 'machine':
|
||||
raise xml.sax.SAXParseException('Unexpected start of element "%s"' % (name, ), None, self.locator)
|
||||
else:
|
||||
runnable = attrs.get('runnable', 'yes')
|
||||
if runnable == 'yes':
|
||||
shortname = attrs['name']
|
||||
source = attrs['sourcefile'].replace('\\', '/')
|
||||
declared = self.drivers.get(shortname)
|
||||
if declared is None:
|
||||
sys.stderr.write('Driver "%s" not declared in list file\n' % (shortname, ))
|
||||
self.bad = True
|
||||
elif declared != source:
|
||||
sys.stderr.write('Driver "%s" found for source file "%s" but defined in source file "%s"\n' % (shortname, declared, source))
|
||||
self.bad = True
|
||||
self.ignored_depth = 1
|
||||
|
||||
def endElement(self, name):
|
||||
if self.ignored_depth > 0:
|
||||
self.ignored_depth -= 1
|
||||
elif self.in_mame:
|
||||
if name != 'mame':
|
||||
raise xml.sax.SAXParseException('Unexpected end of element "%s"' % (name, ), None, self.locator)
|
||||
self.in_mame = False
|
||||
else:
|
||||
raise xml.sax.SAXParseException('Unexpected end of element "%s"' % (name, ), None, self.locator)
|
||||
|
||||
def startDocument(self):
|
||||
if self.in_document:
|
||||
raise xml.sax.SAXParseException('Unexpected start of document', None, self.locator)
|
||||
self.in_document = True
|
||||
|
||||
def endDocument(self):
|
||||
if not self.in_document:
|
||||
raise xml.sax.SAXParseException('Unexpected end of document', None, self.locator)
|
||||
self.in_document = False
|
||||
|
||||
def setDocumentLocator(self, locator):
|
||||
self.locator = locator
|
||||
|
||||
def startPrefixMapping(self, prefix, uri):
|
||||
pass
|
||||
|
||||
def endPrefixMapping(self, prefix):
|
||||
pass
|
||||
|
||||
def characters(self, content):
|
||||
pass
|
||||
|
||||
def ignorableWhitespace(self, whitespace):
|
||||
pass
|
||||
|
||||
def processingInstruction(self, target, data):
|
||||
pass
|
||||
|
||||
|
||||
def __init__(self, options, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def sourcefile(filename):
|
||||
if (state['prevsource'] is not None) and (not state['prevdrivers']):
|
||||
sys.stderr.write('No drivers for source file "%s"\n' % (state['prevsource'], ))
|
||||
self.bad = True
|
||||
if filename in self.sources:
|
||||
sys.stderr.write('Duplicate source file "%s"\n' % (filename, ))
|
||||
state['prevdrivers'] = self.sources[filename]
|
||||
self.bad = True
|
||||
else:
|
||||
drivers = set()
|
||||
state['prevdrivers'] = drivers
|
||||
self.sources[filename] = drivers
|
||||
state['prevsource'] = filename
|
||||
|
||||
def driver(shortname):
|
||||
if shortname in self.drivers:
|
||||
sys.stderr.write('Duplicate driver "%s" for source file "%s" (previously seen for source file "%s")\n' % (shortname, state['prevsource'], self.drivers[shortname]))
|
||||
self.bad = True
|
||||
else:
|
||||
self.drivers[shortname] = state['prevsource']
|
||||
drivers = state['prevdrivers']
|
||||
if drivers is None:
|
||||
sys.stderr.write('Driver "%s" found outside source file section\n' % (shortname, ))
|
||||
self.bad = True
|
||||
else:
|
||||
drivers.add(shortname)
|
||||
|
||||
state = { 'prevsource': None, 'prevdrivers': None }
|
||||
self.bad = False
|
||||
self.sources = { }
|
||||
self.drivers = { }
|
||||
self.parse_list(options.list, sourcefile, driver)
|
||||
|
||||
def reconcile_xml(self, xmlfile):
|
||||
handler = self.InfoHandler(self.drivers)
|
||||
try:
|
||||
xml.sax.parse(xmlfile, handler=handler)
|
||||
if handler.bad:
|
||||
self.bad = True
|
||||
except xml.sax.SAXException as err:
|
||||
sys.stderr.write('Error parsing system information file: %s\n' % (err, ))
|
||||
self.bad = True
|
||||
|
||||
|
||||
def split_path(path):
|
||||
path = os.path.normpath(path)
|
||||
result = [ ]
|
||||
|
@ -619,6 +742,10 @@ def parse_command_line():
|
|||
subparser.add_argument('-f', '--filter', metavar='<fltfile>', help='input filter file')
|
||||
subparser.add_argument('list', metavar='<lstfile>', help='input list file')
|
||||
|
||||
subparser = subparsers.add_parser('reconcilelist', help='reconcile driver list')
|
||||
subparser.add_argument('-l', '--list', metavar='<lstfile>', required=True, help='master driver list file')
|
||||
subparser.add_argument('infoxml', metavar='<xmlfile>', nargs='?', help='XML system information file')
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
|
@ -905,3 +1032,17 @@ if __name__ == '__main__':
|
|||
write_filter(options, sys.stdout)
|
||||
elif options.command == 'driverlist':
|
||||
DriverLister(options).write_source(sys.stdout)
|
||||
elif options.command == 'reconcilelist':
|
||||
reconciler = DriverReconciler(options)
|
||||
if options.infoxml == '-':
|
||||
reconciler.reconcile_xml(sys.stdin)
|
||||
elif options.infoxml is not None:
|
||||
try:
|
||||
xmlfile = io.open(options.infoxml, 'rb')
|
||||
with xmlfile:
|
||||
reconciler.reconcile_xml(xmlfile)
|
||||
except IOError:
|
||||
sys.stderr.write('Unable to open system information file "%s"\n' % (options.infoxml, ))
|
||||
sys.exit(1)
|
||||
if reconciler.bad:
|
||||
sys.exit(1)
|
||||
|
|
Loading…
Reference in a new issue