Преглед на файлове

Prepare shell environment implmentation

Yann Weber преди 1 година
родител
ревизия
9b325d5c36
променени са 5 файла, в които са добавени 290 реда и са изтрити 3 реда
  1. 3
    3
      Makefile.am
  2. 1
    0
      shell.h
  3. 144
    0
      shell_sym.c
  4. 40
    0
      shell_sym.h
  5. 102
    0
      tests/tests_shell_env.c

+ 3
- 3
Makefile.am Целия файл

@@ -1,7 +1,7 @@
1 1
 bin_PROGRAMS = asmsh child
2 2
 
3 3
 libcheck_asmsh_a_SOURCES = mmap_parse.c asm_env.c compile.c logger.c \
4
-			   completion.c shell.c shell_cmds.c
4
+			   completion.c shell.c shell_cmds.c shell_env.c
5 5
 
6 6
 asmsh_SOURCES = asmsh.c $(libcheck_asmsh_a_SOURCES)
7 7
 child_SOURCES = child.s
@@ -21,7 +21,7 @@ noinst_LIBRARIES = libcheck_asmsh.a
21 21
 if HAVE_GCOV
22 22
 libcheck_asmsh_a_CFLAGS = @CFLAGS@ -fprofile-arcs -ftest-coverage
23 23
 
24
-gcov:
24
+gcov: tests/test-suite.log
25 25
 	$(GCOV) -j *.gcno
26 26
 
27 27
 TO_LOCAL_CLEAN=*.gcov *.gcda *.gcno
@@ -34,7 +34,7 @@ LCOV_HTML=lcov_html
34 34
 TO_LOCAL_CLEAN += $(LCOV_INFO) $(LCOV_HTML)
35 35
 
36 36
 $(LCOV_INFO): gcov
37
-	$(LCOV) --capture --directory . --output-file $@
37
+	$(LCOV) --capture --no-recursion --directory . --output-file $@
38 38
 
39 39
 $(LCOV_HTML): $(LCOV_INFO)
40 40
 	genhtml $< --output-directory $@

+ 1
- 0
shell.h Целия файл

@@ -10,6 +10,7 @@
10 10
 #include "compile.h"
11 11
 
12 12
 typedef struct asmsh_s asmsh_t;
13
+#include "shell_sym.h"
13 14
 
14 15
 struct asmsh_s
15 16
 {

+ 144
- 0
shell_sym.c Целия файл

@@ -0,0 +1,144 @@
1
+#include "shell_env.h"
2
+
3
+
4
+int asmsh_symtable_init(asmsh_symtable_t *table, short freeval)
5
+{
6
+	int err;
7
+	table->freeval = freeval?1:0;
8
+	table->alloc = ASMSH_SYMALLOC;
9
+	table->syms = malloc(table->alloc*sizeof(*table->syms));
10
+	if(!table->syms)
11
+	{
12
+		err = errno;
13
+		goto err;
14
+	}
15
+	bzero(table->syms, table->alloc*sizeof(*table->syms));
16
+	table->syms_sz = 0;
17
+	return 0;
18
+err:
19
+	bzero(table, sizeof(*table));
20
+	errno=err;
21
+	return -1;
22
+}
23
+
24
+
25
+void asmsh_symtable_clean(asmsh_symtable_t *table)
26
+{
27
+	if(table->freeval)
28
+	{
29
+		for(int i=0; i<table->syms_sz; i++)
30
+		{
31
+			free(table->syms[i].val);
32
+		}
33
+	}
34
+	free(table->syms);
35
+	bzero(table, sizeof(*table));
36
+}
37
+
38
+
39
+int asmsh_symtable_add(asmsh_symtable_t *table, const char *name, void *val)
40
+{
41
+	int i;
42
+	if(strlen(name)>ASMSH_VARNAME_MAX)
43
+	{
44
+		errno=EINVAL;
45
+		return -1;
46
+	}
47
+	if(table->syms_sz >= table->alloc-1)
48
+	{
49
+		table->alloc += ASMSH_SYMALLOC;
50
+		void *tmp = realloc(table->syms, sizeof(*table->syms)*table->alloc);
51
+		if(!tmp)
52
+		{
53
+			return -1;
54
+		}
55
+		table->syms = tmp;
56
+	}
57
+	for(i=0; i<table->syms_sz; i++)
58
+	{
59
+		int cmp = strcmp(name, table->syms[i].name);
60
+		if(cmp == 0)
61
+		{
62
+			//update value
63
+			if(table->freeval)
64
+			{
65
+				free(table->syms[i].val);
66
+			}
67
+			table->syms[i].val = val;
68
+			return 0;
69
+		}
70
+		else if(cmp > 0)
71
+		{
72
+			break;
73
+		}
74
+	}
75
+	if(i<table->syms_sz)
76
+	{
77
+		memmove(&table->syms[i+1], &table->syms[i],
78
+				sizeof(*table->syms)*(table->syms_sz - i));
79
+	}
80
+
81
+	strncpy(table->syms[i].name, name, ASMSH_VARNAME_MAX);
82
+	table->syms[i].name[ASMSH_VARNAME_MAX] = '\0';
83
+	table->syms[i].val = val;
84
+	table->syms_sz++;
85
+	return 0;
86
+}
87
+
88
+
89
+int asmsh_symtable_del(asmsh_symtable_t *table, const char *name)
90
+{
91
+	if(strlen(name) > ASMSH_VARNAME_MAX)
92
+	{
93
+		return 0;
94
+	}
95
+	int i=0;
96
+	for(i=0; i<table->syms_sz;  i++)
97
+	{
98
+		int cmp = strncmp(name, table->syms[i].name, ASMSH_VARNAME_MAX);
99
+		if(!cmp) { break; }
100
+	}
101
+	if(i==table->syms_sz)
102
+	{
103
+		return 0; // not found
104
+	}
105
+	if(table->freeval) { free(table->syms[i].val); }
106
+	if(table->syms_sz > i+1)
107
+	{
108
+		memmove(&table->syms[i], &table->syms[i+1],
109
+				sizeof(*table->syms)*(table->syms_sz - (i+1)));
110
+		if((table->alloc - table->syms_sz) > ASMSH_SYMALLOC*2)
111
+		{
112
+			table->alloc -= ASMSH_SYMALLOC;
113
+			void *tmp = realloc(table->syms,
114
+					sizeof(*table->syms)*table->alloc);
115
+			if(!tmp)
116
+			{
117
+				return 0; // :/
118
+			}
119
+			table->syms = tmp;
120
+		}
121
+	}
122
+	table->syms_sz--;
123
+	return 1; // 1 deleted
124
+}
125
+
126
+
127
+const asmsh_sym_t *asmsh_symtable_get(asmsh_symtable_t *table, const char *name)
128
+{
129
+	if(strlen(name) > ASMSH_VARNAME_MAX)
130
+	{
131
+		return NULL;
132
+	}
133
+	for(int i=0; i<table->syms_sz; i++)
134
+	{
135
+		int cmp = strcmp(name, table->syms[i].name);
136
+		if(!cmp)
137
+		{
138
+			return &(table->syms[i]);
139
+		}
140
+		if(cmp > 0) { break; }
141
+	}
142
+	return NULL;
143
+}
144
+

+ 40
- 0
shell_sym.h Целия файл

@@ -0,0 +1,40 @@
1
+#ifndef ASMSH_SHELL_ENV_H
2
+#define ASMSH_SHELL_ENV_H
3
+#include "config.h"
4
+
5
+#include <unistd.h>
6
+#include <stdlib.h>
7
+#include <string.h>
8
+
9
+#define ASMSH_VARNAME_MAX 31
10
+#define ASMSH_SYMALLOC 64
11
+
12
+typedef struct asmsh_sym_s asmsh_sym_t;
13
+typedef struct asmsh_symtable_s asmsh_symtable_t;
14
+
15
+struct asmsh_sym_s
16
+{
17
+	char name[ASMSH_VARNAME_MAX + 1];
18
+	void *val;
19
+};
20
+
21
+struct asmsh_symtable_s
22
+{
23
+	short freeval;
24
+	asmsh_sym_t *syms;
25
+	size_t syms_sz;
26
+	size_t alloc;
27
+};
28
+
29
+/** if freeval value given to add are freed on clean */
30
+int asmsh_symtable_init(asmsh_symtable_t *table, short freeval);
31
+void asmsh_symtable_clean(asmsh_symtable_t *table);
32
+
33
+int asmsh_symtable_add(asmsh_symtable_t *table, const char *name, void *val);
34
+int asmsh_symtable_del(asmsh_symtable_t *table, const char *name);
35
+const asmsh_sym_t *asmsh_symtable_get(asmsh_symtable_t *table, const char *name);
36
+
37
+
38
+#include "shell.h"
39
+
40
+#endif

+ 102
- 0
tests/tests_shell_env.c Целия файл

@@ -0,0 +1,102 @@
1
+#include "config.h"
2
+
3
+#include <check.h>
4
+#include <errno.h>
5
+#include <stdio.h>
6
+#include <unistd.h>
7
+
8
+#include "asmsh_check.h"
9
+#include "shell_env.h"
10
+
11
+START_TEST(init)
12
+{
13
+	asmsh_symtable_t st;
14
+	ck_assert_int_eq(asmsh_symtable_init(&st,0), 0);
15
+	asmsh_symtable_clean(&st);
16
+}
17
+END_TEST
18
+
19
+START_TEST(add)
20
+{
21
+	asmsh_symtable_t st;
22
+	ck_assert_int_eq(asmsh_symtable_init(&st,0), 0);
23
+	ck_assert_int_eq(asmsh_symtable_add(&st, "b", NULL), 0);
24
+	ck_assert_int_eq(st.syms_sz, 1);
25
+	ck_assert_int_eq(asmsh_symtable_add(&st, "a", NULL), 0);
26
+	ck_assert_int_eq(st.syms_sz, 2);
27
+	ck_assert_int_eq(asmsh_symtable_add(&st, "a", NULL), 0);
28
+	ck_assert_int_eq(st.syms_sz, 2);
29
+	ck_assert_int_eq(asmsh_symtable_add(&st, "ab", NULL), 0);
30
+	ck_assert_int_eq(st.syms_sz, 3);
31
+	asmsh_symtable_clean(&st);
32
+}
33
+END_TEST
34
+
35
+START_TEST(del)
36
+{
37
+
38
+	asmsh_symtable_t st;
39
+	ck_assert_int_eq(asmsh_symtable_init(&st,0), 0);
40
+	ck_assert_int_eq(asmsh_symtable_del(&st, "a"), 0);
41
+	ck_assert_int_eq(asmsh_symtable_add(&st, "a", NULL), 0);
42
+	ck_assert_int_eq(asmsh_symtable_del(&st, "a"), 1);
43
+	ck_assert_int_eq(asmsh_symtable_del(&st, "a"), 0);
44
+	ck_assert_int_eq(asmsh_symtable_add(&st, "a", NULL), 0);
45
+	ck_assert_int_eq(asmsh_symtable_add(&st, "b", NULL), 0);
46
+	ck_assert_int_eq(asmsh_symtable_add(&st, "c", NULL), 0);
47
+	ck_assert_int_eq(asmsh_symtable_del(&st, "d"), 0);
48
+	ck_assert_int_eq(asmsh_symtable_del(&st, "b"), 1);
49
+	ck_assert_int_eq(asmsh_symtable_del(&st, "b"), 0);
50
+	ck_assert_int_eq(asmsh_symtable_add(&st, "b", NULL), 0);
51
+	ck_assert_int_eq(asmsh_symtable_del(&st, "a"), 1);
52
+	ck_assert_int_eq(asmsh_symtable_del(&st, "a"), 0);
53
+	asmsh_symtable_clean(&st);
54
+}
55
+END_TEST
56
+
57
+
58
+START_TEST(get)
59
+{
60
+	asmsh_symtable_t st;
61
+	const asmsh_sym_t *s;
62
+	ck_assert_int_eq(asmsh_symtable_init(&st,0), 0);
63
+	ck_assert_ptr_null(asmsh_symtable_get(&st, "a"));
64
+	ck_assert_int_eq(asmsh_symtable_add(&st, "a", NULL), 0);
65
+	s = asmsh_symtable_get(&st, "a");
66
+	ck_assert_ptr_nonnull(s);
67
+	ck_assert_ptr_null(s->val);
68
+	ck_assert_int_eq(asmsh_symtable_add(&st, "a", (void*)42), 0);
69
+	s = asmsh_symtable_get(&st, "a");
70
+	ck_assert_ptr_nonnull(s);
71
+	ck_assert_ptr_eq(s->val, (void*)42);
72
+	asmsh_symtable_clean(&st);
73
+}
74
+END_TEST
75
+
76
+START_TEST(_realloc)
77
+{
78
+	asmsh_symtable_t st;
79
+	ck_assert_int_eq(asmsh_symtable_init(&st,0), 0);
80
+	for(int i=0; i<ASMSH_SYMALLOC*3; i++)
81
+	{
82
+		char buf[16];
83
+		snprintf(buf, 15, "a%d", i);
84
+		ck_assert_int_eq(asmsh_symtable_add(&st, buf, NULL), 0);
85
+	}
86
+	for(int i=0; i<ASMSH_SYMALLOC*3; i++)
87
+	{
88
+		char buf[16];
89
+		snprintf(buf, 15, "a%d", i);
90
+		ck_assert_int_eq(asmsh_symtable_del(&st, buf), 1);
91
+	}
92
+	asmsh_symtable_clean(&st);
93
+}
94
+END_TEST
95
+
96
+ASMSH_CHECK_START("testing completion", "Testing completion features")
97
+	ASMSH_ADD_TEST(init);
98
+	ASMSH_ADD_TEST(add);
99
+	ASMSH_ADD_TEST(del);
100
+	ASMSH_ADD_TEST(get);
101
+	ASMSH_ADD_TEST(_realloc);
102
+ASMSH_CHECK_END

Loading…
Отказ
Запис