mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2025-01-18 19:04:02 -05:00
edit: Add string completion support on tab
This commit is contained in:
parent
57f7d03f91
commit
7302a35ed4
126
src/utils/edit.c
126
src/utils/edit.c
@ -31,6 +31,8 @@ static int history_current = 0;
|
|||||||
static void *edit_cb_ctx;
|
static void *edit_cb_ctx;
|
||||||
static void (*edit_cmd_cb)(void *ctx, char *cmd);
|
static void (*edit_cmd_cb)(void *ctx, char *cmd);
|
||||||
static void (*edit_eof_cb)(void *ctx);
|
static void (*edit_eof_cb)(void *ctx);
|
||||||
|
static char ** (*edit_completion_cb)(void *ctx, const char *cmd, int pos) =
|
||||||
|
NULL;
|
||||||
|
|
||||||
static struct termios prevt, newt;
|
static struct termios prevt, newt;
|
||||||
|
|
||||||
@ -289,6 +291,124 @@ static void process_cmd(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void free_completions(char **c)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (c == NULL)
|
||||||
|
return;
|
||||||
|
for (i = 0; c[i]; i++)
|
||||||
|
os_free(c[i]);
|
||||||
|
os_free(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int filter_strings(char **c, char *str, size_t len)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0, j = 0; c[j]; j++) {
|
||||||
|
if (os_strncasecmp(c[j], str, len) == 0) {
|
||||||
|
if (i != j) {
|
||||||
|
c[i] = c[j];
|
||||||
|
c[j] = NULL;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
os_free(c[j]);
|
||||||
|
c[j] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c[i] = NULL;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int common_len(const char *a, const char *b)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
while (a[len] && a[len] == b[len])
|
||||||
|
len++;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int max_common_length(char **c)
|
||||||
|
{
|
||||||
|
int len, i;
|
||||||
|
|
||||||
|
len = os_strlen(c[0]);
|
||||||
|
for (i = 1; c[i]; i++) {
|
||||||
|
int same = common_len(c[0], c[i]);
|
||||||
|
if (same < len)
|
||||||
|
len = same;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void complete(int list)
|
||||||
|
{
|
||||||
|
char **c;
|
||||||
|
int i, len, count;
|
||||||
|
int start, end;
|
||||||
|
int room, plen, add_space;
|
||||||
|
|
||||||
|
if (edit_completion_cb == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cmdbuf[cmdbuf_len] = '\0';
|
||||||
|
c = edit_completion_cb(edit_cb_ctx, cmdbuf, cmdbuf_pos);
|
||||||
|
if (c == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
end = cmdbuf_pos;
|
||||||
|
start = end;
|
||||||
|
while (start > 0 && cmdbuf[start] != ' ')
|
||||||
|
start--;
|
||||||
|
plen = end - start;
|
||||||
|
|
||||||
|
count = filter_strings(c, &cmdbuf[start], plen);
|
||||||
|
if (count == 0) {
|
||||||
|
free_completions(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = max_common_length(c);
|
||||||
|
if (len <= plen) {
|
||||||
|
if (list) {
|
||||||
|
edit_clear_line();
|
||||||
|
printf("\r");
|
||||||
|
for (i = 0; c[i]; i++)
|
||||||
|
printf("%s%s", i > 0 ? " " : "", c[i]);
|
||||||
|
printf("\n");
|
||||||
|
edit_redraw();
|
||||||
|
}
|
||||||
|
free_completions(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
len -= plen;
|
||||||
|
|
||||||
|
room = sizeof(cmdbuf) - 1 - cmdbuf_len;
|
||||||
|
if (room < len)
|
||||||
|
len = room;
|
||||||
|
add_space = count == 1 && len < room;
|
||||||
|
|
||||||
|
os_memmove(cmdbuf + cmdbuf_pos + len, cmdbuf + cmdbuf_pos,
|
||||||
|
cmdbuf_len - cmdbuf_pos + add_space);
|
||||||
|
os_memcpy(&cmdbuf[cmdbuf_pos - plen], c[0], plen + len);
|
||||||
|
if (add_space)
|
||||||
|
cmdbuf[cmdbuf_pos + len] = ' ';
|
||||||
|
|
||||||
|
cmdbuf_pos += len + add_space;
|
||||||
|
cmdbuf_len += len + add_space;
|
||||||
|
|
||||||
|
edit_redraw();
|
||||||
|
|
||||||
|
free_completions(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void edit_read_char(int sock, void *eloop_ctx, void *sock_ctx)
|
static void edit_read_char(int sock, void *eloop_ctx, void *sock_ctx)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
@ -296,6 +416,7 @@ static void edit_read_char(int sock, void *eloop_ctx, void *sock_ctx)
|
|||||||
int res;
|
int res;
|
||||||
static int esc = -1;
|
static int esc = -1;
|
||||||
static char esc_buf[6];
|
static char esc_buf[6];
|
||||||
|
static int last_tab = 0;
|
||||||
|
|
||||||
res = read(sock, buf, 1);
|
res = read(sock, buf, 1);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
@ -305,6 +426,8 @@ static void edit_read_char(int sock, void *eloop_ctx, void *sock_ctx)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
c = buf[0];
|
c = buf[0];
|
||||||
|
if (c != 9)
|
||||||
|
last_tab = 0;
|
||||||
|
|
||||||
if (esc >= 0) {
|
if (esc >= 0) {
|
||||||
if (esc == 5) {
|
if (esc == 5) {
|
||||||
@ -452,6 +575,8 @@ static void edit_read_char(int sock, void *eloop_ctx, void *sock_ctx)
|
|||||||
delete_left();
|
delete_left();
|
||||||
break;
|
break;
|
||||||
case 9: /* ^I = TAB */
|
case 9: /* ^I = TAB */
|
||||||
|
complete(last_tab);
|
||||||
|
last_tab = 1;
|
||||||
break;
|
break;
|
||||||
case 10: /* NL */
|
case 10: /* NL */
|
||||||
case 13: /* CR */
|
case 13: /* CR */
|
||||||
@ -545,4 +670,5 @@ void edit_set_filter_history_cb(int (*cb)(void *ctx, const char *cmd))
|
|||||||
|
|
||||||
void edit_set_completion_cb(char ** (*cb)(void *ctx, const char *cmd, int pos))
|
void edit_set_completion_cb(char ** (*cb)(void *ctx, const char *cmd, int pos))
|
||||||
{
|
{
|
||||||
|
edit_completion_cb = cb;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user