Debug + implements IterExpr in python module (rpn_if objects)

This commit is contained in:
Yann Weber 2020-10-10 14:40:12 +02:00
commit 7167152f6c
14 changed files with 605 additions and 20 deletions

View file

@ -21,7 +21,7 @@ PYTHON_LDFLAGS=-shared -fPIC `$(PYTHON_CONFIG) --libs` `$(PYTHON_CONFIG) --ldfl
all: .deps pyrpn.so
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
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
$(LD) $(LDFLAGS) $(PYTHON_LDFLAGS) -o $@ $^
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
python_rpnexpr.o: python_rpnexpr.c python_rpnexpr.h rpn_jit.o
$(CC) $(PYTHON_CFLAGS) $(CFLAGS) -c $<
python_if.o: python_if.c python_if.h
$(CC) $(PYTHON_CFLAGS) $(CFLAGS) -c $<
python_const.o: python_const.c python_const.h
$(CC) $(PYTHON_CFLAGS) $(CFLAGS) -c $<
rpn_jit.o: rpn_jit.c rpn_jit.h rpn_parse.o rpn_lib.o
$(CC) $(CFLAGS) -c $<

50
python_const.c Normal file
View file

@ -0,0 +1,50 @@
#include "python_const.h"
PyModuleDef rpnconstmodule = {
PyModuleDef_HEAD_INIT,
"pyrpn.const",
"librarie's constants",
-1, // module size
NULL, // methods
NULL,
NULL,
NULL
};
int Py_rpnconst_add(PyObject* mod, const char* name, int value)
{
PyObject *val;
val = Py_BuildValue("i", value);
Py_INCREF(val);
if(PyModule_AddObject(mod, name, val) < 0)
{
Py_DECREF(val);
return -1;
}
return 0;
}
PyObject *Py_rpnconst_init(void)
{
PyObject *mod;
mod = PyModule_Create(&rpnconstmodule);
if(mod == NULL) { return NULL; }
if(Py_rpnconst_add(mod, "POS_LINEAR", RPN_IF_POSITION_LINEAR) ||
Py_rpnconst_add(mod, "POS_XY", RPN_IF_POSITION_XY) ||
Py_rpnconst_add(mod, "POS_XDIM", RPN_IF_POSITION_XDIM) ||
Py_rpnconst_add(mod, "RESULT_BOOL", RPN_IF_RES_BOOL) ||
Py_rpnconst_add(mod, "RESULT_CONST", RPN_IF_RES_CONST) ||
Py_rpnconst_add(mod, "RESULT_CONST_RGBA", RPN_IF_RES_CONST_RGBA) ||
Py_rpnconst_add(mod, "RESULT_COUNT", RPN_IF_RES_COUNT) ||
Py_rpnconst_add(mod, "RESULT_XFUN", RPN_IF_RES_XFUN) ||
Py_rpnconst_add(mod, "RESULT_RGB", RPN_IF_RES_RGB) ||
Py_rpnconst_add(mod, "RESULT_RGBA", RPN_IF_RES_RGBA))
{
Py_DECREF(mod);
return NULL;
}
return mod;
}

40
python_const.h Normal file
View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2020 Weber Yann
*
* This file is part of pyrpn.
*
* pyrpn is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* pyrpn is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with pyrpn. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _PYTHON_CONST_H__
#define _PYTHON_CONST_H__
#include "config.h"
#include <errno.h>
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "structmember.h"
#include "rpn_if_default.h"
/**@brief pyrpn.const module specs
* @ingroup python_module */
extern PyModuleDef rpnconstmodule;
/**@brief pyrpn.const module initialisation function
* @ingroup python_module */
PyObject *Py_rpnconst_init(void);
#endif

View file

@ -1,8 +1,206 @@
#include "python_if.h"
int rpnexpr_init(PyObject *self, PyObject *args, PyObject *kwds)
PyMethodDef RPNIterExpr_methods[] = {
/*
{"eval", (PyCFunction)rpnexpr_eval, METH_FASTCALL, "Evaluate an expression"},
{"reset_stack", (PyCFunction)rpnexpr_reset_stack, METH_NOARGS,
"Reset stack memory storage (set all items to 0)"},
*/
{"__getstate__", (PyCFunction)rpnif_getstate, METH_NOARGS,
"Pickling method. Return a bytes repr of tokenized expression \
and the stack state."},
{"__setstate__", (PyCFunction)rpnif_setstate, METH_O,
"Unpickling method"},
{NULL} //Sentinel
};
PyMemberDef RPNIterExpr_members[] = {
{NULL}
};
PyGetSetDef RPNIterExpr_getset[] = {
{"POS_LINEAR", rpnif_get_const, NULL,
"", NULL},
{"POS_XY", rpnif_get_const, NULL,
"", NULL},
{"POS_XDIM", rpnif_get_const, NULL,
"", NULL},
{NULL}
};
PyTypeObject RPNIterExprType = {
PyVarObject_HEAD_INIT(NULL, 0)
"pyrpn.RPNIterExpr", /* tp_name */
sizeof(PyRPNIterExpr_t), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)rpnif_del, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
rpnif_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
rpnif_str, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT |
Py_TPFLAGS_BASETYPE, /* tp_flags */
"RPN expression evaluator", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
RPNIterExpr_methods, /* tp_methods */
RPNIterExpr_members, /* tp_members */
RPNIterExpr_getset, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
rpnif_init, /* tp_init */
0, /* tp_alloc */
rpnif_new, /* tp_new */
};
PyObject* rpnif_new(PyTypeObject *subtype, PyObject *args, PyObject* kwds)
{
/**@todo Need a C function returning RPNExpr (or must take
RPNExpr as arguments... */
PyObject *ret, *err;
PyRPNIterExpr_t *expr;
ret = PyType_GenericNew(subtype, args, kwds);
if((err = PyErr_Occurred()))
{
Py_DECREF(err);
return ret;
}
expr = (PyRPNIterExpr_t*)ret;
expr->rif = NULL;
return ret;
}
int rpnif_init(PyObject *self, PyObject *args, PyObject *kwds)
{
PyRPNExpr_t *expr_self;
char *names[] = {"expression", "args_count", "stack_size", NULL};
char err_str[256];
const char *expr;
long long int args_count, stack_size;
expr_self = (PyRPNExpr_t*)self;
stack_size = 16;
expr_self->rpn = NULL;
if(!PyArg_ParseTupleAndKeywords(args, kwds, "sL|L:RPNExpr.__init__", names, &expr,
&args_count, &stack_size))
{
return -1;
}
if(strlen(expr) == 0)
{
PyErr_SetString(PyExc_ValueError,
"RpnExpr.__init__() expect expression argument to be not empty");
return -1;
}
if(args_count < 0 || args_count > 255)
{
snprintf(err_str, 128,
"Argument count should be in [4..255] but %lld given",
args_count);
PyErr_SetString(PyExc_ValueError, err_str);
return -1;
}
if(stack_size < 4 || stack_size > 255)
{
snprintf(err_str, 128,
"Stack size should be in [0..255] but %lld given",
stack_size);
PyErr_SetString(PyExc_ValueError, err_str);
return -1;
}
expr_self->rpn = malloc(sizeof(rpn_expr_t));
if(!expr_self->rpn)
{
snprintf(err_str, 256,
"Expression memory allocation error : %s",
strerror(errno));
}
bzero(expr_self->rpn, sizeof(rpn_expr_t));
if(rpn_expr_init(expr_self->rpn, stack_size, args_count) < 0)
{
snprintf(err_str, 256,
"Expression init error : %s",
expr_self->rpn->err_reason);
PyErr_SetString(PyExc_ValueError, err_str);
return -1;
}
expr_self->args = malloc(sizeof(rpn_value_t) * args_count);
if(!expr_self->args)
{
snprintf(err_str, 256,
"Error allocating arguments memory : %s",
strerror(errno));
return -1;
}
if(rpn_expr_compile(expr_self->rpn, expr))
{
PyErr_SetString(PyExc_ValueError, expr_self->rpn->err_reason);
return -1;
}
return 0;
}
void rpnif_del(PyObject *self)
{
PyRPNIterExpr_t *expr_self;
expr_self = (PyRPNIterExpr_t*)self;
if(expr_self->rif)
{
rpn_if_free(expr_self->rif);
expr_self->rif = NULL;
}
}
PyObject* rpnif_str(PyObject *self)
{
Py_RETURN_NONE;
}
PyObject* rpnif_repr(PyObject *self)
{
Py_RETURN_NONE;
}
PyObject* rpnif_getstate(PyObject *self, PyObject *noargs)
{
Py_RETURN_NONE;
}
PyObject* rpnif_setstate(PyObject *self, PyObject *state_bytes)
{
Py_RETURN_NONE;
}
PyObject* rpnif_get_const(PyObject *self, void* val)
{
return Py_BuildValue("i", (int)(long int)42);
}

View file

@ -28,7 +28,8 @@
#include "structmember.h"
#include "rpn_if.h"
#incdlue "pyton_rpnexpr.h"
#include "rpn_if_default.h"
#include "python_rpnexpr.h"
/**@defgroup python_if RPN Iterated Function Python class
* @ingroup python_module
@ -66,16 +67,65 @@ typedef struct
/**@brief Pointer on @ref rpn_if_s */
rpn_if_t *rif;
} PyRPNIterExpr_t;
/**@brief RpnIterExpr __new__ method
* @param subtype Type of object being created (pyrpn.RPNIterExpr)
* @param args positional arguments for subtype
* @param kwargs keyword argumenrs for subtype
* @return The new Python RPNIterExpr object
*/
PyObject* rpnif_new(PyTypeObject *subtype, PyObject* args, PyObject* kwds);
/**@brief RpnIterExpr constructor
* @param self New RPNExpr instance
* @param self New RPNIterExpr instance
* @param args Positional arguments list
* @param kwds Keywords arguments dict
* @return 0 if no error else -1
* @ingroup python_if
*/
int rpnexpr_init(PyObject *self, PyObject *args, PyObject *kwds);
int rpnif_init(PyObject *self, PyObject *args, PyObject *kwds);
/**@brief RPNIterExpr __del__ method
* @param self RPNExpr instance
* @ingroup python_type
*/
void rpnif_del(PyObject *self);
/**@brief RPNIterExpr __getstate__ method for pickling
* @param cls RPNIterExpr type object
* @param noargs Not an argument...
* @return A bytes Python instance suitable as argument for
* @ref rpnexpr_setstate
*/
PyObject* rpnif_getstate(PyObject *cls, PyObject *noargs);
/**@brief RPNIterExpr __setstate__ method for pickling
* @param cls RPNIterExpr type object
* @param state Should by a bytes Python instance returned by @ref
* rpnexpr_getstate
* @return A bytes Python instance suitable as argument for
* @ref rpnexpr_setstate
*/
PyObject* rpnif_setstate(PyObject *cls, PyObject *state);
/**@brief RPNIterExpr.__repr__()
* @param self RPNIterExpr instance
* @ingroup python_type
*/
PyObject* rpnif_repr(PyObject *self);
/**@brief RPNIterExpr.__str__()
* @param self RPNIterExpr instance
* @ingroup python_type
*/
PyObject* rpnif_str(PyObject *self);
/**@brief Constant val getter
* @ingroup python_type
*/
PyObject* rpnif_get_const(PyObject *self, void* name);
#endif

View file

@ -49,11 +49,26 @@ PyMODINIT_FUNC
PyInit_pyrpn(void)
{
PyObject *mod;
PyObject *mod, *const_mod;
// init module & globals
mod = PyModule_Create(&rpnmodule);
if(mod == NULL) { return NULL; }
//init constants module
const_mod = Py_rpnconst_init();
if(const_mod == NULL)
{
Py_DECREF(mod);
return NULL;
}
Py_INCREF(const_mod);
if(PyModule_AddObject(mod, "const", const_mod) < 0)
{
Py_DECREF(const_mod);
Py_DECREF(mod);
return NULL;
}
// Init RPNExpr type
if(PyType_Ready(&RPNExprType) < 0)
{
@ -66,6 +81,22 @@ PyInit_pyrpn(void)
{
Py_DECREF(&RPNExprType);
Py_DECREF(mod);
Py_DECREF(const_mod);
return NULL;
}
// Init RPNIterExpr type
if(PyType_Ready(&RPNIterExprType) < 0)
{
return NULL;
}
Py_INCREF(&RPNIterExprType);
if(PyModule_AddObject(mod, "RPNIterExpr", (PyObject*)&RPNIterExprType) < 0)
{
Py_DECREF(&RPNExprType);
Py_DECREF(&RPNIterExprType);
Py_DECREF(mod);
return NULL;
}

View file

@ -29,6 +29,8 @@
#include "rpn_jit.h"
#include "python_rpnexpr.h"
#include "python_if.h"
#include "python_const.h"
/**@defgroup python_ext Python API
* @brief Python API definitions

View file

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

View file

@ -27,6 +27,11 @@ rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_value_t *memmap)
res = malloc(sizeof(rpn_if_t));
if(!res)
{
#if DEBUG
err = errno;
perror("rpn_if_new() struct malloc failed");
errno = err;
#endif
goto error;
}
@ -41,10 +46,15 @@ rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_value_t *memmap)
else
{
res->self_mem = 1;
res->mem = mmap(NULL, params->mem_sz, PROT_READ|PROT_WRITE, MAP_ANON,
-1, 0);
res->mem = mmap(NULL, params->mem_sz, PROT_READ|PROT_WRITE,
MAP_ANON | MAP_PRIVATE, -1, 0);
if(res->mem == (void*)-1)
{
#if DEBUG
err = errno;
perror("rpn_if_new() mmap failed");
errno = err;
#endif
goto mmap_err;
}
}
@ -53,6 +63,11 @@ rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_value_t *memmap)
(params->rpn_sz + params->rpn_argc));
if(!res->rpn_res)
{
#if DEBUG
err = errno;
perror("rpn_if_new() rpn_res malloc failed");
errno = err;
#endif
goto rpn_malloc_err;
}
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)
res->rpn = malloc(sizeof(rpn_expr_t*) * params->rpn_sz);
if(!res->rpn)
{
#if DEBUG
err = errno;
perror("rpn_if_new() rpn expr malloc failed");
errno = err;
#endif
goto rpn_expr_err;
}
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)
if(rpn_expr_init(&(res->rpn[i]), params->rpn_stack_sz,
params->rpn_argc) < 0)
{
#if DEBUG
err = errno;
perror("rpn_if_new() rpn_expr_init() failed");
errno = err;
#endif
goto rpn_init_error;
}
}
@ -126,7 +151,7 @@ size_t rpn_if_step(rpn_if_t *rif, size_t pos)
rif->rpn_res[i] = rpn_expr_eval(&(rif->rpn[i]), rif->rpn_args);
}
//rif->params->res_f(rif, &newpos, rif->rpn_res);
/* MEGA WRONG ! rif->rpn_res is in rif structure and do not have to be
/* WRONG ! rif->rpn_res is in rif structure and do not have to be
given as argument... */
rif->params->res_f(rif, &newpos, NULL);
return newpos;

View file

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

View file

@ -1,5 +1,124 @@
#include "rpn_if_default.h"
rpn_if_param_t* rpn_if_default_params(short pos_flag, short res_flag,
const size_t *lim, const rpn_value_t *val, unsigned char rpn_stack_sz)
{
rpn_if_param_t *res;
rpn_if_default_data_t *data;
size_t lim_sz, const_val_sz, param_sz, rpn_sz, mem_sz, argc, i;
// Calculating full params + default_data + size_lim + const_val size
switch(pos_flag)
{
case RPN_IF_POSITION_LINEAR:
lim_sz = 1;
break;
case RPN_IF_POSITION_XY:
lim_sz = 2;
break;
case RPN_IF_POSITION_XDIM:
lim_sz = *lim;
break;
default:
fprintf(stderr,
"Invalid position flag for if params : %d\n",
pos_flag);
return NULL;
}
mem_sz = 1;
for(i=1;i<lim_sz;i++)
{
mem_sz *= lim[i];
}
argc = rpn_sz = lim_sz;
lim_sz *= sizeof(size_t);
const_val_sz = 0;
switch(res_flag)
{
case RPN_IF_RES_BOOL:
rpn_sz += 1;
argc += 1;
break;
case RPN_IF_RES_COUNT:
argc += 1;
break;
case RPN_IF_RES_XFUN:
rpn_sz += 1;
argc += 1;
break;
case RPN_IF_RES_RGB:
rpn_sz += 3;
argc += 3;
break;
case RPN_IF_RES_RGBA:
rpn_sz += 4;
argc += 4;
break;
case RPN_IF_RES_CONST:
const_val_sz = 1;
argc += 1;
break;
case RPN_IF_RES_CONST_RGBA:
const_val_sz = 4;
argc += 4;
break;
default:
fprintf(stderr,
"Invalid result flag for if params : %d\n",
pos_flag);
return NULL;
}
if(const_val_sz && !val)
{
fprintf(stderr,
"Missing values when creating if params");
return NULL;
}
else if(!const_val_sz && val)
{
//Warning
}
const_val_sz *= sizeof(rpn_value_t);
param_sz = lim_sz + const_val_sz + \
sizeof(rpn_if_param_t) + sizeof(rpn_if_default_data_t);
//Allocating result and setting fields values
res = malloc(param_sz);
if(!res)
{
perror("Unable to alloc iterated function params");
return NULL;
}
res->data = data = (rpn_if_default_data_t*)(&(res[1]));
data->size_lim = (size_t*)&(data[1]);
data->pos_flag = pos_flag;
data->res_flag = res_flag;
memcpy(data->size_lim, lim, lim_sz);
if(const_val_sz)
{
data->const_val = (rpn_value_t*)(&(data->size_lim[1]));
memcpy(data->const_val, val, const_val_sz);
}
else
{
data->const_val = NULL;
}
res->arg_f = rpn_if_argf_default;
res->res_f = rpn_if_resf_default;
res->rpn_argc = argc;
res->rpn_stack_sz = rpn_stack_sz;
res->value_sz = 1; /* @TODO set res->value_sz with a good value.. */
res->mem_sz = mem_sz * res->value_sz;
res->rpn_sz = rpn_sz;
return res;
}
int rpn_if_argf_default(rpn_if_t *rif, size_t pos, rpn_value_t *args)
{

View file

@ -82,24 +82,29 @@ struct rpn_if_default_data_s
size_t *size_lim;
/**@brief Store constant values to set mem giver res_flag
* - For @ref RPN_IF_RES_CONST_RGBA const_val points on a single value
* - For @ref RPN_IF_RES_CONST const_val points on a single value
* - For @ref RPN_IF_RES_CONST_RGBA const_val points on 4 values
* - Else const_val is set to NULL
*/
rpn_value_t *const_val;
};
/**@brief Create a new @ref rpn_if_s corresponding to given flags
/**@brief Create a new @ref rpn_if_param_s corresponding to given flags
* @ingroup ifs_if_default
*
* @param pos_flag Binary OR combination of RPN_IF_POSITION_*
* (@ref ifs_if_default_posflag )
* @param pos_flag Binary OR combination of RPN_IF_RES_*
* (@ref ifs_if_default_posflag )
* @returns A new @ref rpn_if_t (see @ref rpn_if_new ) or NULL on
* error
* @param lim Depends on pos_flag parameter (
* see @ref rpn_if_default_data_s::size_lim )
* @param val Depends on res_flag parameter (
* see @ref rpn_if_default_data_s::const_val )
* @returns A new @ref rpn_if_param_t or NULL on error
* @todo Implementation/testing
*/
rpn_if_t* rpn_if_new_default(short pos_flag, short res_flag);
rpn_if_param_t* rpn_if_default_params(short pos_flag, short res_flag,
const size_t *lim, const rpn_value_t *val, unsigned char rpn_stack_sz);
/**@brief Default argf function ( see @ref rpn_if_param_s.arg_f ) */
int rpn_if_argf_default(rpn_if_t *rif, size_t pos, rpn_value_t *args);

View file

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

View file

@ -28,6 +28,8 @@
#include "rpn_lib.h"
#include "rpn_jit.h"
#include "rpn_parse.h"
#include "rpn_if.h"
#include "rpn_if_default.h"
int test0()
{
@ -227,6 +229,59 @@ int test_tokenization()
return 0;
}
int test_rpn_if_default()
{
rpn_if_param_t *rif_param;
rpn_if_t *rif;
size_t lim[2] = {1024,768};
rif_param = rpn_if_default_params(RPN_IF_POSITION_XY, RPN_IF_RES_RGB,
lim, NULL, 32);
if(!rif_param)
{
fprintf(stderr, "rpn_if_default_params() failed\n");
return -1;
}
rif = rpn_if_new(rif_param, NULL);
if(!rif)
{
perror("rpn_if_new() failed");
return -1;
}
free(rif_param);
rpn_if_free(rif);
return 0;
}
int test_rpn_if_default2()
{
rpn_if_param_t *rif_param;
rpn_if_t *rif;
size_t lim[2] = {1024};
rif_param = rpn_if_default_params(RPN_IF_POSITION_LINEAR, RPN_IF_RES_RGB,
lim, NULL, 32);
if(!rif_param)
{
fprintf(stderr, "rpn_if_default_params() failed\n");
return -1;
}
rif = rpn_if_new(rif_param, NULL);
if(!rif)
{
perror("rpn_if_new() failed");
return -1;
}
free(rif_param);
rpn_if_free(rif);
return 0;
}
@ -254,5 +309,7 @@ int main()
RUNTEST(test_args);
RUNTEST(test_stack_sz);
RUNTEST(test_tokenization);
RUNTEST(test_rpn_if_default);
RUNTEST(test_rpn_if_default2);
return res;
}