Merge branch 'master' into Dennis_CCS
This commit is contained in:
commit
cd72e519a1
316
CLI/CLI.c
316
CLI/CLI.c
@ -3,13 +3,44 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
// #include <config.h>
|
||||||
|
|
||||||
#include "../FIFOBuff/FIFOBuffChar.h"
|
#include "../FIFOBuff/FIFOBuffChar.h"
|
||||||
|
#ifdef HISTORY
|
||||||
|
#include "../History/history.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
CLI_charOutFn CLI_charOut;
|
CLI_charOutFn CLI_charOut;
|
||||||
CMDList_t* CMDList;
|
CMDList_t* CMDList;
|
||||||
FIFOBuffChar_t* FIFO;
|
FIFOBuffChar_t* FIFO;
|
||||||
int i;
|
enum {
|
||||||
|
CLI_State_Default,
|
||||||
|
CLI_State_Esc,
|
||||||
|
CLI_State_ANSIVT100
|
||||||
|
} CLI_State = CLI_State_Default;
|
||||||
|
#ifdef HISTORY
|
||||||
|
History_t* History;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void CLI_charOut_save(char ch)
|
||||||
|
{
|
||||||
|
if (CLI_charOut != NULL)
|
||||||
|
{
|
||||||
|
// create string of size one to be compatable with string print function
|
||||||
|
char c[2] = {ch, 0};
|
||||||
|
(*CLI_charOut)(&c[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLI_stringOut(char* str)
|
||||||
|
{
|
||||||
|
for (; *str != 0; str++)
|
||||||
|
{
|
||||||
|
CLI_charOut_save(*str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// initilize and register the lineout print function
|
// initilize and register the lineout print function
|
||||||
bool CLI_init(CLI_charOutFn lineOut, CMDList_t* cmdList)
|
bool CLI_init(CLI_charOutFn lineOut, CMDList_t* cmdList)
|
||||||
@ -18,11 +49,13 @@ bool CLI_init(CLI_charOutFn lineOut, CMDList_t* cmdList)
|
|||||||
CMDList = cmdList;
|
CMDList = cmdList;
|
||||||
|
|
||||||
FIFO = FIFOBuffChar_create();
|
FIFO = FIFOBuffChar_create();
|
||||||
|
#ifdef HISTORY
|
||||||
|
History = History_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (CLI_charOut != NULL)
|
if (CLI_charOut != NULL)
|
||||||
{
|
{
|
||||||
(*CLI_charOut)(">");
|
CLI_stringOut((char*)"> ");
|
||||||
(*CLI_charOut)(" ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -34,6 +67,9 @@ bool CLI_deinit()
|
|||||||
CMDList = NULL;
|
CMDList = NULL;
|
||||||
|
|
||||||
FIFOBuffChar_delete(FIFO);
|
FIFOBuffChar_delete(FIFO);
|
||||||
|
#ifdef HISTORY
|
||||||
|
History_deinit(History);
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,6 +78,7 @@ char* fifoToString(FIFOBuffChar_t* fifo)
|
|||||||
char* out = malloc(fifo->size + 1);
|
char* out = malloc(fifo->size + 1);
|
||||||
char* write_p = out;
|
char* write_p = out;
|
||||||
|
|
||||||
|
int i;
|
||||||
for (i = fifo->size; i > 0; i--)
|
for (i = fifo->size; i > 0; i--)
|
||||||
{
|
{
|
||||||
FIFOBuffChar_get(fifo, write_p);
|
FIFOBuffChar_get(fifo, write_p);
|
||||||
@ -53,109 +90,238 @@ char* fifoToString(FIFOBuffChar_t* fifo)
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HISTORY
|
||||||
|
void CLI_PrintHistory()
|
||||||
|
{
|
||||||
|
char** historyList;
|
||||||
|
int ret = History_getFullHistory(History, &historyList);
|
||||||
|
if (ret >= 0)
|
||||||
|
{
|
||||||
|
for (int i=0; *(historyList + i) != NULL; i++)
|
||||||
|
{
|
||||||
|
printf("%03i: %s\n", i, *(historyList + i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("ERROR: get history returnd: %i\n", ret);
|
||||||
|
}
|
||||||
|
free(historyList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void historyPrevius()
|
||||||
|
{
|
||||||
|
char* line;
|
||||||
|
int i;
|
||||||
|
if (
|
||||||
|
(History_getCurrPos(History) == History_getSize(History))
|
||||||
|
&& (FIFOBuffChar_getSize(FIFO) > 0)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// add current text to end of history
|
||||||
|
line = fifoToString(FIFO);
|
||||||
|
History_put(History, line);
|
||||||
|
for (i=0; *(line + i) != '\0'; i++)
|
||||||
|
{
|
||||||
|
CLI_stringOut((char*)"\x1b[D \x1b[D");
|
||||||
|
}
|
||||||
|
History_getPrev(History, &line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// empty current line
|
||||||
|
while (FIFOBuffChar_getSize(FIFO) > 0)
|
||||||
|
{
|
||||||
|
CLI_stringOut((char*)"\x1b[D \x1b[D");
|
||||||
|
FIFOBuffChar_pop(FIFO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get previus command
|
||||||
|
int ret = History_getPrev(History, &line);
|
||||||
|
|
||||||
|
// write line
|
||||||
|
if ((ret >= 0) && (line != NULL))
|
||||||
|
{
|
||||||
|
for (i=0; *(line + i) != '\0'; i++)
|
||||||
|
{
|
||||||
|
CLI_charIn(*(line + i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void historyNext()
|
||||||
|
{
|
||||||
|
char* line;
|
||||||
|
// empty current line
|
||||||
|
while (FIFOBuffChar_getSize(FIFO) > 0)
|
||||||
|
{
|
||||||
|
CLI_stringOut((char*)"\x1b[D \x1b[D");
|
||||||
|
FIFOBuffChar_pop(FIFO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get next command
|
||||||
|
int ret = History_getNext(History, &line);
|
||||||
|
|
||||||
|
// write line
|
||||||
|
if ((ret >= 0) && (line != NULL))
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0; *(line + i) != '\0'; i++)
|
||||||
|
{
|
||||||
|
CLI_charIn(*(line + i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int tryExecute(FIFOBuffChar_t* fifo)
|
int tryExecute(FIFOBuffChar_t* fifo)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
|
CMD_t* cmd = NULL;
|
||||||
char* line = fifoToString(fifo);
|
char* line = fifoToString(fifo);
|
||||||
CMD_t* cmd = CMDList_get(CMDList, line);
|
if (*line == '\0')
|
||||||
|
{ // empty line
|
||||||
|
ret = 1;
|
||||||
|
CLI_stringOut((char*)"> ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmd = CMDList_get(CMDList, line);
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd != NULL)
|
if (cmd != NULL)
|
||||||
{
|
{
|
||||||
(*(cmd->fn))(line);
|
#ifdef HISTORY
|
||||||
|
History_put(History, line);
|
||||||
|
#endif
|
||||||
|
int ret = (*(cmd->fn))(line);
|
||||||
|
|
||||||
if (CLI_charOut != NULL)
|
if (ret != INT_MIN)
|
||||||
{
|
{
|
||||||
(*CLI_charOut)(">");
|
CLI_stringOut((char*)"> ");
|
||||||
(*CLI_charOut)(" ");
|
|
||||||
}
|
}
|
||||||
return true;
|
ret = 0;
|
||||||
}
|
}
|
||||||
else
|
else if (ret == 0)
|
||||||
{
|
{
|
||||||
if (CLI_charOut != NULL)
|
if (CLI_charOut != NULL)
|
||||||
{
|
{
|
||||||
char err[100];
|
char err[100];
|
||||||
sprintf(&err[0], "command not found: %s\n> ", line);
|
sprintf(&err[0], "command not found: %s\n> ", line);
|
||||||
for (i=0; err[i] != 0; i++)
|
CLI_stringOut(&err[0]);
|
||||||
{
|
|
||||||
char c[2] = {err[i], 0};
|
|
||||||
(*CLI_charOut)(&c[0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
ret = -1;
|
||||||
|
|
||||||
|
#ifdef HISTORY
|
||||||
|
free(line);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#ifndef HISTORY
|
||||||
|
free(line);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// to recive a single caracter
|
// to recive a single caracter
|
||||||
bool CLI_charIn(char c)
|
bool CLI_charIn(char c)
|
||||||
{
|
{
|
||||||
bool ok = true;
|
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
|
switch (CLI_State)
|
||||||
((c >= 'A') && (c <= 'Z'))
|
|
||||||
|| ((c >= '0') && (c <= '9'))
|
|
||||||
|| (c == ' ')
|
|
||||||
|| (c == '-')
|
|
||||||
|| (c == '_')
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
FIFOBuffChar_put(FIFO, c); // save char in buffer
|
case CLI_State_Default:
|
||||||
if (CLI_charOut != NULL)
|
if ( //TODO: update list of accepted characters
|
||||||
{ // echo to terminal
|
((C >= 'A') && (C <= 'Z'))
|
||||||
(*CLI_charOut)(&c);
|
|| ((c >= '0') && (c <= '9'))
|
||||||
}
|
|| (c == ' ')
|
||||||
}
|
|| (c == '-')
|
||||||
else
|
|| (c == '_')
|
||||||
{
|
)
|
||||||
char str[100];
|
{
|
||||||
switch (c)
|
FIFOBuffChar_put(FIFO, C); // save char in buffer
|
||||||
{
|
CLI_charOut_save(c);
|
||||||
case '\n':
|
}
|
||||||
case '\r':
|
else
|
||||||
if (CLI_charOut != NULL)
|
{
|
||||||
{ // echo to terminal
|
switch (c)
|
||||||
(*CLI_charOut)(&c);
|
|
||||||
}
|
|
||||||
FIFOBuffChar_t* fifo = FIFO;
|
|
||||||
FIFO = FIFOBuffChar_create();
|
|
||||||
ok = tryExecute(fifo);
|
|
||||||
FIFOBuffChar_delete(fifo);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 127: // backspace
|
|
||||||
if (FIFOBuffChar_pop(FIFO))
|
|
||||||
{
|
{
|
||||||
(*CLI_charOut)("\x1b");
|
case '\n':
|
||||||
(*CLI_charOut)("[");
|
case '\r':
|
||||||
(*CLI_charOut)("D");
|
if (CLI_charOut != NULL)
|
||||||
(*CLI_charOut)(" ");
|
{ // echo to terminal
|
||||||
(*CLI_charOut)("\x1b");
|
char ch[2] = {c, 0};
|
||||||
(*CLI_charOut)("[");
|
(*CLI_charOut)(&ch[0]);
|
||||||
(*CLI_charOut)("D");
|
}
|
||||||
}
|
FIFOBuffChar_t* fifo = FIFO;
|
||||||
break;
|
FIFO = FIFOBuffChar_create();
|
||||||
|
ok = (tryExecute(fifo) == 0);
|
||||||
|
FIFOBuffChar_delete(fifo);
|
||||||
|
break;
|
||||||
|
|
||||||
case 27: // escape (start for arrow keys)
|
case 127: // backspace
|
||||||
sprintf(&str[0], "\ninvlid char: ESC - (%i)\n", c);
|
if (FIFOBuffChar_pop(FIFO))
|
||||||
for (i=0; str[i] != 0; i++)
|
{ // pop something of the buffer
|
||||||
{
|
CLI_stringOut((char*)"\x1b[D \x1b[D"); // "<left arrow><space><left arrow>"
|
||||||
char ch[2] = {str[i], 0};
|
}
|
||||||
(*CLI_charOut)(&ch[0]);
|
break;
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
case 27: // escape (start for arrow keys)
|
||||||
sprintf(&str[0], "\ninvlid char: '%c' - (%i)\n", c, c);
|
CLI_State = CLI_State_Esc;
|
||||||
for (i=0; str[i] != 0; i++)
|
break;
|
||||||
{
|
|
||||||
char ch[2] = {str[i], 0};
|
default:
|
||||||
(*CLI_charOut)(&ch[0]);
|
sprintf(&str[0], "\ninvlid char: '%c' - (%i)\n", c, c);
|
||||||
|
CLI_stringOut(&str[0]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
}
|
break;
|
||||||
|
|
||||||
|
case CLI_State_Esc:
|
||||||
|
if (c == '[')
|
||||||
|
{
|
||||||
|
CLI_State = CLI_State_ANSIVT100;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CLI_State = CLI_State_Default;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLI_State_ANSIVT100:
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
#ifdef HISTORY
|
||||||
|
case 'A': // arrow up
|
||||||
|
CLI_State = CLI_State_Default;
|
||||||
|
historyPrevius();
|
||||||
|
break;
|
||||||
|
case 'B': // arrow down
|
||||||
|
CLI_State = CLI_State_Default;
|
||||||
|
historyNext();
|
||||||
|
break;
|
||||||
|
case 'C': // arrow right
|
||||||
|
CLI_stringOut((char*)"(key: arrow right)");
|
||||||
|
CLI_State = CLI_State_Default;
|
||||||
|
break;
|
||||||
|
case 'D': // arrow left
|
||||||
|
CLI_stringOut((char*)"(key: arrow left)");
|
||||||
|
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_State = CLI_State_Default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
|
|||||||
@ -11,6 +11,10 @@ typedef int (*CLI_charOutFn)(const char* line);
|
|||||||
bool CLI_init(CLI_charOutFn lineOut, CMDList_t* cmdList);
|
bool CLI_init(CLI_charOutFn lineOut, CMDList_t* cmdList);
|
||||||
bool CLI_deinit();
|
bool CLI_deinit();
|
||||||
|
|
||||||
|
#ifdef HISTORY
|
||||||
|
extern void CLI_PrintHistory();
|
||||||
|
#endif
|
||||||
|
|
||||||
// to recive a single caracter
|
// to recive a single caracter
|
||||||
bool CLI_charIn(char c);
|
bool CLI_charIn(char c);
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int i;
|
|
||||||
// initilises a CMDList_t with all NULL pointers
|
// initilises a CMDList_t with all NULL pointers
|
||||||
CMDList_t* CMDList_init()
|
CMDList_t* CMDList_init()
|
||||||
{
|
{
|
||||||
@ -19,20 +18,17 @@ CMDList_t* CMDList_init()
|
|||||||
int CMDList_deinit(CMDList_t *list)
|
int CMDList_deinit(CMDList_t *list)
|
||||||
{
|
{
|
||||||
CMDList_t** list_p = (CMDList_t**)list;
|
CMDList_t** list_p = (CMDList_t**)list;
|
||||||
// printf("deinit %p\n", (void*)list);
|
|
||||||
// printf("deinit e %p\n", list->e);
|
|
||||||
|
|
||||||
|
int i;
|
||||||
for (i = 0; i < 26; i++)
|
for (i = 0; i < 26; i++)
|
||||||
{
|
{
|
||||||
if (*(list_p + i) != NULL)
|
if (*(list_p + i) != NULL)
|
||||||
{
|
{
|
||||||
// printf("deinit %i\n", i);
|
|
||||||
CMDList_deinit(*(list_p + i));
|
CMDList_deinit(*(list_p + i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: fix "free(): invalid pointer"
|
free(*list_p);
|
||||||
free(list);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
typedef struct CMD_t {
|
typedef struct CMD_t {
|
||||||
char* cmd;
|
char* cmd;
|
||||||
void (*fn)(char* line);
|
int (*fn)(char* line);
|
||||||
} CMD_t;
|
} CMD_t;
|
||||||
|
|
||||||
typedef struct CMDList_s {
|
typedef struct CMDList_s {
|
||||||
|
|||||||
@ -6,6 +6,13 @@ add_library(FIFOBuffChar FIFOBuff/FIFOBuffChar.c)
|
|||||||
add_library(CMDList CMDList/CMDList.c)
|
add_library(CMDList CMDList/CMDList.c)
|
||||||
add_library(CMDListPrint CMDList/printList.c)
|
add_library(CMDListPrint CMDList/printList.c)
|
||||||
|
|
||||||
|
# History
|
||||||
|
add_library(history History/History.c)
|
||||||
|
|
||||||
# CLI
|
# CLI
|
||||||
add_library(CLI CLI/CLI.c)
|
add_library(CLI CLI/CLI.c)
|
||||||
target_link_libraries(CLI CMDList FIFOBuffChar)
|
target_link_libraries(CLI CMDList FIFOBuffChar)
|
||||||
|
|
||||||
|
add_library(CLI_History CLI/CLI.c)
|
||||||
|
target_link_libraries(CLI_History CMDList FIFOBuffChar history)
|
||||||
|
target_compile_definitions(CLI_History PRIVATE HISTORY)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#include "C:\Users\denbo\git\ems31_2023-2024_groep_09_ccs\ ems31_2023-2024_groep_09_submodules_2\FIFOBuff\FIFOBuffChar.h"
|
#include "FIFOBuffChar.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|||||||
204
History/History.c
Normal file
204
History/History.c
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
#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)
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
|
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 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
for (int 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;
|
||||||
|
for (int 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);
|
||||||
|
|
||||||
|
// 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
|
||||||
Loading…
x
Reference in New Issue
Block a user