diff --git a/hw4/include/store.h b/hw4/include/store.h new file mode 100644 index 0000000..275fabd --- /dev/null +++ b/hw4/include/store.h @@ -0,0 +1,16 @@ +typedef struct store_data +{ + char *name; + char *value; + struct store_data *prev; + struct store_data *next; +} store_data; + +store_data *head; + +void store_init(); +store_data* store_get_data(char* var); +void store_remove_data(store_data* data); +void store_add_data(store_data* data); +void store_fini(); +char* store_strcpy(char *str); \ No newline at end of file diff --git a/hw4/src/jobs.c b/hw4/src/jobs.c index 8be3158..19ec671 100644 --- a/hw4/src/jobs.c +++ b/hw4/src/jobs.c @@ -11,6 +11,7 @@ #include "mush.h" #include "debug.h" +#include "store.h" /* * This is the "jobs" module for Mush. @@ -47,8 +48,8 @@ * @return 0 if initialization is successful, otherwise -1. */ int jobs_init(void) { - // TO BE IMPLEMENTED - abort(); + store_init(); + return 0; } /** @@ -62,8 +63,8 @@ int jobs_init(void) { * @return 0 if finalization is completely successful, otherwise -1. */ int jobs_fini(void) { - // TO BE IMPLEMENTED - abort(); + store_fini(); + return 0; } /** diff --git a/hw4/src/main.c b/hw4/src/main.c index 9178838..ca5b15a 100644 --- a/hw4/src/main.c +++ b/hw4/src/main.c @@ -4,6 +4,7 @@ #include #include "mush.h" +#include "store.h" int main(int argc, char *argv[]) { jobs_init(); diff --git a/hw4/src/store.c b/hw4/src/store.c index db9da8b..aca225e 100644 --- a/hw4/src/store.c +++ b/hw4/src/store.c @@ -1,6 +1,7 @@ #include #include #include +#include "store.h" /* * This is the "data store" module for Mush. @@ -29,8 +30,10 @@ * otherwise NULL. */ char *store_get_string(char *var) { - // TO BE IMPLEMENTED - abort(); + store_data *data = store_get_data(var); + if (data) + return data->value; + return NULL; } /** @@ -47,8 +50,29 @@ char *store_get_string(char *var) { * otherwise 0 is returned. */ int store_get_int(char *var, long *valp) { - // TO BE IMPLEMENTED - abort(); + store_data *data = store_get_data(var); + if (data) { + // is NULL + char *ptr = data->value; + if (!ptr) + return -1; + + // find whether negative or not + int sign = 1; + if (*ptr == '-') + sign = -1, ptr ++; + + long ans = 0; + while (*ptr) + { + // cannot be interpreted as an integer + if(*ptr > '9' || *ptr < '0') + return -1; + ans = ans * 10 +(*(ptr++) - '0'); + } + *valp = ans * sign; + } + return -1; } /** @@ -67,8 +91,33 @@ int store_get_int(char *var, long *valp) { * un-set. */ int store_set_string(char *var, char *val) { - // TO BE IMPLEMENTED - abort(); + store_data* data = store_get_data(var); + // if want to unset a value that does not exist + if (!data && !val) + return -1; + + // unset is val is NULL + if (!val) + { + store_remove_data(data); + return 0; + } + + // set the data to val if data exists + if (data) + { + char *tmp = data->value; + data->value = store_strcpy(val); + free(tmp); + return 0; + } + + // create a new data with the value and insert it + data = malloc(sizeof(store_data)); + data->name = store_strcpy(var); + data->value = store_strcpy(val); + store_add_data(data); + return 0; } /** @@ -84,8 +133,53 @@ int store_set_string(char *var, char *val) { * @param val The value to set. */ int store_set_int(char *var, long val) { - // TO BE IMPLEMENTED - abort(); + // if val is 0, set var to 0 + if (val == 0) + return store_set_string(var, "0"); + + char *str, *tmp, *ptr; + tmp = malloc(sizeof(char)); + int is_negative = 0, size = 0; + + // check whether val is negative + if (val < 0) + is_negative = 1; + + // get a string with reversed direction + while (val) + { + int remainder = val % 10; + if (is_negative) + remainder *= -1; + tmp[size] = ('0' + remainder); + tmp = realloc(tmp, (++size + 1) * sizeof(char)); + val /= 10; + } + + // alloc memory to str + if (is_negative) { + str = malloc((size+2)*sizeof(char)); + ptr = str + 1; + str[0] = '-'; + } + else { + str = malloc((size+1)*sizeof(char)); + ptr = str; + } + + // reverse the string back + for (size_t i = 0; i < size; i++) + ptr[i] = tmp[size - i - 1]; + + ptr[size] = '\0'; + + // put it in data + int return_val = store_set_string(var, str); + + free(str); + free(tmp); + + return return_val; } /** @@ -97,6 +191,75 @@ int store_set_int(char *var, long val) { * @param f The stream to which the store contents are to be printed. */ void store_show(FILE *f) { - // TO BE IMPLEMENTED - abort(); + store_data* ptr = head->next; + + fprintf(f, "{"); + while (ptr != head) + { + fprintf(f, "%s=%s", ptr->name, ptr->value); + ptr = ptr->next; + if ((ptr != head)) + fprintf(f, ", "); + + } + fprintf(f, "}\n"); } + +void store_init() { + head = malloc(sizeof(store_data)); + head->name = NULL; + head->value = NULL; + head->next = head; + head->prev = head; +} + +store_data* store_get_data(char* var) { + store_data* ptr = head->next; + + while (ptr != head) + { + if (strcmp(ptr->name, var) == 0) + return ptr; + + ptr = ptr->next; + } + + return NULL; +} + +void store_remove_data(store_data* data) { + data->prev->next = data->next; + data->next->prev = data->prev; + if (data->name) + free(data->name); + if (data->value) + free(data->value); + free(data); +} + +void store_add_data(store_data* data) { + data->next = head->next; + data->prev = head; + data->next->prev = data; + data->prev->next = data; +} + +void store_fini() { + while (head->next != head) + store_remove_data(head->next); + + free(head); + head = NULL; +} + +char* store_strcpy(char *str) { + size_t size = 0; + char *result = malloc(sizeof(char)); + while (*str) + { + result[size] = *(str++); + result = realloc(result, (++size + 1) * sizeof(char)); + } + result[size] = '\0'; + return result; +} \ No newline at end of file