diff --git a/CLI/CLI.c b/CLI/CLI.c new file mode 100644 index 0000000..050ce30 --- /dev/null +++ b/CLI/CLI.c @@ -0,0 +1,157 @@ +#include "CLI.h" + +#include +#include +#include + +#include "../FIFOBuff/FIFOBuffChar.h" + +CLI_lineOutFn CLI_lineOut; +CMDList_t* CMDList; +FIFOBuffChar_t* FIFO; + +// initilize and register the lineout print function +bool CLI_init(CLI_lineOutFn lineOut, CMDList_t* cmdList) +{ + CLI_lineOut = lineOut; + CMDList = cmdList; + + FIFO = FIFOBuffChar_create(); + + if (CLI_lineOut != NULL) + { + (*CLI_lineOut)(">"); + (*CLI_lineOut)(" "); + } + + return true; +} + +bool CLI_deinit() +{ + CLI_lineOut = NULL; + CMDList = NULL; + + FIFOBuffChar_delete(FIFO); + return true; +} + +char* fifoToString(FIFOBuffChar_t* fifo) +{ + char* out = malloc(fifo->size + 1); + char* write_p = out; + + for (int i = fifo->size; i > 0; i--) + { + FIFOBuffChar_get(fifo, write_p); + write_p++; + } + + *write_p = 0; + + return out; +} + +int tryExecute(FIFOBuffChar_t* fifo) +{ + char* line = fifoToString(fifo); + CMD_t* cmd = CMDList_get(CMDList, line); + + if (cmd != NULL) + { + (*(cmd->fn))(line); + + if (CLI_lineOut != NULL) + { + (*CLI_lineOut)(">"); + (*CLI_lineOut)(" "); + } + return true; + } + else + { + if (CLI_lineOut != NULL) + { + char err[100]; + sprintf(&err[0], "command not found: %s\n> ", line); + for (int i=0; err[i] != 0; i++) + { + char c[2] = {err[i], 0}; + (*CLI_lineOut)(&c[0]); + } + } + return false; + } +} + +// to recive a single caracter +bool CLI_charIn(char c) +{ + bool ok = true; + if ((c >= 'a') && (c <= 'z')) + { + c &= (~0x20); // convert to uppercase + } + + if ( //TODO: update list of accepted characters + ((c >= 'A') && (c <= 'Z')) + || ((c >= '0') && (c <= '9')) + || (c == ' ') + || (c == '-') + || (c == '_') + ) + { + FIFOBuffChar_put(FIFO, c); // save char in buffer + if (CLI_lineOut != NULL) + { // echo to terminal + (*CLI_lineOut)(&c); + } + } + else + { + char str[100]; + switch (c) + { + case '\n': + case '\r': + if (CLI_lineOut != NULL) + { // echo to terminal + (*CLI_lineOut)(&c); + } + FIFOBuffChar_t* fifo = FIFO; + FIFO = FIFOBuffChar_create(); + ok = tryExecute(fifo); + FIFOBuffChar_delete(fifo); + break; + + case 127: // backspace + if (FIFOBuffChar_pop(FIFO)) + { + (*CLI_lineOut)("\x1b"); + (*CLI_lineOut)("["); + (*CLI_lineOut)("D"); + } + break; + + case 27: // escape (start for arrow keys) + sprintf(&str[0], "\ninvlid char: ESC - (%i)\n", c); + for (int i=0; str[i] != 0; i++) + { + char ch[2] = {str[i], 0}; + (*CLI_lineOut)(&ch[0]); + } + break; + + default: + sprintf(&str[0], "\ninvlid char: '%c' - (%i)\n", c, c); + for (int i=0; str[i] != 0; i++) + { + char ch[2] = {str[i], 0}; + (*CLI_lineOut)(&ch[0]); + } + break; + } + } + + return ok; +} diff --git a/CLI/CLI.h b/CLI/CLI.h index e7d72e6..763dfad 100644 --- a/CLI/CLI.h +++ b/CLI/CLI.h @@ -5,10 +5,10 @@ #include "../CMDList/CMDList.h" -typedef CLI_lineOutFn(char* line) CLI_lineoutFn_t; +typedef int (*CLI_lineOutFn)(const char* line); // initilize and register the lineout print function -bool CLI_init(CLI_lineoutFn_t* lineOut, CMDList_t* cmdList); +bool CLI_init(CLI_lineOutFn lineOut, CMDList_t* cmdList); bool CLI_deinit(); // to recive a single caracter diff --git a/CMDList/printList.c b/CMDList/printList.c new file mode 100644 index 0000000..a10d073 --- /dev/null +++ b/CMDList/printList.c @@ -0,0 +1,75 @@ +#ifndef PRINTCMDLIST_H +#define PRINTCMDLIST_H + +#include "CMDList.h" +#include "printList.h" + +#include +#include +#include +#include + +void printCMD(CMDList_t* list, char c, char* indent) +{ + char* cmd; + if (list->cmd == NULL) + { + cmd = "(no cmd)"; + } + else + { + cmd = list->cmd->cmd; + } + + printf("%s%c -> %s\n", indent, c, cmd); + + char* indent_p = indent; + while (*indent_p != 0) + { + indent_p++; + } + *indent_p = ' '; + *(indent_p+1) = ' '; + *(indent_p+2) = 0; + + printCMDList(list, indent); + + *indent_p = 0; +} + +void printCMDList(CMDList_t* list, char* indent) +{ + if (indent == NULL) + { + indent = (char*)malloc(100 * sizeof(char)); + *indent = 0; + } + if (list->a != NULL) printCMD((CMDList_t*)list->a, 'a', indent); + if (list->b != NULL) printCMD((CMDList_t*)list->b, 'b', indent); + if (list->c != NULL) printCMD((CMDList_t*)list->c, 'c', indent); + if (list->d != NULL) printCMD((CMDList_t*)list->d, 'd', indent); + if (list->e != NULL) printCMD((CMDList_t*)list->e, 'e', indent); + if (list->f != NULL) printCMD((CMDList_t*)list->f, 'f', indent); + if (list->g != NULL) printCMD((CMDList_t*)list->g, 'g', indent); + if (list->h != NULL) printCMD((CMDList_t*)list->h, 'h', indent); + if (list->i != NULL) printCMD((CMDList_t*)list->i, 'i', indent); + if (list->j != NULL) printCMD((CMDList_t*)list->j, 'j', indent); + if (list->k != NULL) printCMD((CMDList_t*)list->k, 'k', indent); + if (list->l != NULL) printCMD((CMDList_t*)list->l, 'l', indent); + if (list->m != NULL) printCMD((CMDList_t*)list->m, 'm', indent); + if (list->n != NULL) printCMD((CMDList_t*)list->n, 'n', indent); + if (list->o != NULL) printCMD((CMDList_t*)list->o, 'o', indent); + if (list->p != NULL) printCMD((CMDList_t*)list->p, 'p', indent); + if (list->q != NULL) printCMD((CMDList_t*)list->q, 'q', indent); + if (list->r != NULL) printCMD((CMDList_t*)list->r, 'r', indent); + if (list->s != NULL) printCMD((CMDList_t*)list->s, 's', indent); + if (list->t != NULL) printCMD((CMDList_t*)list->t, 't', indent); + if (list->u != NULL) printCMD((CMDList_t*)list->u, 'u', indent); + if (list->v != NULL) printCMD((CMDList_t*)list->v, 'v', indent); + if (list->w != NULL) printCMD((CMDList_t*)list->w, 'w', indent); + if (list->x != NULL) printCMD((CMDList_t*)list->x, 'x', indent); + if (list->y != NULL) printCMD((CMDList_t*)list->y, 'y', indent); + if (list->z != NULL) printCMD((CMDList_t*)list->z, 'z', indent); +} + +#endif diff --git a/CMDList/printList.h b/CMDList/printList.h new file mode 100644 index 0000000..59856e0 --- /dev/null +++ b/CMDList/printList.h @@ -0,0 +1,8 @@ +#ifndef PRINTCMDLIST_H +#define PRINTCMDLIST_H + +#include "CMDList.h" + +extern void printCMDList(CMDList_t* list, char* indent); + +#endif diff --git a/FIFOBuff/FIFOBuffChar.c b/FIFOBuff/FIFOBuffChar.c index 5756401..6f41aef 100644 --- a/FIFOBuff/FIFOBuffChar.c +++ b/FIFOBuff/FIFOBuffChar.c @@ -1,9 +1,8 @@ +#include "FIFOBuffChar.h" + #include #include #include -#include "FIFOBuffChar.h" - - bool FIFOBuffChar_put(FIFOBuffChar_t *fifo, char i) // Change the function parameters to match the declaration { @@ -122,6 +121,48 @@ bool FIFOBuffChar_get(FIFOBuffChar_t *fifo, char *p) // Change the function para return ok; } +bool FIFOBuffChar_pop(FIFOBuffChar_t *fifo) +{ + bool ok = true; + + switch (fifo->size){ + case 0: // buffer is empty + ok = false; + break; + + case 1: // singel item in buffer + // make buffer empty + free(fifo->FirstEl_p); + fifo->FirstEl_p = NULL; + fifo->LastEl_p = NULL; + fifo->size = 0; + ok = true; + break; + + default: // buffer is at least 2 element big + // find the second last element + FIFOBuffChar_element_t* secondLastEl = fifo->FirstEl_p; + while ( + secondLastEl->nextElement != fifo->LastEl_p + && ((FIFOBuffChar_element_t*)secondLastEl->nextElement)->nextElement != NULL + ){ + secondLastEl = secondLastEl->nextElement; + } + + // remove last element + free(fifo->LastEl_p); + + // update chain + secondLastEl->nextElement = NULL; + fifo->LastEl_p = secondLastEl; + fifo->size--; + ok = true; + break; + } + + return ok; +} + bool FIFOBuffChar_is_full(FIFOBuffChar_t *fifo) { return fifo->full; diff --git a/FIFOBuff/FIFOBuffChar.h b/FIFOBuff/FIFOBuffChar.h index b6eb1b3..9671b9d 100644 --- a/FIFOBuff/FIFOBuffChar.h +++ b/FIFOBuff/FIFOBuffChar.h @@ -32,7 +32,10 @@ extern bool FIFOBuffChar_put(FIFOBuffChar_t *fifo, char i); // get value from buffer and writes it to *p if buffer not empty // returns true on success or false otherways -extern bool FIFOBuffChar_get(FIFOBuffChar_t *fifo, char *p); //moet dit "char" zijn of "uint8_t" +extern bool FIFOBuffChar_get(FIFOBuffChar_t *fifo, char *p); + +// pop last added value from the buffer +extern bool FIFOBuffChar_pop(FIFOBuffChar_t *fifo); // returns false if last put fails to gain memory and no get is called afterwards or true otherwise extern bool FIFOBuffChar_is_full(FIFOBuffChar_t *fifo);