/* * 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_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; } rpn_expr_t **rpn_if_rpn_get(rpn_if_t *rif) { return &(rif->rpn); }