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
|
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 $@ $^
|
$(LD) $(LDFLAGS) $(PYTHON_LDFLAGS) -o $@ $^
|
||||||
|
|
||||||
python_pyrpn.o: python_pyrpn.c python_rpnexpr.h python_rpnexpr.o rpn_jit.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
|
rpn_if.o: rpn_if.c rpn_if.h rpn_jit.o
|
||||||
$(CC) $(CFLAGS) -c $<
|
$(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
|
rpn_lib.o: rpn_lib.asm rpn_lib.h
|
||||||
$(NASM) $(NASMCFLAGS) -o $@ $<
|
$(NASM) $(NASMCFLAGS) -o $@ $<
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,7 @@ PyObject* rpnexpr_new(PyTypeObject *subtype, PyObject *args, PyObject* kwds);
|
||||||
* @ingroup python_type
|
* @ingroup python_type
|
||||||
*/
|
*/
|
||||||
int rpnexpr_init(PyObject *self, PyObject *args, PyObject *kwds);
|
int rpnexpr_init(PyObject *self, PyObject *args, PyObject *kwds);
|
||||||
|
|
||||||
/**@brief RPNExpr __del__ method
|
/**@brief RPNExpr __del__ method
|
||||||
* @param self RPNExpr instance
|
* @param self RPNExpr instance
|
||||||
* @ingroup python_type
|
* @ingroup python_type
|
||||||
|
|
|
||||||
150
rpn_if.c
150
rpn_if.c
|
|
@ -18,66 +18,86 @@
|
||||||
*/
|
*/
|
||||||
#include "rpn_if.h"
|
#include "rpn_if.h"
|
||||||
|
|
||||||
rpn_if_t* rpn_if_new(size_t mem_sz, rpn_if_transfo_t *if2rpn,
|
rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_expr_t *rpn)
|
||||||
rpn_if_transfo_t *rpn2if, rpn_expr_t *rpn)
|
|
||||||
{
|
{
|
||||||
rpn_if_t *res;
|
rpn_if_t *res;
|
||||||
if(mem_sz != 0)
|
int err;
|
||||||
{
|
|
||||||
if((if2rpn->mem_sz != 0 && if2rpn->mem_sz != mem_sz) ||
|
res = malloc(sizeof(rpn_if_t));
|
||||||
(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);
|
|
||||||
if(!res)
|
if(!res)
|
||||||
{
|
{
|
||||||
return NULL;
|
goto error;
|
||||||
}
|
}
|
||||||
res->if2rpn = if2rpn->if2rpn;
|
|
||||||
res->rpn2if = rpn2if->rpn2if;
|
memcpy(&res->params, params, sizeof(rpn_if_param_t));
|
||||||
res->rpn = rpn;
|
|
||||||
|
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;
|
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)
|
void rpn_if_free(rpn_if_t* rif)
|
||||||
{
|
{
|
||||||
size_t i;
|
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]));
|
rpn_expr_close(&(rif->rpn[i]));
|
||||||
}
|
}
|
||||||
free(rif->rpn);
|
free(rif->rpn);
|
||||||
free(rif->rpn_res);
|
free(rif->rpn_res);
|
||||||
munmap(rif->mem, rif->mem_sz);
|
munmap(rif->mem, rif->params.mem_sz);
|
||||||
free(rif);
|
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)
|
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,
|
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;
|
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
|
* For more details about IF see dedicated page : @ref doc_ifs_if
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef void* rpn_if_arg_t;
|
/**@brief Shortcut for struct @ref rpn_if_s */
|
||||||
typedef unsigned long rpn_arg_t;
|
|
||||||
typedef struct rpn_if_s rpn_if_t;
|
typedef struct rpn_if_s rpn_if_t;
|
||||||
typedef struct rpn_if_res_s rpn_if_res_t;
|
/**@brief Shortcut for struct @ref rpn_if_param_s */
|
||||||
typedef struct rpn_if_state_s rpn_if_state_t;
|
typedef struct rpn_if_param_s rpn_if_param_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 IF state
|
/**@brief Stores IF parameters and transformations function pointers */
|
||||||
*
|
struct rpn_if_param_s
|
||||||
* Will always be something like :
|
|
||||||
* - memory adress/offset/index
|
|
||||||
* - value
|
|
||||||
*/
|
|
||||||
struct rpn_if_state_s
|
|
||||||
{
|
{
|
||||||
/**@brief Data address */
|
/**@brief Memory map size in items */
|
||||||
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 */
|
|
||||||
size_t mem_sz;
|
size_t mem_sz;
|
||||||
/**@brief RPN arg/result size
|
/**@brief Size of a memory item */
|
||||||
*
|
size_t value_sz;
|
||||||
* - if type is RPN_if2rpn argc is the rpn expression argc
|
/**@brief RPN expression count */
|
||||||
* - if type is RPN_rpn2if argc is the rpn expression count (results
|
size_t rpn_sz;
|
||||||
* count)
|
/**@brief Number of arguments expected by RPN expressions */
|
||||||
*/
|
size_t rpn_argc;
|
||||||
size_t argc;
|
|
||||||
union {
|
/**@brief Position to RPN argument transformation */
|
||||||
/**@brief IF state to RPN arguments transformation */
|
int (*arg_f)(rpn_if_t *rif, size_t pos, rpn_value_t *args);
|
||||||
if2rpn_f if2rpn;
|
/**@brief RPN results to data and position transformation
|
||||||
/**@brief RPN arguments to IF state transformation */
|
* @note set memory maps with converted data */
|
||||||
rpn2if_f rpn2if;
|
int (*res_f)(rpn_if_t *rif, size_t *pos,
|
||||||
};
|
rpn_value_t *data);
|
||||||
|
|
||||||
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**@brief Generic Iterated function implementation */
|
/**@brief Generic Iterated function implementation */
|
||||||
struct rpn_if_s
|
struct rpn_if_s
|
||||||
{
|
{
|
||||||
/**@brief Memory map in wich data are fetch & stored */
|
/**@brief IF parameters */
|
||||||
void *mem;
|
rpn_if_param_t params;
|
||||||
/**@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 RPN expression(s) pointer(s) */
|
/**@brief RPN expression(s) pointer(s) */
|
||||||
rpn_expr_t *rpn;
|
rpn_expr_t *rpn;
|
||||||
/**@brief RPN expression count */
|
/**@brief RPN expression(s) result(s) buffer */
|
||||||
size_t rpn_sz;
|
rpn_value_t *rpn_res;
|
||||||
|
/**@brief Arguments given to RPN expression(s) buffer */
|
||||||
/**@brief IF state to RPN arguments transformation */
|
rpn_value_t *rpn_args;
|
||||||
if2rpn_f if2rpn;
|
/**@brief Memory map in wich data are fetch & stored */
|
||||||
/**@brief RPN arguments to IF state transformation */
|
rpn_value_t *mem;
|
||||||
rpn2if_f rpn2if;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#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
|
/**@brief Alloc a new @ref rpn_if_s from two transformation functions
|
||||||
* @param if2rpn informations about data to rpn args transformation
|
* @param params IF parameters
|
||||||
* @param rpn2if informations about rpn args to data transformation
|
* @param rpn list of RPN expresions of params->rpn_sz size
|
||||||
* @param rpn list of RPN expresions ( must be of rpn2if->argc size !!!)
|
|
||||||
* @return A pointer on an allocated @ref rpn_if_s
|
* @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_t* rpn_if_new(const rpn_if_param_t *params, rpn_expr_t *rpn);
|
||||||
rpn_if_transfo_t *rpn2if, 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
|
* @param rif The IF to deallocate
|
||||||
*/
|
*/
|
||||||
void rpn_if_free(rpn_if_t *rif);
|
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
|
/**@brief Update all RPN expressions
|
||||||
* @param rif The concerned IF
|
* @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);
|
* @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);
|
int rpn_if_rpn_upd(rpn_if_t *rif, rpn_tokenized_t *rpns);
|
||||||
|
|
||||||
/**@brief Update a range of RPN expressions
|
/**@brief Update a range of RPN expressions
|
||||||
* @param rif The concerned IF
|
* @param rif The concerned IF
|
||||||
* @param rpn A list of tokenized expressions
|
* @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