diff --git a/tools/abb_extctrl_setup.py b/tools/abb_extctrl_setup.py new file mode 100755 index 0000000000000000000000000000000000000000..e6d021c182ed2b9c16c6155250d8aba0498528dc --- /dev/null +++ b/tools/abb_extctrl_setup.py @@ -0,0 +1,79 @@ +#!/usr/bin/python3 + +import argparse +import globalize +import orcaftp +import sys + +def check_options(parser, options, command, required): + options = dict(options._get_kwargs()) + error = [] + for r in required: + if not r in options: + error.append('--%s is not a recognized option' % r) + pass + elif not options[r]: + error.append('--%s is required for --%s' % (r, command)) + pass + if error: + parser.print_help() + print('\ninvocation errors:', file=sys.stderr) + + for e in error: + print(' %s' % e, file=sys.stderr) + pass + + sys.exit(1) + pass + pass + +if __name__ == '__main__': + optParser = argparse.ArgumentParser(usage="%(prog)s [options]") + optParser.add_argument('--robot', + required=True, + action='store', + metavar='ROBOT', + help='run actions on ROBOT') + optParser.add_argument('--globalize', + action='store', + metavar='C-FILE', + help='globalize IMAGE into C-FILE') + optParser.add_argument('--image', + action='store', + metavar='IMAGE') + optParser.add_argument('--patterns', + nargs='*', + action='store', + metavar='REGEXP', + help='REGEXP to verify that C-FILE matches IMAGE') + optParser.add_argument('--symbols', + nargs='*', + action='store', + metavar='SYMBOL', + help='SYMBOL to globalize') + optParser.add_argument('--robotware', + action='store_true', + help='Get robotware version') + options = optParser.parse_args(sys.argv[1:]) + + robot_ftp = orcaftp.OrcaFTP(options.robot) + system = robot_ftp.read_ascii('/hd0a/system.dir').strip() + release = robot_ftp.read_ascii('/hd0a/%s/INTERNAL/release.dir' % + system).strip() + if options.globalize: + error = [] + check_options(parser=optParser, + options=options, + command='globalize', + required=[ 'image', 'patterns', 'symbols' ]) + func = globalize.globalize(ftp=robot_ftp, + image=options.image, + patterns=options.patterns, + symbols=options.symbols, + robot=options.robot, + release=release) + f = open(options.globalize, 'w') + f.write(str(func)) + + if options.robotware: + print(release) diff --git a/tools/globalize.py b/tools/globalize.py new file mode 100644 index 0000000000000000000000000000000000000000..e98c67f182385d1e3fe9fc3dca5f1e6b6be199d7 --- /dev/null +++ b/tools/globalize.py @@ -0,0 +1,127 @@ +#!/usr/bin/python3 + +import argparse +import globalize +import orcaftp +import re +import subprocess +import sys +import tempfile +import time +import stringarray + +def nm(image): + p = subprocess.Popen([ 'nm', image.name ], stdout=subprocess.PIPE) + for l in p.stdout: + yield l.decode('utf8').split() + pass + pass + +def match(name, patterns): + for p in patterns: + if re.match(p, name): + return True + return False + + +def globalize(ftp, image, patterns, symbols, robot, release): + image_file = tempfile.NamedTemporaryFile( + prefix='globalize.%s.' % image, + suffix='.img') + ftp.retrbinary("RETR /hd0a/%s/bin/%s" % (release, image), + image_file.write) + image_file.flush() + + check = [] + globalize = [] + for value, kind, name in nm(image_file): + if kind.isupper() and match(name, patterns): + check.append((value, name)) + pass + if kind.islower and name in symbols: + globalize.append((value, name)) + pass + pass + result = stringarray.StringArray() + result.append_lines(""" + |char LTH_GLOBALIZE_VERSION[] = + | "Generated /hd0a/%s/bin/%s.globalize for %s"; + """ % (release, image.split('.')[0], robot)) + result.append_lines(""" + |extern void *sysSymTbl; + |extern int symFindByName( + | void *sysSymTbl, + | char *name, + | void **value, + | int *type); + |extern int symAdd( + | void *sysSymTbl, + | char *name, + | void *value, + | int type, + | short group); + |extern int printf( + | char *fmt, ...); + | + |struct symbols { + | void *value; + | char *name; + |}; + | + |static struct symbols to_check[] = { + """) + for value, name in sorted(check): + result += ' { (void*)0x%s, "%s" },' % (value, name) + pass + result.append_lines(""" + | { 0, 0 } + |}; + | + |static struct symbols to_globalize[] = { + """) + for value, name in sorted(globalize): + result += ' { (void*)0x%s, "%s" },' % (value, name) + pass + result.append_lines(""" + | { 0, 0 } + |}; + | + |int lth_globalize_stage_2() + |{ + | struct symbols *s; + | int result = 0; + | + | for (s = to_check ; s->name ; s++) { + | void *value = 0; + | int type; + | + | if (symFindByName(sysSymTbl, s->name, &value, &type) != 0 || + | value != s->value) { + | printf("Symbol mismatch '%s' %p != %p\\n", s->name, s->value, value); + | result = 1; + | goto out; + | } + | } + | for (s = to_globalize ; s->name ; s++) { + | void *value = 0; + | int type; + | + | if (symFindByName(sysSymTbl, s->name, &value, &type) == 0) { + | if (value != s->value) { + | printf("Symbol mismatch '%s' %p != %p \\n", + | s->name, s->value, value); + | result = 1; + | goto out; + | } else { + | printf("Symbol already declared '%s' %p \\n", s->name, s->value); + | } + | } else if (symAdd(sysSymTbl, s->name, s->value, 5, 0) != 0) { + | printf("Symbol declaration failed '%s' %p \\n", s->name, s->value); + | goto out; + | } + | } + |out: + | return result; + |} + """) + return result diff --git a/tools/orcaftp.py b/tools/orcaftp.py new file mode 100644 index 0000000000000000000000000000000000000000..d06bba901acefb84fd28b92ee968efa474afadc5 --- /dev/null +++ b/tools/orcaftp.py @@ -0,0 +1,33 @@ +#!/usr/bin/python3 + +import ftplib +import io + +class OrcaFTP(ftplib.FTP): + + def __init__(self, host, user=None, passwd=None, acct=None, timeout=None): + ftplib.FTP.__init__(self, host, user, passwd, acct, timeout) + self.login() + pass + + def read_ascii(self, path): + result = io.StringIO() + self.retrlines("RETR %s" % path, result.write) + return result.getvalue() + + + def read_binary(self, path): + result = io.BytesIO() + self.retrbinary("RETR %s" % path, result.write) + return result.getvalue() + + def write_ascii(self, path, value): + f = io.StringIO(value) + self.storlines("STOR %s" % path, f) + pass + + def write_binary(self, path, value): + f = io.BytesIO(value) + self.storbinary("STOR %s" % path, f) + pass + diff --git a/tools/stringarray.py b/tools/stringarray.py new file mode 100644 index 0000000000000000000000000000000000000000..c77f2ed183fbc043f512dcc58fc0165686de7473 --- /dev/null +++ b/tools/stringarray.py @@ -0,0 +1,38 @@ +#!/usr/bin/python3 + +class StringArray(list, object): + + def append_lines(self, lines, sep='|'): + for l in map(lambda s: s.strip(), lines.split('\n')): + if not l: + continue + if not l.startswith(sep): + raise Exception('%s do not start with "%s"' % (l, sep)) + self.append(l[len(sep):]) + pass + + def __iadd__(self, other): + try: + lines = other.split('\n') + if len(lines[-1]) == 0: + lines.pop() + pass + self.extend(lines) + pass + except AttributeError: + self.extend(other) + pass + return self + + def indent(self, indent=' '): + for l in self: + yield '%s%s' % (indent, l) + pass + pass + + def __str__(self): + return '\n'.join(self) + '\n' + + pass + +