history: add getFullHistory
CLI: detect arrow keys
This commit is contained in:
parent
e34fe9f213
commit
c8854931b5
202
CLI/CLI.c
202
CLI/CLI.c
@ -5,11 +5,24 @@
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
// #include <config.h>
|
||||
|
||||
#include "../FIFOBuff/FIFOBuffChar.h"
|
||||
#ifdef HISTORY
|
||||
#include "../History/history.h"
|
||||
#endif
|
||||
|
||||
CLI_charOutFn CLI_charOut;
|
||||
CMDList_t* CMDList;
|
||||
FIFOBuffChar_t* FIFO;
|
||||
#ifdef HISTORY
|
||||
enum {
|
||||
CLI_State_Default,
|
||||
CLI_State_Esc,
|
||||
CLI_State_ANSIVT100
|
||||
} CLI_State = CLI_State_Default;
|
||||
History_t* History;
|
||||
#endif
|
||||
|
||||
void CLI_charOut_save(char ch)
|
||||
{
|
||||
@ -36,6 +49,9 @@ bool CLI_init(CLI_charOutFn lineOut, CMDList_t* cmdList)
|
||||
CMDList = cmdList;
|
||||
|
||||
FIFO = FIFOBuffChar_create();
|
||||
#ifdef HISTORY
|
||||
History = History_init();
|
||||
#endif
|
||||
|
||||
if (CLI_charOut != NULL)
|
||||
{
|
||||
@ -51,6 +67,9 @@ bool CLI_deinit()
|
||||
CMDList = NULL;
|
||||
|
||||
FIFOBuffChar_delete(FIFO);
|
||||
#ifdef HISTORY
|
||||
History_deinit(History);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -70,14 +89,46 @@ char* fifoToString(FIFOBuffChar_t* fifo)
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
int tryExecute(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((char*)"> ");
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd = CMDList_get(CMDList, line);
|
||||
}
|
||||
|
||||
if (cmd != NULL)
|
||||
{
|
||||
#ifdef HISTORY
|
||||
History_put(History, line);
|
||||
#endif
|
||||
int ret = (*(cmd->fn))(line);
|
||||
|
||||
if (ret != INT_MIN)
|
||||
@ -86,7 +137,7 @@ int tryExecute(FIFOBuffChar_t* fifo)
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
else if (ret == 0)
|
||||
{
|
||||
if (CLI_charOut != NULL)
|
||||
{
|
||||
@ -95,8 +146,14 @@ int tryExecute(FIFOBuffChar_t* fifo)
|
||||
CLI_stringOut(&err[0]);
|
||||
}
|
||||
ret = -1;
|
||||
|
||||
#ifdef HISTORY
|
||||
free(line);
|
||||
#endif
|
||||
}
|
||||
#ifndef HISTORY
|
||||
free(line);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -104,59 +161,114 @@ int tryExecute(FIFOBuffChar_t* fifo)
|
||||
bool CLI_charIn(char c)
|
||||
{
|
||||
bool ok = true;
|
||||
char str[100];
|
||||
char C = 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 == '_')
|
||||
)
|
||||
#ifdef HISTORY
|
||||
switch (CLI_State)
|
||||
{
|
||||
FIFOBuffChar_put(FIFO, C); // save char in buffer
|
||||
CLI_charOut_save(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[100];
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
case '\r':
|
||||
if (CLI_charOut != NULL)
|
||||
{ // echo to terminal
|
||||
char ch[2] = {c, 0};
|
||||
(*CLI_charOut)(&ch[0]);
|
||||
}
|
||||
FIFOBuffChar_t* fifo = FIFO;
|
||||
FIFO = FIFOBuffChar_create();
|
||||
ok = (tryExecute(fifo) == 0);
|
||||
FIFOBuffChar_delete(fifo);
|
||||
break;
|
||||
|
||||
case 127: // backspace
|
||||
if (FIFOBuffChar_pop(FIFO))
|
||||
{ // pop something of the buffer
|
||||
CLI_stringOut((char*)"\x1b[D \x1b[D"); // "<left arrow><space><left arrow>"
|
||||
}
|
||||
break;
|
||||
case CLI_State_Default:
|
||||
#endif
|
||||
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_charOut_save(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
case '\r':
|
||||
if (CLI_charOut != NULL)
|
||||
{ // echo to terminal
|
||||
char ch[2] = {c, 0};
|
||||
(*CLI_charOut)(&ch[0]);
|
||||
}
|
||||
FIFOBuffChar_t* fifo = FIFO;
|
||||
FIFO = FIFOBuffChar_create();
|
||||
ok = (tryExecute(fifo) == 0);
|
||||
FIFOBuffChar_delete(fifo);
|
||||
break;
|
||||
|
||||
case 127: // backspace
|
||||
if (FIFOBuffChar_pop(FIFO))
|
||||
{ // pop something of the buffer
|
||||
CLI_stringOut((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);
|
||||
CLI_stringOut(&str[0]);
|
||||
break;
|
||||
case 27: // escape (start for arrow keys)
|
||||
#ifdef HISTORY
|
||||
CLI_State = CLI_State_Esc;
|
||||
break;
|
||||
#else
|
||||
sprintf(&str[0], "\ninvlid char: ESC - (%i)\n", c);
|
||||
CLI_stringOut(&str[0]);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
sprintf(&str[0], "\ninvlid char: '%c' - (%i)\n", c, c);
|
||||
CLI_stringOut(&str[0]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sprintf(&str[0], "\ninvlid char: '%c' - (%i)\n", c, c);
|
||||
CLI_stringOut(&str[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef HISTORY
|
||||
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)
|
||||
{
|
||||
case 'A': // arrow up
|
||||
// history previus
|
||||
CLI_stringOut((char*)"(key arrow up)");
|
||||
CLI_State = CLI_State_Default;
|
||||
break;
|
||||
case 'B': // arrow down
|
||||
CLI_stringOut((char*)"(key arrow down)");
|
||||
// history next
|
||||
CLI_State = CLI_State_Default;
|
||||
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;
|
||||
default:
|
||||
if ((C >= 'A') && (C <= 'Z'))
|
||||
{
|
||||
CLI_State = CLI_State_Default;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -11,6 +11,10 @@ typedef int (*CLI_charOutFn)(const char* line);
|
||||
bool CLI_init(CLI_charOutFn lineOut, CMDList_t* cmdList);
|
||||
bool CLI_deinit();
|
||||
|
||||
#ifdef HISTORY
|
||||
extern void CLI_PrintHistory();
|
||||
#endif
|
||||
|
||||
// to recive a single caracter
|
||||
bool CLI_charIn(char c);
|
||||
|
||||
|
||||
@ -6,9 +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)
|
||||
|
||||
# History
|
||||
add_library(history History/History.c)
|
||||
add_library(CLI_History CLI/CLI.c)
|
||||
target_link_libraries(CLI_History CMDList FIFOBuffChar history)
|
||||
target_compile_definitions(CLI_History PRIVATE HISTORY)
|
||||
|
||||
@ -139,6 +139,34 @@ int History_getNext(History_t* history, char** line)
|
||||
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;
|
||||
}
|
||||
|
||||
unsigned int History_getSize(History_t *history)
|
||||
{
|
||||
return history->size;
|
||||
|
||||
@ -31,6 +31,8 @@ extern int History_put(History_t *history, char* line);
|
||||
extern int History_getPrev(History_t* history, char** line);
|
||||
extern int History_getNext(History_t* history, char** line);
|
||||
|
||||
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