From 4001a74869c5e37443e20c3ff107f6ccf8e378f8 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Wed, 2 Mar 2016 20:54:06 +1100 Subject: Update rtems-tool to support Python 2 and 3. Add solaris and netbsd. Close #2619. --- rtemstoolkit/__init__.py | 15 ++++++- rtemstoolkit/check.py | 44 +++++++++++------- rtemstoolkit/config.py | 71 +++++++++++++++++------------ rtemstoolkit/darwin.py | 5 ++- rtemstoolkit/error.py | 10 +++-- rtemstoolkit/execute.py | 83 +++++++++++++++++++++------------- rtemstoolkit/freebsd.py | 14 ++++-- rtemstoolkit/git.py | 59 ++++++++++++++++-------- rtemstoolkit/linux.py | 16 +++++-- rtemstoolkit/log.py | 53 +++++++++++++--------- rtemstoolkit/macros.py | 78 +++++++++++++++++++++----------- rtemstoolkit/mailer.py | 31 ++++++++----- rtemstoolkit/netbsd.py | 96 +++++++++++++++++++++++++++++++++++++++ rtemstoolkit/options.py | 105 ++++++++++++++++++++++++++++++------------- rtemstoolkit/path.py | 60 ++++++++++++++----------- rtemstoolkit/solaris.py | 90 +++++++++++++++++++++++++++++++++++++ rtemstoolkit/stacktraces.py | 5 +-- rtemstoolkit/version.py | 19 ++++++-- rtemstoolkit/windows.py | 18 +++++--- tester/rt/config.py | 10 +++-- tester/rt/console.py | 16 ++++--- tester/rt/gdb.py | 61 ++++++++++++++----------- tester/rt/options.py | 15 ++++--- tester/rt/pygdb/__init__.py | 5 ++- tester/rt/pygdb/mi_parser.py | 32 ++++++------- tester/rt/pygdb/spark.py | 79 ++++++++++++++++---------------- tester/rt/stty.py | 10 +++-- tester/rt/test.py | 38 ++++++++-------- tester/rt/version.py | 16 +++---- tester/rtems-test | 6 ++- 30 files changed, 793 insertions(+), 367 deletions(-) create mode 100644 rtemstoolkit/netbsd.py create mode 100644 rtemstoolkit/solaris.py diff --git a/rtemstoolkit/__init__.py b/rtemstoolkit/__init__.py index 33f49f0..82b14b3 100644 --- a/rtemstoolkit/__init__.py +++ b/rtemstoolkit/__init__.py @@ -37,4 +37,17 @@ all = ['check', 'macros', 'mailer', 'options', - 'path'] + 'path', + 'version'] + +from . import check +from . import config +from . import error +from . import execute +from . import git +from . import log +from . import macros +from . import mailer +from . import options +from . import path +from . import version diff --git a/rtemstoolkit/check.py b/rtemstoolkit/check.py index f4c05b8..2890bd8 100644 --- a/rtemstoolkit/check.py +++ b/rtemstoolkit/check.py @@ -1,6 +1,6 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2010-2014 Chris Johns (chrisj@rtems.org) +# Copyright 2010-2016 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. @@ -32,14 +32,28 @@ # Check the defaults for a specific host. # +from __future__ import print_function + import os -import error -import execute -import log -import options -import path -import version +# +# Support to handle use in a package and as a unit test. +# If there is a better way to let us know. +# +try: + from . import error + from . import execute + from . import log + from . import options + from . import path + from . import version +except (ValueError, SystemError): + import error + import execute + import log + import options + import path + import version def _check_none(_opts, macro, value, constraint): return True @@ -117,7 +131,7 @@ def host_setup(opts): sane = True - for d in opts.defaults.keys(): + for d in list(opts.defaults.keys()): try: (test, constraint, value) = opts.defaults.get(d) except: @@ -155,16 +169,16 @@ def run(): _opts = options.load(args = sys.argv) log.notice('RTEMS Source Builder - Check, v%s' % (version.str())) if host_setup(_opts): - print 'Environment is ok' + print('Environment is ok') else: - print 'Environment is not correctly set up' - except error.general, gerr: - print gerr + print('Environment is not correctly set up') + except error.general as gerr: + print(gerr) sys.exit(1) - except error.internal, ierr: - print ierr + except error.internal as ierr: + print(ierr) sys.exit(1) - except error.exit, eerr: + except error.exit as eerr: pass except KeyboardInterrupt: log.notice('abort: user terminated') diff --git a/rtemstoolkit/config.py b/rtemstoolkit/config.py index 306e3df..697bcaf 100644 --- a/rtemstoolkit/config.py +++ b/rtemstoolkit/config.py @@ -1,6 +1,6 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2010-2014 Chris Johns (chrisj@rtems.org) +# Copyright 2010-2016 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. @@ -36,23 +36,30 @@ # other software modules. # +from __future__ import print_function + import copy +import functools import os import re import sys +# +# Support to handle use in a package and as a unit test. +# If there is a better way to let us know. +# try: + from . import error + from . import execute + from . import log + from . import options + from . import path +except (ValueError, SystemError): import error import execute import log import options import path -except KeyboardInterrupt: - print 'user terminated' - sys.exit(1) -except: - print 'error: unknown application load error' - sys.exit(1) def _check_bool(value): if value.isdigit(): @@ -90,6 +97,8 @@ class file(object): self.macros.define(label) self._includes = [] self.load_depth = 0 + self.lc = 0 + self.name = 'none' def __del__(self): pass @@ -98,7 +107,7 @@ class file(object): def _dict(dd): s = '' - ddl = dd.keys() + ddl = list(dd.keys()) ddl.sort() for d in ddl: s += ' ' + d + ': ' + dd[d] + '\n' @@ -137,14 +146,14 @@ class file(object): outter level. Nested levels will need to split with futher calls.''' trace_me = False if trace_me: - print '------------------------------------------------------' + print('------------------------------------------------------') macros = [] nesting = [] has_braces = False c = 0 while c < len(s): if trace_me: - print 'ms:', c, '"' + s[c:] + '"', has_braces, len(nesting), nesting + print('ms:', c, '"' + s[c:] + '"', has_braces, len(nesting), nesting) # # We need to watch for shell type variables or the form '${var}' because # they can upset the brace matching. @@ -192,9 +201,9 @@ class file(object): macros.append(s[macro_start:c + 1].strip()) c += 1 if trace_me: - print 'ms:', macros + print('ms:', macros) if trace_me: - print '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=' + print('-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=') return macros def _shell(self, line): @@ -432,13 +441,13 @@ class file(object): else: istrue = _check_bool(ifls[0]) if istrue == None: - self._error('invalid if bool value: ' + reduce(add, ls, '')) + self._error('invalid if bool value: ' + functools.reduce(add, ls, '')) istrue = False elif len(ifls) == 2: if ifls[0] == '!': istrue = _check_bool(ifls[1]) if istrue == None: - self._error('invalid if bool value: ' + reduce(add, ls, '')) + self._error('invalid if bool value: ' + functools.reduce(add, ls, '')) istrue = False else: istrue = not istrue @@ -454,7 +463,7 @@ class file(object): elif ifls[1] == '!=': istrue = True else: - self._error('invalid if bool operator: ' + reduce(add, ls, '')) + self._error('invalid if bool operator: ' + functools.reduce(add, ls, '')) elif len(ifls) == 3: if ifls[1] == '==': if ifls[0] == ifls[2]: @@ -487,9 +496,9 @@ class file(object): else: istrue = False else: - self._error('invalid %if operator: ' + reduce(add, ls, '')) + self._error('invalid %if operator: ' + functools.reduce(add, ls, '')) else: - self._error('malformed if: ' + reduce(add, ls, '')) + self._error('malformed if: ' + functools.reduce(add, ls, '')) if invert: istrue = not istrue log.trace('config: %s: _if: %s %s' % (self.init_name, ifls, str(istrue))) @@ -750,7 +759,7 @@ class file(object): try: log.trace('config: %s: _open: %s' % (self.init_name, path.host(configname))) config = open(path.host(configname), 'r') - except IOError, err: + except IOError as err: raise error.general('error opening config file: %s' % (path.host(configname))) self.configpath += [configname] @@ -836,17 +845,23 @@ def run(): # # Run where defaults.mc is located # - opts = options.load(sys.argv, defaults = 'defaults.mc') - log.trace('config: count %d' % (len(opts.config_files()))) - for config_file in opts.config_files(): - s = file(config_file, opts) - print s - del s - except error.general, gerr: - print gerr + long_opts = { + # key macro handler param defs init + '--file' : ('_file', 'path', True, None, False) + } + opts = options.command_line(base_path = '.', + argv = sys.argv, + long_opts = long_opts) + options.load(opts) + s = file(opts.defaults['_file'], opts) + s.load(opts.defaults['_file']) + print(s) + del s + except error.general as gerr: + print(gerr) sys.exit(1) - except error.internal, ierr: - print ierr + except error.internal as ierr: + print(ierr) sys.exit(1) except KeyboardInterrupt: log.notice('abort: user terminated') diff --git a/rtemstoolkit/darwin.py b/rtemstoolkit/darwin.py index 1d092cb..216dea2 100644 --- a/rtemstoolkit/darwin.py +++ b/rtemstoolkit/darwin.py @@ -35,7 +35,10 @@ import os -import execute +try: + from . import execute +except (ValueError, SystemError): + import execute def load(): uname = os.uname() diff --git a/rtemstoolkit/error.py b/rtemstoolkit/error.py index 89ea181..9fe1b8c 100644 --- a/rtemstoolkit/error.py +++ b/rtemstoolkit/error.py @@ -32,6 +32,8 @@ # Various errors we can raise. # +from __future__ import print_function + class error(Exception): """Base class for Builder exceptions.""" def set_output(self, msg): @@ -57,9 +59,9 @@ class exit(error): if __name__ == '__main__': try: raise general('a general error') - except general, gerr: - print 'caught:', gerr + except general as gerr: + print('caught:', gerr) try: raise internal('an internal error') - except internal, ierr: - print 'caught:', ierr + except internal as ierr: + print('caught:', ierr) diff --git a/rtemstoolkit/execute.py b/rtemstoolkit/execute.py index b1afc7c..147d501 100755 --- a/rtemstoolkit/execute.py +++ b/rtemstoolkit/execute.py @@ -1,6 +1,6 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2010-2014 Chris Johns (chrisj@rtems.org) +# Copyright 2010-2016 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. @@ -34,6 +34,9 @@ # Note, the subprocess module is only in Python 2.4 or higher. # +from __future__ import print_function + +import functools import os import re import sys @@ -41,8 +44,16 @@ import subprocess import threading import time -import error -import log +# +# Support to handle use in a package and as a unit test. +# If there is a better way to let us know. +# +try: + from . import error + from . import log +except (ValueError, SystemError): + import error + import log # Trace exceptions trace_threads = False @@ -96,7 +107,7 @@ def arg_subst(command, substs): def arg_subst_str(command, subst): cmd = arg_subst(command, subst) def add(x, y): return x + ' ' + str(y) - return reduce(add, cmd, '') + return functools.reduce(add, cmd, '') class execute(object): """Execute commands or scripts. The 'output' is a funtion that handles the @@ -118,7 +129,7 @@ class execute(object): self.timing_out = False self.proc = None - def _capture(self, command, proc, timeout = None): + def capture(self, proc, command = 'pipe', timeout = None): """Create 3 threads to read stdout and stderr and send to the output handler and call an input handler is provided. Based on the 'communicate' code in the subprocess module.""" @@ -127,13 +138,13 @@ class execute(object): block and return None or False if this thread is to exit and True if this is a timeout check.""" if trace_threads: - print 'executte:_writethread: start' + print('executte:_writethread: start') try: while True: - lines = input() + lines = eval(input()) if type(lines) == str: try: - fh.write(lines) + fh.write(bytes(lines, sys.stdin.encoding)) except: break if lines == None or \ @@ -142,23 +153,22 @@ class execute(object): break except: if trace_threads: - print 'executte:_writethread: exception' + print('executte:_writethread: exception') pass try: fh.close() except: pass if trace_threads: - print 'executte:_writethread: finished' + print('executte:_writethread: finished') def _readthread(exe, fh, out, prefix = ''): """Read from a file handle and write to the output handler until the file closes.""" def _output_line(line, exe, prefix, out, count): - #print 'LINE:%d: %s' % (count, line) - exe.lock.acquire() + #exe.lock.acquire() #exe.outputting = True - exe.lock.release() + #exe.lock.release() if out: out(prefix + line) else: @@ -167,7 +177,7 @@ class execute(object): log.flush() if trace_threads: - print 'executte:_readthread: start' + print('executte:_readthread: start') count = 0 line = '' try: @@ -175,7 +185,8 @@ class execute(object): data = fh.read(1) if len(data) == 0: break - #print '))))) %02x "%s"' % (ord(data), data) + if type(data) == bytes: + data = data.decode(sys.stdout.encoding) for c in data: line += c if c == '\n': @@ -187,7 +198,7 @@ class execute(object): except: raise if trace_threads: - print 'executte:_readthread: exception' + print('executte:_readthread: exception') pass try: fh.close() @@ -196,7 +207,7 @@ class execute(object): if len(line): _output_line(line, exe, prefix, out, 100) if trace_threads: - print 'executte:_readthread: finished' + print('executte:_readthread: finished') def _timerthread(exe, interval, function): """Timer thread is used to timeout a process if no output is @@ -305,11 +316,13 @@ class execute(object): s = command if type(command) is list: def add(x, y): return x + ' ' + str(y) - s = reduce(add, command, '')[1:] + s = functools.reduce(add, command, '')[1:] what = 'spawn' if shell: what = 'shell' log.output(what + ': ' + s) + if self.output is None: + raise error.general('capture needs an output handler') if shell and self.shell_exe: command = arg_list(command) command[:0] = self.shell_exe @@ -340,12 +353,10 @@ class execute(object): stderr = stderr) if not capture: return (0, proc) - if self.output is None: - raise error.general('capture needs an output handler') - exit_code = self._capture(command, proc, timeout) + exit_code = self.capture(proc, command, timeout) if self.verbose: log.output('exit: ' + str(exit_code)) - except OSError, ose: + except OSError as ose: exit_code = ose.errno if self.verbose: log.output('exit: ' + str(ose)) @@ -395,7 +406,7 @@ class execute(object): shell = shell or self.shell_commands, cwd = cwd, env = env, stdin = stdin, stdout = stdout, stderr = stderr, - itmeout = timeout) + timeout = timeout) def set_shell(self, execute): """Set the shell to execute when issuing a shell command.""" @@ -453,7 +464,7 @@ class execute(object): self.lock.acquire() try: if self.proc is not None: - print "sending sig" + print("sending sig") self.proc.send_signal(signal) except: raise @@ -502,6 +513,7 @@ class capture_execution(execute): raise error.general('output capture cannot be overrided') if __name__ == "__main__": + def run_tests(e, commands, use_shell): for c in commands['shell']: e.shell(c) @@ -517,13 +529,20 @@ if __name__ == "__main__": ec, proc = e.command(commands['pipe'][0], commands['pipe'][1], capture = False, stdin = subprocess.PIPE) if ec == 0: - print 'piping input into ' + commands['pipe'][0] + ': ' + \ - commands['pipe'][2] - proc.stdin.write(commands['pipe'][2]) + print('piping input into ' + commands['pipe'][0] + ': ' + \ + commands['pipe'][2]) + try: + out = bytes(commands['pipe'][2], sys.stdin.encoding) + except: + out = bytes(commands['pipe'][2]) + proc.stdin.write(out) proc.stdin.close() e.capture(proc) del proc + def capture_output(text): + print(text, end = '') + cmd_shell_test = 'if "%OS%" == "Windows_NT" (echo It is WinNT) else echo Is is not WinNT' sh_shell_test = 'x="me"; if [ $x = "me" ]; then echo "It was me"; else "It was him"; fi' @@ -544,12 +563,12 @@ if __name__ == "__main__": ('date %0 %1', ['-u', '+%d %D %S'])] commands['unix']['pipe'] = ('grep', 'hello', 'hello world') - print arg_list('cmd a1 a2 "a3 is a string" a4') - print arg_list('cmd b1 b2 "b3 is a string a4') - print arg_subst(['nothing', 'xx-%0-yyy', '%1', '%2-something'], - ['subst0', 'subst1', 'subst2']) + print(arg_list('cmd a1 a2 "a3 is a string" a4')) + print(arg_list('cmd b1 b2 "b3 is a string a4')) + print(arg_subst(['nothing', 'xx-%0-yyy', '%1', '%2-something'], + ['subst0', 'subst1', 'subst2'])) - e = execute(error_prefix = 'ERR: ', verbose = True) + e = execute(error_prefix = 'ERR: ', output = capture_output, verbose = True) if sys.platform == "win32": run_tests(e, commands['windows'], False) if os.path.exists('c:\\msys\\1.0\\bin\\sh.exe'): diff --git a/rtemstoolkit/freebsd.py b/rtemstoolkit/freebsd.py index 11a827f..499d7dd 100644 --- a/rtemstoolkit/freebsd.py +++ b/rtemstoolkit/freebsd.py @@ -1,6 +1,6 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2010-2014 Chris Johns (chrisj@rtems.org) +# Copyright 2010-2016 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. @@ -36,8 +36,16 @@ import pprint import os -import check -import execute +# +# Support to handle use in a package and as a unit test. +# If there is a better way to let us know. +# +try: + from . import check + from . import execute +except (ValueError, SystemError): + import check + import execute def load(): uname = os.uname() diff --git a/rtemstoolkit/git.py b/rtemstoolkit/git.py index c77347c..b89b3d8 100644 --- a/rtemstoolkit/git.py +++ b/rtemstoolkit/git.py @@ -1,6 +1,6 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2010-2015 Chris Johns (chrisj@rtems.org) +# Copyright 2010-2016 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. @@ -29,19 +29,31 @@ # Provide some basic access to the git command. # +from __future__ import print_function + import os -import error -import execute -import log -import options -import path +# +# Support to handle use in a package and as a unit test. +# If there is a better way to let us know. +# +try: + from . import error + from . import execute + from . import log + from . import path +except (ValueError, SystemError): + import error + import execute + import log + import path class repo: """An object to manage a git repo.""" - def _git_exit_code(self, ec): + def _git_exit_code(self, ec, cmd, output): if ec: + print(output) raise error.general('git command failed (%s): %d' % (self.git, ec)) def _run(self, args, check = False): @@ -55,7 +67,7 @@ class repo: exit_code, proc, output = e.spawn(cmd, cwd = path.host(cwd)) log.trace(output) if check: - self._git_exit_code(exit_code) + self._git_exit_code(exit_code, cmd, output) return exit_code, output def __init__(self, _path, opts = None, macros = None): @@ -76,9 +88,11 @@ class repo: if len(gvs) < 3: raise error.general('invalid version string from git: %s' % (output)) vs = gvs[2].split('.') - if len(vs) != 4: - raise error.general('invalid version number from git: %s' % (gvs[2])) - return (int(vs[0]), int(vs[1]), int(vs[2]), int(vs[3])) + if len(vs) == 4: + return (int(vs[0]), int(vs[1]), int(vs[2]), int(vs[3])) + if len(vs) == 3: + return (int(vs[0]), int(vs[1]), int(vs[2])) + raise error.general('invalid version number from git: %s' % (gvs[2])) def clone(self, url, _path): ec, output = self._run(['clone', url, path.host(_path)], check = True) @@ -207,12 +221,19 @@ class repo: if __name__ == '__main__': import sys - opts = options.load(sys.argv) + import options + long_opts = { + # key macro handler param defs init + } + opts = options.command_line(base_path = '.', + argv = sys.argv, + long_opts = long_opts) + options.load(opts) g = repo('.', opts) - print g.git_version() - print g.valid() - print g.status() - print g.clean() - print g.remotes() - print g.email() - print g.head() + print('version:', g.git_version()) + print('valid:', g.valid()) + print('status:', g.status()) + print('dirty:', g.dirty()) + print('remotes:', g.remotes()) + print('email:', g.email()) + print('head:', g.head()) diff --git a/rtemstoolkit/linux.py b/rtemstoolkit/linux.py index 022bcd0..d011f67 100644 --- a/rtemstoolkit/linux.py +++ b/rtemstoolkit/linux.py @@ -35,10 +35,18 @@ import pprint import os - import platform -import execute -import path + +# +# Support to handle use in a package and as a unit test. +# If there is a better way to let us know. +# +try: + from . import execute + from . import path +except (ValueError, SystemError): + import execute + import path def load(): uname = os.uname() @@ -130,7 +138,7 @@ def load(): '__chown': ('exe', 'required', '/usr/sbin/chown') }, } - if variations.has_key(distro): + if variations in distro: for v in variations[distro]: if path.exists(variations[distro][v][2]): defines[v] = variations[distro][v] diff --git a/rtemstoolkit/log.py b/rtemstoolkit/log.py index 92d3ed2..5f1e385 100755 --- a/rtemstoolkit/log.py +++ b/rtemstoolkit/log.py @@ -32,11 +32,20 @@ # Log output to stdout and/or a file. # +from __future__ import print_function + import os import sys import threading -import error +# +# Support to handle use in a package and as a unit test. +# If there is a better way to let us know. +# +try: + from . import error +except (ValueError, SystemError): + import error # # A global log. @@ -74,13 +83,13 @@ def _output(text = os.linesep, log = None): else: lock.acquire() for l in text.replace(chr(13), '').splitlines(): - print l + print(l) lock.release() def stderr(text = os.linesep, log = None): lock.acquire() for l in text.replace(chr(13), '').splitlines(): - print >> sys.stderr, l + print(l, file = sys.stderr) lock.release() def output(text = os.linesep, log = None): @@ -92,7 +101,7 @@ def notice(text = os.linesep, log = None, stdout_only = False): (default is not None and not default.has_stdout() or stdout_only): lock.acquire() for l in text.replace(chr(13), '').splitlines(): - print l + print(l) lock.release() if not stdout_only: _output(text, log) @@ -126,8 +135,8 @@ class log: self.fhs[1] = sys.stderr else: try: - self.fhs.append(file(s, 'w')) - except IOError, ioe: + self.fhs.append(open(s, 'w')) + except IOError as ioe: raise error.general("creating log file '" + s + \ "': " + str(ioe)) @@ -186,41 +195,41 @@ if __name__ == "__main__": l.output('log: hello world CRLF\r\n') l.output('log: hello world NONE') l.flush() - print '=-' * 40 - print 'tail: %d' % (len(l.tail)) - print l - print '=-' * 40 + print('=-' * 40) + print('tail: %d' % (len(l.tail))) + print(l) + print('=-' * 40) for i in range(0, 10): l.output('log: hello world 2: %d\n' % (i)) l.flush() - print '=-' * 40 - print 'tail: %d' % (len(l.tail)) - print l - print '=-' * 40 + print('=-' * 40) + print('tail: %d' % (len(l.tail))) + print(l) + print('=-' * 40) for i in [0, 1]: quiet = False tracing = False - print '- quiet:%s - trace:%s %s' % (str(quiet), str(tracing), '-' * 30) + print('- quiet:%s - trace:%s %s' % (str(quiet), str(tracing), '-' * 30)) trace('trace with quiet and trace off') notice('notice with quiet and trace off') quiet = True tracing = False - print '- quiet:%s - trace:%s %s' % (str(quiet), str(tracing), '-' * 30) + print('- quiet:%s - trace:%s %s' % (str(quiet), str(tracing), '-' * 30)) trace('trace with quiet on and trace off') notice('notice with quiet on and trace off') quiet = False tracing = True - print '- quiet:%s - trace:%s %s' % (str(quiet), str(tracing), '-' * 30) + print('- quiet:%s - trace:%s %s' % (str(quiet), str(tracing), '-' * 30)) trace('trace with quiet off and trace on') notice('notice with quiet off and trace on') quiet = True tracing = True - print '- quiet:%s - trace:%s %s' % (str(quiet), str(tracing), '-' * 30) + print('- quiet:%s - trace:%s %s' % (str(quiet), str(tracing), '-' * 30)) trace('trace with quiet on and trace on') notice('notice with quiet on and trace on') default = l - print '=-' * 40 - print 'tail: %d' % (len(l.tail)) - print l - print '=-' * 40 + print('=-' * 40) + print('tail: %d' % (len(l.tail))) + print(l) + print('=-' * 40) del l diff --git a/rtemstoolkit/macros.py b/rtemstoolkit/macros.py index 8db0729..c9410ae 100644 --- a/rtemstoolkit/macros.py +++ b/rtemstoolkit/macros.py @@ -1,6 +1,6 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2010-2014 Chris Johns (chrisj@rtems.org) +# Copyright 2010-2016 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. @@ -32,14 +32,24 @@ # Macro tables. # +from __future__ import print_function + import copy import inspect import re import os import string -import error -import path +# +# Support to handle use in a package and as a unit test. +# If there is a better way to let us know. +# +try: + from . import error + from . import path +except (ValueError, SystemError): + import error + import path # # Macro tables @@ -54,7 +64,7 @@ class macros: def __iter__(self): return self - def next(self): + def __next__(self): if self.index < len(self.keys): key = self.keys[self.index] self.index += 1 @@ -64,6 +74,19 @@ class macros: def iterkeys(self): return self.keys + def _unicode_to_str(self, us): + try: + if type(us) == unicode: + return us.encode('ascii', 'replace') + except: + pass + try: + if type(us) == bytes: + return us.encode('ascii', 'replace') + except: + pass + return us + def __init__(self, name = None, original = None, rtdir = '.'): self.files = [] self.macro_filter = re.compile(r'%{[^}]+}') @@ -156,7 +179,7 @@ class macros: return text def __iter__(self): - return macros.macro_iterator(self.keys()) + return macros.macro_iterator(list(self.keys())) def __getitem__(self, key): macro = self.get(key) @@ -167,12 +190,17 @@ class macros: def __setitem__(self, key, value): if type(key) is not str: raise TypeError('bad key type (want str): %s' % (type(key))) + if type(value) is not tuple: + value = self._unicode_to_str(value) if type(value) is str: value = ('none', 'none', value) if type(value) is not tuple: raise TypeError('bad value type (want tuple): %s' % (type(value))) if len(value) != 3: raise TypeError('bad value tuple (len not 3): %d' % (len(value))) + value = (self._unicode_to_str(value[0]), + self._unicode_to_str(value[1]), + self._unicode_to_str(value[2])) if type(value[0]) is not str: raise TypeError('bad value tuple type field: %s' % (type(value[0]))) if type(value[1]) is not str: @@ -195,10 +223,10 @@ class macros: return self.has_key(key) def __len__(self): - return len(self.keys()) + return len(list(self.keys())) def keys(self): - keys = self.macros['global'].keys() + keys = list(self.macros['global'].keys()) for rm in self.get_read_maps(): for mk in self.macros[rm]: if self.macros[rm][mk][1] == 'undefine': @@ -211,12 +239,12 @@ class macros: def has_key(self, key): if type(key) is not str: raise TypeError('bad key type (want str): %s' % (type(key))) - if self.key_filter(key) not in self.keys(): + if self.key_filter(key) not in list(self.keys()): return False return True def maps(self): - return self.macros.keys() + return list(self.macros.keys()) def get_read_maps(self): return [rm[5:] for rm in self.read_maps] @@ -239,7 +267,7 @@ class macros: trace_me = False if trace_me: - print '[[[[]]]] parsing macros' + print('[[[[]]]] parsing macros') orig_macros = copy.copy(self.macros) map = 'global' lc = 0 @@ -254,8 +282,8 @@ class macros: l_remaining = l for c in l: if trace_me: - print ']]]]]]]] c:%s(%d) s:%s t:"%s" m:%r M:%s' % \ - (c, ord(c), state, token, macro, map) + print(']]]]]]]] c:%s(%d) s:%s t:"%s" m:%r M:%s' % \ + (c, ord(c), state, token, macro, map)) l_remaining = l_remaining[1:] if c is '#' and not state.startswith('value'): break @@ -378,7 +406,7 @@ class macros: mc.close() self.files += [n] return - except IOError, err: + except IOError as err: pass raise error.general('opening macro file: %s' % \ (path.host(self.expand(name)))) @@ -452,7 +480,7 @@ class macros: def find(self, regex): what = re.compile(regex) keys = [] - for key in self.keys(): + for key in list(self.keys()): if what.match(key): keys += [key] return keys @@ -490,23 +518,23 @@ class macros: if __name__ == "__main__": import copy import sys - print inspect.getfile(macros) - m = macros(name = 'defaults.mc') + print(inspect.getfile(macros)) + m = macros() d = copy.copy(m) m['test1'] = 'something' - if d.has_key('test1'): - print 'error: copy failed.' + if 'test1' in d: + print('error: copy failed.') sys.exit(1) m.parse("[test]\n" \ "test1: none, undefine, ''\n" \ "name: none, override, 'pink'\n") - print 'set test:', m.set_read_map('test') + print('set test:', m.set_read_map('test')) if m['name'] != 'pink': - print 'error: override failed. name is %s' % (m['name']) + print('error: override failed. name is %s' % (m['name'])) sys.exit(1) - if m.has_key('test1'): - print 'error: map undefine failed.' + if 'test1' in m: + print('error: map undefine failed.') sys.exit(1) - print 'unset test:', m.unset_read_map('test') - print m - print m.keys() + print('unset test:', m.unset_read_map('test')) + print(m) + print(list(m.keys())) diff --git a/rtemstoolkit/mailer.py b/rtemstoolkit/mailer.py index df42580..abb7106 100644 --- a/rtemstoolkit/mailer.py +++ b/rtemstoolkit/mailer.py @@ -1,6 +1,6 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2013-2014 Chris Johns (chrisj@rtems.org) +# Copyright 2013-2016 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. @@ -32,13 +32,24 @@ # Manage emailing results or reports. # +from __future__ import print_function + import os import smtplib import socket -import error -import options -import path +# +# Support to handle use in a package and as a unit test. +# If there is a better way to let us know. +# +try: + from . import error + from . import options + from . import path +except (ValueError, SystemError): + import error + import options + import path def append_options(opts): opts['--mail'] = 'Send email report or results.' @@ -75,7 +86,7 @@ class mail: mrc = open(mailrc, 'r') lines = mrc.readlines() mrc.close() - except IOError, err: + except IOError as err: raise error.general('error reading: %s' % (mailrc)) for l in lines: l = _clean(l) @@ -104,17 +115,17 @@ class mail: try: s = smtplib.SMTP(self.smtp_host()) s.sendmail(from_addr, [to_addr], msg) - except smtplib.SMTPException, se: + except smtplib.SMTPException as se: raise error.general('sending mail: %s' % (str(se))) - except socket.error, se: + except socket.error as se: raise error.general('sending mail: %s' % (str(se))) if __name__ == '__main__': import sys optargs = {} append_options(optargs) - opts = options.load(sys.argv, optargs = optargs, defaults = 'defaults.mc') + opts = options.load(sys.argv) m = mail(opts) - print 'From: %s' % (m.from_address()) - print 'SMTP Host: %s' % (m.smtp_host()) + print('From: %s' % (m.from_address())) + print('SMTP Host: %s' % (m.smtp_host())) m.send(m.from_address(), 'Test mailer.py', 'This is a test') diff --git a/rtemstoolkit/netbsd.py b/rtemstoolkit/netbsd.py new file mode 100644 index 0000000..5883682 --- /dev/null +++ b/rtemstoolkit/netbsd.py @@ -0,0 +1,96 @@ +# +# RTEMS Tools Project (http://www.rtems.org/) +# Copyright 2010-2016 Chris Johns (chrisj@rtems.org) +# All rights reserved. +# +# This file is part of the RTEMS Tools package in 'rtems-tools'. +# +# RTEMS Tools is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# RTEMS Tools is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with RTEMS Tools. If not, see . +# + +# +# This code is based on what ever doco about spec files I could find and +# RTEMS project's spec files. +# + +import pprint +import os + +try: + from . import check + from . import execute +except (ValueError, SystemError): + import check + import execute + +def load(): + uname = os.uname() + sysctl = '/sbin/sysctl ' + e = execute.capture_execution() + exit_code, proc, output = e.shell(sysctl + 'hw.ncpu') + if exit_code == 0: + ncpus = output.split(' ')[1].strip() + else: + ncpus = '1' + if uname[4] == 'amd64': + cpu = 'x86_64' + else: + cpu = uname[4] + version = uname[2] + if version.find('-') > 0: + version = version.split('-')[0] + defines = { + '_ncpus': ('none', 'none', '1'), + '_os': ('none', 'none', 'netbsd'), + '_host': ('triplet', 'required', cpu + '-netbsd' + version), + '_host_vendor': ('none', 'none', 'pc'), + '_host_os': ('none', 'none', 'netbsd'), + '_host_os_version': ('none', 'none', version), + '_host_cpu': ('none', 'none', cpu), + '_host_alias': ('none', 'none', '%{nil}'), + '_host_arch': ('none', 'none', cpu), + '_usr': ('dir', 'required', '/usr'), + '_var': ('dir', 'optional', '/var'), + 'optincludes_build': ('none', 'none', '-I/usr/pkg/include -L/usr/pkg/lib'), + '__bash': ('exe', 'optional', '/usr/pkg/bin/bash'), + '__bison': ('exe', 'required', '/usr/pkg/bin/bison'), + '__git': ('exe', 'required', '/usr/pkg/bin/git'), + '__svn': ('exe', 'required', '/usr/pkg/bin/svn'), + '__xz': ('exe', 'optional', '/usr/pkg/bin/xz'), + '__make': ('exe', 'required', 'gmake'), + '__patch_opts': ('none', 'none', '-E') + } + + defines['_build'] = defines['_host'] + defines['_build_vendor'] = defines['_host_vendor'] + defines['_build_os'] = defines['_host_os'] + defines['_build_cpu'] = defines['_host_cpu'] + defines['_build_alias'] = defines['_host_alias'] + defines['_build_arch'] = defines['_host_arch'] + + for gv in ['47', '48', '49']: + gcc = '%s-portbld-netbsd%s-gcc%s' % (cpu, version, gv) + if check.check_exe(gcc, gcc): + defines['__cc'] = gcc + break + for gv in ['47', '48', '49']: + gxx = '%s-portbld-netbsd%s-g++%s' % (cpu, version, gv) + if check.check_exe(gxx, gxx): + defines['__cxx'] = gxx + break + + return defines + +if __name__ == '__main__': + pprint.pprint(load()) diff --git a/rtemstoolkit/options.py b/rtemstoolkit/options.py index 657921d..d0e4c81 100644 --- a/rtemstoolkit/options.py +++ b/rtemstoolkit/options.py @@ -1,6 +1,6 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2010-2014 Chris Johns (chrisj@rtems.org) +# Copyright 2010-2016 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. @@ -32,22 +32,36 @@ # Determine the defaults and load the specific file. # +from __future__ import print_function + import copy import glob import pprint import re import os import string - -import error -import execute -import git -import log -import macros -import path import sys -import version +# +# Support to handle use in a package and as a unit test. +# If there is a better way to let us know. +# +try: + from . import error + from . import execute + from . import git + from . import log + from . import macros + from . import path + from . import version +except (ValueError, SystemError): + import error + import execute + import git + import log + import macros + import path + import version basepath = 'tb' @@ -61,7 +75,7 @@ class command_line(object): def __init__(self, base_path = None, argv = None, optargs = None, defaults = None, long_opts = None, long_opts_help = None, - command_path = None, log_default = None): + command_path = '', log_default = None): if argv is None: return @@ -77,6 +91,9 @@ class command_line(object): raise error.general('log default is a list') self.log_default = log_default + if defaults is None: + defaults = macros.macros() + self.long_opts = { # key macro handler param defs init '--jobs' : ('_jobs', self._lo_jobs, True, 'default', True), @@ -128,7 +145,7 @@ class command_line(object): elif long_opts[lo][1] == 'string': handler = self._lo_string elif long_opts[lo][1] == 'path': - hanlder = self._lo_path + handler = self._lo_path elif long_opts[lo][1] == 'jobs': handler = self._lo_jobs elif long_opts[lo][1] == 'bool': @@ -139,9 +156,10 @@ class command_line(object): raise error.general('invalid option handler: %s: %s' % (lo, long_opts[lo][1])) self.long_opts[lo] = (long_opts[lo][0], handler, long_opts[lo][2], long_opts[lo][3], long_opts[lo][4]) - if lo not in long_opts_help: - raise error.general('no help for option: %s' % (lo)) - self.long_opts_help[lo] = long_opts_help[lo] + if long_opts_help is not None: + if lo not in long_opts_help: + raise error.general('no help for option: %s' % (lo)) + self.long_opts_help[lo] = long_opts_help[lo] def __copy__(self): new = type(self)() @@ -159,7 +177,7 @@ class command_line(object): def __str__(self): def _dict(dd): s = '' - ddl = dd.keys() + ddl = list(dd.keys()) ddl.sort() for d in ddl: s += ' ' + d + ': ' + str(dd[d]) + '\n' @@ -273,12 +291,12 @@ class command_line(object): return indent def help(self): - print '%s: [options] [args]' % (self.command_name) - print 'RTEMS Tools Project (c) 2012-2014 Chris Johns' - print 'Options and arguments:' - opts = self.long_opts_help.keys() + print('%s: [options] [args]' % (self.command_name)) + print('RTEMS Tools Project (c) 2012-2014 Chris Johns') + print('Options and arguments:') + opts = list(self.long_opts_help.keys()) if self.optargs: - opts += self.optargs.keys() + opts += list(self.optargs.keys()) indent = self._help_indent() for o in sorted(opts): if o in self.long_opts_help: @@ -287,7 +305,7 @@ class command_line(object): h = self.optargs[o] else: raise error.general('invalid help data: %s' %(o)) - print '%-*s : %s' % (indent, o, h) + print('%-*s : %s' % (indent, o, h)) raise error.exit() def process(self): @@ -518,6 +536,9 @@ def load(opts): command line. """ + if not isinstance(opts, command_line): + raise error.general('invalid opt type') + global host_windows overrides = None @@ -532,20 +553,40 @@ def load(opts): uname = os.uname() try: if uname[0].startswith('CYGWIN_NT'): - import windows + try: + from . import windows + except: + import windows overrides = windows.load() elif uname[0] == 'Darwin': - import darwin + try: + from . import darwin + except: + import darwin overrides = darwin.load() elif uname[0] == 'FreeBSD': - import freebsd + try: + from . import freebsd + except: + import freebsd overrides = freebsd.load() elif uname[0] == 'NetBSD': - import netbsd + try: + from . import netbsd + except: + import netbsd overrides = netbsd.load() elif uname[0] == 'Linux': - import linux - overrides = linux.load() + try: + from . import linux + except: + import linux + elif uname[0] == 'SunOS': + try: + from . import solaris + except: + import solaris + overrides = solaris.load() except: raise error.general('failed to load %s host support' % (uname[0])) else: @@ -580,13 +621,13 @@ def run(args): log.notice(str(opts)) log.notice('Defaults:') log.notice(str(opts.defaults)) - except error.general, gerr: - print gerr + except error.general as gerr: + print(gerr) sys.exit(1) - except error.internal, ierr: - print ierr + except error.internal as ierr: + print(ierr) sys.exit(1) - except error.exit, eerr: + except error.exit as eerr: pass except KeyboardInterrupt: _notice(opts, 'abort: user terminated') diff --git a/rtemstoolkit/path.py b/rtemstoolkit/path.py index 238e6d9..2e235b3 100644 --- a/rtemstoolkit/path.py +++ b/rtemstoolkit/path.py @@ -1,6 +1,6 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2010-2014 Chris Johns (chrisj@rtems.org) +# Copyright 2010-2016 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. @@ -34,13 +34,23 @@ # level. This allows macro expansion to work. # +from __future__ import print_function + import glob -import log import os import shutil import string -import error +# +# Support to handle use in a package and as a unit test. +# If there is a better way to let us know. +# +try: + from . import error + from . import log +except (ValueError, SystemError): + import error + import log windows = os.name == 'nt' @@ -122,24 +132,24 @@ def mkdir(path): if windows: try: os.makedirs(host(path)) - except IOError, err: + except IOError as err: raise error.general('cannot make directory: %s' % (path)) - except OSError, err: + except OSError as err: raise error.general('cannot make directory: %s' % (path)) - except WindowsError, err: + except WindowsError as err: raise error.general('cannot make directory: %s' % (path)) else: try: os.makedirs(host(path)) - except IOError, err: + except IOError as err: raise error.general('cannot make directory: %s' % (path)) - except OSError, err: + except OSError as err: raise error.general('cannot make directory: %s' % (path)) def removeall(path): def _onerror(function, path, excinfo): - print 'removeall error: (%s) %s' % (excinfo, path) + print('removeall error: (%s) %s' % (excinfo, path)) path = host(path) shutil.rmtree(path, onerror = _onerror) @@ -208,13 +218,13 @@ def copy_tree(src, dst): copy_tree(srcname, dstname) else: shutil.copy2(srcname, dstname) - except shutil.Error, err: + except shutil.Error as err: raise error.general('copying tree: %s -> %s: %s' % (src, dst, str(err))) - except EnvironmentError, why: + except EnvironmentError as why: raise error.general('copying tree: %s -> %s: %s' % (srcname, dstname, str(why))) try: shutil.copystat(src, dst) - except OSError, why: + except OSError as why: ok = False if windows: if WindowsError is not None and isinstance(why, WindowsError): @@ -223,17 +233,17 @@ def copy_tree(src, dst): raise error.general('copying tree: %s -> %s: %s' % (src, dst, str(why))) if __name__ == '__main__': - print host('/a/b/c/d-e-f') - print host('//a/b//c/d-e-f') - print shell('/w/x/y/z') - print basename('/as/sd/df/fg/me.txt') - print dirname('/as/sd/df/fg/me.txt') - print join('/d', 'g', '/tyty/fgfg') + print(host('/a/b/c/d-e-f')) + print(host('//a/b//c/d-e-f')) + print(shell('/w/x/y/z')) + print(basename('/as/sd/df/fg/me.txt')) + print(dirname('/as/sd/df/fg/me.txt')) + print(join('/d', 'g', '/tyty/fgfg')) windows = True - print host('/a/b/c/d-e-f') - print host('//a/b//c/d-e-f') - print shell('/w/x/y/z') - print shell('w:/x/y/z') - print basename('x:/sd/df/fg/me.txt') - print dirname('x:/sd/df/fg/me.txt') - print join('s:/d/', '/g', '/tyty/fgfg') + print(host('/a/b/c/d-e-f')) + print(host('//a/b//c/d-e-f')) + print(shell('/w/x/y/z')) + print(shell('w:/x/y/z')) + print(basename('x:/sd/df/fg/me.txt')) + print(dirname('x:/sd/df/fg/me.txt')) + print(join('s:/d/', '/g', '/tyty/fgfg')) diff --git a/rtemstoolkit/solaris.py b/rtemstoolkit/solaris.py new file mode 100644 index 0000000..397df68 --- /dev/null +++ b/rtemstoolkit/solaris.py @@ -0,0 +1,90 @@ +# +# RTEMS Tools Project (http://www.rtems.org/) +# Copyright 2010-2016 Chris Johns (chrisj@rtems.org) +# All rights reserved. +# +# This file is part of the RTEMS Tools package in 'rtems-tools'. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +# +# This code is based on what ever doco about spec files I could find and +# RTEMS project's spec files. +# + +import pprint +import os + +try: + from . import check + from . import error + from . import execute +except (ValueError, SystemError): + import check + import error + import execute + +def load(): + uname = os.uname() + psrinfo = '/sbin/psrinfo|wc -l' + e = execute.capture_execution() + exit_code, proc, output = e.shell(psrinfo) + if exit_code == 0: + ncpus = output + else: + ncpus = '1' + if uname[4] == 'i86pc': + cpu = 'i386' + else: + cpu = uname[4] + version = uname[2] + if version.find('-') > 0: + version = version.split('-')[0] + defines = { + '_ncpus': ('none', 'none', ncpus), + '_os': ('none', 'none', 'solaris'), + '_host': ('triplet', 'required', cpu + '-pc-solaris2'), + '_host_vendor': ('none', 'none', 'pc'), + '_host_os': ('none', 'none', 'solaris'), + '_host_os_version': ('none', 'none', version), + '_host_cpu': ('none', 'none', cpu), + '_host_alias': ('none', 'none', '%{nil}'), + '_host_arch': ('none', 'none', cpu), + '_usr': ('dir', 'required', '/usr'), + '_var': ('dir', 'optional', '/var'), + '__bash': ('exe', 'optional', '/usr/bin/bash'), + '__bison': ('exe', 'required', '/usr/bin/bison'), + '__git': ('exe', 'required', '/usr/bin/git'), + '__svn': ('exe', 'required', '/usr/bin/svn'), + '__cvs': ('exe', 'required', '/usr/bin/cvs'), + '__xz': ('exe', 'optional', '/usr/bin/xz'), + '__make': ('exe', 'required', 'gmake'), + '__patch_opts': ('none', 'none', '-E'), + '__chown': ('exe', 'required', '/usr/bin/chown'), + '__install': ('exe', 'required', '/usr/bin/ginstall'), + '__cc': ('exe', 'required', '/usr/bin/gcc'), + '__cxx': ('exe', 'required', '/usr/bin/g++'), + 'with_iconv': ('none', 'none', '0') + } + + defines['_build'] = defines['_host'] + defines['_build_vendor'] = defines['_host_vendor'] + defines['_build_os'] = defines['_host_os'] + defines['_build_cpu'] = defines['_host_cpu'] + defines['_build_alias'] = defines['_host_alias'] + defines['_build_arch'] = defines['_host_arch'] + + return defines + +if __name__ == '__main__': + pprint.pprint(load()) diff --git a/rtemstoolkit/stacktraces.py b/rtemstoolkit/stacktraces.py index e589618..dc1dbad 100644 --- a/rtemstoolkit/stacktraces.py +++ b/rtemstoolkit/stacktraces.py @@ -1,6 +1,6 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2013-2014 Chris Johns (chrisj@rtems.org) +# Copyright 2013-2016 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. @@ -33,11 +33,10 @@ import traceback def trace(): code = [] - for threadId, stack in sys._current_frames().items(): + for threadId, stack in list(sys._current_frames().items()): code.append("\n# thread-id: %s" % threadId) for filename, lineno, name, line in traceback.extract_stack(stack): code.append('file: "%s", line %d, in %s' % (filename, lineno, name)) if line: code.append(" %s" % (line.strip())) return '\n'.join(code) - diff --git a/rtemstoolkit/version.py b/rtemstoolkit/version.py index 26ac655..6d00fb3 100644 --- a/rtemstoolkit/version.py +++ b/rtemstoolkit/version.py @@ -33,11 +33,22 @@ # file to the top directory. # +from __future__ import print_function + import sys -import error -import git -import path +# +# Support to handle use in a package and as a unit test. +# If there is a better way to let us know. +# +try: + from . import error + from . import git + from . import path +except (ValueError, SystemError): + import error + import git + import path # # Default to an internal string. @@ -94,4 +105,4 @@ def str(): return _version_str if __name__ == '__main__': - print 'Version: %s' % (str()) + print('Version: %s' % (str())) diff --git a/rtemstoolkit/windows.py b/rtemstoolkit/windows.py index be4e1f6..f8007d8 100644 --- a/rtemstoolkit/windows.py +++ b/rtemstoolkit/windows.py @@ -1,6 +1,6 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2010-2014 Chris Johns (chrisj@rtems.org) +# Copyright 2010-2016 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. @@ -32,17 +32,25 @@ # Windows specific support and overrides. # -import error import pprint import os -import execute +# +# Support to handle use in a package and as a unit test. +# If there is a better way to let us know. +# +try: + from . import error + from . import execute +except (ValueError, SystemError): + import error + import execute def load(): # Default to the native Windows Python. uname = 'win32' system = 'mingw32' - if os.environ.has_key('HOSTTYPE'): + if 'HOSTTYPE' in os.environ: hosttype = os.environ['HOSTTYPE'] else: hosttype = 'i686' @@ -68,7 +76,7 @@ def load(): except: pass - if os.environ.has_key('NUMBER_OF_PROCESSORS'): + if 'NUMBER_OF_PROCESSORS' in os.environ: ncpus = os.environ['NUMBER_OF_PROCESSORS'] else: ncpus = '1' diff --git a/tester/rt/config.py b/tester/rt/config.py index ac9c8aa..1662f52 100644 --- a/tester/rt/config.py +++ b/tester/rt/config.py @@ -1,6 +1,6 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2013-2014 Chris Johns (chrisj@rtems.org) +# Copyright 2013-2016 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. @@ -32,6 +32,8 @@ # RTEMS Testing Config # +from __future__ import print_function + import datetime import os import threading @@ -42,8 +44,8 @@ from rtemstoolkit import execute from rtemstoolkit import log from rtemstoolkit import path -import console -import gdb +from . import console +from . import gdb timeout = 15 @@ -185,7 +187,7 @@ class file(config.file): def _realtime_trace(self, text): if self.realtime_trace: for l in text: - print ' '.join(l) + print(' '.join(l)) def run(self): self.load(self.name) diff --git a/tester/rt/console.py b/tester/rt/console.py index 74ec3bf..c473ad2 100644 --- a/tester/rt/console.py +++ b/tester/rt/console.py @@ -1,6 +1,6 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2013-2014 Chris Johns (chrisj@rtems.org) +# Copyright 2013-2016 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. @@ -32,13 +32,15 @@ # RTEMS Testing Consoles # +from __future__ import print_function + import errno import fcntl import os import threading import time -import stty +from . import stty def save(): return stty.save() @@ -90,7 +92,7 @@ class tty(console): def __del__(self): super(tty, self).__del__() if self._tracing(): - print ':: tty close', self.dev + print(':: tty close', self.dev) fcntl.fcntl(me.tty.fd, fcntl.F_SETFL, fcntl.fcntl(me.tty.fd, fcntl.F_GETFL) & ~os.O_NONBLOCK) self.close() @@ -98,7 +100,7 @@ class tty(console): def open(self): def _readthread(me, x): if self._tracing(): - print ':: tty runner started', self.dev + print(':: tty runner started', self.dev) fcntl.fcntl(me.tty.fd, fcntl.F_SETFL, fcntl.fcntl(me.tty.fd, fcntl.F_GETFL) | os.O_NONBLOCK) line = '' @@ -106,7 +108,7 @@ class tty(console): time.sleep(0.05) try: data = me.tty.fd.read() - except IOError, ioe: + except IOError as ioe: if ioe.errno == errno.EAGAIN: continue raise @@ -121,9 +123,9 @@ class tty(console): me.output(line) line = '' if self._tracing(): - print ':: tty runner finished', self.dev + print(':: tty runner finished', self.dev) if self._tracing(): - print ':: tty open', self.dev + print(':: tty open', self.dev) self.tty = stty.tty(self.dev) self.tty.set(self.setup) self.tty.on() diff --git a/tester/rt/gdb.py b/tester/rt/gdb.py index 956b395..c054422 100644 --- a/tester/rt/gdb.py +++ b/tester/rt/gdb.py @@ -1,6 +1,6 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2013-2014 Chris Johns (chrisj@rtems.org) +# Copyright 2013-2016 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. @@ -32,19 +32,26 @@ # RTEMS Testing GDB Interface # +from __future__ import print_function + import os -import Queue import sys import termios import threading +try: + import queue +except ImportError: + import Queue + queue = Queue + from rtemstoolkit import error from rtemstoolkit import execute from rtemstoolkit import options from rtemstoolkit import path -import console -import pygdb +from . import console +from . import pygdb # # The MI parser needs a global lock. It has global objects. @@ -65,8 +72,8 @@ class gdb(object): self.bsp_arch = bsp_arch self.output = None self.gdb_console = None - self.input = Queue.Queue() - self.commands = Queue.Queue() + self.input = queue.Queue() + self.commands = queue.Queue() self.process = None self.state = {} self.running = False @@ -77,12 +84,12 @@ class gdb(object): def _lock(self, msg): if self.lock_trace: - print '|[ LOCK:%s ]|' % (msg) + print('|[ LOCK:%s ]|' % (msg)) self.lock.acquire() def _unlock(self, msg): if self.lock_trace: - print '|] UNLOCK:%s [|' % (msg) + print('|] UNLOCK:%s [|' % (msg)) self.lock.release() def _mi_lock(self): @@ -93,7 +100,7 @@ class gdb(object): def _put(self, text): if self.trace: - print ')))', text + print(')))', text) self.commands.put(text) def _input_commands(self): @@ -101,11 +108,11 @@ class gdb(object): return False try: if self.trace: - print '... input empty ', self.input.empty() + print('... input empty ', self.input.empty()) if self.input.empty(): line = self.commands.get(block = False) if self.trace: - print '+++', line + print('+++', line) self.input.put(line) except: pass @@ -114,12 +121,12 @@ class gdb(object): def _reader(self, line): self._lock('_reader') if self.trace: - print '<<<', line + print('<<<', line) try: self.lc += 1 if line.startswith('(gdb)'): if self.trace: - print '^^^ (gdb)' + print('^^^ (gdb)') if not self._input_commands(): self.gdb_expect() self._input_commands() @@ -139,18 +146,18 @@ class gdb(object): self._unlock('_open') line = self.input.get(timeout = 0.5) if self.trace: - print '>>> input: queue=%d' % (self.input.qsize()), line - except Queue.Empty: + print('>>> input: queue=%d' % (self.input.qsize()), line) + except queue.Empty: return True if line is None: return None return line + os.linesep except: if self.trace: - print 'writer exception' + print('writer exception') pass if self.trace: - print 'writer closing' + print('writer closing') return False def _timeout(self): @@ -207,7 +214,7 @@ class gdb(object): self.gdb_console('gdb: %s' % (' '.join(cmds))) ec, proc = self.process.open(cmds, timeout = (timeout, self._timeout)) if self.trace: - print 'gdb done', ec + print('gdb done', ec) if ec > 0: raise error.general('gdb exec: %s: %s' % (cmds[0], os.strerror(ec))) except: @@ -220,7 +227,7 @@ class gdb(object): def gdb_expect(self): if self.trace: - print '}}} gdb-expect' + print('}}} gdb-expect') if self.process and not self.running and self.script is not None: if self.script_line == len(self.script): self._put(None) @@ -239,12 +246,12 @@ class gdb(object): self._mi_lock() try: if self.mi_trace: - print 'mi-data:', lines + print('mi-data:', lines) rec = pygdb.mi_parser.process(lines) finally: self._mi_unlock() if self.mi_trace: - print 'mi-rec:', rec + print('mi-rec:', rec) if rec.record_type == 'result': if rec.type == 'result': if rec.class_ == 'error': @@ -256,12 +263,12 @@ class gdb(object): elif rec.type == 'exec': if rec.class_ == 'running': if self.trace: - print '*** running' + print('*** running') self._put('') self.running = True elif rec.class_ == 'stopped': if self.trace: - print '*** stopped' + print('*** stopped') self.running = False #self._put('-data-list-register-values') elif rec.type == 'breakpoint': @@ -284,13 +291,13 @@ class gdb(object): if last_lf >= 0: lines = self.output_buffer[:last_lf] if self.trace: - print '/// console output' + print('/// console output') for line in lines.splitlines(): self.output(line) self.output_buffer = self.output_buffer[last_lf + 1:] except: if self.trace: - print '/// console output' + print('/// console output') for line in lines.splitlines(): self.output(line) @@ -298,9 +305,9 @@ if __name__ == "__main__": stdtty = console.save() try: def output(text): - print ']', text + print(']', text) def gdb_console(text): - print '>', text + print('>', text) script = ['target sim'] if len(sys.argv) > 1: executable = sys.argv[1] diff --git a/tester/rt/options.py b/tester/rt/options.py index a916cbb..3b1adef 100644 --- a/tester/rt/options.py +++ b/tester/rt/options.py @@ -32,6 +32,8 @@ # Determine the defaults and load the specific file. # +from __future__ import print_function + import glob import pprint import re @@ -45,8 +47,7 @@ from rtemstoolkit import log from rtemstoolkit import macros from rtemstoolkit import options from rtemstoolkit import path - -import version +from rtemstoolkit import version # # The path for the defaults. @@ -114,13 +115,13 @@ def run(args): log.notice(str(_opts)) log.notice('Defaults:') log.notice(str(_opts.defaults)) - except error.general, gerr: - print gerr + except error.general as gerr: + print(gerr) sys.exit(1) - except error.internal, ierr: - print ierr + except error.internal as ierr: + print(ierr) sys.exit(1) - except error.exit, eerr: + except error.exit as eerr: pass except KeyboardInterrupt: log.notice('abort: user terminated') diff --git a/tester/rt/pygdb/__init__.py b/tester/rt/pygdb/__init__.py index b52f6f9..00b3364 100644 --- a/tester/rt/pygdb/__init__.py +++ b/tester/rt/pygdb/__init__.py @@ -17,5 +17,6 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. all = ['mi_parser'] -from mi_parser import scan -from mi_parser import process +from . import mi_parser +scan = mi_parser.scan +process = mi_parser.process diff --git a/tester/rt/pygdb/mi_parser.py b/tester/rt/pygdb/mi_parser.py index 65ea5e0..dd1d08f 100755 --- a/tester/rt/pygdb/mi_parser.py +++ b/tester/rt/pygdb/mi_parser.py @@ -28,10 +28,12 @@ # $Id$ +from __future__ import print_function import re import pprint -import spark + +from . import spark def __private(): class Token: @@ -93,7 +95,7 @@ def __private(): def t_default(self, s): r'( . | \n )+' - raise Exception, "Specification error: unmatched input for '%s'" % s + raise Exception("Specification error: unmatched input for '%s'" % s) def __unescape(self, s): s = re.sub(r'\\r', r'\r', s) @@ -167,8 +169,8 @@ def __private(): def error(self, token, i=0, tokens=None): if i > 2: - print '%s %s %s %s' % (tokens[i-3], tokens[i-2], tokens[i-1], tokens[i]) - raise Exception, "Syntax error at or near %d:'%s' token" % (i, token) + print('%s %s %s %s' % (tokens[i-3], tokens[i-2], tokens[i-1], tokens[i])) + raise Exception("Syntax error at or near %d:'%s' token" % (i, token)) class GdbMiInterpreter(spark.GenericASTTraversal): def __init__(self, ast): @@ -203,8 +205,8 @@ def __private(): # tuple ::= { result result_list } node.value = node[1].value for result in node[2].value: - for n, v in result.items(): - if node.value.has_key(n): + for n, v in list(result.items()): + if n in node.value: #print '**********list conversion: [%s] %s -> %s' % (n, node.value[n], v) old = node.value[n] if not isinstance(old, list): @@ -213,7 +215,7 @@ def __private(): else: node.value[n] = v else: - raise Exception, 'Invalid tuple' + raise Exception('Invalid tuple') #print 'tuple: %s' % node.value def n_list(self, node): @@ -305,7 +307,7 @@ def __private(): def __repr__(self): return pprint.pformat(self.__dict__) - def __nonzero__(self): + def __bool__(self): return len(self.__dict__) > 0 def __getitem__(self, i): @@ -320,7 +322,7 @@ def __private(): return None def graft(self, dict_): - for name, value in dict_.items(): + for name, value in list(dict_.items()): name = name.replace('-', '_') if isinstance(value, dict): value = GdbDynamicObject(value) @@ -336,7 +338,7 @@ def __private(): class GdbMiRecord: def __init__(self, record): self.result = None - for name, value in record[0].items(): + for name, value in list(record[0].items()): name = name.replace('-', '_') if name == 'results': for result in value: @@ -363,19 +365,19 @@ def parse(tokens): def process(input): tokens = scan(input) - ast = parse(tokens) + ast = parse(tokens) __the_interpreter(ast) return __the_output(ast.value) if __name__ == '__main__': def main(): def print_tokens(tokens): - print + print() for token in tokens: if token.value: - print token.type + ': ' + token.value + print(token.type + ': ' + token.value) else: - print token.type + print(token.type) def run_test(test): lines = test.splitlines() @@ -386,7 +388,7 @@ if __name__ == '__main__': ast = parse(tokens) __the_interpreter(ast) output = __the_output(ast.value) - print output + print(output) x = '"No symbol table is loaded. Use the \\"file\\" command."' m = re.match('\".*?(?> sys.stderr, "Incorrect RTEMS Tools installation" + print("Incorrect RTEMS Tools installation", file = sys.stderr) sys.exit(1) -- cgit v1.2.3