Author: Armin Rigo <[email protected]>
Branch: cffi-1.0
Changeset: r1695:d5b493dd8a62
Date: 2015-04-11 18:25 +0200
http://bitbucket.org/cffi/cffi/changeset/d5b493dd8a62/

Log:    Realizing C types from parsed _cffi_opcode arrays: write the basics,
        needs to be integrated with _cffi_backend.c

diff --git a/new/parse_c_type.c b/new/parse_c_type.c
--- a/new/parse_c_type.c
+++ b/new/parse_c_type.c
@@ -349,70 +349,6 @@
     return _CFFI_GETARG(result);
 }
 
-#if 0
-static void fetch_delay_slots(token_t *tok, _crx_qual_type *result,
-                              intptr_t *delay_slot)
-{
-    if (tok->kind == TOK_ERROR)
-        return;
-    tok->delay_slots = delay_slot;
-    while (1) {
-        intptr_t tok_kind = *delay_slot++;
-        if (tok_kind <= 0) {
-            delay_slot = tok->all_delay_slots + (-tok_kind);
-            continue;
-        }
-        switch (tok_kind) {
-        case TOK_END:
-            return;    /* done */
-        case TOK_STAR:
-            result->type = tok->cb->get_pointer_type(tok->cb, result->type,
-                                                     result->qualifiers);
-            result->qualifiers = 0;
-            break;
-        case TOK_CONST:
-            result->qualifiers |= _CRX_CONST;
-            break;
-        case TOK_VOLATILE:
-            result->qualifiers |= _CRX_VOLATILE;
-            break;
-        case TOK_OPEN_BRACKET:   /* array */
-            {
-                uintptr_t length = (uintptr_t)*delay_slot++;
-                if (length != (uintptr_t)-1)
-                    result->type = tok->cb->get_array_type(
-                        tok->cb, result->type, length);
-                else
-                    result->type = tok->cb->get_incomplete_array_type(
-                        tok->cb, result->type);
-                /* result->qualifiers remains unmodified */
-                break;
-            }
-        case TOK_OPEN_PAREN:   /* function */
-        case TOK_DOTDOTDOT:    /* function ending with a '...' */
-            {
-                intptr_t nbargs = *delay_slot++;
-                _crx_type_t *t1;
-                _crx_qual_type *argtypes = (_crx_qual_type *)delay_slot;
-                delay_slot += 2 * nbargs;
-                if (tok_kind == TOK_DOTDOTDOT)
-                    t1 = tok->cb->get_ellipsis_function_type(tok->cb,
-                                                             result->type,
-                                                             argtypes, nbargs);
-                else
-                    t1 = tok->cb->get_function_type(tok->cb, result->type,
-                                                    argtypes, nbargs, NULL);
-                result->type = t1;
-                result->qualifiers = 0; /* drop qualifiers on the return type 
*/
-                break;
-            }
-        default:
-            assert(!"missing delay slot case");
-        }
-    }
-}
-#endif
-
 static int search_struct_union(struct _cffi_type_context_s *ctx,
                                const char *search, size_t search_len)
 {
diff --git a/new/parse_c_type.h b/new/parse_c_type.h
--- a/new/parse_c_type.h
+++ b/new/parse_c_type.h
@@ -1,3 +1,4 @@
+#include <stddef.h>
 
 
 typedef void *_cffi_opcode_t;
@@ -33,6 +34,7 @@
 #define _CFFI_PRIM_FLOAT        13
 #define _CFFI_PRIM_DOUBLE       14
 #define _CFFI_PRIM_LONGDOUBLE   15
+#define _CFFI__NUM_PRIM         16
 
 
 struct _cffi_global_s {
@@ -79,6 +81,7 @@
 };
 
 struct _cffi_type_context_s {
+    _cffi_opcode_t *types;
     const struct _cffi_global_s *globals;
     const struct _cffi_constant_s *constants;
     const struct _cffi_struct_union_s *structs_unions;
diff --git a/new/realize_c_type.c b/new/realize_c_type.c
new file mode 100644
--- /dev/null
+++ b/new/realize_c_type.c
@@ -0,0 +1,97 @@
+#include <Python.h>
+#include "parse_c_type.h"
+
+
+static PyObject *all_primitives[_CFFI__NUM_PRIM];
+
+
+PyObject *build_primitive_type(int num)
+{
+    PyObject *x;
+
+    switch (num) {
+
+    case _CFFI_PRIM_VOID:
+        x = PyString_FromString("VOID");
+        break;
+
+    case _CFFI_PRIM_INT:
+        x = PyString_FromString("INT");
+        break;
+
+    default:
+        PyErr_Format(PyExc_NotImplementedError, "prim=%d", num);
+        return NULL;
+    }
+
+    all_primitives[num] = x;
+    return x;
+}
+
+
+PyObject *realize_c_type(struct _cffi_type_context_s *ctx,
+                         _cffi_opcode_t opcodes[], int index)
+{
+    PyObject *x, *y;
+    _cffi_opcode_t op = opcodes[index];
+
+    switch (_CFFI_GETOP(op)) {
+
+    case _CFFI_OP_PRIMITIVE:
+        x = all_primitives[_CFFI_GETARG(op)];
+        if (x == NULL)
+            x = build_primitive_type(_CFFI_GETARG(op));
+        Py_XINCREF(x);
+        return x;
+
+    case _CFFI_OP_POINTER:
+        y = realize_c_type(ctx, opcodes, _CFFI_GETARG(op));
+        if (y == NULL)
+            return NULL;
+        x = Py_BuildValue("sO", "pointer", y);
+        Py_DECREF(y);
+        return x;
+
+    default:
+        PyErr_Format(PyExc_NotImplementedError, "op=%d", (int)_CFFI_GETOP(op));
+        return NULL;
+    }
+}
+
+
+struct _cffi_type_context_s global_ctx = {
+};
+
+
+static PyObject *b_test(PyObject *self, PyObject *args)
+{
+    char *s;
+    if (!PyArg_ParseTuple(args, "s", &s))
+        return NULL;
+
+    _cffi_opcode_t opcodes[100];
+    struct _cffi_parse_info_s parse_info = {
+        .ctx = &global_ctx,
+        .output = opcodes,
+        .output_size = 100,
+    };
+    int res = parse_c_type(&parse_info, s);
+    if (res < 0) {
+        PyErr_SetString(PyExc_ValueError, parse_info.error_message);
+        return NULL;
+    }
+
+    return realize_c_type(&global_ctx, opcodes, res);
+}
+
+static PyMethodDef MyMethods[] = {
+    {"test",   b_test,  METH_VARARGS},
+    {NULL,     NULL}    /* Sentinel */
+};
+
+PyMODINIT_FUNC
+initrealize_c_type(void)
+{
+    PyObject *m = Py_InitModule("realize_c_type", MyMethods);
+    (void)m;
+}
diff --git a/new/setup.py b/new/setup.py
new file mode 100644
--- /dev/null
+++ b/new/setup.py
@@ -0,0 +1,6 @@
+from distutils.core import setup
+from distutils.extension import Extension
+setup(name='realize_c_type',
+      ext_modules=[Extension(name='realize_c_type',
+                             sources=['realize_c_type.c',
+                                      'parse_c_type.c'])])
diff --git a/new/test_parse_c_type.py b/new/test_parse_c_type.py
--- a/new/test_parse_c_type.py
+++ b/new/test_parse_c_type.py
@@ -3,7 +3,7 @@
 import py
 import cffi
 
-r_macro = re.compile(r"#define \w+[(][^\n]*")
+r_macro = re.compile(r"#define \w+[(][^\n]*|#include [^\n]*")
 r_define = re.compile(r"(#define \w+) [^\n]*")
 header = open('parse_c_type.h').read()
 header = r_macro.sub(r"", header)
diff --git a/new/test_realize_c_type.py b/new/test_realize_c_type.py
new file mode 100644
--- /dev/null
+++ b/new/test_realize_c_type.py
@@ -0,0 +1,13 @@
+import os
+
+def setup_module():
+    os.system("python setup.py build_ext -i")
+    global realize_c_type
+    import realize_c_type
+
+
+def test_void():
+    assert realize_c_type.test("void") == "VOID"
+
+def test_int_star():
+    assert realize_c_type.test("int *") == ("pointer", "INT")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to