diff options
author | David Malcolm <dmalcolm@redhat.com> | 2009-11-13 18:40:22 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2009-11-13 18:40:22 -0500 |
commit | 3ca4127da545d54fb285864892883cea079da642 (patch) | |
tree | 51458d8475c0e6328adf43ace6ed7f9be05f83f0 /validate.py | |
parent | 5f27e15adc7a7edf7adc20e081b59ab468610627 (diff) | |
download | check-cpython-3ca4127da545d54fb285864892883cea079da642.tar.gz check-cpython-3ca4127da545d54fb285864892883cea079da642.tar.xz check-cpython-3ca4127da545d54fb285864892883cea079da642.zip |
Various fixups
Diffstat (limited to 'validate.py')
-rw-r--r-- | validate.py | 77 |
1 files changed, 58 insertions, 19 deletions
diff --git a/validate.py b/validate.py index 5827ddf..950e0e7 100644 --- a/validate.py +++ b/validate.py @@ -4,13 +4,16 @@ Hooks for validating CPython extension source code def get_types(strfmt): """ Generate a list of C type names from a PyArg_ParseTuple format string + Compare to Python/getargs.c:vgetargs1 """ result = [] i = 0 while i < len(strfmt): c = strfmt[i] - if c == 'i': - result.append('int *') + simple = {'i':'int', + 's':'char *'} + if c in simple: + result.append(simple[c] + ' *') if c in [':', ';']: break i += 1 @@ -18,27 +21,63 @@ def get_types(strfmt): class CExtensionError(Exception): # Base class for errors discovered by static analysis in C extension code - pass + def __init__(self, location): + self.location = location + + def __str__(self): + return '%s:%s: %s' % (self.location.file, + self.location.line, + self._get_desc()) + + def _get_desc(self): + raise NotImplementedError + class WrongNumberOfVars(CExtensionError): - pass + def __init__(self, location, exp_types, actual_types): + CExtensionError.__init__(self, location) + self.exp_types = exp_types + self.actual_types = actual_types class NotEnoughVars(WrongNumberOfVars): - pass + def _get_desc(self): + return 'Not enough arguments: expected %i (%s), but got %i (%s)' % ( + len(self.exp_types), + self.exp_types, + len(self.actual_types), + self.actual_types) class TooManyVars(WrongNumberOfVars): - pass - -class MismatchingType(WrongNumberOfVars): - pass - -def validate_types(format_string, actual_types): - exp_types = get_types(format_string) - if len(actual_types) < len(exp_types): - raise NotEnoughVars(actual_types, exp_types) - if len(actual_types) > len(exp_types): - raise TooManyVars(actual_types, exp_types) - for exp, actual in zip(exp_types, actual_types): - if exp != actual: - raise MismatchingType(exp, actual) + def _get_desc(self): + return 'Too many arguments: expected %i (%s), but got %i (%s)' % ( + len(self.exp_types), + self.exp_types, + len(self.actual_types), + self.actual_types) + +class MismatchingType(CExtensionError): + def __init__(self, location, arg_num, exp_type, actual_type): + super(self.__class__, self).__init__(location) + self.arg_num = arg_num + self.exp_type = exp_type + self.actual_type = actual_type + + def _get_desc(self): + return 'Mismatching type of argument %i: expected "%s" but got "%s"' % ( + self.arg_num, + self.exp_type, + self.actual_type) + +def validate_types(location, format_string, actual_types): + try: + exp_types = get_types(format_string) + if len(actual_types) < len(exp_types): + raise NotEnoughVars(location, actual_types, exp_types) + if len(actual_types) > len(exp_types): + raise TooManyVars(location, actual_types, exp_types) + for i, (exp, actual) in enumerate(zip(exp_types, actual_types)): + if exp != actual: + raise MismatchingType(location, i+1, exp, actual) + except CExtensionError, err: + print err |