diff options
Diffstat (limited to 'smash')
| -rw-r--r-- | smash/Makefile | 7 | ||||
| -rw-r--r-- | smash/parser.c | 76 | ||||
| -rw-r--r-- | smash/parser.h | 19 | ||||
| -rw-r--r-- | smash/variables.c | 120 | ||||
| -rw-r--r-- | smash/variables.h | 8 |
5 files changed, 230 insertions, 0 deletions
diff --git a/smash/Makefile b/smash/Makefile new file mode 100644 index 0000000..3f684cd --- /dev/null +++ b/smash/Makefile @@ -0,0 +1,7 @@ +unit_test_parser: + gcc parser.c ../lib/cstr/cstr.c ../lib/malloc/malloc.c ../lib/sys/start.S -static -nostdlib -fno-stack-protector -o test -DPARSER_UNIT_TEST -g + ./test + +unit_test_variables: + gcc variables.c ../lib/avl_tree/avl_tree.c ../lib/cstr/cstr.c ../lib/malloc/malloc.c ../lib/sys/start.S -static -nostdlib -fno-stack-protector -o test -DVARIABLES_UNIT_TEST -g + ./test diff --git a/smash/parser.c b/smash/parser.c new file mode 100644 index 0000000..33fb410 --- /dev/null +++ b/smash/parser.c @@ -0,0 +1,76 @@ +#include "parser.h" + +#include "../lib/malloc/malloc.h" +#include "../lib/cstr/cstr.h" + +#include "../lib/sys/write.h" + +char **__new_argv(char *exp); +void __free_argv(char **argv); + +expression_list_t *new_expression_from_line(char *line) +{ + + u64 n = cstr_split(line, '|'); + char *current = line; + char *next = 0; + + + for (; n > 0; --n) { + next = (char*)next_split(current); + + strip_cstr(current, ' '); + + write(0, current, cstr_length(current)); + write(0, "\\n\n", 3); + + current = next; + } + return 0; +} + +char **__new_argv(char *exp) +{ + u64 n = cstr_split(exp, ' '); + char **argv = malloc(sizeof(char*) * n + 1); + u64 i = 0; + char *current = exp; + char *next; + + for (; n > 0; --n) { + next = (char*)next_split(current); + strip_cstr(current, ' '); + + if (cstr_length(current)) + argv[i++] = current; + + current = next; + } + + argv[i] = 0; + + return argv; +} + + +void __free_argv(char **argv) +{ + free(argv); +} + +#ifdef PARSER_UNIT_TEST + +#include "../lib/sys/execve.h" + +int main() { + const char exp[] = "/bin/ls -a -l -h"; + char **argv = __new_argv(exp); + char **p = argv; + char *const envp[] = { 0 }; + + execve(argv[0], argv, envp); + + free(argv); +} + +#endif diff --git a/smash/parser.h b/smash/parser.h new file mode 100644 index 0000000..9c23e0f --- /dev/null +++ b/smash/parser.h @@ -0,0 +1,19 @@ +#ifndef PARSER_H +#define PARSER_H + +#include "../lib/sys/sizes.h" + +typedef struct { + const char *head; + const char **args; +} expression_t; + +typedef struct expression_list_t__ { + expression_t expression; + struct expression_list_t__ *next; +} expression_list_t; + +expression_list_t *new_expression_from_line(char *line); +void free_expression(expression_list_t *expression); + +#endif diff --git a/smash/variables.c b/smash/variables.c new file mode 100644 index 0000000..b3b6689 --- /dev/null +++ b/smash/variables.c @@ -0,0 +1,120 @@ +#include "variables.h" + +#include "../lib/avl_tree/avl_tree.h" +#include "../lib/cstr/cstr.h" +#include "../lib/malloc/malloc.h" + +typedef struct { + const char *name; + const char *value; +} variable_pair_t; + +i8 __variable_pair_compare(void *a, void *b); + +avl_tree_t *variable_tree; + + +/** DOC + * @type function + * @name __variable_pair_compare + * + * @param void *a + * @param void *b + * @return u8 + * + * @description + * Compair function for `variable_pair_t`. + */ +i8 __variable_pair_compare(void *a, void *b) +{ + variable_pair_t *va = (variable_pair_t*)a; + variable_pair_t *vb = (variable_pair_t*)b; + + return cstr_compare(va->name, vb->name); +} + + +/** DOC + * @type function + * @name init_variables + * + * @description + * Initializes the variable binary tree. + */ +void init_variables() +{ + variable_tree = new_avl_tree(__variable_pair_compare, 1); +} + + +/** DOC + * @type function + * @name set_variable + * + * @param const char *name + * @param const char *value + * + * @description + * Sets a variable. + */ +void set_variable(const char *name, const char *value) +{ + variable_pair_t *pair = malloc(sizeof(variable_pair_t)); + pair->name = name; + pair->value = value; + avl_tree_insert(variable_tree, pair); +} + + +/** DOC + * @type function + * @name get_variable + * + * @param const char *name + * + * @description + * Gets a variable. + */ +const char *get_variable(const char *name) +{ + variable_pair_t query = { .name = name, .value = 0 }; + variable_pair_t *res = avl_tree_search(variable_tree, &query); + + if (res) + return res->value; + return 0; +} + + +#ifdef VARIABLES_UNIT_TEST + +#include "../lib/sys/write.h" + +void test_get(const char *name) +{ + const char *value = get_variable(name); + if (value) + write(0, value, cstr_length(value)); + else + write(0, "value = nullptr", 15); + + write(0, "\n", 1); + +} + +int main() +{ + init_variables(); + set_variable("name", "john"); + set_variable("user", "n8"); + + test_get("name"); + test_get("user"); + + set_variable("user", "freak"); + + test_get("user"); + +} + +#endif diff --git a/smash/variables.h b/smash/variables.h new file mode 100644 index 0000000..af71ee4 --- /dev/null +++ b/smash/variables.h @@ -0,0 +1,8 @@ +#ifndef VARIABLES_H +#define VARIABLES_H + +void set_variable(const char *name, const char *value); +const char *get_variable(const char *name); +void init_variables(); + +#endif |