/*
* 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 .
*/
#include "rpn_if.h"
rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_expr_t *rpn,
rpn_value_t *memmap)
{
rpn_if_t *res;
size_t i;
int err;
res = malloc(sizeof(rpn_if_t));
if(!res)
{
goto error;
}
//memcpy(&res->params, params, sizeof(rpn_if_param_t));
res->params = params;
if(memmap)
{
res->self_mem = 0;
res->mem = memmap;
}
else
{
res->self_mem = 1;
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;
}
for(i=0; irpn_sz; i++)
{
if(rpn_expr_init(&(res->rpn[i]), params->rpn_stack_sz,
params->rpn_argc) < 0)
{
goto rpn_init_error;
}
}
return res;
rpn_init_error:
err = errno;
while(i)
{
rpn_expr_close(&(res->rpn[i]));
i--;
}
rpn_expr_err:
err = errno;
free(res->rpn_res);
rpn_malloc_err:
err = errno;
if(res->self_mem)
{
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; iparams->rpn_sz; i++)
{
rpn_expr_close(&(rif->rpn[i]));
}
free(rif->rpn);
free(rif->rpn_res);
if(rif->self_mem)
{
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);
/* WRONG ! rif->rpn_args is in rif structure and do not have to be
given as argument... */
for(i=0; iparams->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);
/* MEGA 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;
}
int rpn_if_rpn_upd(rpn_if_t *rif, rpn_tokenized_t *rpns)
{
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,
size_t offset)
{
size_t i;
for(i=offset; i