Compare commits
40 Commits
Dennis_buf
...
multie-cli
| Author | SHA1 | Date | |
|---|---|---|---|
|
42aec53edb
|
|||
|
8f71535dfd
|
|||
|
8261e605bc
|
|||
|
f08c8e5788
|
|||
|
09ae51070b
|
|||
|
|
34f830bd1d | ||
|
|
7eab42c3b9 | ||
| 522c14710e | |||
| 3ed2ab432b | |||
| 8ddf982e78 | |||
|
|
91f3c8461e | ||
| 9c30ea4ef1 | |||
| 62f45f7256 | |||
|
|
92eb70f4b5 | ||
|
|
cb7b573eed | ||
|
|
04eebfc3fc | ||
|
|
5ed7154183 | ||
|
|
51c1c28756 | ||
|
|
cd72e519a1 | ||
| df2129a1bb | |||
| e7ea706157 | |||
| 3b3761faa9 | |||
|
|
edc09d505b | ||
|
|
ee501b17ce | ||
|
|
bb79053b1e | ||
|
|
2495ac6ee6 | ||
|
|
1d033c88fb | ||
| 0eed939e87 | |||
| 73c0013ee9 | |||
| 8f8000d9ca | |||
| d4edc2cd8f | |||
| c8854931b5 | |||
| e34fe9f213 | |||
| a1fef05168 | |||
| c49ed49a0b | |||
| bbbc0c4683 | |||
| dea1c8ae52 | |||
| e267e6f907 | |||
| 9a437218a2 | |||
| 64a72b70ef |
315
CLI/CLI.c
315
CLI/CLI.c
@@ -3,36 +3,56 @@
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "../FIFOBuff/FIFOBuffChar.h"
|
||||
|
||||
CLI_charOutFn CLI_charOut;
|
||||
CMDList_t* CMDList;
|
||||
FIFOBuffChar_t* FIFO;
|
||||
|
||||
// initilize and register the lineout print function
|
||||
bool CLI_init(CLI_charOutFn lineOut, CMDList_t* cmdList)
|
||||
void CLI_charOut_save(CLI_t* cli, char ch)
|
||||
{
|
||||
CLI_charOut = lineOut;
|
||||
CMDList = cmdList;
|
||||
|
||||
FIFO = FIFOBuffChar_create();
|
||||
|
||||
if (CLI_charOut != NULL)
|
||||
if (cli->CLI_charOut != NULL)
|
||||
{
|
||||
(*CLI_charOut)(">");
|
||||
(*CLI_charOut)(" ");
|
||||
// create string of size one to be compatable with string print function
|
||||
char c[2] = {ch, 0};
|
||||
(*(cli->CLI_charOut))(&c[0]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CLI_deinit()
|
||||
void CLI_stringOut(CLI_t* cli, char* str)
|
||||
{
|
||||
CLI_charOut = NULL;
|
||||
CMDList = NULL;
|
||||
for (; *str != 0; str++)
|
||||
{
|
||||
CLI_charOut_save(cli, *str);
|
||||
}
|
||||
}
|
||||
|
||||
FIFOBuffChar_delete(FIFO);
|
||||
// initilize and register the lineout print function
|
||||
CLI_t CLI_init(CLI_charOutFn lineOut, CMDList_t* cmdList)
|
||||
{
|
||||
CLI_t cli;
|
||||
cli.CLI_charOut = lineOut;
|
||||
cli.CMDList = cmdList;
|
||||
cli.CLI_State = CLI_State_Default;
|
||||
|
||||
cli.FIFO = FIFOBuffChar_create();
|
||||
#ifdef HISTORY
|
||||
cli.History = History_init();
|
||||
#endif
|
||||
|
||||
if (cli.CLI_charOut != NULL)
|
||||
{
|
||||
CLI_stringOut(&cli, (char*)"> ");
|
||||
}
|
||||
|
||||
return cli;
|
||||
}
|
||||
|
||||
bool CLI_deinit(CLI_t* cli)
|
||||
{
|
||||
cli->CLI_charOut = NULL;
|
||||
cli->CMDList = NULL;
|
||||
|
||||
FIFOBuffChar_delete(cli->FIFO);
|
||||
#ifdef HISTORY
|
||||
History_deinit(cli->History, true);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -41,7 +61,8 @@ char* fifoToString(FIFOBuffChar_t* fifo)
|
||||
char* out = malloc(fifo->size + 1);
|
||||
char* write_p = out;
|
||||
|
||||
for (int i = fifo->size; i > 0; i--)
|
||||
int i;
|
||||
for (i = fifo->size; i > 0; i--)
|
||||
{
|
||||
FIFOBuffChar_get(fifo, write_p);
|
||||
write_p++;
|
||||
@@ -52,110 +73,236 @@ char* fifoToString(FIFOBuffChar_t* fifo)
|
||||
return out;
|
||||
}
|
||||
|
||||
int tryExecute(FIFOBuffChar_t* fifo)
|
||||
#ifdef HISTORY
|
||||
void CLI_PrintHistory(CLI_t* cli)
|
||||
{
|
||||
char** historyList;
|
||||
int ret = History_getFullHistory(cli->History, &historyList);
|
||||
int i;
|
||||
char str[150];
|
||||
if (ret >= 0)
|
||||
{
|
||||
for (i=0; *(historyList + i) != NULL; i++)
|
||||
{
|
||||
snprintf(&str[0], 150, "%03i: %s\n", i, *(historyList + i));
|
||||
CLI_stringOut(cli, &str[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(&str[0], 150, "ERROR: get history returnd: %i\n", ret);
|
||||
CLI_stringOut(cli, &str[0]);
|
||||
}
|
||||
free(historyList);
|
||||
}
|
||||
|
||||
void historyPrevius(CLI_t* cli)
|
||||
{
|
||||
char* line;
|
||||
int i;
|
||||
if (
|
||||
(History_getCurrPos(cli->History) == History_getSize(cli->History))
|
||||
&& (FIFOBuffChar_getSize(cli->FIFO) > 0)
|
||||
)
|
||||
{
|
||||
// add current text to end of history
|
||||
line = fifoToString(cli->FIFO);
|
||||
History_put(cli->History, line);
|
||||
for (i=0; *(line + i) != '\0'; i++)
|
||||
{
|
||||
CLI_stringOut(cli, (char*)"\x1b[D \x1b[D");
|
||||
}
|
||||
History_getPrev(cli->History, &line);
|
||||
}
|
||||
|
||||
// empty current line
|
||||
while (FIFOBuffChar_getSize(cli->FIFO) > 0)
|
||||
{
|
||||
CLI_stringOut(cli, (char*)"\x1b[D \x1b[D");
|
||||
FIFOBuffChar_pop(cli->FIFO);
|
||||
}
|
||||
|
||||
// get previus command
|
||||
int ret = History_getPrev(cli->History, &line);
|
||||
|
||||
// write line
|
||||
if ((ret >= 0) && (line != NULL))
|
||||
{
|
||||
int i;
|
||||
for (i=0; *(line + i) != '\0'; i++)
|
||||
{
|
||||
CLI_charIn(cli, *(line + i));
|
||||
}
|
||||
}
|
||||
}
|
||||
void historyNext(CLI_t* cli)
|
||||
{
|
||||
char* line;
|
||||
// empty current line
|
||||
while (FIFOBuffChar_getSize(cli->FIFO) > 0)
|
||||
{
|
||||
CLI_stringOut(cli, (char*)"\x1b[D \x1b[D");
|
||||
FIFOBuffChar_pop(cli->FIFO);
|
||||
}
|
||||
|
||||
// get next command
|
||||
int ret = History_getNext(cli->History, &line);
|
||||
|
||||
// write line
|
||||
if ((ret >= 0) && (line != NULL))
|
||||
{
|
||||
int i;
|
||||
for (i=0; *(line + i) != '\0'; i++)
|
||||
{
|
||||
CLI_charIn(cli, *(line + i));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int tryExecute(CLI_t* cli, FIFOBuffChar_t* fifo)
|
||||
{
|
||||
int ret = 0;
|
||||
CMD_t* cmd = NULL;
|
||||
char* line = fifoToString(fifo);
|
||||
CMD_t* cmd = CMDList_get(CMDList, line);
|
||||
if (*line == '\0')
|
||||
{ // empty line
|
||||
ret = 1;
|
||||
CLI_stringOut(cli, (char*)"> ");
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd = CMDList_get(cli->CMDList, line);
|
||||
}
|
||||
|
||||
if (cmd != NULL)
|
||||
{
|
||||
(*(cmd->fn))(line);
|
||||
#ifdef HISTORY
|
||||
History_put(cli->History, line);
|
||||
#endif
|
||||
int ret = (*(cmd->fn))(line, cli);
|
||||
|
||||
if (CLI_charOut != NULL)
|
||||
if (ret != INT_MIN)
|
||||
{
|
||||
(*CLI_charOut)(">");
|
||||
(*CLI_charOut)(" ");
|
||||
CLI_stringOut(cli, (char*)"> ");
|
||||
}
|
||||
return true;
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CLI_charOut != NULL)
|
||||
else if (ret == 0)
|
||||
{
|
||||
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_charOut)(&c[0]);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
CLI_stringOut(cli, &err[0]);
|
||||
ret = -1;
|
||||
|
||||
#ifdef HISTORY
|
||||
free(line);
|
||||
#endif
|
||||
}
|
||||
#ifndef HISTORY
|
||||
free(line);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
// to recive a single caracter
|
||||
bool CLI_charIn(char c)
|
||||
bool CLI_charIn(CLI_t* cli, char c)
|
||||
{
|
||||
bool ok = true;
|
||||
if ((c >= 'a') && (c <= 'z'))
|
||||
char str[100];
|
||||
char C = c;
|
||||
if ((C >= 'a') && (C <= 'z'))
|
||||
{
|
||||
c &= (~0x20); // convert to uppercase
|
||||
C &= (~0x20); // convert to uppercase
|
||||
}
|
||||
|
||||
if ( //TODO: update list of accepted characters
|
||||
((c >= 'A') && (c <= 'Z'))
|
||||
|| ((c >= '0') && (c <= '9'))
|
||||
|| (c == ' ')
|
||||
|| (c == '-')
|
||||
|| (c == '_')
|
||||
)
|
||||
switch (cli->CLI_State)
|
||||
{
|
||||
FIFOBuffChar_put(FIFO, c); // save char in buffer
|
||||
if (CLI_charOut != NULL)
|
||||
{ // echo to terminal
|
||||
(*CLI_charOut)(&c);
|
||||
}
|
||||
case CLI_State_Default:
|
||||
if ((C >= ' ') && (C <= '~')) // see ascii table
|
||||
{
|
||||
FIFOBuffChar_put(cli->FIFO, C); // save char in buffer
|
||||
CLI_charOut_save(cli, c);
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[100];
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
case '\r':
|
||||
if (CLI_charOut != NULL)
|
||||
{ // echo to terminal
|
||||
(*CLI_charOut)(&c);
|
||||
}
|
||||
FIFOBuffChar_t* fifo = FIFO;
|
||||
FIFO = FIFOBuffChar_create();
|
||||
ok = tryExecute(fifo);
|
||||
// echo to terminal
|
||||
CLI_charOut_save(cli, c);
|
||||
// copy buffer and create new buffer
|
||||
FIFOBuffChar_t* fifo = cli->FIFO;
|
||||
cli->FIFO = FIFOBuffChar_create();
|
||||
// execute command if valid
|
||||
ok = (tryExecute(cli, fifo) == 0);
|
||||
// delete old buffer
|
||||
FIFOBuffChar_delete(fifo);
|
||||
break;
|
||||
|
||||
case 127: // backspace
|
||||
if (FIFOBuffChar_pop(FIFO))
|
||||
{
|
||||
(*CLI_charOut)("\x1b");
|
||||
(*CLI_charOut)("[");
|
||||
(*CLI_charOut)("D");
|
||||
(*CLI_charOut)(" ");
|
||||
(*CLI_charOut)("\x1b");
|
||||
(*CLI_charOut)("[");
|
||||
(*CLI_charOut)("D");
|
||||
case 8:
|
||||
case 127: // delete (backspace)
|
||||
if (FIFOBuffChar_pop(cli->FIFO))
|
||||
{ // pop something of the buffer
|
||||
CLI_stringOut(cli, (char*)"\x1b[D \x1b[D"); // "<left arrow><space><left arrow>"
|
||||
}
|
||||
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_charOut)(&ch[0]);
|
||||
}
|
||||
cli->CLI_State = CLI_State_Esc;
|
||||
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_charOut)(&ch[0]);
|
||||
}
|
||||
CLI_stringOut(cli, &str[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CLI_State_Esc:
|
||||
if (c == '[')
|
||||
{
|
||||
cli->CLI_State = CLI_State_ANSIVT100;
|
||||
}
|
||||
else
|
||||
{
|
||||
cli->CLI_State = CLI_State_Default;
|
||||
}
|
||||
break;
|
||||
|
||||
case CLI_State_ANSIVT100:
|
||||
switch (c)
|
||||
{
|
||||
#ifdef HISTORY
|
||||
case 'A': // arrow up
|
||||
cli->CLI_State = CLI_State_Default;
|
||||
historyPrevius(cli);
|
||||
break;
|
||||
case 'B': // arrow down
|
||||
cli->CLI_State = CLI_State_Default;
|
||||
historyNext(cli);
|
||||
break;
|
||||
case 'C': // arrow right
|
||||
CLI_stringOut(cli, (char*)"(key: arrow right)");
|
||||
cli->CLI_State = CLI_State_Default;
|
||||
break;
|
||||
case 'D': // arrow left
|
||||
CLI_stringOut(cli, (char*)"(key: arrow left)");
|
||||
cli->CLI_State = CLI_State_Default;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
// only to back on on alpha char. seems to be the with all '\x1d[' commands
|
||||
if ((C >= 'A') && (C <= 'Z'))
|
||||
{
|
||||
cli->CLI_State = CLI_State_Default;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
37
CLI/CLI.h
37
CLI/CLI.h
@@ -3,16 +3,43 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../CMDList/CMDList.h"
|
||||
#include <config.h>
|
||||
|
||||
typedef int (*CLI_charOutFn)(const char* line);
|
||||
#include "../CMDList/CMDList.h"
|
||||
#include "../FIFOBuff/FIFOBuffChar.h"
|
||||
#ifdef HISTORY
|
||||
#include "../History/history.h"
|
||||
#endif
|
||||
|
||||
typedef int (*CLI_charOutFn)(const char* c);
|
||||
typedef enum {
|
||||
CLI_State_Default,
|
||||
CLI_State_Esc,
|
||||
CLI_State_ANSIVT100
|
||||
} CLI_State_t;
|
||||
|
||||
typedef struct CLI {
|
||||
CLI_charOutFn CLI_charOut;
|
||||
CMDList_t* CMDList;
|
||||
FIFOBuffChar_t* FIFO;
|
||||
#ifdef HISTORY
|
||||
History_t* History;
|
||||
#endif
|
||||
CLI_State_t CLI_State;
|
||||
} CLI_t;
|
||||
|
||||
// initilize and register the lineout print function
|
||||
bool CLI_init(CLI_charOutFn lineOut, CMDList_t* cmdList);
|
||||
bool CLI_deinit();
|
||||
CLI_t CLI_init(CLI_charOutFn lineOut, CMDList_t* cmdList);
|
||||
bool CLI_deinit(CLI_t* cli);
|
||||
|
||||
#ifdef HISTORY
|
||||
extern void CLI_PrintHistory(CLI_t* cli);
|
||||
#endif
|
||||
|
||||
// to recive a single caracter
|
||||
bool CLI_charIn(char c);
|
||||
bool CLI_charIn(CLI_t* cli, char c);
|
||||
void CLI_charOut_save(CLI_t* cli, char ch);
|
||||
void CLI_stringOut(CLI_t* cli, char* str);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -8,46 +8,43 @@
|
||||
// initilises a CMDList_t with all NULL pointers
|
||||
CMDList_t* CMDList_init()
|
||||
{
|
||||
CMDList_t *list = malloc(sizeof(CMDList_t));
|
||||
CMDList_t* list = malloc(sizeof(CMDList_t));
|
||||
memset(list, 0, sizeof(CMDList_t));
|
||||
return list;
|
||||
}
|
||||
|
||||
// free up the full tree from memory
|
||||
// does not free up the commands
|
||||
int CMDList_deinit(CMDList_t *list)
|
||||
int CMDList_deinit(CMDList_t* list)
|
||||
{
|
||||
CMDList_t** list_p = (CMDList_t**)list;
|
||||
// printf("deinit %p\n", (void*)list);
|
||||
// printf("deinit e %p\n", list->e);
|
||||
|
||||
for (int i = 0; i < 26; i++)
|
||||
int i;
|
||||
for (i = 0; i < 26; i++)
|
||||
{
|
||||
if (*(list_p + i) != NULL)
|
||||
{
|
||||
// printf("deinit %i\n", i);
|
||||
CMDList_deinit(*(list_p + i));
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: fix "free(): invalid pointer"
|
||||
// free(list);
|
||||
free(list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// add a command in the command tree
|
||||
int CMDList_add(CMDList_t *list, CMD_t* cmd)
|
||||
int CMDList_add(CMDList_t *list, CMD_t* cmd, char* cmdName)
|
||||
{
|
||||
int returnCode = 0;
|
||||
char* read_p = cmd->cmd;
|
||||
char* read_p = cmdName;
|
||||
CMDList_t** list_p = (CMDList_t**)list;
|
||||
|
||||
if (read_p == NULL)
|
||||
{ // cmd is missing a string for the commnad name
|
||||
returnCode = -1;
|
||||
{
|
||||
read_p = cmd->cmd;
|
||||
}
|
||||
|
||||
while (returnCode == 0)
|
||||
while (returnCode >= 0)
|
||||
{
|
||||
char c = *read_p & (~0x20); // convert to uppercase
|
||||
if ((c >= 'A') && (c <= 'Z'))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
typedef struct CMD_t {
|
||||
char* cmd;
|
||||
void (*fn)(char* line);
|
||||
int (*fn)(char* line, void* cli);
|
||||
} CMD_t;
|
||||
|
||||
typedef struct CMDList_s {
|
||||
@@ -46,7 +46,7 @@ extern CMDList_t* CMDList_init();
|
||||
extern int CMDList_deinit(CMDList_t *list);
|
||||
|
||||
// add a command in the command tree
|
||||
extern int CMDList_add(CMDList_t *list, CMD_t* cmd);
|
||||
extern int CMDList_add(CMDList_t *list, CMD_t* cmd, char* cmdName);
|
||||
|
||||
// search command in the tree
|
||||
extern CMD_t* CMDList_get(CMDList_t *list, char* cmd);
|
||||
|
||||
@@ -6,6 +6,13 @@ add_library(FIFOBuffChar FIFOBuff/FIFOBuffChar.c)
|
||||
add_library(CMDList CMDList/CMDList.c)
|
||||
add_library(CMDListPrint CMDList/printList.c)
|
||||
|
||||
# History
|
||||
add_library(history History/History.c)
|
||||
|
||||
# CLI
|
||||
add_library(CLI CLI/CLI.c)
|
||||
target_link_libraries(CLI CMDList FIFOBuffChar)
|
||||
target_link_libraries(CLI CMDList FIFOBuffChar history)
|
||||
|
||||
add_library(CLI_History CLI/CLI.c)
|
||||
target_link_libraries(CLI_History CMDList FIFOBuffChar history)
|
||||
target_compile_definitions(CLI_History PRIVATE HISTORY)
|
||||
|
||||
@@ -141,6 +141,7 @@ bool FIFOBuffChar_pop(FIFOBuffChar_t *fifo)
|
||||
|
||||
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
|
||||
@@ -159,6 +160,7 @@ bool FIFOBuffChar_pop(FIFOBuffChar_t *fifo)
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
210
History/History.c
Normal file
210
History/History.c
Normal file
@@ -0,0 +1,210 @@
|
||||
#include "history.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
History_t* History_init()
|
||||
{
|
||||
History_t* history = malloc(sizeof(History_t));
|
||||
|
||||
if (history != NULL) {
|
||||
history->FirstEl_p = NULL;
|
||||
history->LastEl_p = NULL;
|
||||
history->CurrEl_p = NULL;
|
||||
history->size = 0;
|
||||
}
|
||||
|
||||
return history;
|
||||
}
|
||||
|
||||
|
||||
int History_deinit(History_t* history, bool freeLines)
|
||||
{
|
||||
// Check if the buffer there is something in the buffer
|
||||
if (history->FirstEl_p == NULL)
|
||||
{
|
||||
// Delete all elements in the buffer
|
||||
History_element_t* el = history->FirstEl_p;
|
||||
while (el != NULL)
|
||||
{
|
||||
History_element_t* nextEl = el->nextEl_p;
|
||||
if (freeLines)
|
||||
{
|
||||
free(el->line);
|
||||
}
|
||||
free(el);
|
||||
el = nextEl;
|
||||
}
|
||||
}
|
||||
|
||||
free(history);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int History_put(History_t *history, char* line)
|
||||
{
|
||||
int retCode;
|
||||
if ((history->LastEl_p == NULL) && (history->FirstEl_p == NULL))
|
||||
{
|
||||
// buffer is empty. add first element
|
||||
history->FirstEl_p = malloc(sizeof(History_element_t));
|
||||
if (history->FirstEl_p != NULL)
|
||||
{
|
||||
history->FirstEl_p->line = line;
|
||||
history->FirstEl_p->prevEl_p = NULL;
|
||||
history->FirstEl_p->nextEl_p = NULL;
|
||||
|
||||
history->LastEl_p = history->FirstEl_p;
|
||||
history->size = 1;
|
||||
retCode = 0;
|
||||
}
|
||||
else
|
||||
{ // failt to allocate memory
|
||||
retCode = -1;
|
||||
}
|
||||
}
|
||||
else if ((history->LastEl_p != NULL) && (history->FirstEl_p != NULL))
|
||||
{
|
||||
// add element to exsiting buffer
|
||||
History_element_t* el = malloc(sizeof(History_element_t));
|
||||
if (el != NULL)
|
||||
{
|
||||
el->line = line;
|
||||
el->prevEl_p = history->LastEl_p;
|
||||
el->nextEl_p = NULL;
|
||||
history->LastEl_p->nextEl_p = el;
|
||||
history->LastEl_p = el;
|
||||
history->size++;
|
||||
retCode = 0;
|
||||
}
|
||||
else
|
||||
{ // failt to allocate memory
|
||||
retCode = -2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
retCode = -3;
|
||||
}
|
||||
|
||||
if (retCode >= 0)
|
||||
{
|
||||
// reset current pointer
|
||||
history->CurrEl_p = NULL;
|
||||
}
|
||||
|
||||
return retCode;
|
||||
}
|
||||
|
||||
int History_getPrev(History_t* history, char** line)
|
||||
{
|
||||
int retCode;
|
||||
if (history->CurrEl_p == NULL)
|
||||
{
|
||||
history->CurrEl_p = history->LastEl_p;
|
||||
}
|
||||
else if (history->CurrEl_p->prevEl_p != NULL)
|
||||
{
|
||||
history->CurrEl_p = history->CurrEl_p->prevEl_p;
|
||||
}
|
||||
else
|
||||
{ // no previus line
|
||||
retCode = -2;
|
||||
}
|
||||
|
||||
if (history->CurrEl_p != NULL)
|
||||
{
|
||||
*line = history->CurrEl_p->line;
|
||||
retCode = 0;
|
||||
}
|
||||
else
|
||||
{ // no items in history?
|
||||
*line = NULL;
|
||||
retCode = -1;
|
||||
}
|
||||
return retCode;
|
||||
}
|
||||
|
||||
int History_getNext(History_t* history, char** line)
|
||||
{
|
||||
int retCode;
|
||||
if (history->CurrEl_p != NULL)
|
||||
{
|
||||
history->CurrEl_p = history->CurrEl_p->nextEl_p;
|
||||
}
|
||||
|
||||
if (history->CurrEl_p != NULL)
|
||||
{
|
||||
*line = history->CurrEl_p->line;
|
||||
retCode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*line = NULL;
|
||||
retCode = -1;
|
||||
}
|
||||
return retCode;
|
||||
}
|
||||
|
||||
int History_getFullHistory(History_t* history, char*** list)
|
||||
{
|
||||
int retCode = 0;
|
||||
*list = malloc(sizeof(char**) * (History_getSize(history) + 1));
|
||||
History_element_t* el = history->FirstEl_p;
|
||||
|
||||
int i;
|
||||
for (i = 0; (i < History_getSize(history)-1) && (retCode >= 0); i++)
|
||||
{
|
||||
*((*list) + i) = el->line;
|
||||
if (el->nextEl_p == NULL)
|
||||
{
|
||||
retCode = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
el = (History_element_t*)el->nextEl_p;
|
||||
}
|
||||
}
|
||||
|
||||
if (retCode >= 0)
|
||||
{
|
||||
// indicate end of list
|
||||
*((*list) + History_getSize(history)) = NULL;
|
||||
}
|
||||
|
||||
return retCode;
|
||||
}
|
||||
|
||||
int History_getCurrPos(History_t* history)
|
||||
{
|
||||
int retCode = 0;
|
||||
|
||||
if (history->CurrEl_p != NULL)
|
||||
{
|
||||
History_element_t* el = history->FirstEl_p;
|
||||
int i;
|
||||
for (i = 0; (el != history->CurrEl_p) && (retCode >= 0); i++)
|
||||
{
|
||||
if (el->nextEl_p == NULL)
|
||||
{
|
||||
retCode = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
el = (History_element_t*)el->nextEl_p;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
retCode = History_getSize(history);
|
||||
}
|
||||
|
||||
return retCode;
|
||||
}
|
||||
|
||||
unsigned int History_getSize(History_t *history)
|
||||
{
|
||||
return history->size;
|
||||
}
|
||||
40
History/history.h
Normal file
40
History/history.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef HISTORY_H
|
||||
#define HISTORY_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
// one element in the buffer
|
||||
typedef struct History_element_s {
|
||||
void* prevEl_p;
|
||||
char* line;
|
||||
void* nextEl_p;
|
||||
} History_element_t;
|
||||
|
||||
// defines all vars for the buffer to operate
|
||||
typedef struct History_s {
|
||||
History_element_t* FirstEl_p;
|
||||
History_element_t* LastEl_p;
|
||||
History_element_t* CurrEl_p;
|
||||
unsigned char size;
|
||||
} History_t;
|
||||
|
||||
// create a fifo buffer and initilizes it with zeros
|
||||
extern History_t* History_init();
|
||||
|
||||
// destroy a fifo buffer (free up its space)
|
||||
extern int History_deinit(History_t* history, bool freeLines);
|
||||
|
||||
// put value i in buffer if there is still memory avaliable
|
||||
extern int History_put(History_t *history, char* line);
|
||||
|
||||
// get value from buffer and writes it to *line
|
||||
extern int History_getPrev(History_t* history, char** line);
|
||||
extern int History_getNext(History_t* history, char** line);
|
||||
|
||||
extern int History_getCurrPos(History_t* history);
|
||||
|
||||
extern int History_getFullHistory(History_t* history, char*** list);
|
||||
|
||||
extern unsigned int History_getSize(History_t *history);
|
||||
|
||||
#endif
|
||||
25
library.json
Normal file
25
library.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/schema/library.json",
|
||||
"name": "cli",
|
||||
"version": "1.0.0",
|
||||
"export": {
|
||||
"include": [
|
||||
"*/*.h"
|
||||
]
|
||||
},
|
||||
"keywords": [
|
||||
"cli",
|
||||
"EMS31",
|
||||
"HR",
|
||||
"submodules"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://gitea.finnvanreenen.nl/HR/EMS31_submodules.git"
|
||||
},
|
||||
"build": {
|
||||
"flags": [
|
||||
"-I$PROJECT_DIR/src"
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user