diff options
Diffstat (limited to 'finsh/finsh_node.c')
| -rw-r--r-- | finsh/finsh_node.c | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/finsh/finsh_node.c b/finsh/finsh_node.c new file mode 100644 index 0000000000..b5d7461adc --- /dev/null +++ b/finsh/finsh_node.c @@ -0,0 +1,174 @@ +#include <finsh.h> + +#include "finsh_node.h" +#include "finsh_error.h" +#include "finsh_var.h" +#include "finsh_heap.h" + +struct finsh_node global_node_table[FINSH_NODE_MAX]; + +int finsh_node_init() +{ + memset(global_node_table, 0, sizeof(global_node_table)); + + return 0; +} + +struct finsh_node* finsh_node_allocate(u_char type) +{ + int i; + + /* find an empty entry */ + for (i = 0; i < FINSH_NODE_MAX; i ++) + { + if (global_node_table[i].node_type == FINSH_NODE_UNKNOWN) break; + } + + if (i == FINSH_NODE_MAX) return NULL; + + /* fill type field */ + global_node_table[i].node_type = type; + + /* return this allocated node */ + return &global_node_table[i]; +} + +struct finsh_node* finsh_node_new_id(char* id) +{ + struct finsh_node* node; + void* symbol; + unsigned char type; + + symbol = NULL; + type = 0; + node = NULL; + + /* lookup variable firstly */ + symbol = (void*)finsh_var_lookup(id); + if (symbol == NULL) + { + /* then lookup system variable */ + symbol = (void*)finsh_sysvar_lookup(id); + if (symbol == NULL) + { + /* then lookup system call */ + symbol = (void*)finsh_syscall_lookup(id); + if (symbol != NULL) type = FINSH_IDTYPE_SYSCALL; + } + else type = FINSH_IDTYPE_SYSVAR; + } + else type = FINSH_IDTYPE_VAR; + + if (symbol != NULL) + { + /* allocate a new node */ + node = finsh_node_allocate(FINSH_NODE_ID); + + /* allocate node error */ + if (node == NULL) + { + finsh_error_set(FINSH_ERROR_MEMORY_FULL); + return NULL; + } + + /* fill node value according type */ + switch (type) + { + case FINSH_IDTYPE_VAR: + node->id.var = (struct finsh_var*)symbol; + break; + + case FINSH_IDTYPE_SYSVAR: + node->id.sysvar = (struct finsh_sysvar*)symbol; + break; + + case FINSH_IDTYPE_SYSCALL: + node->id.syscall = (struct finsh_syscall*)symbol; + break; + } + /* fill identifier type */ + node->idtype = type; + } + else finsh_error_set(FINSH_ERROR_UNKNOWN_SYMBOL); + + return node; +} + +struct finsh_node* finsh_node_new_char(char c) +{ + struct finsh_node* node; + + node = finsh_node_allocate(FINSH_NODE_VALUE_CHAR); + if (node == NULL) + { + finsh_error_set(FINSH_ERROR_MEMORY_FULL); + return NULL; + } + + node->value.char_value = c; + return node; +} + +struct finsh_node* finsh_node_new_int(int i) +{ + struct finsh_node* node; + + node = finsh_node_allocate(FINSH_NODE_VALUE_INT); + if (node == NULL) + { + finsh_error_set(FINSH_ERROR_MEMORY_FULL); + return NULL; + } + + node->value.int_value = i; + return node; +} + +struct finsh_node* finsh_node_new_long(long l) +{ + struct finsh_node* node; + + node = finsh_node_allocate(FINSH_NODE_VALUE_LONG); + if (node == NULL) + { + finsh_error_set(FINSH_ERROR_MEMORY_FULL); + return NULL; + } + + node->value.long_value = l; + return node; +} + +struct finsh_node* finsh_node_new_string(char* s) +{ + struct finsh_node* node; + + node = finsh_node_allocate(FINSH_NODE_VALUE_STRING); + if (node == NULL) + { + finsh_error_set(FINSH_ERROR_MEMORY_FULL); + return NULL; + } + + /* make string */ + node->value.ptr = finsh_heap_allocate(strlen(s) + 1); + strncpy(node->value.ptr, s, strlen(s)); + ((u_char*)node->value.ptr)[strlen(s)] = '\0'; + + return node; +} + +struct finsh_node* finsh_node_new_ptr(void* ptr) +{ + struct finsh_node* node; + + node = finsh_node_allocate(FINSH_NODE_VALUE_NULL); + if (node == NULL) + { + finsh_error_set(FINSH_ERROR_MEMORY_FULL); + return NULL; + } + + node->value.ptr = ptr; + return node; +} |
