Continuing implementation of rpn_if, adding default if functions implementation
This commit is contained in:
parent
c018076887
commit
eeac401bb3
6 changed files with 467 additions and 185 deletions
5
Makefile
5
Makefile
|
@ -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
|
||||
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
|
||||
$(LD) $(LDFLAGS) $(PYTHON_LDFLAGS) -o $@ $^
|
||||
|
||||
python_pyrpn.o: python_pyrpn.c python_rpnexpr.h python_rpnexpr.o rpn_jit.o
|
||||
|
@ -42,6 +42,9 @@ rpn_mutation.o: rpn_mutation.c rpn_mutation.h rpn_parse.o
|
|||
rpn_if.o: rpn_if.c rpn_if.h rpn_jit.o
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
rpn_if_default.o: rpn_if_default.c rpn_if_default.h rpn_if.o
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
rpn_lib.o: rpn_lib.asm rpn_lib.h
|
||||
$(NASM) $(NASMCFLAGS) -o $@ $<
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ PyObject* rpnexpr_new(PyTypeObject *subtype, PyObject *args, PyObject* kwds);
|
|||
* @ingroup python_type
|
||||
*/
|
||||
int rpnexpr_init(PyObject *self, PyObject *args, PyObject *kwds);
|
||||
|
||||
/**@brief RPNExpr __del__ method
|
||||
* @param self RPNExpr instance
|
||||
* @ingroup python_type
|
||||
|
|
150
rpn_if.c
150
rpn_if.c
|
@ -18,66 +18,86 @@
|
|||
*/
|
||||
#include "rpn_if.h"
|
||||
|
||||
rpn_if_t* rpn_if_new(size_t mem_sz, rpn_if_transfo_t *if2rpn,
|
||||
rpn_if_transfo_t *rpn2if, rpn_expr_t *rpn)
|
||||
rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_expr_t *rpn)
|
||||
{
|
||||
rpn_if_t *res;
|
||||
if(mem_sz != 0)
|
||||
{
|
||||
if((if2rpn->mem_sz != 0 && if2rpn->mem_sz != mem_sz) ||
|
||||
(rpn2if->mem_sz != 0 && rpn2if->mem_sz != mem_sz))
|
||||
{
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(if2rpn->mem_sz == 0 && rpn2if->mem_sz == 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
if(if2rpn->mem_sz != rpn2if->mem_sz && if2rpn->mem_sz != 0 &&
|
||||
rpn2if->mem_sz != 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
mem_sz = if2rpn->mem_sz != 0?if2rpn->mem_sz:rpn2if->mem_sz;
|
||||
}
|
||||
if(if2rpn->data_sz != rpn2if->data_sz || if2rpn->data_sz == 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
res = _rpn_if_new(mem_sz, if2rpn->argc, rpn2if->argc, rpn2if->data_sz);
|
||||
int err;
|
||||
|
||||
res = malloc(sizeof(rpn_if_t));
|
||||
if(!res)
|
||||
{
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
res->if2rpn = if2rpn->if2rpn;
|
||||
res->rpn2if = rpn2if->rpn2if;
|
||||
res->rpn = rpn;
|
||||
|
||||
memcpy(&res->params, params, sizeof(rpn_if_param_t));
|
||||
|
||||
res->mem = mmap(NULL, params->mem_sz, PROT_READ|PROT_WRITE, MAP_ANON,
|
||||
-1, 0);
|
||||
if(res->mem == (void*)-1)
|
||||
{
|
||||
goto mmap_err;
|
||||
}
|
||||
|
||||
res->rpn_res = malloc(sizeof(rpn_value_t) *
|
||||
(params->rpn_sz + params->rpn_argc));
|
||||
if(!res->rpn_res)
|
||||
{
|
||||
goto rpn_malloc_err;
|
||||
}
|
||||
res->rpn_args = &(res->rpn_res[params->rpn_sz]);
|
||||
|
||||
res->rpn = malloc(sizeof(rpn_expr_t) * params->rpn_sz);
|
||||
if(!res->rpn)
|
||||
{
|
||||
goto rpn_expr_err;
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
rpn_expr_err:
|
||||
err = errno;
|
||||
free(res->rpn_res);
|
||||
rpn_malloc_err:
|
||||
err = errno;
|
||||
munmap(res->mem, params->mem_sz);
|
||||
mmap_err:
|
||||
err = errno;
|
||||
free(res);
|
||||
error:
|
||||
err = errno;
|
||||
errno = err;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rpn_if_free(rpn_if_t* rif)
|
||||
{
|
||||
size_t i;
|
||||
for(i=0; i<rif->rpn_sz; i++)
|
||||
for(i=0; i<rif->params.rpn_sz; i++)
|
||||
{
|
||||
rpn_expr_close(&(rif->rpn[i]));
|
||||
}
|
||||
free(rif->rpn);
|
||||
free(rif->rpn_res);
|
||||
munmap(rif->mem, rif->mem_sz);
|
||||
munmap(rif->mem, rif->params.mem_sz);
|
||||
free(rif);
|
||||
}
|
||||
|
||||
size_t rpn_if_step(rpn_if_t *rif, size_t pos)
|
||||
{
|
||||
size_t i;
|
||||
size_t newpos;
|
||||
rif->params.arg_f(rif, pos, rif->rpn_args);
|
||||
for(i=0; i<rif->params.rpn_sz; i++)
|
||||
{
|
||||
rif->rpn_res[i] = rpn_expr_eval(&(rif->rpn[i]), rif->rpn_args);
|
||||
}
|
||||
rif->params.res_f(rif, &newpos, rif->rpn_res);
|
||||
return newpos;
|
||||
}
|
||||
|
||||
int rpn_if_rpn_upd(rpn_if_t *rif, rpn_tokenized_t *rpns)
|
||||
{
|
||||
return rpn_if_rpn_upd_rng(rif, rpns, rif->rpn_sz, 0);
|
||||
return rpn_if_rpn_upd_rng(rif, rpns, rif->params.rpn_sz, 0);
|
||||
}
|
||||
|
||||
int rpn_if_rpn_upd_rng(rpn_if_t *rif, rpn_tokenized_t *rpns, size_t sz,
|
||||
|
@ -91,55 +111,3 @@ int rpn_if_rpn_upd_rng(rpn_if_t *rif, rpn_tokenized_t *rpns, size_t sz,
|
|||
return 0;
|
||||
}
|
||||
|
||||
rpn_if_t* _rpn_if_new(size_t mem_sz, size_t rpn_argc, size_t rpn_count, size_t
|
||||
value_sz)
|
||||
{
|
||||
rpn_if_t *res;
|
||||
int err;
|
||||
|
||||
res = malloc(sizeof(rpn_if_t));
|
||||
if(!res)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
res->rpn_sz = rpn_count;
|
||||
res->rpn_argc = rpn_argc;
|
||||
res->mem_sz = mem_sz;
|
||||
res->value_sz = value_sz;
|
||||
|
||||
res->mem = mmap(NULL, mem_sz, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0);
|
||||
if(res->mem == (void*)-1)
|
||||
{
|
||||
goto mmap_err;
|
||||
}
|
||||
|
||||
res->rpn_res = malloc(sizeof(unsigned long) * (rpn_count +rpn_argc));
|
||||
if(!res->rpn_res)
|
||||
{
|
||||
goto rpn_malloc_err;
|
||||
}
|
||||
res->rpn_args = &(res->rpn_res[res->rpn_sz]);
|
||||
|
||||
res->rpn = malloc(sizeof(rpn_expr_t) * res->rpn_sz);
|
||||
if(!res->rpn)
|
||||
{
|
||||
goto rpn_expr_err;
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
rpn_expr_err:
|
||||
err = errno;
|
||||
free(res->rpn_res);
|
||||
rpn_malloc_err:
|
||||
err = errno;
|
||||
munmap(res->mem, mem_sz);
|
||||
mmap_err:
|
||||
err = errno;
|
||||
free(res);
|
||||
error:
|
||||
err = errno;
|
||||
errno = err;
|
||||
return NULL;
|
||||
}
|
||||
|
|
136
rpn_if.h
136
rpn_if.h
|
@ -34,120 +34,69 @@
|
|||
* For more details about IF see dedicated page : @ref doc_ifs_if
|
||||
*/
|
||||
|
||||
typedef void* rpn_if_arg_t;
|
||||
typedef unsigned long rpn_arg_t;
|
||||
/**@brief Shortcut for struct @ref rpn_if_s */
|
||||
typedef struct rpn_if_s rpn_if_t;
|
||||
typedef struct rpn_if_res_s rpn_if_res_t;
|
||||
typedef struct rpn_if_state_s rpn_if_state_t;
|
||||
typedef struct rpn_if_transfo_s rpn_if_transfo_t;
|
||||
typedef enum rpn_if_transfo_type_e rpn_if_transfo_type_t;
|
||||
/**@brief IF state to RPN arguments transformation */
|
||||
typedef void (*if2rpn_f)(rpn_if_t *rif, rpn_if_state_t, rpn_arg_t*);
|
||||
/**@brief RPN arguments to IF state transformation */
|
||||
typedef rpn_if_res_t (*rpn2if_f)(rpn_if_t *rif, rpn_arg_t, rpn_if_state_t);
|
||||
/**@brief Shortcut for struct @ref rpn_if_param_s */
|
||||
typedef struct rpn_if_param_s rpn_if_param_t;
|
||||
|
||||
/**@brief IF state
|
||||
*
|
||||
* Will always be something like :
|
||||
* - memory adress/offset/index
|
||||
* - value
|
||||
*/
|
||||
struct rpn_if_state_s
|
||||
/**@brief Stores IF parameters and transformations function pointers */
|
||||
struct rpn_if_param_s
|
||||
{
|
||||
/**@brief Data address */
|
||||
size_t i;
|
||||
/**@brief Data value(s) */
|
||||
void *val;
|
||||
};
|
||||
|
||||
/**@brief Indicate function type for @ref rpn_if_transfo_s */
|
||||
enum rpn_if_transfo_type_e
|
||||
{
|
||||
/**@brief No transformation
|
||||
*
|
||||
* Default behavior is to copy data in args directly assuming
|
||||
* argc * sizeof(unsigned long) = data_sz */
|
||||
RPN_f_null,
|
||||
/**@brief Transform RPN result into data */
|
||||
RPN_f_rpn2if,
|
||||
/**@brief Transform data into RPN result */
|
||||
RPN_f_if2rpn
|
||||
};
|
||||
/**@brief Represent an IF transformation function
|
||||
*
|
||||
* Can transform data into arguments or arguments into data, depending
|
||||
* on function type.
|
||||
*/
|
||||
struct rpn_if_transfo_s
|
||||
{
|
||||
/**@brief Function pointer type
|
||||
* @note optionnal, for type checking
|
||||
*/
|
||||
rpn_if_transfo_type_t type;
|
||||
/**@brief Data size (a @ref rpn_if_s::mem item ) in bytes */
|
||||
size_t data_sz;
|
||||
/**@brief Memory size in byte */
|
||||
/**@brief Memory map size in items */
|
||||
size_t mem_sz;
|
||||
/**@brief RPN arg/result size
|
||||
*
|
||||
* - if type is RPN_if2rpn argc is the rpn expression argc
|
||||
* - if type is RPN_rpn2if argc is the rpn expression count (results
|
||||
* count)
|
||||
*/
|
||||
size_t argc;
|
||||
union {
|
||||
/**@brief IF state to RPN arguments transformation */
|
||||
if2rpn_f if2rpn;
|
||||
/**@brief RPN arguments to IF state transformation */
|
||||
rpn2if_f rpn2if;
|
||||
};
|
||||
/**@brief Size of a memory item */
|
||||
size_t value_sz;
|
||||
/**@brief RPN expression count */
|
||||
size_t rpn_sz;
|
||||
/**@brief Number of arguments expected by RPN expressions */
|
||||
size_t rpn_argc;
|
||||
|
||||
/**@brief Position to RPN argument transformation */
|
||||
int (*arg_f)(rpn_if_t *rif, size_t pos, rpn_value_t *args);
|
||||
/**@brief RPN results to data and position transformation
|
||||
* @note set memory maps with converted data */
|
||||
int (*res_f)(rpn_if_t *rif, size_t *pos,
|
||||
rpn_value_t *data);
|
||||
|
||||
void *data;
|
||||
};
|
||||
|
||||
/**@brief Generic Iterated function implementation */
|
||||
struct rpn_if_s
|
||||
{
|
||||
/**@brief Memory map in wich data are fetch & stored */
|
||||
void *mem;
|
||||
/**@brief Memory map size in bytes */
|
||||
size_t mem_sz;
|
||||
/**@brief Size of a memory item */
|
||||
size_t value_sz;
|
||||
|
||||
/**@brief IF last position + value buffer */
|
||||
rpn_if_state_t state;
|
||||
/**@brief RPN expression(s) result(s) buffer */
|
||||
unsigned long *rpn_res;
|
||||
/**@brief Arguments given to RPN expression(s) buffer */
|
||||
rpn_arg_t *rpn_args;
|
||||
/**@brief Number of arguments expected by RPN expressions */
|
||||
size_t rpn_argc;
|
||||
|
||||
/**@brief IF parameters */
|
||||
rpn_if_param_t params;
|
||||
/**@brief RPN expression(s) pointer(s) */
|
||||
rpn_expr_t *rpn;
|
||||
/**@brief RPN expression count */
|
||||
size_t rpn_sz;
|
||||
|
||||
/**@brief IF state to RPN arguments transformation */
|
||||
if2rpn_f if2rpn;
|
||||
/**@brief RPN arguments to IF state transformation */
|
||||
rpn2if_f rpn2if;
|
||||
|
||||
/**@brief RPN expression(s) result(s) buffer */
|
||||
rpn_value_t *rpn_res;
|
||||
/**@brief Arguments given to RPN expression(s) buffer */
|
||||
rpn_value_t *rpn_args;
|
||||
/**@brief Memory map in wich data are fetch & stored */
|
||||
rpn_value_t *mem;
|
||||
};
|
||||
|
||||
#define rpn_if_getitem(rif, pos) (rif->mem + (rif->params.value_sz * pos))
|
||||
|
||||
/**@brief Alloc a new @ref rpn_if_s from two transformation functions
|
||||
* @param if2rpn informations about data to rpn args transformation
|
||||
* @param rpn2if informations about rpn args to data transformation
|
||||
* @param rpn list of RPN expresions ( must be of rpn2if->argc size !!!)
|
||||
* @param params IF parameters
|
||||
* @param rpn list of RPN expresions of params->rpn_sz size
|
||||
* @return A pointer on an allocated @ref rpn_if_s
|
||||
*/
|
||||
rpn_if_t* rpn_if_new(size_t mem_sz, rpn_if_transfo_t *if2rpn,
|
||||
rpn_if_transfo_t *rpn2if, rpn_expr_t *rpn);
|
||||
rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_expr_t *rpn);
|
||||
|
||||
/**@brief Deallocate an @ref rpn_ifs_s and close associated @ref rpn_expr_s
|
||||
/**@brief Deallocate an @ref rpn_ifs_s and its ressources and close associated
|
||||
* @ref rpn_expr_s
|
||||
* @param rif The IF to deallocate
|
||||
*/
|
||||
void rpn_if_free(rpn_if_t *rif);
|
||||
|
||||
/**@brief Run an IF
|
||||
* @param rif Pointer on IF
|
||||
* @param pos Input position
|
||||
* @return new position
|
||||
*/
|
||||
size_t rpn_if_step(rpn_if_t *rif, size_t pos);
|
||||
|
||||
/**@brief Update all RPN expressions
|
||||
* @param rif The concerned IF
|
||||
|
@ -156,6 +105,7 @@ void rpn_if_free(rpn_if_t *rif);
|
|||
* @note Shortcut for @ref rpn_if_rpn_upd_rng(rif, rpns, rif->rpn_sz, 0);
|
||||
*/
|
||||
int rpn_if_rpn_upd(rpn_if_t *rif, rpn_tokenized_t *rpns);
|
||||
|
||||
/**@brief Update a range of RPN expressions
|
||||
* @param rif The concerned IF
|
||||
* @param rpn A list of tokenized expressions
|
||||
|
|
233
rpn_if_default.c
Normal file
233
rpn_if_default.c
Normal file
|
@ -0,0 +1,233 @@
|
|||
#include "rpn_if_default.h"
|
||||
|
||||
|
||||
int rpn_if_argf_default(rpn_if_t *rif, size_t pos, rpn_value_t *args)
|
||||
{
|
||||
size_t cur_arg, i, rgb_imax;
|
||||
rpn_if_default_data_t *data;
|
||||
rpn_value_t *values;
|
||||
|
||||
data = (rpn_if_default_data_t*)rif->params.data;
|
||||
|
||||
switch(data->pos_flag)
|
||||
{
|
||||
case RPN_IF_POSITION_LINEAR:
|
||||
rpn_if_argf_linear(rif, pos, args);
|
||||
cur_arg = 1;
|
||||
break;
|
||||
case RPN_IF_POSITION_XY:
|
||||
rpn_if_argf_xy(rif, pos, args);
|
||||
cur_arg = 2;
|
||||
break;
|
||||
case RPN_IF_POSITION_XDIM:
|
||||
rpn_if_argf_xdim(rif, pos, args);
|
||||
cur_arg = *(data->size_lim);
|
||||
break;
|
||||
}
|
||||
if(cur_arg >= rif->params.rpn_argc)
|
||||
{
|
||||
/* Too many arguments for given rif !! */
|
||||
return -1;
|
||||
}
|
||||
rgb_imax = 4; /* rgba */
|
||||
values = rpn_if_getitem(rif, pos);
|
||||
switch(data->res_flag)
|
||||
{
|
||||
case RPN_IF_RES_BOOL:
|
||||
args[cur_arg] = values[0]?1:0;
|
||||
break;
|
||||
case RPN_IF_RES_CONST:
|
||||
case RPN_IF_RES_COUNT:
|
||||
args[cur_arg] = *values;
|
||||
break;
|
||||
case RPN_IF_RES_RGB:
|
||||
rgb_imax = 3;
|
||||
case RPN_IF_RES_CONST_RGBA:
|
||||
case RPN_IF_RES_RGBA:
|
||||
for(i=0; i<rgb_imax; i++)
|
||||
{
|
||||
args[cur_arg+i] = values[i];
|
||||
}
|
||||
break;
|
||||
case RPN_IF_RES_XFUN:
|
||||
for(i=0; i < rif->params.rpn_sz - cur_arg; i++)
|
||||
{
|
||||
args[cur_arg+i] = values[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rpn_if_resf_default(rpn_if_t *rif, size_t *pos, rpn_value_t *data);
|
||||
|
||||
int rpn_if_argf_linear(rpn_if_t *rif, size_t pos, rpn_value_t *args)
|
||||
{
|
||||
rpn_if_default_data_t *data;
|
||||
data = (rpn_if_default_data_t*)rif->params.data;
|
||||
if(data->size_lim && pos >= *data->size_lim)
|
||||
{
|
||||
if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
pos %= *(data->size_lim);
|
||||
}
|
||||
args[0] = pos;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpn_if_resf_linear(rpn_if_t *rif, size_t *pos, rpn_value_t *_data)
|
||||
{
|
||||
rpn_if_default_data_t *data;
|
||||
size_t res;
|
||||
data = (rpn_if_default_data_t*)rif->params.data;
|
||||
res = rif->rpn_res[0];
|
||||
if(data->size_lim && res >= *data->size_lim)
|
||||
{
|
||||
if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
res %= *(data->size_lim);
|
||||
}
|
||||
*pos = res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpn_if_argf_xy(rpn_if_t *rif, size_t pos, rpn_value_t *args)
|
||||
{
|
||||
rpn_if_default_data_t *data;
|
||||
|
||||
data = (rpn_if_default_data_t*)rif->params.data;
|
||||
if(!data->size_lim)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
args[0] = pos % data->size_lim[0];
|
||||
args[1] = pos / data->size_lim[0];
|
||||
if(args[1] > data->size_lim[1])
|
||||
{
|
||||
if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
args[1] %= data->size_lim[1];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpn_if_resf_xy(rpn_if_t *rif, size_t *pos, rpn_value_t *_data)
|
||||
{
|
||||
rpn_if_default_data_t *data;
|
||||
size_t xy[2];
|
||||
|
||||
data = (rpn_if_default_data_t*)rif->params.data;
|
||||
|
||||
xy[0] = rif->rpn_res[0];
|
||||
xy[1] = rif->rpn_res[1];
|
||||
|
||||
if(!data->size_lim)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(xy[0] >= data->size_lim[0] || xy[1] >= data->size_lim[1])
|
||||
{
|
||||
if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
xy[0] %= data->size_lim[0];
|
||||
xy[1] %= data->size_lim[1];
|
||||
}
|
||||
*pos = xy[0]+(xy[1]*data->size_lim[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpn_if_argf_xdim(rpn_if_t *rif, size_t pos, rpn_value_t *args)
|
||||
{
|
||||
rpn_if_default_data_t *data;
|
||||
size_t i, curdim_sz, curpos;
|
||||
|
||||
data = (rpn_if_default_data_t*)rif->params.data;
|
||||
|
||||
if(!data->size_lim)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(*(data->size_lim) < 1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
/**@todo check if *(data->size_lim) overflow rif->params->rpn_argc */
|
||||
|
||||
curdim_sz = 1;
|
||||
curpos = pos;
|
||||
for(i=0; i<*(data->size_lim)-1; i++)
|
||||
{
|
||||
curdim_sz *= data->size_lim[i+1];
|
||||
args[i] = curpos % curdim_sz;
|
||||
curpos /= curdim_sz;
|
||||
}
|
||||
args[i] = curpos;
|
||||
if(args[i] >= curdim_sz)
|
||||
{
|
||||
if(data->pos_flag && RPN_IF_POSITION_OF_ERR)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
args[i] %= curdim_sz;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpn_if_resf_xdim(rpn_if_t *rif, size_t *pos, rpn_value_t *_data)
|
||||
{
|
||||
rpn_if_default_data_t *data;
|
||||
size_t i, res, cur, curlim, prevlim;
|
||||
|
||||
data = (rpn_if_default_data_t*)rif->params.data;
|
||||
res = 0;
|
||||
|
||||
if(!data->size_lim)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(*(data->size_lim) < 1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
/**@todo check if *(data->size_lim) overflow rif->params->rpn_argc */
|
||||
|
||||
res = rif->rpn_res[0];
|
||||
if(res >= data->size_lim[1])
|
||||
{
|
||||
if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
res %= data->size_lim[1];
|
||||
}
|
||||
|
||||
for(i=1; i < *(data->size_lim); i++)
|
||||
{
|
||||
cur = rif->rpn_res[i];
|
||||
prevlim = data->size_lim[i];
|
||||
curlim = data->size_lim[i+1];
|
||||
if(cur >= curlim)
|
||||
{
|
||||
if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
cur %= curlim;
|
||||
}
|
||||
res += cur * prevlim;
|
||||
}
|
||||
*pos = res;
|
||||
return 0;
|
||||
}
|
||||
|
127
rpn_if_default.h
Normal file
127
rpn_if_default.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* 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 __rpn_if_default__h__
|
||||
#define __rpn_if_default__h__
|
||||
|
||||
/**@file rpn_if_default.h Defines default IF
|
||||
* @brief Default IF definitions
|
||||
*/
|
||||
/**@defgroup ifs_if_default Default functions
|
||||
* @brief Simple iterated functions functions
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "rpn_if.h"
|
||||
|
||||
#define RPN_IF_POSITION_LINEAR 0 // One expr for position
|
||||
#define RPN_IF_POSITION_XY 1 // two expr for poisition
|
||||
#define RPN_IF_POSITION_XDIM 2 // X expr for position
|
||||
|
||||
#define RPN_IF_POSITION_OF_LOOP 0 // Loop on position overflow
|
||||
#define RPN_IF_POSITION_OF_ERR 16 // Trigger error on position overflow
|
||||
|
||||
#define RPN_IF_RES_BOOL 0 // Set to one when position occurs
|
||||
#define RPN_IF_RES_CONST 1 // Set to a constant value
|
||||
#define RPN_IF_RES_CONST_RGBA 2 // Set to a constant RGB using alpha channel
|
||||
#define RPN_IF_RES_COUNT 3 // Count number of time position occurs
|
||||
#define RPN_IF_RES_XFUN 4 // Set to result of rpn_expr
|
||||
#define RPN_IF_RES_RGB 5 // Set result to RGB color from rpn_expr
|
||||
#define RPN_IF_RES_RGBA 6 // Set result to RGB using alpha channel from rpn_expr
|
||||
|
||||
typedef struct rpn_if_default_data_s rpn_if_default_data_t;
|
||||
|
||||
/**@brief Stores default IF data
|
||||
*
|
||||
* Stores flags and size limit
|
||||
*/
|
||||
struct rpn_if_default_data_s
|
||||
{
|
||||
short pos_flag;
|
||||
short res_flag;
|
||||
/**@brief Stores size limits given pos_flag
|
||||
*
|
||||
* @note If NULL no limit
|
||||
* - For @ref RPN_IF_POSITION_LINEAR size_lim is a single size_t
|
||||
* - For @ref RPN_IF_POSITION_XY size_lim is two size_t (height and width)
|
||||
* - For @ref RPN_IF_POSITION_XDIM *size_lim is the size of size_lim
|
||||
*/
|
||||
size_t *size_lim;
|
||||
|
||||
/**@brief Store constant values to set mem giver res_flag
|
||||
* - For @ref RPN_IF_CONST_RGBA const_val points on a single value
|
||||
* - For @ref RPN_IF_RES_CONST_RGBA const_val points on 4 values
|
||||
*/
|
||||
rpn_value_t *const_val;
|
||||
};
|
||||
|
||||
int rpn_if_argf_default(rpn_if_t *rif, size_t pos, rpn_value_t *args);
|
||||
int rpn_if_resf_default(rpn_if_t *rif, size_t *pos, rpn_value_t *data);
|
||||
|
||||
/**@brief Set the first expression argument from position
|
||||
* @params rif Expressions
|
||||
* @params pos Memory map offset
|
||||
* @params args pointer on expressions arguments
|
||||
* @note Other arguments are set using the generic @ref rpn_if_argf_default
|
||||
* function
|
||||
*/
|
||||
int rpn_if_argf_linear(rpn_if_t *rif, size_t pos, rpn_value_t *args);
|
||||
/**@brief Transform 1st expression result to position
|
||||
* @params rif Expressions
|
||||
* @params pos Pointer on resulting position in memory map
|
||||
* @params data Pointer on resulting data
|
||||
* @note Data from position fecth is done by generic @ref rpn_if_resf_default
|
||||
* function
|
||||
*/
|
||||
int rpn_if_resf_linear(rpn_if_t *rif, size_t *pos, rpn_value_t *data);
|
||||
|
||||
/**@brief Set the 1st & 2nd argument from position
|
||||
* @params rif Expressions
|
||||
* @params pos Memory map offset
|
||||
* @params args pointer on expression arguments
|
||||
* @note Other arguments are set using the generic @ref rpn_if_argf_default
|
||||
* function
|
||||
*/
|
||||
int rpn_if_argf_xy(rpn_if_t *rif, size_t pos, rpn_value_t *args);
|
||||
/**@brief Transform 1st and 2nd result into a memory map's offset
|
||||
* @params rif Expressions
|
||||
* @param pos Memory map offset pointer
|
||||
* @params data Pointer on resulting data
|
||||
* @note Data from position fetch is done by generic @ref rpn_if_resf_default
|
||||
* function
|
||||
*/
|
||||
int rpn_if_resf_xy(rpn_if_t *rif, size_t *pos, rpn_value_t *data);
|
||||
|
||||
/**@brief Set X first arguments from position
|
||||
* @params rif Expressions
|
||||
* @params pos Memory map offset
|
||||
* @params args Pointer on expression arguments
|
||||
* @note Other arguments are set using the generic @ref rpn_if_argf_default
|
||||
* function
|
||||
*/
|
||||
int rpn_if_argf_xdim(rpn_if_t *rif, size_t pos, rpn_value_t *args);
|
||||
/**@brief Transform X arguments into a memory map's offset
|
||||
* @params rif Expressions
|
||||
* @param pos Memory map offset pointer
|
||||
* @param data Pointer on resulting data
|
||||
* @note Data from position fetch is done by generic @ref rpn_if_resf_default
|
||||
* function
|
||||
*/
|
||||
int rpn_if_resf_xdim(rpn_if_t *rif, size_t *pos, rpn_value_t *data);
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue