From 3dbe121389193508693ed2424504ba8b5986a8c4 Mon Sep 17 00:00:00 2001 From: FReenen Date: Sat, 6 Apr 2024 22:14:53 +0200 Subject: [PATCH 1/5] first draft of CLI --- CLI/CLI.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 CLI/CLI.c diff --git a/CLI/CLI.c b/CLI/CLI.c new file mode 100644 index 0000000..8fbe350 --- /dev/null +++ b/CLI/CLI.c @@ -0,0 +1,95 @@ +#include "CLI.h" + +#include "../FIFOBuffChar.h" + +void (*CLI_lineOut)(char* line); +CMDList_t* CMDList; +FIFOBuffChar_t* FIFO; + +// initilize and register the lineout print function +bool CLI_init(CLI_lineoutFn_t* lineOut, CMDList_t* cmdList) +{ + CLI_lineOut = lineOut; + CMDList = cmdList; + + FIFO = FIFOBuffChar_create(); +} + +bool CLI_deinit() +{ + CLI_lineOut = NULL; + CMDList = NULL; + + FIFOBuffChar_delete(FIFO); +} + +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); + return true; + } + else + { + return false; + } +} + +// to recive a single caracter +bool CLI_charIn(char c) +{ + 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 + (*CLI_lineOut)(&c); // echo to terminal + } + else + { + switch (c) + { + case '\n': + case '\r': + (*CLI_lineOut)(&c); // echo to terminal + FIFOBuffChar_t* fifo = FIFO; + FIFO = FIFOBuffChar_create(); + tryExecute(fifo); + FIFOBuffChar_delete(fifo); + break; + + //TODO: add hire backspace and arrow detection + default: + break; + } + } +} From feec2a0a91f1987eccb28d88cf5282b4b85fbaa1 Mon Sep 17 00:00:00 2001 From: FReenen Date: Mon, 8 Apr 2024 13:39:24 +0200 Subject: [PATCH 2/5] update CLI --- CLI/CLI.c | 31 +++++++++++++------ CLI/CLI.h | 4 +-- CMDList/printList.c | 75 +++++++++++++++++++++++++++++++++++++++++++++ CMDList/printList.h | 8 +++++ 4 files changed, 107 insertions(+), 11 deletions(-) create mode 100644 CMDList/printList.c create mode 100644 CMDList/printList.h diff --git a/CLI/CLI.c b/CLI/CLI.c index 8fbe350..f2021f2 100644 --- a/CLI/CLI.c +++ b/CLI/CLI.c @@ -1,13 +1,16 @@ #include "CLI.h" -#include "../FIFOBuffChar.h" +#include +#include + +#include "../FIFOBuff/FIFOBuffChar.h" void (*CLI_lineOut)(char* line); CMDList_t* CMDList; FIFOBuffChar_t* FIFO; // 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) { CLI_lineOut = lineOut; CMDList = cmdList; @@ -42,7 +45,7 @@ char* fifoToString(FIFOBuffChar_t* fifo) int tryExecute(FIFOBuffChar_t* fifo) { char* line = fifoToString(fifo); - CMD_t cmd = CMDList_get(CMDList, line); + CMD_t* cmd = CMDList_get(CMDList, line); if (cmd != NULL) { @@ -51,6 +54,7 @@ int tryExecute(FIFOBuffChar_t* fifo) } else { + printf("command not found: %s\n", line); return false; } } @@ -58,6 +62,7 @@ int tryExecute(FIFOBuffChar_t* fifo) // to recive a single caracter bool CLI_charIn(char c) { + bool ok = true; if ((c >= 'a') && (c <= 'z')) { c &= (~0x20); // convert to uppercase @@ -66,13 +71,16 @@ bool CLI_charIn(char c) if ( //TODO: update list of accepted characters ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9')) - || (c = ' ') - || (c = '-') - || (c = '_') + || (c == ' ') + || (c == '-') + || (c == '_') ) { FIFOBuffChar_put(FIFO, c); // save char in buffer - (*CLI_lineOut)(&c); // echo to terminal + if (CLI_lineOut != NULL) + { // echo to terminal + (*CLI_lineOut)(&c); + } } else { @@ -80,10 +88,13 @@ bool CLI_charIn(char c) { case '\n': case '\r': - (*CLI_lineOut)(&c); // echo to terminal + if (CLI_lineOut != NULL) + { // echo to terminal + (*CLI_lineOut)(&c); + } FIFOBuffChar_t* fifo = FIFO; FIFO = FIFOBuffChar_create(); - tryExecute(fifo); + ok = tryExecute(fifo); FIFOBuffChar_delete(fifo); break; @@ -92,4 +103,6 @@ bool CLI_charIn(char c) 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 From b08f1afe7f9445cf1ea0d758971f8efa41a3089d Mon Sep 17 00:00:00 2001 From: FReenen Date: Mon, 8 Apr 2024 14:36:53 +0200 Subject: [PATCH 3/5] add pop function in FIFOBuff --- FIFOBuff/FIFOBuffChar.c | 28 ++++++++++++++++++++++++++++ FIFOBuff/FIFOBuffChar.h | 5 ++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/FIFOBuff/FIFOBuffChar.c b/FIFOBuff/FIFOBuffChar.c index 5756401..9b5fa98 100644 --- a/FIFOBuff/FIFOBuffChar.c +++ b/FIFOBuff/FIFOBuffChar.c @@ -122,6 +122,34 @@ bool FIFOBuffChar_get(FIFOBuffChar_t *fifo, char *p) // Change the function para return ok; } +bool FIFOBuffChar_pop(FIFOBuffChar_t *fifo) +{ + bool ok = true; + + if (fifo->FirstEl_p == NULL) + { // buffer is empty + ok = false; + } + else + { // there is data in the buffer + // find the second last element + FIFOBuffChar_element_t* secondLastEl; = fifo->FirstEl_p; + while (secondLastEl->nextElement != fifo->LastEl_p) + { + secondLastEl = secondLastEl->nextElement; + } + + // remove last element + free(fifo->LastEl_p); + + // update chain + secondLastEl->nextElement == NULL; + fifo->LastEl_p = secondLastEl; + } + + 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); From e6d9bb1da6d5a249d412e2cad868de4eb7673d2f Mon Sep 17 00:00:00 2001 From: FReenen Date: Mon, 8 Apr 2024 14:37:21 +0200 Subject: [PATCH 4/5] update CLI --- CLI/CLI.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/CLI/CLI.c b/CLI/CLI.c index f2021f2..918fcc0 100644 --- a/CLI/CLI.c +++ b/CLI/CLI.c @@ -5,7 +5,7 @@ #include "../FIFOBuff/FIFOBuffChar.h" -void (*CLI_lineOut)(char* line); +CLI_lineOutFn CLI_lineOut; CMDList_t* CMDList; FIFOBuffChar_t* FIFO; @@ -16,6 +16,14 @@ bool CLI_init(CLI_lineOutFn lineOut, CMDList_t* cmdList) CMDList = cmdList; FIFO = FIFOBuffChar_create(); + + if (CLI_lineOut != NULL) + { + (*CLI_lineOut)(">"); + (*CLI_lineOut)(" "); + } + + return true; } bool CLI_deinit() @@ -24,6 +32,7 @@ bool CLI_deinit() CMDList = NULL; FIFOBuffChar_delete(FIFO); + return true; } char* fifoToString(FIFOBuffChar_t* fifo) @@ -50,11 +59,27 @@ int tryExecute(FIFOBuffChar_t* fifo) if (cmd != NULL) { (*(cmd->fn))(line); + + if (CLI_lineOut != NULL) + { + (*CLI_lineOut)("\n"); + (*CLI_lineOut)(">"); + (*CLI_lineOut)(" "); + } return true; } else { - printf("command not found: %s\n", line); + if (CLI_lineOut != NULL) + { + char err[100]; + sprintf(&err, "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; } } @@ -84,6 +109,7 @@ bool CLI_charIn(char c) } else { + char str[100]; switch (c) { case '\n': @@ -97,9 +123,29 @@ bool CLI_charIn(char c) ok = tryExecute(fifo); FIFOBuffChar_delete(fifo); break; + + case 127: // backspace + (*CLI_lineOut)("\x1b"); + (*CLI_lineOut)("["); + (*CLI_lineOut)("D"); + break; + + case 27: // escape (start for arrow keys) + sprintf(&str, "\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; - //TODO: add hire backspace and arrow detection default: + sprintf(&str, "\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; } } From 24738ebeea98df71f5f9a2b1b8992eda288f3725 Mon Sep 17 00:00:00 2001 From: FReenen Date: Mon, 8 Apr 2024 15:08:10 +0200 Subject: [PATCH 5/5] fix pop from FIFOBuff and fix warnings for CLI --- CLI/CLI.c | 17 +++++++------ FIFOBuff/FIFOBuffChar.c | 53 +++++++++++++++++++++++++---------------- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/CLI/CLI.c b/CLI/CLI.c index 918fcc0..050ce30 100644 --- a/CLI/CLI.c +++ b/CLI/CLI.c @@ -2,6 +2,7 @@ #include #include +#include #include "../FIFOBuff/FIFOBuffChar.h" @@ -62,7 +63,6 @@ int tryExecute(FIFOBuffChar_t* fifo) if (CLI_lineOut != NULL) { - (*CLI_lineOut)("\n"); (*CLI_lineOut)(">"); (*CLI_lineOut)(" "); } @@ -73,7 +73,7 @@ int tryExecute(FIFOBuffChar_t* fifo) if (CLI_lineOut != NULL) { char err[100]; - sprintf(&err, "command not found: %s\n> ", line); + sprintf(&err[0], "command not found: %s\n> ", line); for (int i=0; err[i] != 0; i++) { char c[2] = {err[i], 0}; @@ -125,13 +125,16 @@ bool CLI_charIn(char c) break; case 127: // backspace - (*CLI_lineOut)("\x1b"); - (*CLI_lineOut)("["); - (*CLI_lineOut)("D"); + if (FIFOBuffChar_pop(FIFO)) + { + (*CLI_lineOut)("\x1b"); + (*CLI_lineOut)("["); + (*CLI_lineOut)("D"); + } break; case 27: // escape (start for arrow keys) - sprintf(&str, "\ninvlid char: ESC - (%i)\n", c); + sprintf(&str[0], "\ninvlid char: ESC - (%i)\n", c); for (int i=0; str[i] != 0; i++) { char ch[2] = {str[i], 0}; @@ -140,7 +143,7 @@ bool CLI_charIn(char c) break; default: - sprintf(&str, "\ninvlid char: '%c' - (%i)\n", c, c); + sprintf(&str[0], "\ninvlid char: '%c' - (%i)\n", c, c); for (int i=0; str[i] != 0; i++) { char ch[2] = {str[i], 0}; diff --git a/FIFOBuff/FIFOBuffChar.c b/FIFOBuff/FIFOBuffChar.c index 9b5fa98..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 { @@ -126,25 +125,39 @@ bool FIFOBuffChar_pop(FIFOBuffChar_t *fifo) { bool ok = true; - if (fifo->FirstEl_p == NULL) - { // buffer is empty - ok = false; - } - else - { // there is data in the buffer - // find the second last element - FIFOBuffChar_element_t* secondLastEl; = fifo->FirstEl_p; - while (secondLastEl->nextElement != fifo->LastEl_p) - { - secondLastEl = secondLastEl->nextElement; - } + switch (fifo->size){ + case 0: // buffer is empty + ok = false; + break; - // remove last element - free(fifo->LastEl_p); + 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; - // update chain - secondLastEl->nextElement == NULL; - fifo->LastEl_p = secondLastEl; + 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;