history: add getFullHistory

CLI: detect arrow keys
This commit is contained in:
Laila van Reenen 2024-04-13 20:20:44 +02:00
parent e34fe9f213
commit c8854931b5
5 changed files with 197 additions and 47 deletions

202
CLI/CLI.c
View File

@ -5,11 +5,24 @@
#include <stdio.h> #include <stdio.h>
#include <limits.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;
#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) void CLI_charOut_save(char ch)
{ {
@ -36,6 +49,9 @@ 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)
{ {
@ -51,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;
} }
@ -70,14 +89,46 @@ 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);
}
#endif
int tryExecute(FIFOBuffChar_t* fifo) int tryExecute(FIFOBuffChar_t* fifo)
{ {
int ret = 0; 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)
{ {
#ifdef HISTORY
History_put(History, line);
#endif
int ret = (*(cmd->fn))(line); int ret = (*(cmd->fn))(line);
if (ret != INT_MIN) if (ret != INT_MIN)
@ -86,7 +137,7 @@ int tryExecute(FIFOBuffChar_t* fifo)
} }
ret = 0; ret = 0;
} }
else else if (ret == 0)
{ {
if (CLI_charOut != NULL) if (CLI_charOut != NULL)
{ {
@ -95,8 +146,14 @@ int tryExecute(FIFOBuffChar_t* fifo)
CLI_stringOut(&err[0]); CLI_stringOut(&err[0]);
} }
ret = -1; ret = -1;
#ifdef HISTORY
free(line);
#endif
} }
#ifndef HISTORY
free(line); free(line);
#endif
return ret; return ret;
} }
@ -104,59 +161,114 @@ int tryExecute(FIFOBuffChar_t* fifo)
bool CLI_charIn(char c) bool CLI_charIn(char c)
{ {
bool ok = true; bool ok = true;
char str[100];
char C = c; char C = c;
if ((C >= 'a') && (C <= 'z')) if ((C >= 'a') && (C <= 'z'))
{ {
C &= (~0x20); // convert to uppercase C &= (~0x20); // convert to uppercase
} }
if ( //TODO: update list of accepted characters #ifdef HISTORY
((C >= 'A') && (C <= 'Z')) switch (CLI_State)
|| ((c >= '0') && (c <= '9'))
|| (c == ' ')
|| (c == '-')
|| (c == '_')
)
{ {
FIFOBuffChar_put(FIFO, C); // save char in buffer case CLI_State_Default:
CLI_charOut_save(c); #endif
} if ( //TODO: update list of accepted characters
else ((C >= 'A') && (C <= 'Z'))
{ || ((c >= '0') && (c <= '9'))
char str[100]; || (c == ' ')
switch (c) || (c == '-')
{ || (c == '_')
case '\n': )
case '\r': {
if (CLI_charOut != NULL) FIFOBuffChar_put(FIFO, C); // save char in buffer
{ // echo to terminal CLI_charOut_save(c);
char ch[2] = {c, 0}; }
(*CLI_charOut)(&ch[0]); else
} {
FIFOBuffChar_t* fifo = FIFO; switch (c)
FIFO = FIFOBuffChar_create(); {
ok = (tryExecute(fifo) == 0); case '\n':
FIFOBuffChar_delete(fifo); case '\r':
break; if (CLI_charOut != NULL)
{ // echo to terminal
case 127: // backspace char ch[2] = {c, 0};
if (FIFOBuffChar_pop(FIFO)) (*CLI_charOut)(&ch[0]);
{ // pop something of the buffer }
CLI_stringOut((char*)"\x1b[D \x1b[D"); // "<left arrow><space><left arrow>" FIFOBuffChar_t* fifo = FIFO;
} FIFO = FIFOBuffChar_create();
break; 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) case 27: // escape (start for arrow keys)
sprintf(&str[0], "\ninvlid char: ESC - (%i)\n", c); #ifdef HISTORY
CLI_stringOut(&str[0]); CLI_State = CLI_State_Esc;
break; break;
#else
sprintf(&str[0], "\ninvlid char: ESC - (%i)\n", c);
CLI_stringOut(&str[0]);
break;
#endif
default: default:
sprintf(&str[0], "\ninvlid char: '%c' - (%i)\n", c, c); sprintf(&str[0], "\ninvlid char: '%c' - (%i)\n", c, c);
CLI_stringOut(&str[0]); CLI_stringOut(&str[0]);
break; 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; return ok;
} }

View File

@ -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);

View File

@ -6,9 +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)
# History add_library(CLI_History CLI/CLI.c)
add_library(history History/History.c) target_link_libraries(CLI_History CMDList FIFOBuffChar history)
target_compile_definitions(CLI_History PRIVATE HISTORY)

View File

@ -139,6 +139,34 @@ int History_getNext(History_t* history, char** line)
return 0; 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) unsigned int History_getSize(History_t *history)
{ {
return history->size; return history->size;

View File

@ -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_getPrev(History_t* history, char** line);
extern int History_getNext(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); extern unsigned int History_getSize(History_t *history);
#endif #endif