Bläddra i källkod

Debug + implements IterExpr in python module (rpn_if objects)

Yann Weber 3 år sedan
förälder
incheckning
7167152f6c
14 ändrade filer med 605 tillägg och 20 borttagningar
  1. 7
    1
      Makefile
  2. 50
    0
      python_const.c
  3. 40
    0
      python_const.h
  4. 201
    3
      python_if.c
  5. 53
    3
      python_if.h
  6. 32
    1
      python_pyrpn.c
  7. 2
    0
      python_pyrpn.h
  8. 2
    2
      python_rpnexpr.h
  9. 28
    3
      rpn_if.c
  10. 1
    0
      rpn_if.h
  11. 119
    0
      rpn_if_default.c
  12. 10
    5
      rpn_if_default.h
  13. 3
    2
      tests/Makefile
  14. 57
    0
      tests/test_rpn.c

+ 7
- 1
Makefile Visa fil

@@ -21,7 +21,7 @@ PYTHON_LDFLAGS=-shared  -fPIC `$(PYTHON_CONFIG) --libs` `$(PYTHON_CONFIG) --ldfl
21 21
 
22 22
 all: .deps pyrpn.so
23 23
 
24
-pyrpn.so: python_pyrpn.o python_rpnexpr.o rpn_lib.o rpn_jit.o rpn_parse.o rpn_mutation.o rpn_if.o rpn_if_default.o rpn_ifs.o
24
+pyrpn.so: python_pyrpn.o python_rpnexpr.o python_if.o python_const.o rpn_lib.o rpn_jit.o rpn_parse.o rpn_mutation.o rpn_if.o rpn_if_default.o rpn_ifs.o
25 25
 	$(LD) $(LDFLAGS) $(PYTHON_LDFLAGS) -o $@ $^
26 26
 
27 27
 python_pyrpn.o: python_pyrpn.c python_rpnexpr.h python_rpnexpr.o rpn_jit.o
@@ -30,6 +30,12 @@ python_pyrpn.o: python_pyrpn.c python_rpnexpr.h python_rpnexpr.o rpn_jit.o
30 30
 python_rpnexpr.o: python_rpnexpr.c python_rpnexpr.h rpn_jit.o
31 31
 	$(CC) $(PYTHON_CFLAGS) $(CFLAGS) -c $<
32 32
 
33
+python_if.o: python_if.c python_if.h
34
+	$(CC) $(PYTHON_CFLAGS) $(CFLAGS) -c $<
35
+
36
+python_const.o: python_const.c python_const.h
37
+	$(CC) $(PYTHON_CFLAGS) $(CFLAGS) -c $<
38
+
33 39
 rpn_jit.o: rpn_jit.c rpn_jit.h rpn_parse.o rpn_lib.o
34 40
 	$(CC) $(CFLAGS) -c $<
35 41
 

+ 50
- 0
python_const.c Visa fil

@@ -0,0 +1,50 @@
1
+#include "python_const.h"
2
+
3
+PyModuleDef rpnconstmodule = {
4
+	PyModuleDef_HEAD_INIT,
5
+	"pyrpn.const",
6
+	"librarie's constants",
7
+	-1, // module size
8
+	NULL, // methods
9
+	NULL,
10
+	NULL,
11
+	NULL
12
+};
13
+
14
+int Py_rpnconst_add(PyObject* mod, const char* name, int value)
15
+{
16
+	PyObject *val;
17
+	val = Py_BuildValue("i", value);
18
+	Py_INCREF(val);
19
+	if(PyModule_AddObject(mod, name, val) < 0)
20
+	{
21
+		Py_DECREF(val);
22
+		return -1;
23
+	}
24
+	return 0;
25
+}
26
+
27
+PyObject *Py_rpnconst_init(void)
28
+{
29
+	PyObject *mod;
30
+	mod = PyModule_Create(&rpnconstmodule);
31
+	if(mod == NULL) { return NULL; }
32
+
33
+	if(Py_rpnconst_add(mod, "POS_LINEAR", RPN_IF_POSITION_LINEAR) ||
34
+		Py_rpnconst_add(mod, "POS_XY", RPN_IF_POSITION_XY) ||
35
+		Py_rpnconst_add(mod, "POS_XDIM", RPN_IF_POSITION_XDIM) ||
36
+		Py_rpnconst_add(mod, "RESULT_BOOL", RPN_IF_RES_BOOL) ||
37
+		Py_rpnconst_add(mod, "RESULT_CONST", RPN_IF_RES_CONST) ||
38
+		Py_rpnconst_add(mod, "RESULT_CONST_RGBA", RPN_IF_RES_CONST_RGBA) ||
39
+		Py_rpnconst_add(mod, "RESULT_COUNT", RPN_IF_RES_COUNT) ||
40
+		Py_rpnconst_add(mod, "RESULT_XFUN", RPN_IF_RES_XFUN) ||
41
+		Py_rpnconst_add(mod, "RESULT_RGB", RPN_IF_RES_RGB) ||
42
+		Py_rpnconst_add(mod, "RESULT_RGBA", RPN_IF_RES_RGBA))
43
+	{
44
+		Py_DECREF(mod);
45
+		return NULL;
46
+	}
47
+	return mod;
48
+}
49
+
50
+

+ 40
- 0
python_const.h Visa fil

@@ -0,0 +1,40 @@
1
+/*
2
+ * Copyright (C) 2020 Weber Yann
3
+ * 
4
+ * This file is part of pyrpn.
5
+ * 
6
+ * pyrpn is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * any later version.
10
+ * 
11
+ * pyrpn is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ * 
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with pyrpn.  If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+#ifndef _PYTHON_CONST_H__
20
+#define _PYTHON_CONST_H__
21
+
22
+#include "config.h"
23
+
24
+#include <errno.h>
25
+
26
+#define PY_SSIZE_T_CLEAN
27
+#include <Python.h>
28
+#include "structmember.h"
29
+
30
+#include "rpn_if_default.h"
31
+
32
+/**@brief pyrpn.const module specs
33
+ * @ingroup python_module */
34
+extern PyModuleDef rpnconstmodule;
35
+
36
+/**@brief pyrpn.const module initialisation function
37
+ * @ingroup python_module */
38
+PyObject *Py_rpnconst_init(void);
39
+
40
+#endif

+ 201
- 3
python_if.c Visa fil

@@ -1,8 +1,206 @@
1 1
 #include "python_if.h"
2 2
 
3
-int rpnexpr_init(PyObject *self, PyObject *args, PyObject *kwds)
3
+PyMethodDef RPNIterExpr_methods[] = {
4
+/*
5
+	{"eval", (PyCFunction)rpnexpr_eval, METH_FASTCALL, "Evaluate an expression"},
6
+	{"reset_stack", (PyCFunction)rpnexpr_reset_stack, METH_NOARGS,
7
+		"Reset stack memory storage (set all items to 0)"},
8
+*/
9
+	{"__getstate__", (PyCFunction)rpnif_getstate, METH_NOARGS,
10
+		"Pickling method. Return a bytes repr of tokenized expression \
11
+and the stack state."},
12
+	{"__setstate__", (PyCFunction)rpnif_setstate, METH_O,
13
+		"Unpickling method"},
14
+	{NULL} //Sentinel
15
+};
16
+
17
+PyMemberDef RPNIterExpr_members[] = {
18
+	{NULL}
19
+};
20
+
21
+PyGetSetDef RPNIterExpr_getset[] = {
22
+	{"POS_LINEAR", rpnif_get_const, NULL,
23
+	 "", NULL},
24
+	{"POS_XY", rpnif_get_const, NULL,
25
+	 "", NULL},
26
+	{"POS_XDIM", rpnif_get_const, NULL,
27
+	 "", NULL},
28
+
29
+	{NULL}
30
+};
31
+
32
+PyTypeObject RPNIterExprType = {
33
+	PyVarObject_HEAD_INIT(NULL, 0)
34
+	"pyrpn.RPNIterExpr",                     /* tp_name */
35
+	sizeof(PyRPNIterExpr_t),                        /* tp_basicsize */
36
+	0,                                               /* tp_itemsize */
37
+	(destructor)rpnif_del, /* tp_dealloc */
38
+	0,                                               /* tp_print */
39
+	0,                                               /* tp_getattr */
40
+	0,                                               /* tp_setattr */
41
+	0,                                               /* tp_reserved */
42
+	rpnif_repr,                                    /* tp_repr */
43
+	0,                                               /* tp_as_number */
44
+	0,                                               /* tp_as_sequence */
45
+	0,                              /* tp_as_mapping */
46
+	0,                                               /* tp_hash  */
47
+	0,                                               /* tp_call */
48
+	rpnif_str,                                               /* tp_str */
49
+	0,                                               /* tp_getattro */
50
+	0,                                               /* tp_setattro */
51
+	0,                                               /* tp_as_buffer */
52
+	Py_TPFLAGS_DEFAULT |
53
+	Py_TPFLAGS_BASETYPE,   /* tp_flags */
54
+	"RPN expression evaluator",                /* tp_doc */
55
+	0,                                               /* tp_traverse */
56
+	0,                                               /* tp_clear */
57
+	0,                                               /* tp_richcompare */
58
+	0,                                               /* tp_weaklistoffset */
59
+	0,                                               /* tp_iter */
60
+	0,                                               /* tp_iternext */
61
+	RPNIterExpr_methods,                        /* tp_methods */
62
+	RPNIterExpr_members,                        /* tp_members */
63
+	RPNIterExpr_getset,                              /* tp_getset */
64
+	0,                                               /* tp_base */
65
+	0,                                               /* tp_dict */
66
+	0,                                               /* tp_descr_get */
67
+	0,                                               /* tp_descr_set */
68
+	0,                                               /* tp_dictoffset */
69
+	rpnif_init,          /* tp_init */
70
+	0,                                               /* tp_alloc */
71
+	rpnif_new,                            /* tp_new */
72
+};
73
+
74
+PyObject* rpnif_new(PyTypeObject *subtype, PyObject *args, PyObject* kwds)
4 75
 {
5
-	/**@todo Need a C function returning RPNExpr (or must take
6
-	RPNExpr as arguments... */
76
+	PyObject *ret, *err;
77
+	PyRPNIterExpr_t *expr;
78
+	ret = PyType_GenericNew(subtype, args, kwds);
79
+	if((err = PyErr_Occurred()))
80
+	{
81
+		Py_DECREF(err);
82
+		return ret;
83
+	}
84
+	expr = (PyRPNIterExpr_t*)ret;
85
+	expr->rif = NULL;
86
+
87
+	return ret;
7 88
 }
8 89
 
90
+
91
+int rpnif_init(PyObject *self, PyObject *args, PyObject *kwds)
92
+{
93
+	PyRPNExpr_t *expr_self;
94
+	char *names[] = {"expression", "args_count", "stack_size", NULL};
95
+	char err_str[256];
96
+	const char *expr;
97
+	long long int args_count, stack_size;
98
+
99
+	expr_self = (PyRPNExpr_t*)self;
100
+
101
+	stack_size = 16;
102
+	expr_self->rpn = NULL;
103
+
104
+	if(!PyArg_ParseTupleAndKeywords(args, kwds, "sL|L:RPNExpr.__init__", names, &expr,
105
+		&args_count, &stack_size))
106
+	{
107
+		return -1;
108
+	}
109
+
110
+	if(strlen(expr) == 0)
111
+	{
112
+		PyErr_SetString(PyExc_ValueError,
113
+			"RpnExpr.__init__() expect expression argument to be not empty");
114
+		return -1;
115
+	}
116
+
117
+	if(args_count < 0 || args_count > 255)
118
+	{
119
+		snprintf(err_str, 128,
120
+			"Argument count should be in [4..255] but %lld given",
121
+			args_count);
122
+		PyErr_SetString(PyExc_ValueError, err_str);
123
+		return -1;
124
+	}
125
+
126
+	if(stack_size < 4 || stack_size > 255)
127
+	{
128
+		snprintf(err_str, 128,
129
+			"Stack size should be in [0..255] but %lld given",
130
+			stack_size);
131
+		PyErr_SetString(PyExc_ValueError, err_str);
132
+		return -1;
133
+	}
134
+
135
+	expr_self->rpn = malloc(sizeof(rpn_expr_t));
136
+	if(!expr_self->rpn)
137
+	{
138
+		snprintf(err_str, 256,
139
+			"Expression memory allocation error : %s",
140
+			strerror(errno));
141
+	}
142
+	bzero(expr_self->rpn, sizeof(rpn_expr_t));
143
+
144
+	if(rpn_expr_init(expr_self->rpn, stack_size, args_count) < 0)
145
+	{
146
+		snprintf(err_str, 256,
147
+			"Expression init error : %s",
148
+			expr_self->rpn->err_reason);
149
+		PyErr_SetString(PyExc_ValueError, err_str);
150
+		return -1;
151
+	}
152
+
153
+	expr_self->args = malloc(sizeof(rpn_value_t) * args_count);
154
+	if(!expr_self->args)
155
+	{
156
+		snprintf(err_str, 256,
157
+			"Error allocating arguments memory : %s",
158
+			strerror(errno));
159
+		return -1;
160
+	}
161
+
162
+	if(rpn_expr_compile(expr_self->rpn, expr))
163
+	{
164
+		PyErr_SetString(PyExc_ValueError, expr_self->rpn->err_reason);
165
+		return -1;
166
+	}
167
+
168
+	return 0;
169
+}
170
+
171
+void rpnif_del(PyObject *self)
172
+{
173
+	PyRPNIterExpr_t *expr_self;
174
+
175
+	expr_self = (PyRPNIterExpr_t*)self;
176
+	if(expr_self->rif)
177
+	{
178
+		rpn_if_free(expr_self->rif);
179
+		expr_self->rif = NULL;
180
+	}
181
+}
182
+
183
+PyObject* rpnif_str(PyObject *self)
184
+{
185
+	Py_RETURN_NONE;
186
+}
187
+
188
+PyObject* rpnif_repr(PyObject *self)
189
+{
190
+	Py_RETURN_NONE;
191
+}
192
+
193
+PyObject* rpnif_getstate(PyObject *self, PyObject *noargs)
194
+{
195
+	Py_RETURN_NONE;
196
+}
197
+
198
+PyObject* rpnif_setstate(PyObject *self, PyObject *state_bytes)
199
+{
200
+	Py_RETURN_NONE;
201
+}
202
+
203
+PyObject* rpnif_get_const(PyObject *self, void* val)
204
+{
205
+	return Py_BuildValue("i", (int)(long int)42);
206
+}

+ 53
- 3
python_if.h Visa fil

@@ -28,7 +28,8 @@
28 28
 #include "structmember.h"
29 29
 
30 30
 #include "rpn_if.h"
31
-#incdlue "pyton_rpnexpr.h"
31
+#include "rpn_if_default.h"
32
+#include "python_rpnexpr.h"
32 33
 
33 34
 /**@defgroup python_if RPN Iterated Function Python class
34 35
  * @ingroup python_module
@@ -66,16 +67,65 @@ typedef struct
66 67
 	
67 68
 	/**@brief Pointer on @ref rpn_if_s */
68 69
 	rpn_if_t *rif;
70
+
69 71
 } PyRPNIterExpr_t;
70 72
 
73
+/**@brief RpnIterExpr __new__ method
74
+ * @param subtype Type of object being created (pyrpn.RPNIterExpr)
75
+ * @param args positional arguments for subtype
76
+ * @param kwargs keyword argumenrs for subtype
77
+ * @return The new Python RPNIterExpr object
78
+ */
79
+PyObject* rpnif_new(PyTypeObject *subtype, PyObject* args, PyObject* kwds);
80
+
71 81
 /**@brief RpnIterExpr constructor
72
- * @param self New RPNExpr instance
82
+ * @param self New RPNIterExpr instance
73 83
  * @param args Positional arguments list
74 84
  * @param kwds Keywords arguments dict
75 85
  * @return 0 if no error else -1
76 86
  * @ingroup python_if
77 87
  */
78
-int rpnexpr_init(PyObject *self, PyObject *args, PyObject *kwds);
88
+int rpnif_init(PyObject *self, PyObject *args, PyObject *kwds);
89
+
90
+/**@brief RPNIterExpr __del__ method 
91
+ * @param self RPNExpr instance
92
+ * @ingroup python_type
93
+ */
94
+void rpnif_del(PyObject *self);
95
+
96
+/**@brief RPNIterExpr __getstate__ method for pickling
97
+ * @param cls RPNIterExpr type object
98
+ * @param noargs Not an argument...
99
+ * @return A bytes Python instance suitable as argument for
100
+ * @ref rpnexpr_setstate
101
+ */
102
+PyObject* rpnif_getstate(PyObject *cls, PyObject *noargs);
103
+
104
+/**@brief RPNIterExpr __setstate__ method for pickling
105
+ * @param cls RPNIterExpr type object
106
+ * @param state Should by a bytes Python instance returned by @ref
107
+ * rpnexpr_getstate
108
+ * @return A bytes Python instance suitable as argument for
109
+ * @ref rpnexpr_setstate
110
+ */
111
+PyObject* rpnif_setstate(PyObject *cls, PyObject *state);
112
+
113
+/**@brief RPNIterExpr.__repr__()
114
+ * @param self RPNIterExpr instance
115
+ * @ingroup python_type
116
+ */
117
+PyObject* rpnif_repr(PyObject *self);
118
+
119
+/**@brief RPNIterExpr.__str__()
120
+ * @param self RPNIterExpr instance
121
+ * @ingroup python_type
122
+ */
123
+PyObject* rpnif_str(PyObject *self);
124
+
125
+/**@brief Constant val getter
126
+ * @ingroup python_type
127
+ */
128
+PyObject* rpnif_get_const(PyObject *self, void* name);
79 129
 
80 130
 #endif
81 131
 

+ 32
- 1
python_pyrpn.c Visa fil

@@ -49,11 +49,26 @@ PyMODINIT_FUNC
49 49
 PyInit_pyrpn(void)
50 50
 {
51 51
 
52
-	PyObject *mod;
52
+	PyObject *mod, *const_mod;
53 53
 	// init module & globals
54 54
 	mod = PyModule_Create(&rpnmodule);
55 55
 	if(mod == NULL) { return NULL; }
56 56
 	
57
+	//init constants module
58
+	const_mod = Py_rpnconst_init();
59
+	if(const_mod == NULL)
60
+	{
61
+		Py_DECREF(mod);
62
+		return NULL;
63
+	}
64
+	Py_INCREF(const_mod);
65
+	if(PyModule_AddObject(mod, "const", const_mod) < 0)
66
+	{
67
+		Py_DECREF(const_mod);
68
+		Py_DECREF(mod);
69
+		return NULL;
70
+	}
71
+
57 72
 	// Init RPNExpr type
58 73
 	if(PyType_Ready(&RPNExprType) < 0)
59 74
 	{
@@ -66,6 +81,22 @@ PyInit_pyrpn(void)
66 81
 	{
67 82
 		Py_DECREF(&RPNExprType);
68 83
 		Py_DECREF(mod);
84
+		Py_DECREF(const_mod);
85
+		return NULL;
86
+	}
87
+
88
+	// Init RPNIterExpr type
89
+	if(PyType_Ready(&RPNIterExprType) < 0)
90
+	{
91
+		return NULL;
92
+	}
93
+
94
+	Py_INCREF(&RPNIterExprType);
95
+	if(PyModule_AddObject(mod, "RPNIterExpr", (PyObject*)&RPNIterExprType) < 0)
96
+	{
97
+		Py_DECREF(&RPNExprType);
98
+		Py_DECREF(&RPNIterExprType);
99
+		Py_DECREF(mod);
69 100
 		return NULL;
70 101
 	}
71 102
 

+ 2
- 0
python_pyrpn.h Visa fil

@@ -29,6 +29,8 @@
29 29
 
30 30
 #include "rpn_jit.h"
31 31
 #include "python_rpnexpr.h"
32
+#include "python_if.h"
33
+#include "python_const.h"
32 34
 
33 35
 /**@defgroup python_ext Python API
34 36
  * @brief Python API definitions

+ 2
- 2
python_rpnexpr.h Visa fil

@@ -16,8 +16,8 @@
16 16
  * You should have received a copy of the GNU General Public License
17 17
  * along with pyrpn.  If not, see <http://www.gnu.org/licenses/>.
18 18
  */
19
-#ifndef _PYTHON_PYRPN_H__
20
-#define _PYTHON_PYRPN_H__
19
+#ifndef _PYTHON_RPNEXPR_H__
20
+#define _PYTHON_RPNEXPR_H__
21 21
 
22 22
 #include "config.h"
23 23
 

+ 28
- 3
rpn_if.c Visa fil

@@ -27,6 +27,11 @@ rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_value_t *memmap)
27 27
 	res = malloc(sizeof(rpn_if_t));
28 28
 	if(!res)
29 29
 	{
30
+		#if DEBUG
31
+		err = errno;
32
+		perror("rpn_if_new() struct malloc failed");
33
+		errno = err;
34
+		#endif
30 35
 		goto error;
31 36
 	}
32 37
 	
@@ -41,10 +46,15 @@ rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_value_t *memmap)
41 46
 	else
42 47
 	{
43 48
 		res->self_mem = 1;
44
-		res->mem = mmap(NULL, params->mem_sz, PROT_READ|PROT_WRITE, MAP_ANON,
45
-			-1, 0);
49
+		res->mem = mmap(NULL, params->mem_sz, PROT_READ|PROT_WRITE,
50
+			MAP_ANON | MAP_PRIVATE, -1, 0);
46 51
 		if(res->mem == (void*)-1)
47 52
 		{
53
+			#if DEBUG
54
+			err = errno;
55
+			perror("rpn_if_new() mmap failed");
56
+			errno = err;
57
+			#endif
48 58
 			goto mmap_err;
49 59
 		}
50 60
 	}
@@ -53,6 +63,11 @@ rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_value_t *memmap)
53 63
 		(params->rpn_sz + params->rpn_argc));
54 64
 	if(!res->rpn_res)
55 65
 	{
66
+		#if DEBUG
67
+		err = errno;
68
+		perror("rpn_if_new() rpn_res malloc failed");
69
+		errno = err;
70
+		#endif
56 71
 		goto rpn_malloc_err;
57 72
 	}
58 73
 	res->rpn_args = &(res->rpn_res[params->rpn_sz]);
@@ -60,6 +75,11 @@ rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_value_t *memmap)
60 75
 	res->rpn = malloc(sizeof(rpn_expr_t*) * params->rpn_sz);
61 76
 	if(!res->rpn)
62 77
 	{
78
+		#if DEBUG
79
+		err = errno;
80
+		perror("rpn_if_new() rpn expr malloc failed");
81
+		errno = err;
82
+		#endif
63 83
 		goto rpn_expr_err;
64 84
 	}
65 85
 	for(i=0; i<params->rpn_sz; i++)
@@ -67,6 +87,11 @@ rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_value_t *memmap)
67 87
 		if(rpn_expr_init(&(res->rpn[i]), params->rpn_stack_sz,
68 88
 				params->rpn_argc) < 0)
69 89
 		{
90
+			#if DEBUG
91
+			err = errno;
92
+			perror("rpn_if_new() rpn_expr_init() failed");
93
+			errno = err;
94
+			#endif
70 95
 			goto rpn_init_error;
71 96
 		}
72 97
 	}
@@ -126,7 +151,7 @@ size_t rpn_if_step(rpn_if_t *rif, size_t pos)
126 151
 		rif->rpn_res[i] = rpn_expr_eval(&(rif->rpn[i]), rif->rpn_args);
127 152
 	}
128 153
 	//rif->params->res_f(rif, &newpos, rif->rpn_res);
129
-	/* MEGA WRONG ! rif->rpn_res is in rif structure and do not have to be
154
+	/* WRONG ! rif->rpn_res is in rif structure and do not have to be
130 155
 	   given as argument... */
131 156
 	rif->params->res_f(rif, &newpos, NULL);
132 157
 	return newpos;

+ 1
- 0
rpn_if.h Visa fil

@@ -71,6 +71,7 @@ struct rpn_if_param_s
71 71
 	int (*res_f)(rpn_if_t *rif, size_t *pos,
72 72
 		rpn_value_t *data);
73 73
 
74
+	/**@brief Arbitrary data, if set must be freed in one free() call */
74 75
 	void *data;
75 76
 };
76 77
 

+ 119
- 0
rpn_if_default.c Visa fil

@@ -1,5 +1,124 @@
1 1
 #include "rpn_if_default.h"
2 2
 
3
+rpn_if_param_t* rpn_if_default_params(short pos_flag, short res_flag,
4
+	const size_t *lim, const rpn_value_t *val, unsigned char rpn_stack_sz)
5
+{
6
+	rpn_if_param_t *res;
7
+	rpn_if_default_data_t *data;
8
+	size_t lim_sz, const_val_sz, param_sz, rpn_sz, mem_sz, argc, i;
9
+
10
+	// Calculating full params + default_data + size_lim + const_val size
11
+	switch(pos_flag)
12
+	{
13
+		case RPN_IF_POSITION_LINEAR:
14
+			lim_sz = 1;
15
+			break;
16
+		case RPN_IF_POSITION_XY:
17
+			lim_sz = 2;
18
+			break;
19
+		case RPN_IF_POSITION_XDIM:
20
+			lim_sz = *lim;
21
+			break;
22
+		default:
23
+			fprintf(stderr,
24
+				"Invalid position flag for if params : %d\n",
25
+				pos_flag);
26
+			return NULL;
27
+	}
28
+	mem_sz = 1;
29
+	for(i=1;i<lim_sz;i++)
30
+	{
31
+		mem_sz *= lim[i];
32
+	}
33
+	argc = rpn_sz = lim_sz;
34
+	lim_sz *= sizeof(size_t);
35
+
36
+	const_val_sz = 0;
37
+	switch(res_flag)
38
+	{
39
+		case RPN_IF_RES_BOOL:
40
+			rpn_sz += 1;
41
+			argc += 1;
42
+			break;
43
+		case RPN_IF_RES_COUNT:
44
+			argc += 1;
45
+			break;
46
+		case RPN_IF_RES_XFUN:
47
+			rpn_sz += 1;
48
+			argc += 1;
49
+			break;
50
+		case RPN_IF_RES_RGB:
51
+			rpn_sz += 3;
52
+			argc += 3;
53
+			break;
54
+		case RPN_IF_RES_RGBA:
55
+			rpn_sz += 4;
56
+			argc += 4;
57
+			break;
58
+		case RPN_IF_RES_CONST:
59
+			const_val_sz = 1;
60
+			argc += 1;
61
+			break;
62
+		case RPN_IF_RES_CONST_RGBA:
63
+			const_val_sz = 4;
64
+			argc += 4;
65
+			break;
66
+		default:
67
+			fprintf(stderr,
68
+				"Invalid result flag for if params : %d\n",
69
+				pos_flag);
70
+			return NULL;
71
+	}
72
+	if(const_val_sz && !val)
73
+	{
74
+		fprintf(stderr,
75
+			"Missing values when creating if params");
76
+		return NULL;
77
+	}
78
+	else if(!const_val_sz && val)
79
+	{
80
+		//Warning
81
+	}
82
+	const_val_sz *= sizeof(rpn_value_t);
83
+
84
+	param_sz = lim_sz + const_val_sz + \
85
+		sizeof(rpn_if_param_t) + sizeof(rpn_if_default_data_t);
86
+
87
+	//Allocating result and setting fields values
88
+	res = malloc(param_sz);
89
+	if(!res)
90
+	{
91
+		perror("Unable to alloc iterated function params");
92
+		return NULL;
93
+	}
94
+	res->data = data = (rpn_if_default_data_t*)(&(res[1]));
95
+
96
+	data->size_lim = (size_t*)&(data[1]);
97
+	data->pos_flag = pos_flag;
98
+	data->res_flag = res_flag;
99
+
100
+	memcpy(data->size_lim, lim, lim_sz);
101
+	if(const_val_sz)
102
+	{
103
+		data->const_val = (rpn_value_t*)(&(data->size_lim[1]));
104
+		memcpy(data->const_val, val, const_val_sz);
105
+	}
106
+	else
107
+	{
108
+		data->const_val = NULL;
109
+	}
110
+
111
+	res->arg_f = rpn_if_argf_default;
112
+	res->res_f = rpn_if_resf_default;
113
+
114
+	res->rpn_argc = argc;
115
+	res->rpn_stack_sz = rpn_stack_sz;
116
+	res->value_sz = 1; /* @TODO set res->value_sz with a good value.. */
117
+	res->mem_sz = mem_sz * res->value_sz;
118
+	res->rpn_sz = rpn_sz;
119
+
120
+	return res;
121
+}
3 122
 
4 123
 int rpn_if_argf_default(rpn_if_t *rif, size_t pos, rpn_value_t *args)
5 124
 {

+ 10
- 5
rpn_if_default.h Visa fil

@@ -82,24 +82,29 @@ struct rpn_if_default_data_s
82 82
 	size_t *size_lim;
83 83
 
84 84
 	/**@brief Store constant values to set mem giver res_flag
85
-	 * - For @ref RPN_IF_RES_CONST_RGBA const_val points on a single value
85
+	 * - For @ref RPN_IF_RES_CONST const_val points on a single value
86 86
 	 * - For @ref RPN_IF_RES_CONST_RGBA const_val points on 4 values
87
+	 * - Else const_val is set to NULL
87 88
 	 */
88 89
 	rpn_value_t *const_val;
89 90
 };
90 91
 
91
-/**@brief Create a new @ref rpn_if_s corresponding to given flags
92
+/**@brief Create a new @ref rpn_if_param_s corresponding to given flags
92 93
  * @ingroup ifs_if_default
93 94
  *
94 95
  * @param pos_flag Binary OR combination of RPN_IF_POSITION_*
95 96
  *     (@ref ifs_if_default_posflag )
96 97
  * @param pos_flag Binary OR combination of RPN_IF_RES_*
97 98
  *     (@ref ifs_if_default_posflag )
98
- * @returns A new @ref rpn_if_t (see @ref rpn_if_new ) or NULL on
99
- * error
99
+ * @param lim Depends on pos_flag parameter (
100
+ *	see @ref rpn_if_default_data_s::size_lim )
101
+ * @param val Depends on res_flag parameter (
102
+ *	see @ref rpn_if_default_data_s::const_val )
103
+ * @returns A new @ref rpn_if_param_t or NULL on error
100 104
  * @todo Implementation/testing
101 105
  */
102
-rpn_if_t* rpn_if_new_default(short pos_flag, short res_flag);
106
+rpn_if_param_t* rpn_if_default_params(short pos_flag, short res_flag,
107
+	const size_t *lim, const rpn_value_t *val, unsigned char rpn_stack_sz);
103 108
 
104 109
 /**@brief Default argf function ( see @ref rpn_if_param_s.arg_f ) */
105 110
 int rpn_if_argf_default(rpn_if_t *rif, size_t pos, rpn_value_t *args);

+ 3
- 2
tests/Makefile Visa fil

@@ -3,10 +3,11 @@ LD=ld
3 3
 SOURCES=$(wildcard test_*.c)
4 4
 OBJS=$(patsubst %.c,%.o, $(SOURCES))
5 5
 BINARIES=$(patsubst %.o, %, $(OBJS))
6
+DEPS=$(wildcard ../*.o)
6 7
 
7 8
 all: checks
8 9
 
9
-checks: $(BINARIES)
10
+checks: $(BINARIES) $(SOURCES)
10 11
 	for test_bin in $(BINARIES); do echo "Running $${test_bin}.c"; ./$$test_bin && echo "OK" || echo "fail"; done
11 12
 
12 13
 ../%.o:
@@ -15,7 +16,7 @@ checks: $(BINARIES)
15 16
 %.o: %.c
16 17
 	$(CC) -I.. $(CFLAGS) -c -o $@ $<
17 18
 
18
-test_%: test_%.o ../rpn_lib.o ../rpn_jit.o ../rpn_parse.o
19
+test_%: test_%.o ../rpn_lib.o ../rpn_jit.o ../rpn_parse.o ../rpn_if.o ../rpn_if_default.o
19 20
 	$(CC) -I..  $(CFLAGS) -o $@ $^
20 21
 	
21 22
 .PHONY: clean

+ 57
- 0
tests/test_rpn.c Visa fil

@@ -28,6 +28,8 @@
28 28
 #include "rpn_lib.h"
29 29
 #include "rpn_jit.h"
30 30
 #include "rpn_parse.h"
31
+#include "rpn_if.h"
32
+#include "rpn_if_default.h"
31 33
 
32 34
 int test0()
33 35
 {
@@ -227,6 +229,59 @@ int test_tokenization()
227 229
 	return 0;
228 230
 }
229 231
 
232
+int test_rpn_if_default()
233
+{
234
+	rpn_if_param_t *rif_param;
235
+	rpn_if_t *rif;
236
+	size_t lim[2] = {1024,768};
237
+
238
+	rif_param = rpn_if_default_params(RPN_IF_POSITION_XY, RPN_IF_RES_RGB,
239
+		lim, NULL, 32);
240
+	if(!rif_param)
241
+	{
242
+		fprintf(stderr, "rpn_if_default_params() failed\n");
243
+		return -1;
244
+	}
245
+	
246
+	rif = rpn_if_new(rif_param, NULL);
247
+	if(!rif)
248
+	{
249
+		perror("rpn_if_new() failed");
250
+		return -1;
251
+	}
252
+
253
+	free(rif_param);
254
+	rpn_if_free(rif);
255
+
256
+	return 0;
257
+}
258
+
259
+int test_rpn_if_default2()
260
+{
261
+	rpn_if_param_t *rif_param;
262
+	rpn_if_t *rif;
263
+	size_t lim[2] = {1024};
264
+
265
+	rif_param = rpn_if_default_params(RPN_IF_POSITION_LINEAR, RPN_IF_RES_RGB,
266
+		lim, NULL, 32);
267
+	if(!rif_param)
268
+	{
269
+		fprintf(stderr, "rpn_if_default_params() failed\n");
270
+		return -1;
271
+	}
272
+	
273
+	rif = rpn_if_new(rif_param, NULL);
274
+	if(!rif)
275
+	{
276
+		perror("rpn_if_new() failed");
277
+		return -1;
278
+	}
279
+
280
+	free(rif_param);
281
+	rpn_if_free(rif);
282
+
283
+	return 0;
284
+}
230 285
 
231 286
 
232 287
 
@@ -254,5 +309,7 @@ int main()
254 309
 	RUNTEST(test_args);
255 310
 	RUNTEST(test_stack_sz);
256 311
 	RUNTEST(test_tokenization);
312
+	RUNTEST(test_rpn_if_default);
313
+	RUNTEST(test_rpn_if_default2);
257 314
 	return res;
258 315
 }

Loading…
Avbryt
Spara