/* Copyright Yann Weber This file is part of asmsh. asmsh 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. asmsh 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 asmsh. If not, see . */ #include "shell_env.h" int asmsh_symtable_init(asmsh_symtable_t *table, short freeval) { int err; table->freeval = freeval?1:0; table->alloc = ASMSH_SYMALLOC; table->syms = malloc(table->alloc*sizeof(*table->syms)); if(!table->syms) { err = errno; goto err; } bzero(table->syms, table->alloc*sizeof(*table->syms)); table->syms_sz = 0; return 0; err: bzero(table, sizeof(*table)); errno=err; return -1; } void asmsh_symtable_clean(asmsh_symtable_t *table) { if(table->freeval) { for(int i=0; isyms_sz; i++) { free(table->syms[i].val); } } free(table->syms); bzero(table, sizeof(*table)); } int asmsh_symtable_add(asmsh_symtable_t *table, const char *name, void *val) { int i; if(strlen(name)>ASMSH_VARNAME_MAX) { errno=EINVAL; return -1; } if(table->syms_sz >= table->alloc-1) { table->alloc += ASMSH_SYMALLOC; void *tmp = realloc(table->syms, sizeof(*table->syms)*table->alloc); if(!tmp) { return -1; } table->syms = tmp; } for(i=0; isyms_sz; i++) { int cmp = strcmp(name, table->syms[i].name); if(cmp == 0) { //update value if(table->freeval) { free(table->syms[i].val); } table->syms[i].val = val; return 0; } else if(cmp > 0) { break; } } if(isyms_sz) { memmove(&table->syms[i+1], &table->syms[i], sizeof(*table->syms)*(table->syms_sz - i)); } strncpy(table->syms[i].name, name, ASMSH_VARNAME_MAX); table->syms[i].name[ASMSH_VARNAME_MAX] = '\0'; table->syms[i].val = val; table->syms_sz++; return 0; } int asmsh_symtable_del(asmsh_symtable_t *table, const char *name) { if(strlen(name) > ASMSH_VARNAME_MAX) { return 0; } int i=0; for(i=0; isyms_sz; i++) { int cmp = strncmp(name, table->syms[i].name, ASMSH_VARNAME_MAX); if(!cmp) { break; } } if(i==table->syms_sz) { return 0; // not found } if(table->freeval) { free(table->syms[i].val); } if(table->syms_sz > i+1) { memmove(&table->syms[i], &table->syms[i+1], sizeof(*table->syms)*(table->syms_sz - (i+1))); if((table->alloc - table->syms_sz) > ASMSH_SYMALLOC*2) { table->alloc -= ASMSH_SYMALLOC; void *tmp = realloc(table->syms, sizeof(*table->syms)*table->alloc); if(!tmp) { return 0; // :/ } table->syms = tmp; } } table->syms_sz--; return 1; // 1 deleted } const asmsh_sym_t *asmsh_symtable_get(asmsh_symtable_t *table, const char *name) { if(strlen(name) > ASMSH_VARNAME_MAX) { return NULL; } for(int i=0; isyms_sz; i++) { int cmp = strcmp(name, table->syms[i].name); if(!cmp) { return &(table->syms[i]); } if(cmp > 0) { break; } } return NULL; }