kopia lustrzana https://github.com/bristol-seds/pico-tracker
More work on the verification suite. Fully working with the initial test case now.
rodzic
4e720aba6c
commit
42fb155291
|
@ -6,31 +6,44 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
sys.path.append("./tools/verification")
|
sys.path.append("./tools/verification")
|
||||||
from verification import *
|
from verification import *
|
||||||
import verification_tc
|
import verification_tc
|
||||||
|
|
||||||
|
from random import randint
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Test Script
|
# Test Script
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
class times_two_tc:
|
class times_two_tc:
|
||||||
def __init__(self, tester):
|
def __init__(self):
|
||||||
self.name = self.__class__.__name__
|
self.name = self.__class__.__name__
|
||||||
|
self.iterations = 20
|
||||||
|
|
||||||
tester.print_header(self.__class__.__name__)
|
|
||||||
|
|
||||||
|
def get_test(self):
|
||||||
|
"""Returns some suitable test parameters"""
|
||||||
params = verification_tc.struct_times_two_tc_params()
|
params = verification_tc.struct_times_two_tc_params()
|
||||||
params.input = 4
|
params.input = randint(0, 10000)
|
||||||
|
|
||||||
result = tester.run_tc(self.name, params)
|
return params
|
||||||
|
|
||||||
tester.print_info(str(result))
|
def is_correct(self, params, result):
|
||||||
|
"""Returns if a result is correct for the given parameters"""
|
||||||
|
|
||||||
|
print_info("%d * 2 = %d"%(params.input, result['result']))
|
||||||
|
|
||||||
|
if (params.input * 2 == result['result']):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Run test
|
# Run test
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
tester = samd20_test()
|
tester = samd20_test()
|
||||||
times_two_tc(tester)
|
tester.run_test_case(times_two_tc())
|
||||||
del tester
|
del tester
|
||||||
|
|
|
@ -28,29 +28,53 @@ import sys
|
||||||
from time import *
|
from time import *
|
||||||
from colorama import *
|
from colorama import *
|
||||||
|
|
||||||
|
LINE_LENGTH = 80
|
||||||
|
|
||||||
|
##### Public Print utilities
|
||||||
|
|
||||||
def printf(string):
|
def printf(string):
|
||||||
|
"""All writes go to stderr"""
|
||||||
print (string, file=sys.stderr)
|
print (string, file=sys.stderr)
|
||||||
|
|
||||||
LINE_LENGTH = 80
|
def print_info(string):
|
||||||
|
"""Prints an info line"""
|
||||||
|
printf("")
|
||||||
|
printf(Fore.CYAN + "INFO " + Fore.RESET + string)
|
||||||
|
|
||||||
|
##### Tester
|
||||||
|
|
||||||
class samd20_test:
|
class samd20_test:
|
||||||
|
|
||||||
# Prints something in the centre of the line
|
|
||||||
def print_centre(self, string):
|
def print_centre(self, string):
|
||||||
|
"""Prints something in the centre of the line"""
|
||||||
count = (LINE_LENGTH - len(string)) / 2
|
count = (LINE_LENGTH - len(string)) / 2
|
||||||
printf ((" " * count) + string)
|
printf ((" " * count) + string)
|
||||||
|
|
||||||
# Prints a pretty header
|
def print_header_line(self):
|
||||||
def print_header(self, string):
|
"""Prints a yellow line. Yo"""
|
||||||
printf (Fore.YELLOW)
|
|
||||||
printf (("*" * LINE_LENGTH) + Fore.RESET)
|
|
||||||
self.print_centre(string)
|
|
||||||
printf (Fore.YELLOW + ("*" * LINE_LENGTH) + Fore.RESET)
|
printf (Fore.YELLOW + ("*" * LINE_LENGTH) + Fore.RESET)
|
||||||
|
|
||||||
def print_info(self, string):
|
def print_header(self, string):
|
||||||
"""Prints an info line"""
|
"""Prints a pretty header"""
|
||||||
printf(Fore.CYAN + "\nINFO " + Fore.RESET + string + "\n\n")
|
printf ("")
|
||||||
|
self.print_header_line()
|
||||||
|
self.print_centre(string)
|
||||||
|
self.print_header_line()
|
||||||
|
|
||||||
|
def print_pass(self, tc_name, time):
|
||||||
|
"""Nice green pass notice"""
|
||||||
|
offset = (LINE_LENGTH / 2) - len(tc_name)
|
||||||
|
|
||||||
|
printf("")
|
||||||
|
printf(Fore.GREEN + " " + tc_name + " - PASS" \
|
||||||
|
+ (" " * offset) + str(time) + Fore.RESET)
|
||||||
|
|
||||||
|
def print_fail(self, tc_name, time):
|
||||||
|
"""Evil red pass notice"""
|
||||||
|
|
||||||
|
printf("")
|
||||||
|
printf(Fore.RED + " " + tc_name + "- FAIL" \
|
||||||
|
+ str(time) + Fore.RESET)
|
||||||
|
|
||||||
#### GDB
|
#### GDB
|
||||||
|
|
||||||
|
@ -69,19 +93,19 @@ class samd20_test:
|
||||||
gdb.execute("c")
|
gdb.execute("c")
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
self.print_info("quit")
|
print_info("quit")
|
||||||
gdb.execute("quit")
|
gdb.execute("quit")
|
||||||
|
|
||||||
|
|
||||||
def run_tc(self, tc_name, parameters):
|
def hw_run_tc(self, tc_name, parameters):
|
||||||
"""Runs a test case"""
|
"""Runs a test case on hardware"""
|
||||||
|
|
||||||
# Write the parameters
|
# Write the parameters
|
||||||
self.write_varible(tc_name+"_params", parameters)
|
self.write_varible(tc_name+"_params", parameters)
|
||||||
|
|
||||||
# Presuming there"s a breakpoint at the top of tc_main
|
# Presuming there"s a breakpoint at the top of tc_main
|
||||||
gdb.execute("set $lr=$pc")
|
#gdb.execute("set $lr=tc_main")
|
||||||
gdb.execute("set $pc="+tc_name)
|
gdb.execute("set tc_ptr="+tc_name+"+1")
|
||||||
gdb.execute("c")
|
gdb.execute("c")
|
||||||
|
|
||||||
# Test case done. Return results
|
# Test case done. Return results
|
||||||
|
@ -96,3 +120,24 @@ class samd20_test:
|
||||||
def write_varible(self, name, value):
|
def write_varible(self, name, value):
|
||||||
pvar = self.read_variable(name)
|
pvar = self.read_variable(name)
|
||||||
self.inferior.write_memory(pvar.address, value)
|
self.inferior.write_memory(pvar.address, value)
|
||||||
|
|
||||||
|
#### Test Case
|
||||||
|
|
||||||
|
def run_test_case(self, test_case):
|
||||||
|
tc_name = test_case.__class__.__name__
|
||||||
|
self.print_header(tc_name)
|
||||||
|
fail = False
|
||||||
|
|
||||||
|
if test_case.iterations:
|
||||||
|
for i in range(test_case.iterations):
|
||||||
|
params = test_case.get_test()
|
||||||
|
result = self.hw_run_tc(tc_name, params)
|
||||||
|
|
||||||
|
if not test_case.is_correct(params, result):
|
||||||
|
fail = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if not fail:
|
||||||
|
self.print_pass(tc_name, 0)
|
||||||
|
else:
|
||||||
|
self.print_fail(tc_name, 0)
|
||||||
|
|
|
@ -69,12 +69,16 @@ __verification__ void times_two_tc(void) {
|
||||||
|
|
||||||
/*******************************//* tc_main *//********************************/
|
/*******************************//* tc_main *//********************************/
|
||||||
|
|
||||||
|
typedef void (*tc_ptr_type)(void);
|
||||||
|
volatile tc_ptr_type tc_ptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called at the start of the test case run
|
* Called at the start of the test case run
|
||||||
*/
|
*/
|
||||||
__verification__ void tc_main(void) {
|
__verification__ void tc_main(void) {
|
||||||
/* Test enviroment initialisation */
|
|
||||||
|
|
||||||
/* Wait forever while test cases execute */
|
/* Wait forever while test cases execute */
|
||||||
while (1);
|
while (1) {
|
||||||
|
(*tc_ptr)();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,694 @@
|
||||||
|
'''Wrapper for verification_tc.c
|
||||||
|
|
||||||
|
Generated with:
|
||||||
|
ctypes/ctypesgen.py -o verification_tc.py --cpp=gcc -E -DCTYPESGEN verification_tc.c
|
||||||
|
|
||||||
|
Do not modify this file.
|
||||||
|
'''
|
||||||
|
|
||||||
|
__docformat__ = 'restructuredtext'
|
||||||
|
|
||||||
|
# Begin preamble
|
||||||
|
|
||||||
|
import ctypes, os, sys
|
||||||
|
from ctypes import *
|
||||||
|
|
||||||
|
_int_types = (c_int16, c_int32)
|
||||||
|
if hasattr(ctypes, 'c_int64'):
|
||||||
|
# Some builds of ctypes apparently do not have c_int64
|
||||||
|
# defined; it's a pretty good bet that these builds do not
|
||||||
|
# have 64-bit pointers.
|
||||||
|
_int_types += (c_int64,)
|
||||||
|
for t in _int_types:
|
||||||
|
if sizeof(t) == sizeof(c_size_t):
|
||||||
|
c_ptrdiff_t = t
|
||||||
|
del t
|
||||||
|
del _int_types
|
||||||
|
|
||||||
|
class c_void(Structure):
|
||||||
|
# c_void_p is a buggy return type, converting to int, so
|
||||||
|
# POINTER(None) == c_void_p is actually written as
|
||||||
|
# POINTER(c_void), so it can be treated as a real pointer.
|
||||||
|
_fields_ = [('dummy', c_int)]
|
||||||
|
|
||||||
|
def POINTER(obj):
|
||||||
|
p = ctypes.POINTER(obj)
|
||||||
|
|
||||||
|
# Convert None to a real NULL pointer to work around bugs
|
||||||
|
# in how ctypes handles None on 64-bit platforms
|
||||||
|
if not isinstance(p.from_param, classmethod):
|
||||||
|
def from_param(cls, x):
|
||||||
|
if x is None:
|
||||||
|
return cls()
|
||||||
|
else:
|
||||||
|
return x
|
||||||
|
p.from_param = classmethod(from_param)
|
||||||
|
|
||||||
|
return p
|
||||||
|
|
||||||
|
class UserString:
|
||||||
|
def __init__(self, seq):
|
||||||
|
if isinstance(seq, basestring):
|
||||||
|
self.data = seq
|
||||||
|
elif isinstance(seq, UserString):
|
||||||
|
self.data = seq.data[:]
|
||||||
|
else:
|
||||||
|
self.data = str(seq)
|
||||||
|
def __str__(self): return str(self.data)
|
||||||
|
def __repr__(self): return repr(self.data)
|
||||||
|
def __int__(self): return int(self.data)
|
||||||
|
def __long__(self): return long(self.data)
|
||||||
|
def __float__(self): return float(self.data)
|
||||||
|
def __complex__(self): return complex(self.data)
|
||||||
|
def __hash__(self): return hash(self.data)
|
||||||
|
|
||||||
|
def __cmp__(self, string):
|
||||||
|
if isinstance(string, UserString):
|
||||||
|
return cmp(self.data, string.data)
|
||||||
|
else:
|
||||||
|
return cmp(self.data, string)
|
||||||
|
def __contains__(self, char):
|
||||||
|
return char in self.data
|
||||||
|
|
||||||
|
def __len__(self): return len(self.data)
|
||||||
|
def __getitem__(self, index): return self.__class__(self.data[index])
|
||||||
|
def __getslice__(self, start, end):
|
||||||
|
start = max(start, 0); end = max(end, 0)
|
||||||
|
return self.__class__(self.data[start:end])
|
||||||
|
|
||||||
|
def __add__(self, other):
|
||||||
|
if isinstance(other, UserString):
|
||||||
|
return self.__class__(self.data + other.data)
|
||||||
|
elif isinstance(other, basestring):
|
||||||
|
return self.__class__(self.data + other)
|
||||||
|
else:
|
||||||
|
return self.__class__(self.data + str(other))
|
||||||
|
def __radd__(self, other):
|
||||||
|
if isinstance(other, basestring):
|
||||||
|
return self.__class__(other + self.data)
|
||||||
|
else:
|
||||||
|
return self.__class__(str(other) + self.data)
|
||||||
|
def __mul__(self, n):
|
||||||
|
return self.__class__(self.data*n)
|
||||||
|
__rmul__ = __mul__
|
||||||
|
def __mod__(self, args):
|
||||||
|
return self.__class__(self.data % args)
|
||||||
|
|
||||||
|
# the following methods are defined in alphabetical order:
|
||||||
|
def capitalize(self): return self.__class__(self.data.capitalize())
|
||||||
|
def center(self, width, *args):
|
||||||
|
return self.__class__(self.data.center(width, *args))
|
||||||
|
def count(self, sub, start=0, end=sys.maxint):
|
||||||
|
return self.data.count(sub, start, end)
|
||||||
|
def decode(self, encoding=None, errors=None): # XXX improve this?
|
||||||
|
if encoding:
|
||||||
|
if errors:
|
||||||
|
return self.__class__(self.data.decode(encoding, errors))
|
||||||
|
else:
|
||||||
|
return self.__class__(self.data.decode(encoding))
|
||||||
|
else:
|
||||||
|
return self.__class__(self.data.decode())
|
||||||
|
def encode(self, encoding=None, errors=None): # XXX improve this?
|
||||||
|
if encoding:
|
||||||
|
if errors:
|
||||||
|
return self.__class__(self.data.encode(encoding, errors))
|
||||||
|
else:
|
||||||
|
return self.__class__(self.data.encode(encoding))
|
||||||
|
else:
|
||||||
|
return self.__class__(self.data.encode())
|
||||||
|
def endswith(self, suffix, start=0, end=sys.maxint):
|
||||||
|
return self.data.endswith(suffix, start, end)
|
||||||
|
def expandtabs(self, tabsize=8):
|
||||||
|
return self.__class__(self.data.expandtabs(tabsize))
|
||||||
|
def find(self, sub, start=0, end=sys.maxint):
|
||||||
|
return self.data.find(sub, start, end)
|
||||||
|
def index(self, sub, start=0, end=sys.maxint):
|
||||||
|
return self.data.index(sub, start, end)
|
||||||
|
def isalpha(self): return self.data.isalpha()
|
||||||
|
def isalnum(self): return self.data.isalnum()
|
||||||
|
def isdecimal(self): return self.data.isdecimal()
|
||||||
|
def isdigit(self): return self.data.isdigit()
|
||||||
|
def islower(self): return self.data.islower()
|
||||||
|
def isnumeric(self): return self.data.isnumeric()
|
||||||
|
def isspace(self): return self.data.isspace()
|
||||||
|
def istitle(self): return self.data.istitle()
|
||||||
|
def isupper(self): return self.data.isupper()
|
||||||
|
def join(self, seq): return self.data.join(seq)
|
||||||
|
def ljust(self, width, *args):
|
||||||
|
return self.__class__(self.data.ljust(width, *args))
|
||||||
|
def lower(self): return self.__class__(self.data.lower())
|
||||||
|
def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars))
|
||||||
|
def partition(self, sep):
|
||||||
|
return self.data.partition(sep)
|
||||||
|
def replace(self, old, new, maxsplit=-1):
|
||||||
|
return self.__class__(self.data.replace(old, new, maxsplit))
|
||||||
|
def rfind(self, sub, start=0, end=sys.maxint):
|
||||||
|
return self.data.rfind(sub, start, end)
|
||||||
|
def rindex(self, sub, start=0, end=sys.maxint):
|
||||||
|
return self.data.rindex(sub, start, end)
|
||||||
|
def rjust(self, width, *args):
|
||||||
|
return self.__class__(self.data.rjust(width, *args))
|
||||||
|
def rpartition(self, sep):
|
||||||
|
return self.data.rpartition(sep)
|
||||||
|
def rstrip(self, chars=None): return self.__class__(self.data.rstrip(chars))
|
||||||
|
def split(self, sep=None, maxsplit=-1):
|
||||||
|
return self.data.split(sep, maxsplit)
|
||||||
|
def rsplit(self, sep=None, maxsplit=-1):
|
||||||
|
return self.data.rsplit(sep, maxsplit)
|
||||||
|
def splitlines(self, keepends=0): return self.data.splitlines(keepends)
|
||||||
|
def startswith(self, prefix, start=0, end=sys.maxint):
|
||||||
|
return self.data.startswith(prefix, start, end)
|
||||||
|
def strip(self, chars=None): return self.__class__(self.data.strip(chars))
|
||||||
|
def swapcase(self): return self.__class__(self.data.swapcase())
|
||||||
|
def title(self): return self.__class__(self.data.title())
|
||||||
|
def translate(self, *args):
|
||||||
|
return self.__class__(self.data.translate(*args))
|
||||||
|
def upper(self): return self.__class__(self.data.upper())
|
||||||
|
def zfill(self, width): return self.__class__(self.data.zfill(width))
|
||||||
|
|
||||||
|
class MutableString(UserString):
|
||||||
|
"""mutable string objects
|
||||||
|
|
||||||
|
Python strings are immutable objects. This has the advantage, that
|
||||||
|
strings may be used as dictionary keys. If this property isn't needed
|
||||||
|
and you insist on changing string values in place instead, you may cheat
|
||||||
|
and use MutableString.
|
||||||
|
|
||||||
|
But the purpose of this class is an educational one: to prevent
|
||||||
|
people from inventing their own mutable string class derived
|
||||||
|
from UserString and than forget thereby to remove (override) the
|
||||||
|
__hash__ method inherited from UserString. This would lead to
|
||||||
|
errors that would be very hard to track down.
|
||||||
|
|
||||||
|
A faster and better solution is to rewrite your program using lists."""
|
||||||
|
def __init__(self, string=""):
|
||||||
|
self.data = string
|
||||||
|
def __hash__(self):
|
||||||
|
raise TypeError("unhashable type (it is mutable)")
|
||||||
|
def __setitem__(self, index, sub):
|
||||||
|
if index < 0:
|
||||||
|
index += len(self.data)
|
||||||
|
if index < 0 or index >= len(self.data): raise IndexError
|
||||||
|
self.data = self.data[:index] + sub + self.data[index+1:]
|
||||||
|
def __delitem__(self, index):
|
||||||
|
if index < 0:
|
||||||
|
index += len(self.data)
|
||||||
|
if index < 0 or index >= len(self.data): raise IndexError
|
||||||
|
self.data = self.data[:index] + self.data[index+1:]
|
||||||
|
def __setslice__(self, start, end, sub):
|
||||||
|
start = max(start, 0); end = max(end, 0)
|
||||||
|
if isinstance(sub, UserString):
|
||||||
|
self.data = self.data[:start]+sub.data+self.data[end:]
|
||||||
|
elif isinstance(sub, basestring):
|
||||||
|
self.data = self.data[:start]+sub+self.data[end:]
|
||||||
|
else:
|
||||||
|
self.data = self.data[:start]+str(sub)+self.data[end:]
|
||||||
|
def __delslice__(self, start, end):
|
||||||
|
start = max(start, 0); end = max(end, 0)
|
||||||
|
self.data = self.data[:start] + self.data[end:]
|
||||||
|
def immutable(self):
|
||||||
|
return UserString(self.data)
|
||||||
|
def __iadd__(self, other):
|
||||||
|
if isinstance(other, UserString):
|
||||||
|
self.data += other.data
|
||||||
|
elif isinstance(other, basestring):
|
||||||
|
self.data += other
|
||||||
|
else:
|
||||||
|
self.data += str(other)
|
||||||
|
return self
|
||||||
|
def __imul__(self, n):
|
||||||
|
self.data *= n
|
||||||
|
return self
|
||||||
|
|
||||||
|
class String(MutableString, Union):
|
||||||
|
|
||||||
|
_fields_ = [('raw', POINTER(c_char)),
|
||||||
|
('data', c_char_p)]
|
||||||
|
|
||||||
|
def __init__(self, obj=""):
|
||||||
|
if isinstance(obj, (str, unicode, UserString)):
|
||||||
|
self.data = str(obj)
|
||||||
|
else:
|
||||||
|
self.raw = obj
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return self.data and len(self.data) or 0
|
||||||
|
|
||||||
|
def from_param(cls, obj):
|
||||||
|
# Convert None or 0
|
||||||
|
if obj is None or obj == 0:
|
||||||
|
return cls(POINTER(c_char)())
|
||||||
|
|
||||||
|
# Convert from String
|
||||||
|
elif isinstance(obj, String):
|
||||||
|
return obj
|
||||||
|
|
||||||
|
# Convert from str
|
||||||
|
elif isinstance(obj, str):
|
||||||
|
return cls(obj)
|
||||||
|
|
||||||
|
# Convert from c_char_p
|
||||||
|
elif isinstance(obj, c_char_p):
|
||||||
|
return obj
|
||||||
|
|
||||||
|
# Convert from POINTER(c_char)
|
||||||
|
elif isinstance(obj, POINTER(c_char)):
|
||||||
|
return obj
|
||||||
|
|
||||||
|
# Convert from raw pointer
|
||||||
|
elif isinstance(obj, int):
|
||||||
|
return cls(cast(obj, POINTER(c_char)))
|
||||||
|
|
||||||
|
# Convert from object
|
||||||
|
else:
|
||||||
|
return String.from_param(obj._as_parameter_)
|
||||||
|
from_param = classmethod(from_param)
|
||||||
|
|
||||||
|
def ReturnString(obj, func=None, arguments=None):
|
||||||
|
return String.from_param(obj)
|
||||||
|
|
||||||
|
# As of ctypes 1.0, ctypes does not support custom error-checking
|
||||||
|
# functions on callbacks, nor does it support custom datatypes on
|
||||||
|
# callbacks, so we must ensure that all callbacks return
|
||||||
|
# primitive datatypes.
|
||||||
|
#
|
||||||
|
# Non-primitive return values wrapped with UNCHECKED won't be
|
||||||
|
# typechecked, and will be converted to c_void_p.
|
||||||
|
def UNCHECKED(type):
|
||||||
|
if (hasattr(type, "_type_") and isinstance(type._type_, str)
|
||||||
|
and type._type_ != "P"):
|
||||||
|
return type
|
||||||
|
else:
|
||||||
|
return c_void_p
|
||||||
|
|
||||||
|
# ctypes doesn't have direct support for variadic functions, so we have to write
|
||||||
|
# our own wrapper class
|
||||||
|
class _variadic_function(object):
|
||||||
|
def __init__(self,func,restype,argtypes):
|
||||||
|
self.func=func
|
||||||
|
self.func.restype=restype
|
||||||
|
self.argtypes=argtypes
|
||||||
|
def _as_parameter_(self):
|
||||||
|
# So we can pass this variadic function as a function pointer
|
||||||
|
return self.func
|
||||||
|
def __call__(self,*args):
|
||||||
|
fixed_args=[]
|
||||||
|
i=0
|
||||||
|
for argtype in self.argtypes:
|
||||||
|
# Typecheck what we can
|
||||||
|
fixed_args.append(argtype.from_param(args[i]))
|
||||||
|
i+=1
|
||||||
|
return self.func(*fixed_args+list(args[i:]))
|
||||||
|
|
||||||
|
# End preamble
|
||||||
|
|
||||||
|
_libs = {}
|
||||||
|
_libdirs = []
|
||||||
|
|
||||||
|
# Begin loader
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Copyright (c) 2008 David James
|
||||||
|
# Copyright (c) 2006-2008 Alex Holkner
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# * Neither the name of pyglet nor the names of its
|
||||||
|
# contributors may be used to endorse or promote products
|
||||||
|
# derived from this software without specific prior written
|
||||||
|
# permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import os.path, re, sys, glob
|
||||||
|
import platform
|
||||||
|
import ctypes
|
||||||
|
import ctypes.util
|
||||||
|
|
||||||
|
def _environ_path(name):
|
||||||
|
if name in os.environ:
|
||||||
|
return os.environ[name].split(":")
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
|
class LibraryLoader(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.other_dirs=[]
|
||||||
|
|
||||||
|
def load_library(self,libname):
|
||||||
|
"""Given the name of a library, load it."""
|
||||||
|
paths = self.getpaths(libname)
|
||||||
|
|
||||||
|
for path in paths:
|
||||||
|
if os.path.exists(path):
|
||||||
|
return self.load(path)
|
||||||
|
|
||||||
|
raise ImportError("%s not found." % libname)
|
||||||
|
|
||||||
|
def load(self,path):
|
||||||
|
"""Given a path to a library, load it."""
|
||||||
|
try:
|
||||||
|
# Darwin requires dlopen to be called with mode RTLD_GLOBAL instead
|
||||||
|
# of the default RTLD_LOCAL. Without this, you end up with
|
||||||
|
# libraries not being loadable, resulting in "Symbol not found"
|
||||||
|
# errors
|
||||||
|
if sys.platform == 'darwin':
|
||||||
|
return ctypes.CDLL(path, ctypes.RTLD_GLOBAL)
|
||||||
|
else:
|
||||||
|
return ctypes.cdll.LoadLibrary(path)
|
||||||
|
except OSError,e:
|
||||||
|
raise ImportError(e)
|
||||||
|
|
||||||
|
def getpaths(self,libname):
|
||||||
|
"""Return a list of paths where the library might be found."""
|
||||||
|
if os.path.isabs(libname):
|
||||||
|
yield libname
|
||||||
|
else:
|
||||||
|
# FIXME / TODO return '.' and os.path.dirname(__file__)
|
||||||
|
for path in self.getplatformpaths(libname):
|
||||||
|
yield path
|
||||||
|
|
||||||
|
path = ctypes.util.find_library(libname)
|
||||||
|
if path: yield path
|
||||||
|
|
||||||
|
def getplatformpaths(self, libname):
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Darwin (Mac OS X)
|
||||||
|
|
||||||
|
class DarwinLibraryLoader(LibraryLoader):
|
||||||
|
name_formats = ["lib%s.dylib", "lib%s.so", "lib%s.bundle", "%s.dylib",
|
||||||
|
"%s.so", "%s.bundle", "%s"]
|
||||||
|
|
||||||
|
def getplatformpaths(self,libname):
|
||||||
|
if os.path.pathsep in libname:
|
||||||
|
names = [libname]
|
||||||
|
else:
|
||||||
|
names = [format % libname for format in self.name_formats]
|
||||||
|
|
||||||
|
for dir in self.getdirs(libname):
|
||||||
|
for name in names:
|
||||||
|
yield os.path.join(dir,name)
|
||||||
|
|
||||||
|
def getdirs(self,libname):
|
||||||
|
'''Implements the dylib search as specified in Apple documentation:
|
||||||
|
|
||||||
|
http://developer.apple.com/documentation/DeveloperTools/Conceptual/
|
||||||
|
DynamicLibraries/Articles/DynamicLibraryUsageGuidelines.html
|
||||||
|
|
||||||
|
Before commencing the standard search, the method first checks
|
||||||
|
the bundle's ``Frameworks`` directory if the application is running
|
||||||
|
within a bundle (OS X .app).
|
||||||
|
'''
|
||||||
|
|
||||||
|
dyld_fallback_library_path = _environ_path("DYLD_FALLBACK_LIBRARY_PATH")
|
||||||
|
if not dyld_fallback_library_path:
|
||||||
|
dyld_fallback_library_path = [os.path.expanduser('~/lib'),
|
||||||
|
'/usr/local/lib', '/usr/lib']
|
||||||
|
|
||||||
|
dirs = []
|
||||||
|
|
||||||
|
if '/' in libname:
|
||||||
|
dirs.extend(_environ_path("DYLD_LIBRARY_PATH"))
|
||||||
|
else:
|
||||||
|
dirs.extend(_environ_path("LD_LIBRARY_PATH"))
|
||||||
|
dirs.extend(_environ_path("DYLD_LIBRARY_PATH"))
|
||||||
|
|
||||||
|
dirs.extend(self.other_dirs)
|
||||||
|
dirs.append(".")
|
||||||
|
dirs.append(os.path.dirname(__file__))
|
||||||
|
|
||||||
|
if hasattr(sys, 'frozen') and sys.frozen == 'macosx_app':
|
||||||
|
dirs.append(os.path.join(
|
||||||
|
os.environ['RESOURCEPATH'],
|
||||||
|
'..',
|
||||||
|
'Frameworks'))
|
||||||
|
|
||||||
|
dirs.extend(dyld_fallback_library_path)
|
||||||
|
|
||||||
|
return dirs
|
||||||
|
|
||||||
|
# Posix
|
||||||
|
|
||||||
|
class PosixLibraryLoader(LibraryLoader):
|
||||||
|
_ld_so_cache = None
|
||||||
|
|
||||||
|
def _create_ld_so_cache(self):
|
||||||
|
# Recreate search path followed by ld.so. This is going to be
|
||||||
|
# slow to build, and incorrect (ld.so uses ld.so.cache, which may
|
||||||
|
# not be up-to-date). Used only as fallback for distros without
|
||||||
|
# /sbin/ldconfig.
|
||||||
|
#
|
||||||
|
# We assume the DT_RPATH and DT_RUNPATH binary sections are omitted.
|
||||||
|
|
||||||
|
directories = []
|
||||||
|
for name in ("LD_LIBRARY_PATH",
|
||||||
|
"SHLIB_PATH", # HPUX
|
||||||
|
"LIBPATH", # OS/2, AIX
|
||||||
|
"LIBRARY_PATH", # BE/OS
|
||||||
|
):
|
||||||
|
if name in os.environ:
|
||||||
|
directories.extend(os.environ[name].split(os.pathsep))
|
||||||
|
directories.extend(self.other_dirs)
|
||||||
|
directories.append(".")
|
||||||
|
directories.append(os.path.dirname(__file__))
|
||||||
|
|
||||||
|
try: directories.extend([dir.strip() for dir in open('/etc/ld.so.conf')])
|
||||||
|
except IOError: pass
|
||||||
|
|
||||||
|
unix_lib_dirs_list = ['/lib', '/usr/lib', '/lib64', '/usr/lib64']
|
||||||
|
if sys.platform.startswith('linux'):
|
||||||
|
# Try and support multiarch work in Ubuntu
|
||||||
|
# https://wiki.ubuntu.com/MultiarchSpec
|
||||||
|
bitage = platform.architecture()[0]
|
||||||
|
if bitage.startswith('32'):
|
||||||
|
# Assume Intel/AMD x86 compat
|
||||||
|
unix_lib_dirs_list += ['/lib/i386-linux-gnu', '/usr/lib/i386-linux-gnu']
|
||||||
|
elif bitage.startswith('64'):
|
||||||
|
# Assume Intel/AMD x86 compat
|
||||||
|
unix_lib_dirs_list += ['/lib/x86_64-linux-gnu', '/usr/lib/x86_64-linux-gnu']
|
||||||
|
else:
|
||||||
|
# guess...
|
||||||
|
unix_lib_dirs_list += glob.glob('/lib/*linux-gnu')
|
||||||
|
directories.extend(unix_lib_dirs_list)
|
||||||
|
|
||||||
|
cache = {}
|
||||||
|
lib_re = re.compile(r'lib(.*)\.s[ol]')
|
||||||
|
ext_re = re.compile(r'\.s[ol]$')
|
||||||
|
for dir in directories:
|
||||||
|
try:
|
||||||
|
for path in glob.glob("%s/*.s[ol]*" % dir):
|
||||||
|
file = os.path.basename(path)
|
||||||
|
|
||||||
|
# Index by filename
|
||||||
|
if file not in cache:
|
||||||
|
cache[file] = path
|
||||||
|
|
||||||
|
# Index by library name
|
||||||
|
match = lib_re.match(file)
|
||||||
|
if match:
|
||||||
|
library = match.group(1)
|
||||||
|
if library not in cache:
|
||||||
|
cache[library] = path
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self._ld_so_cache = cache
|
||||||
|
|
||||||
|
def getplatformpaths(self, libname):
|
||||||
|
if self._ld_so_cache is None:
|
||||||
|
self._create_ld_so_cache()
|
||||||
|
|
||||||
|
result = self._ld_so_cache.get(libname)
|
||||||
|
if result: yield result
|
||||||
|
|
||||||
|
path = ctypes.util.find_library(libname)
|
||||||
|
if path: yield os.path.join("/lib",path)
|
||||||
|
|
||||||
|
# Windows
|
||||||
|
|
||||||
|
class _WindowsLibrary(object):
|
||||||
|
def __init__(self, path):
|
||||||
|
self.cdll = ctypes.cdll.LoadLibrary(path)
|
||||||
|
self.windll = ctypes.windll.LoadLibrary(path)
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
try: return getattr(self.cdll,name)
|
||||||
|
except AttributeError:
|
||||||
|
try: return getattr(self.windll,name)
|
||||||
|
except AttributeError:
|
||||||
|
raise
|
||||||
|
|
||||||
|
class WindowsLibraryLoader(LibraryLoader):
|
||||||
|
name_formats = ["%s.dll", "lib%s.dll", "%slib.dll"]
|
||||||
|
|
||||||
|
def load_library(self, libname):
|
||||||
|
try:
|
||||||
|
result = LibraryLoader.load_library(self, libname)
|
||||||
|
except ImportError:
|
||||||
|
result = None
|
||||||
|
if os.path.sep not in libname:
|
||||||
|
for name in self.name_formats:
|
||||||
|
try:
|
||||||
|
result = getattr(ctypes.cdll, name % libname)
|
||||||
|
if result:
|
||||||
|
break
|
||||||
|
except WindowsError:
|
||||||
|
result = None
|
||||||
|
if result is None:
|
||||||
|
try:
|
||||||
|
result = getattr(ctypes.cdll, libname)
|
||||||
|
except WindowsError:
|
||||||
|
result = None
|
||||||
|
if result is None:
|
||||||
|
raise ImportError("%s not found." % libname)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def load(self, path):
|
||||||
|
return _WindowsLibrary(path)
|
||||||
|
|
||||||
|
def getplatformpaths(self, libname):
|
||||||
|
if os.path.sep not in libname:
|
||||||
|
for name in self.name_formats:
|
||||||
|
dll_in_current_dir = os.path.abspath(name % libname)
|
||||||
|
if os.path.exists(dll_in_current_dir):
|
||||||
|
yield dll_in_current_dir
|
||||||
|
path = ctypes.util.find_library(name % libname)
|
||||||
|
if path:
|
||||||
|
yield path
|
||||||
|
|
||||||
|
# Platform switching
|
||||||
|
|
||||||
|
# If your value of sys.platform does not appear in this dict, please contact
|
||||||
|
# the Ctypesgen maintainers.
|
||||||
|
|
||||||
|
loaderclass = {
|
||||||
|
"darwin": DarwinLibraryLoader,
|
||||||
|
"cygwin": WindowsLibraryLoader,
|
||||||
|
"win32": WindowsLibraryLoader
|
||||||
|
}
|
||||||
|
|
||||||
|
loader = loaderclass.get(sys.platform, PosixLibraryLoader)()
|
||||||
|
|
||||||
|
def add_library_search_dirs(other_dirs):
|
||||||
|
loader.other_dirs = other_dirs
|
||||||
|
|
||||||
|
load_library = loader.load_library
|
||||||
|
|
||||||
|
del loaderclass
|
||||||
|
|
||||||
|
# End loader
|
||||||
|
|
||||||
|
add_library_search_dirs([])
|
||||||
|
|
||||||
|
# No libraries
|
||||||
|
|
||||||
|
# No modules
|
||||||
|
|
||||||
|
# /richard/_longshot/firmware/tools/verification/verification_tc.c: 42
|
||||||
|
class struct_nmea_decode_tc_params(Structure):
|
||||||
|
pass
|
||||||
|
|
||||||
|
struct_nmea_decode_tc_params.__slots__ = [
|
||||||
|
'_in',
|
||||||
|
]
|
||||||
|
struct_nmea_decode_tc_params._fields_ = [
|
||||||
|
('_in', c_int),
|
||||||
|
]
|
||||||
|
|
||||||
|
# /richard/_longshot/firmware/tools/verification/verification_tc.c: 42
|
||||||
|
for _lib in _libs.values():
|
||||||
|
try:
|
||||||
|
nmea_decode_tc_params = (struct_nmea_decode_tc_params).in_dll(_lib, 'nmea_decode_tc_params')
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# /richard/_longshot/firmware/tools/verification/verification_tc.c: 46
|
||||||
|
class struct_nmea_decode_tc_results(Structure):
|
||||||
|
pass
|
||||||
|
|
||||||
|
struct_nmea_decode_tc_results.__slots__ = [
|
||||||
|
'result',
|
||||||
|
]
|
||||||
|
struct_nmea_decode_tc_results._fields_ = [
|
||||||
|
('result', c_int),
|
||||||
|
]
|
||||||
|
|
||||||
|
# /richard/_longshot/firmware/tools/verification/verification_tc.c: 46
|
||||||
|
for _lib in _libs.values():
|
||||||
|
try:
|
||||||
|
nmea_decode_tc_results = (struct_nmea_decode_tc_results).in_dll(_lib, 'nmea_decode_tc_results')
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# /richard/_longshot/firmware/tools/verification/verification_tc.c: 59
|
||||||
|
class struct_times_two_tc_params(Structure):
|
||||||
|
pass
|
||||||
|
|
||||||
|
struct_times_two_tc_params.__slots__ = [
|
||||||
|
'input',
|
||||||
|
]
|
||||||
|
struct_times_two_tc_params._fields_ = [
|
||||||
|
('input', c_int),
|
||||||
|
]
|
||||||
|
|
||||||
|
# /richard/_longshot/firmware/tools/verification/verification_tc.c: 59
|
||||||
|
for _lib in _libs.values():
|
||||||
|
try:
|
||||||
|
times_two_tc_params = (struct_times_two_tc_params).in_dll(_lib, 'times_two_tc_params')
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# /richard/_longshot/firmware/tools/verification/verification_tc.c: 63
|
||||||
|
class struct_times_two_tc_results(Structure):
|
||||||
|
pass
|
||||||
|
|
||||||
|
struct_times_two_tc_results.__slots__ = [
|
||||||
|
'result',
|
||||||
|
]
|
||||||
|
struct_times_two_tc_results._fields_ = [
|
||||||
|
('result', c_int),
|
||||||
|
]
|
||||||
|
|
||||||
|
# /richard/_longshot/firmware/tools/verification/verification_tc.c: 63
|
||||||
|
for _lib in _libs.values():
|
||||||
|
try:
|
||||||
|
times_two_tc_results = (struct_times_two_tc_results).in_dll(_lib, 'times_two_tc_results')
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
nmea_decode_tc_params = struct_nmea_decode_tc_params # /richard/_longshot/firmware/tools/verification/verification_tc.c: 42
|
||||||
|
|
||||||
|
nmea_decode_tc_results = struct_nmea_decode_tc_results # /richard/_longshot/firmware/tools/verification/verification_tc.c: 46
|
||||||
|
|
||||||
|
times_two_tc_params = struct_times_two_tc_params # /richard/_longshot/firmware/tools/verification/verification_tc.c: 59
|
||||||
|
|
||||||
|
times_two_tc_results = struct_times_two_tc_results # /richard/_longshot/firmware/tools/verification/verification_tc.c: 63
|
||||||
|
|
||||||
|
# No inserted files
|
||||||
|
|
Ładowanie…
Reference in New Issue