summaryrefslogtreecommitdiffstats
path: root/pyarg-parsetuple.cocci
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2009-11-13 17:21:58 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2009-11-13 17:21:58 -0500
commitcdfd25bd47710289cb119f1fc5088870f3418134 (patch)
tree6c2554cbe5f5bbc199fc96f7409268f1c8251a11 /pyarg-parsetuple.cocci
downloadcheck-cpython-cdfd25bd47710289cb119f1fc5088870f3418134.tar.gz
check-cpython-cdfd25bd47710289cb119f1fc5088870f3418134.tar.xz
check-cpython-cdfd25bd47710289cb119f1fc5088870f3418134.zip
Initial commit
Diffstat (limited to 'pyarg-parsetuple.cocci')
-rw-r--r--pyarg-parsetuple.cocci69
1 files changed, 69 insertions, 0 deletions
diff --git a/pyarg-parsetuple.cocci b/pyarg-parsetuple.cocci
new file mode 100644
index 0000000..2bc454b
--- /dev/null
+++ b/pyarg-parsetuple.cocci
@@ -0,0 +1,69 @@
+@ParseTuple@
+expression args;
+expression fmt;
+type t1;
+t1 p1;
+@@
+
+PyArg_ParseTuple(args, fmt, p1)
+
+@script:python@
+args << ParseTuple.args;
+fmt << ParseTuple.fmt;
+t1 << ParseTuple.t1;
+
+@@
+
+"""
+Analyze
+"""
+# FIXME: generalize thisto varargs
+
+
+def get_types(strfmt):
+ """
+ Generate a list of C type names from a format string
+ """
+ result = []
+ i = 0
+ while i < len(strfmt):
+ c = strfmt[i]
+ if c == 'i':
+ result.append('int *')
+ if c in [':', ';']:
+ break
+ i += 1
+ return result
+
+class CExtensionError(Exception):
+ # Base class for errors discovered by static analysis in C extension code
+ pass
+
+class WrongNumberOfVars(CExtensionError):
+ pass
+
+class NotEnoughVars(WrongNumberOfVars):
+ pass
+
+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)
+
+print "args: %s" % args
+print "fmt: %s" % fmt
+print "var1: %s" % t1
+print get_types(fmt.expr)
+
+validate_types(fmt.expr, [t1])