libui/test/testlist.py

160 lines
3.3 KiB
Python

# 20 january 2020
# note: python 3
import abc
import fileinput
import re
import sys
def errf(fmt, *args):
print(fmt.format(*args), file = sys.stderr)
class command(metaclass = abc.ABCMeta):
@classmethod
@abc.abstractmethod
def name(cls):
raise NotImplementedError
@classmethod
@abc.abstractmethod
def usageString(cls):
raise NotImplementedError
# returns the list of filenames to iterate through
# returns None if there was an error parsing arguments
@abc.abstractmethod
def processArgs(self, args):
raise NotImplementedError
@abc.abstractmethod
def run(self, casenames):
raise NotImplementedError
class listCommand:
@classmethod
def name(cls):
return 'list'
@classmethod
def usageString(cls):
return 'list [source-files...]'
def processArgs(self, args):
return args
def run(self, casenames):
for x in casenames:
print('Test' + x)
command.register(listCommand)
headerHeader = '''// Generated by testlist.py; do not edit
struct testingprivCase {
const char *name;
void (*f)(void);
};
extern const struct testingprivCase testingprivCases[];
extern const size_t testingprivNumCases;'''
headerEntryFmt = 'extern void testingprivScaffoldName(Test{})(void);'
class headerCommand:
filename = None
@classmethod
def name(cls):
return 'header'
@classmethod
def usageString(cls):
return 'header header-file [source-files...]'
def processArgs(self, args):
if len(args) < 1:
errf('error: output filename missing')
return None
self.filename = args[0]
return args[1:]
def run(self, casenames):
with open(self.filename, 'wt') as f:
print(headerHeader, file = f)
for x in casenames:
print(headerEntryFmt.format(x), file = f)
command.register(headerCommand)
sourceHeader = '''// Generated by testlist.py; do not edit
#include "test.h"
const struct testingprivCase testingprivCases[] = {'''
sourceEntryFmt = ' {{ "Test{0}", testingprivScaffoldName(Test{0}) }},'
sourceFooter = '''}};
const size_t testingprivNumCases = {};'''
class sourceCommand:
filename = None
@classmethod
def name(cls):
return 'source'
@classmethod
def usageString(cls):
return 'source source-file [source-files...]'
def processArgs(self, args):
if len(args) < 1:
errf('error: output filename missing')
return None
self.filename = args[0]
return args[1:]
def run(self, casenames):
with open(self.filename, 'wt') as f:
print(sourceHeader, file = f)
for x in casenames:
print(sourceEntryFmt.format(x), file = f)
print(sourceFooter.format(len(casenames)), file = f)
command.register(sourceCommand)
commands = [
listCommand,
headerCommand,
sourceCommand,
]
def usage():
errf('usage:')
errf('{} help', sys.argv[0])
for cmd in commands:
errf('{} {}', sys.argv[0], cmd.usageString())
sys.exit(1)
def main():
r = re.compile('^(?:Test|TestNoInit)\(([A-Za-z0-9_]+)\)$')
if len(sys.argv) < 2:
usage()
cmdname = sys.argv[1]
if cmdname == 'help':
usage()
cmdtype = None
for cmd in commands:
if cmd.name() == cmdname:
cmdtype = cmd
break
if cmdtype is None:
errf('error: unknown command {!r}', cmdname)
usage()
cmd = cmdtype()
files = cmd.processArgs(sys.argv[2:])
if files is None:
usage()
casenames = []
for line in fileinput.input(files = files):
match = r.match(line)
if match is not None:
casenames.append(match.group(1))
cmd.run(sorted(casenames))
main()