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