Prepare shell environment implmentation
This commit is contained in:
parent
22e6614238
commit
9b325d5c36
5 changed files with 290 additions and 3 deletions
|
|
@ -1,7 +1,7 @@
|
|||
bin_PROGRAMS = asmsh child
|
||||
|
||||
libcheck_asmsh_a_SOURCES = mmap_parse.c asm_env.c compile.c logger.c \
|
||||
completion.c shell.c shell_cmds.c
|
||||
completion.c shell.c shell_cmds.c shell_env.c
|
||||
|
||||
asmsh_SOURCES = asmsh.c $(libcheck_asmsh_a_SOURCES)
|
||||
child_SOURCES = child.s
|
||||
|
|
@ -21,7 +21,7 @@ noinst_LIBRARIES = libcheck_asmsh.a
|
|||
if HAVE_GCOV
|
||||
libcheck_asmsh_a_CFLAGS = @CFLAGS@ -fprofile-arcs -ftest-coverage
|
||||
|
||||
gcov:
|
||||
gcov: tests/test-suite.log
|
||||
$(GCOV) -j *.gcno
|
||||
|
||||
TO_LOCAL_CLEAN=*.gcov *.gcda *.gcno
|
||||
|
|
@ -34,7 +34,7 @@ LCOV_HTML=lcov_html
|
|||
TO_LOCAL_CLEAN += $(LCOV_INFO) $(LCOV_HTML)
|
||||
|
||||
$(LCOV_INFO): gcov
|
||||
$(LCOV) --capture --directory . --output-file $@
|
||||
$(LCOV) --capture --no-recursion --directory . --output-file $@
|
||||
|
||||
$(LCOV_HTML): $(LCOV_INFO)
|
||||
genhtml $< --output-directory $@
|
||||
|
|
|
|||
1
shell.h
1
shell.h
|
|
@ -10,6 +10,7 @@
|
|||
#include "compile.h"
|
||||
|
||||
typedef struct asmsh_s asmsh_t;
|
||||
#include "shell_sym.h"
|
||||
|
||||
struct asmsh_s
|
||||
{
|
||||
|
|
|
|||
144
shell_sym.c
Normal file
144
shell_sym.c
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
#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; i<table->syms_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; i<table->syms_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(i<table->syms_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; i<table->syms_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; i<table->syms_sz; i++)
|
||||
{
|
||||
int cmp = strcmp(name, table->syms[i].name);
|
||||
if(!cmp)
|
||||
{
|
||||
return &(table->syms[i]);
|
||||
}
|
||||
if(cmp > 0) { break; }
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
40
shell_sym.h
Normal file
40
shell_sym.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef ASMSH_SHELL_ENV_H
|
||||
#define ASMSH_SHELL_ENV_H
|
||||
#include "config.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ASMSH_VARNAME_MAX 31
|
||||
#define ASMSH_SYMALLOC 64
|
||||
|
||||
typedef struct asmsh_sym_s asmsh_sym_t;
|
||||
typedef struct asmsh_symtable_s asmsh_symtable_t;
|
||||
|
||||
struct asmsh_sym_s
|
||||
{
|
||||
char name[ASMSH_VARNAME_MAX + 1];
|
||||
void *val;
|
||||
};
|
||||
|
||||
struct asmsh_symtable_s
|
||||
{
|
||||
short freeval;
|
||||
asmsh_sym_t *syms;
|
||||
size_t syms_sz;
|
||||
size_t alloc;
|
||||
};
|
||||
|
||||
/** if freeval value given to add are freed on clean */
|
||||
int asmsh_symtable_init(asmsh_symtable_t *table, short freeval);
|
||||
void asmsh_symtable_clean(asmsh_symtable_t *table);
|
||||
|
||||
int asmsh_symtable_add(asmsh_symtable_t *table, const char *name, void *val);
|
||||
int asmsh_symtable_del(asmsh_symtable_t *table, const char *name);
|
||||
const asmsh_sym_t *asmsh_symtable_get(asmsh_symtable_t *table, const char *name);
|
||||
|
||||
|
||||
#include "shell.h"
|
||||
|
||||
#endif
|
||||
102
tests/tests_shell_env.c
Normal file
102
tests/tests_shell_env.c
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
#include "config.h"
|
||||
|
||||
#include <check.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "asmsh_check.h"
|
||||
#include "shell_env.h"
|
||||
|
||||
START_TEST(init)
|
||||
{
|
||||
asmsh_symtable_t st;
|
||||
ck_assert_int_eq(asmsh_symtable_init(&st,0), 0);
|
||||
asmsh_symtable_clean(&st);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(add)
|
||||
{
|
||||
asmsh_symtable_t st;
|
||||
ck_assert_int_eq(asmsh_symtable_init(&st,0), 0);
|
||||
ck_assert_int_eq(asmsh_symtable_add(&st, "b", NULL), 0);
|
||||
ck_assert_int_eq(st.syms_sz, 1);
|
||||
ck_assert_int_eq(asmsh_symtable_add(&st, "a", NULL), 0);
|
||||
ck_assert_int_eq(st.syms_sz, 2);
|
||||
ck_assert_int_eq(asmsh_symtable_add(&st, "a", NULL), 0);
|
||||
ck_assert_int_eq(st.syms_sz, 2);
|
||||
ck_assert_int_eq(asmsh_symtable_add(&st, "ab", NULL), 0);
|
||||
ck_assert_int_eq(st.syms_sz, 3);
|
||||
asmsh_symtable_clean(&st);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(del)
|
||||
{
|
||||
|
||||
asmsh_symtable_t st;
|
||||
ck_assert_int_eq(asmsh_symtable_init(&st,0), 0);
|
||||
ck_assert_int_eq(asmsh_symtable_del(&st, "a"), 0);
|
||||
ck_assert_int_eq(asmsh_symtable_add(&st, "a", NULL), 0);
|
||||
ck_assert_int_eq(asmsh_symtable_del(&st, "a"), 1);
|
||||
ck_assert_int_eq(asmsh_symtable_del(&st, "a"), 0);
|
||||
ck_assert_int_eq(asmsh_symtable_add(&st, "a", NULL), 0);
|
||||
ck_assert_int_eq(asmsh_symtable_add(&st, "b", NULL), 0);
|
||||
ck_assert_int_eq(asmsh_symtable_add(&st, "c", NULL), 0);
|
||||
ck_assert_int_eq(asmsh_symtable_del(&st, "d"), 0);
|
||||
ck_assert_int_eq(asmsh_symtable_del(&st, "b"), 1);
|
||||
ck_assert_int_eq(asmsh_symtable_del(&st, "b"), 0);
|
||||
ck_assert_int_eq(asmsh_symtable_add(&st, "b", NULL), 0);
|
||||
ck_assert_int_eq(asmsh_symtable_del(&st, "a"), 1);
|
||||
ck_assert_int_eq(asmsh_symtable_del(&st, "a"), 0);
|
||||
asmsh_symtable_clean(&st);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST(get)
|
||||
{
|
||||
asmsh_symtable_t st;
|
||||
const asmsh_sym_t *s;
|
||||
ck_assert_int_eq(asmsh_symtable_init(&st,0), 0);
|
||||
ck_assert_ptr_null(asmsh_symtable_get(&st, "a"));
|
||||
ck_assert_int_eq(asmsh_symtable_add(&st, "a", NULL), 0);
|
||||
s = asmsh_symtable_get(&st, "a");
|
||||
ck_assert_ptr_nonnull(s);
|
||||
ck_assert_ptr_null(s->val);
|
||||
ck_assert_int_eq(asmsh_symtable_add(&st, "a", (void*)42), 0);
|
||||
s = asmsh_symtable_get(&st, "a");
|
||||
ck_assert_ptr_nonnull(s);
|
||||
ck_assert_ptr_eq(s->val, (void*)42);
|
||||
asmsh_symtable_clean(&st);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(_realloc)
|
||||
{
|
||||
asmsh_symtable_t st;
|
||||
ck_assert_int_eq(asmsh_symtable_init(&st,0), 0);
|
||||
for(int i=0; i<ASMSH_SYMALLOC*3; i++)
|
||||
{
|
||||
char buf[16];
|
||||
snprintf(buf, 15, "a%d", i);
|
||||
ck_assert_int_eq(asmsh_symtable_add(&st, buf, NULL), 0);
|
||||
}
|
||||
for(int i=0; i<ASMSH_SYMALLOC*3; i++)
|
||||
{
|
||||
char buf[16];
|
||||
snprintf(buf, 15, "a%d", i);
|
||||
ck_assert_int_eq(asmsh_symtable_del(&st, buf), 1);
|
||||
}
|
||||
asmsh_symtable_clean(&st);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
ASMSH_CHECK_START("testing completion", "Testing completion features")
|
||||
ASMSH_ADD_TEST(init);
|
||||
ASMSH_ADD_TEST(add);
|
||||
ASMSH_ADD_TEST(del);
|
||||
ASMSH_ADD_TEST(get);
|
||||
ASMSH_ADD_TEST(_realloc);
|
||||
ASMSH_CHECK_END
|
||||
Loading…
Add table
Add a link
Reference in a new issue