summaryrefslogtreecommitdiffstats
path: root/validate.py
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2009-11-13 18:40:22 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2009-11-13 18:40:22 -0500
commit3ca4127da545d54fb285864892883cea079da642 (patch)
tree51458d8475c0e6328adf43ace6ed7f9be05f83f0 /validate.py
parent5f27e15adc7a7edf7adc20e081b59ab468610627 (diff)
downloadcheck-cpython-3ca4127da545d54fb285864892883cea079da642.tar.gz
check-cpython-3ca4127da545d54fb285864892883cea079da642.tar.xz
check-cpython-3ca4127da545d54fb285864892883cea079da642.zip
Various fixups
Diffstat (limited to 'validate.py')
-rw-r--r--validate.py77
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