mirror of
git://projects.qi-hardware.com/xburst-tools.git
synced 2024-11-01 12:28:06 +02:00
Implemented tab completion
This commit is contained in:
parent
a80ec957c6
commit
7c1d9c0144
3
main.c
3
main.c
@ -156,7 +156,7 @@ int main(int argc, char *argv[]) {
|
|||||||
goto exit_ingenic;
|
goto exit_ingenic;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(config)
|
if(config) {
|
||||||
if(shell_source(shell, config) == -1) {
|
if(shell_source(shell, config) == -1) {
|
||||||
perror("shell_source");
|
perror("shell_source");
|
||||||
|
|
||||||
@ -164,6 +164,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
goto exit_shell;
|
goto exit_shell;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(cmd != NULL) {
|
if(cmd != NULL) {
|
||||||
if(shell_execute(shell, cmd) == -1) {
|
if(shell_execute(shell, cmd) == -1) {
|
||||||
|
93
shell.c
93
shell.c
@ -103,7 +103,7 @@ int shell_run(shell_context_t *ctx, int argc, char *argv[]) {
|
|||||||
|
|
||||||
int ret = shell_enumerate_commands(ctx, shell_run_function, &data);
|
int ret = shell_enumerate_commands(ctx, shell_run_function, &data);
|
||||||
|
|
||||||
if(ret != 0) {
|
if(ret == 0) {
|
||||||
debug(LEVEL_ERROR, "Bad command '%s'\n", argv[0]);
|
debug(LEVEL_ERROR, "Bad command '%s'\n", argv[0]);
|
||||||
|
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@ -127,12 +127,12 @@ int shell_execute(shell_context_t *ctx, const char *cmd) {
|
|||||||
int state = STATE_WANTSTR;
|
int state = STATE_WANTSTR;
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
char **argv = NULL;
|
char **argv = NULL;
|
||||||
int fret = -1;
|
int fret = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
int noway = 0;
|
int noway = 0;
|
||||||
|
|
||||||
token = yylex(&scanner);
|
token = yylex(scanner);
|
||||||
|
|
||||||
if((token == TOK_SEPARATOR || token == TOK_COMMENT || token == 0)) {
|
if((token == TOK_SEPARATOR || token == TOK_COMMENT || token == 0)) {
|
||||||
if(argc > 0) {
|
if(argc > 0) {
|
||||||
@ -203,7 +203,7 @@ int shell_execute(shell_context_t *ctx, const char *cmd) {
|
|||||||
|
|
||||||
free(ptr);
|
free(ptr);
|
||||||
|
|
||||||
yylex_destroy(&scanner);
|
yylex_destroy(scanner);
|
||||||
|
|
||||||
return fret;
|
return fret;
|
||||||
}
|
}
|
||||||
@ -249,6 +249,88 @@ int shell_source(shell_context_t *ctx, const char *filename) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_READLINE
|
||||||
|
static shell_context_t *completion_context;
|
||||||
|
static char **completion_matches;
|
||||||
|
static int completion_matches_count = 0;
|
||||||
|
|
||||||
|
static int shell_completion_filler(shell_context_t *ctx, const shell_command_t *cmd, void *arg) {
|
||||||
|
const char *part = arg;
|
||||||
|
|
||||||
|
size_t len = strlen(part), cmdlen = strlen(cmd->cmd);
|
||||||
|
|
||||||
|
if(cmdlen >= len && memcmp(part, cmd->cmd, len) == 0) {
|
||||||
|
int idx = completion_matches_count++;
|
||||||
|
|
||||||
|
completion_matches = realloc(completion_matches, sizeof(char **) * completion_matches_count);
|
||||||
|
completion_matches[idx] = strdup(cmd->cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *shell_completion(const char *partial, int state) {
|
||||||
|
static int completion_pass = 0, completion_matches_offset = 0;
|
||||||
|
|
||||||
|
if(state == 0) {
|
||||||
|
if(completion_matches) {
|
||||||
|
for(int i = 0; i < completion_matches_count; i++)
|
||||||
|
if(completion_matches[i])
|
||||||
|
free(completion_matches[i]);
|
||||||
|
|
||||||
|
free(completion_matches);
|
||||||
|
|
||||||
|
completion_matches = NULL;
|
||||||
|
completion_matches_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
completion_pass = 0;
|
||||||
|
|
||||||
|
char *tmp = rl_line_buffer;
|
||||||
|
|
||||||
|
while(isspace(*tmp)) tmp++;
|
||||||
|
|
||||||
|
int not_first = 0;
|
||||||
|
|
||||||
|
for(; *tmp; tmp++) {
|
||||||
|
for(const char *sep = rl_basic_word_break_characters; *sep; sep++) {
|
||||||
|
if(*tmp == *sep) {
|
||||||
|
not_first = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(not_first)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(not_first) {
|
||||||
|
completion_pass = 1;
|
||||||
|
|
||||||
|
return rl_filename_completion_function(partial, state);
|
||||||
|
} else {
|
||||||
|
shell_enumerate_commands(completion_context, shell_completion_filler, (void *) partial);
|
||||||
|
|
||||||
|
completion_matches_offset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(completion_pass) {
|
||||||
|
return rl_filename_completion_function(partial, state);
|
||||||
|
|
||||||
|
} else if(completion_matches_offset == completion_matches_count) {
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
char *val = completion_matches[completion_matches_offset];
|
||||||
|
|
||||||
|
completion_matches[completion_matches_offset++] = NULL;
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void shell_interactive(shell_context_t *ctx) {
|
void shell_interactive(shell_context_t *ctx) {
|
||||||
ctx->shell_exit = 0;
|
ctx->shell_exit = 0;
|
||||||
|
|
||||||
@ -267,9 +349,12 @@ void shell_interactive(shell_context_t *ctx) {
|
|||||||
shell_execute(ctx, line);
|
shell_execute(ctx, line);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
rl_completion_entry_function = shell_completion;
|
||||||
|
completion_context = ctx;
|
||||||
|
|
||||||
rl_set_signals();
|
rl_set_signals();
|
||||||
|
|
||||||
|
rl_filename_quote_characters = "\" ";
|
||||||
while(!ctx->shell_exit) {
|
while(!ctx->shell_exit) {
|
||||||
char *line = readline("jzboot> ");
|
char *line = readline("jzboot> ");
|
||||||
|
|
||||||
|
@ -136,9 +136,11 @@ static int builtin_redetect(shell_context_t *ctx, int argc, char *argv[]) {
|
|||||||
|
|
||||||
|
|
||||||
static int builtin_set(shell_context_t *ctx, int argc, char *argv[]) {
|
static int builtin_set(shell_context_t *ctx, int argc, char *argv[]) {
|
||||||
if(argc == 1 && cfg_environ) {
|
if(argc == 1) {
|
||||||
|
if(cfg_environ) {
|
||||||
for(int i = 0; cfg_environ[i] != NULL; i++)
|
for(int i = 0; cfg_environ[i] != NULL; i++)
|
||||||
printf("%s\n", cfg_environ[i]);
|
printf("%s\n", cfg_environ[i]);
|
||||||
|
}
|
||||||
|
|
||||||
} else if(argc == 2) {
|
} else if(argc == 2) {
|
||||||
cfg_unsetenv(argv[1]);
|
cfg_unsetenv(argv[1]);
|
||||||
|
Loading…
Reference in New Issue
Block a user