From dfd4227e7a3ec33dc7dbf77254928c36cca7db89 Mon Sep 17 00:00:00 2001 From: MadnessASAP Date: Thu, 12 Mar 2020 14:57:27 -0700 Subject: [PATCH 1/7] Don't return NULL on 0 length input A 0 length string is still a valid input and should be treated as such, a NULL return should be reserved for when errors occur during line editing or EOF is reached. Merges https://github.com/espressif/esp-idf/pull/4926 --- components/console/linenoise/linenoise.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/console/linenoise/linenoise.c b/components/console/linenoise/linenoise.c index f78e238af5..3b2e1c18e7 100644 --- a/components/console/linenoise/linenoise.c +++ b/components/console/linenoise/linenoise.c @@ -979,11 +979,11 @@ char *linenoise(const char *prompt) { } else { count = linenoiseDumb(buf, LINENOISE_MAX_LINE, prompt); } - if (count > 0) { + if (count >= 0) { sanitize(buf); count = strlen(buf); } - if (count <= 0) { + if (count < 0) { free(buf); return NULL; } From 868039416797df735ca5ee8afc10fb47a27a2a14 Mon Sep 17 00:00:00 2001 From: MadnessASAP Date: Thu, 12 Mar 2020 15:10:40 -0700 Subject: [PATCH 2/7] Break the input loop on error or EOF --- examples/system/console/main/console_example_main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/system/console/main/console_example_main.c b/examples/system/console/main/console_example_main.c index 0caae21279..697a0345a8 100644 --- a/examples/system/console/main/console_example_main.c +++ b/examples/system/console/main/console_example_main.c @@ -170,8 +170,8 @@ void app_main(void) * The line is returned when ENTER is pressed. */ char* line = linenoise(prompt); - if (line == NULL) { /* Ignore empty lines */ - continue; + if (line == NULL) { /* Break on EOF or error */ + break; } /* Add the command to the history */ linenoiseHistoryAdd(line); @@ -195,4 +195,8 @@ void app_main(void) /* linenoise allocates line buffer on the heap, so need to free it */ linenoiseFree(line); } + + ESP_LOGE(TAG, "Error or end-of-input, terminating console"); + esp_console_deinit(); + vTaskDelete(NULL); /* terminate app_main */ } From 8a2413b5c03390a5f615ede487172c3168d9cff3 Mon Sep 17 00:00:00 2001 From: Michael 'ASAP' Weinrich Date: Sun, 15 Mar 2020 21:09:46 -0700 Subject: [PATCH 3/7] Added filtering blank lines from history --- examples/system/console/main/console_example_main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/system/console/main/console_example_main.c b/examples/system/console/main/console_example_main.c index 697a0345a8..0292b7fd72 100644 --- a/examples/system/console/main/console_example_main.c +++ b/examples/system/console/main/console_example_main.c @@ -173,12 +173,14 @@ void app_main(void) if (line == NULL) { /* Break on EOF or error */ break; } - /* Add the command to the history */ - linenoiseHistoryAdd(line); + /* Add the command to the history if not empty*/ + if(strlen(line) > 0) { + linenoiseHistoryAdd(line); #if CONFIG_STORE_HISTORY - /* Save command history to filesystem */ - linenoiseHistorySave(HISTORY_PATH); + /* Save command history to filesystem */ + linenoiseHistorySave(HISTORY_PATH); #endif + } /* Try to run the command */ int ret; From c34352549ac1fda8eab9b45260dfda4d2b6488f1 Mon Sep 17 00:00:00 2001 From: Michael 'ASAP' Weinrich Date: Sun, 15 Mar 2020 21:31:48 -0700 Subject: [PATCH 4/7] Added Kconfig for enabling 0 length returns from linenoise --- components/console/Kconfig | 10 ++++++++++ components/console/linenoise/linenoise.c | 8 ++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 components/console/Kconfig diff --git a/components/console/Kconfig b/components/console/Kconfig new file mode 100644 index 0000000000..a153b490de --- /dev/null +++ b/components/console/Kconfig @@ -0,0 +1,10 @@ +menu "Linenoise" + + config ESP_LINENOISE_RETURN_ZERO_STRING + bool "Return 0 length strings" + default n + help + If enabled linenoise will return 0 length strings if the user presses enter with out typing + a command, if disabled NULL will be returned instead. + +endmenu \ No newline at end of file diff --git a/components/console/linenoise/linenoise.c b/components/console/linenoise/linenoise.c index 3b2e1c18e7..0cf86fc0c2 100644 --- a/components/console/linenoise/linenoise.c +++ b/components/console/linenoise/linenoise.c @@ -116,6 +116,7 @@ #include #include #include "linenoise.h" +#include "sdkconfig.h" #define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100 #define LINENOISE_MAX_LINE 4096 @@ -979,11 +980,14 @@ char *linenoise(const char *prompt) { } else { count = linenoiseDumb(buf, LINENOISE_MAX_LINE, prompt); } +#ifdef CONFIG_ESP_LINENOISE_RETURN_ZERO_STRING if (count >= 0) { +#else + if (count > 0) { +#endif sanitize(buf); count = strlen(buf); - } - if (count < 0) { + } else { free(buf); return NULL; } From ece41b04e3d5edeaf747665ab91d24b02eb7c882 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 3 Apr 2020 00:16:21 +0200 Subject: [PATCH 5/7] console: make empty line behavior run-time configurable --- components/console/Kconfig | 10 ---------- components/console/linenoise/linenoise.c | 12 +++++++----- components/console/linenoise/linenoise.h | 3 +++ docs/en/api-reference/system/console.rst | 3 +++ examples/system/console/main/console_example_main.c | 8 +++++--- 5 files changed, 18 insertions(+), 18 deletions(-) delete mode 100644 components/console/Kconfig diff --git a/components/console/Kconfig b/components/console/Kconfig deleted file mode 100644 index a153b490de..0000000000 --- a/components/console/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -menu "Linenoise" - - config ESP_LINENOISE_RETURN_ZERO_STRING - bool "Return 0 length strings" - default n - help - If enabled linenoise will return 0 length strings if the user presses enter with out typing - a command, if disabled NULL will be returned instead. - -endmenu \ No newline at end of file diff --git a/components/console/linenoise/linenoise.c b/components/console/linenoise/linenoise.c index 0cf86fc0c2..91dc9e3d2e 100644 --- a/components/console/linenoise/linenoise.c +++ b/components/console/linenoise/linenoise.c @@ -116,7 +116,6 @@ #include #include #include "linenoise.h" -#include "sdkconfig.h" #define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100 #define LINENOISE_MAX_LINE 4096 @@ -130,6 +129,7 @@ static int dumbmode = 0; /* Dumb mode where line editing is disabled. Off by def static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN; static int history_len = 0; static char **history = NULL; +static bool allow_empty = true; /* The linenoiseState structure represents the state during line editing. * We pass this state to functions implementing specific editing @@ -888,6 +888,10 @@ static int linenoiseEdit(char *buf, size_t buflen, const char *prompt) return l.len; } +void linenoiseAllowEmpty(bool val) { + allow_empty = val; +} + int linenoiseProbe(void) { /* Switch to non-blocking mode */ int flags = fcntl(STDIN_FILENO, F_GETFL); @@ -980,13 +984,11 @@ char *linenoise(const char *prompt) { } else { count = linenoiseDumb(buf, LINENOISE_MAX_LINE, prompt); } -#ifdef CONFIG_ESP_LINENOISE_RETURN_ZERO_STRING - if (count >= 0) { -#else if (count > 0) { -#endif sanitize(buf); count = strlen(buf); + } else if (count == 0 && allow_empty) { + /* will return an empty (0-length) string */ } else { free(buf); return NULL; diff --git a/components/console/linenoise/linenoise.h b/components/console/linenoise/linenoise.h index 04c6f8b0cc..58756a5230 100644 --- a/components/console/linenoise/linenoise.h +++ b/components/console/linenoise/linenoise.h @@ -43,6 +43,8 @@ extern "C" { #endif +#include + typedef struct linenoiseCompletions { size_t len; char **cvec; @@ -68,6 +70,7 @@ void linenoiseClearScreen(void); void linenoiseSetMultiLine(int ml); void linenoiseSetDumbMode(int set); void linenoisePrintKeyCodes(void); +void linenoiseAllowEmpty(bool); #ifdef __cplusplus } diff --git a/docs/en/api-reference/system/console.rst b/docs/en/api-reference/system/console.rst index d256a517e1..273bf4a886 100644 --- a/docs/en/api-reference/system/console.rst +++ b/docs/en/api-reference/system/console.rst @@ -36,6 +36,9 @@ Linenoise library does not need explicit initialization. However, some configura :cpp:func:`linenoiseSetMultiLine` Switch between single line and multi line editing modes. In single line mode, if the length of the command exceeds the width of the terminal, the command text is scrolled within the line to show the end of the text. In this case the beginning of the text is hidden. Single line needs less data to be sent to refresh screen on each key press, so exhibits less glitching compared to the multi line mode. On the flip side, editing commands and copying command text from terminal in single line mode is harder. Default is single line mode. +:cpp:func:`linenoiseAllowEmpty` + Set whether linenoise library will return a zero-length string (if ``true``) or ``NULL`` (if ``false``) for empty lines. By default, zero-length strings are returned. + Main loop ^^^^^^^^^ diff --git a/examples/system/console/main/console_example_main.c b/examples/system/console/main/console_example_main.c index 0292b7fd72..c91d79509f 100644 --- a/examples/system/console/main/console_example_main.c +++ b/examples/system/console/main/console_example_main.c @@ -112,6 +112,9 @@ static void initialize_console(void) /* Set command history size */ linenoiseHistorySetMaxLen(100); + /* Don't return empty lines */ + linenoiseAllowEmpty(false); + #if CONFIG_STORE_HISTORY /* Load command history from filesystem */ linenoiseHistoryLoad(HISTORY_PATH); @@ -174,7 +177,7 @@ void app_main(void) break; } /* Add the command to the history if not empty*/ - if(strlen(line) > 0) { + if (strlen(line) > 0) { linenoiseHistoryAdd(line); #if CONFIG_STORE_HISTORY /* Save command history to filesystem */ @@ -197,8 +200,7 @@ void app_main(void) /* linenoise allocates line buffer on the heap, so need to free it */ linenoiseFree(line); } - + ESP_LOGE(TAG, "Error or end-of-input, terminating console"); esp_console_deinit(); - vTaskDelete(NULL); /* terminate app_main */ } From 19f6da99ed651781ad6995aa0a8db03acbafa0c5 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 3 Apr 2020 00:16:54 +0200 Subject: [PATCH 6/7] examples/console: match prompt to the target name --- examples/system/console/main/console_example_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/system/console/main/console_example_main.c b/examples/system/console/main/console_example_main.c index c91d79509f..db062a263a 100644 --- a/examples/system/console/main/console_example_main.c +++ b/examples/system/console/main/console_example_main.c @@ -22,6 +22,7 @@ #include "nvs_flash.h" static const char* TAG = "example"; +#define PROMPT_STR CONFIG_IDF_TARGET /* Console command history can be stored to and loaded from a file. * The easiest way to do this is to use FATFS filesystem on top of @@ -143,7 +144,7 @@ void app_main(void) /* Prompt to be printed before each line. * This can be customized, made dynamic, etc. */ - const char* prompt = LOG_COLOR_I "esp32> " LOG_RESET_COLOR; + const char* prompt = LOG_COLOR_I PROMPT_STR "> " LOG_RESET_COLOR; printf("\n" "This is an example of ESP-IDF console component.\n" @@ -163,7 +164,7 @@ void app_main(void) /* Since the terminal doesn't support escape sequences, * don't use color codes in the prompt. */ - prompt = "esp32> "; + prompt = PROMPT_STR "> "; #endif //CONFIG_LOG_COLORS } From 466998d48704264321b43d68d0401d551acbc272 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 29 Apr 2020 23:46:58 +0200 Subject: [PATCH 7/7] examples/console: add note about Ctrl+C --- examples/system/console/main/console_example_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/system/console/main/console_example_main.c b/examples/system/console/main/console_example_main.c index db062a263a..2fb295d0de 100644 --- a/examples/system/console/main/console_example_main.c +++ b/examples/system/console/main/console_example_main.c @@ -150,7 +150,8 @@ void app_main(void) "This is an example of ESP-IDF console component.\n" "Type 'help' to get the list of commands.\n" "Use UP/DOWN arrows to navigate through command history.\n" - "Press TAB when typing command name to auto-complete.\n"); + "Press TAB when typing command name to auto-complete.\n" + "Press Enter or Ctrl+C will terminate the console environment.\n"); /* Figure out if the terminal supports escape sequences */ int probe_status = linenoiseProbe();