Есть ли хороший способ обработки многострочного ввода с помощью строки чтения GNU?
-
03-07-2019 - |
Вопрос
Мое приложение имеет интерфейс командной строки, и я подумываю об использовании Библиотека чтения GNU Readline для предоставления истории, редактируемой командной строки и т. д.
Проблема в том, что мои команды могут быть довольно длинными и сложными (например, SQL), и я хотел бы позволить пользователям распределять команды по нескольким строкам, чтобы сделать их более читабельными в истории.
Можно ли сделать это в строке чтения (возможно, указав разницу между новой строкой и концом команды)?
Или мне лучше реализовать свою собственную командную строку (но, возможно, используя Библиотека истории GNU)?
Решение
Вы уверены, что можете.
Вы можете определить параметры для значений ' ' и ' ' с помощью
rl_bind_key('\r', return_func);
Теперь ваша return_func может решить, что делать с этими ключами.
int return_func(int cnt, int key) { ... }
Если вы делаете это внутри терминала UNIX, вам нужно будет узнать о кодах терминалов ANSI, если вы хотите перемещать курсор.Есть начальная ссылка в википедии.
Вот пример кода, который использует readline для чтения многострочных строк и прекращает редактирование, когда вы вводите точку с запятой (я установил это как EOQ или конец или запрос).Readline чрезвычайно мощный инструмент, здесь есть чему поучиться.
#include <stdio.h>
#include <unistd.h>
#include <readline/readline.h>
#include <readline/history.h>
int my_startup(void);
int my_bind_cr(int, int);
int my_bind_eoq(int, int);
char *my_readline(void);
int my_eoq;
int
main(int argc, char *argv[])
{
if (isatty(STDIN_FILENO)) {
rl_readline_name = "my";
rl_startup_hook = my_startup;
my_readline();
}
}
int
my_startup(void)
{
my_eoq = 0;
rl_bind_key('\n', my_bind_cr);
rl_bind_key('\r', my_bind_cr);
rl_bind_key(';', my_bind_eoq);
}
int
my_bind_cr(int count, int key) {
if (my_eoq == 1) {
rl_done = 1;
}
printf("\n");
}
int
my_bind_eoq(int count, int key) {
my_eoq = 1;
printf(";");
}
char *
my_readline(void)
{
char *line;
if ((line = readline("")) == NULL) {
return NULL;
}
printf("LINE : %s\n", line);
}