/* * Interface to GNU readline for command parser. * */ #include "v9t9_common.h" #if HAVE_READLINE #ifdef __unix__ #include #else #include #endif #include #include "command.h" #include "command_rl.h" static command_symbol **command_matches; static int command_nmatches; static int command_match_idx; static char *command_match_idx_ptr; static char * commands_matching(char *text, int state) { int ln; char *ret; if (!state) { if (command_matches) { xfree(command_matches); command_matches = NULL; command_nmatches = 0; } command_match_symbols(universe, text, &command_matches, &command_nmatches); command_match_idx = 0; command_match_idx_ptr = 0; } if (command_match_idx >= command_nmatches) return NULL; if (!command_match_idx_ptr || !*command_match_idx_ptr) command_match_idx_ptr = command_matches[command_match_idx]->name; ln = 0; while (command_match_idx_ptr[ln] && command_match_idx_ptr[ln] != '|') ln++; ret = xstrdup(command_match_idx_ptr); ret[ln] = 0; command_match_idx_ptr += ln; if (*command_match_idx_ptr == '|') command_match_idx_ptr++; if (!*command_match_idx_ptr) command_match_idx++; return ret; } static char ** readline_completion(char *text, int start, int end) { char **matches = NULL; int nwc = 1; // new command? int ptr; ptr = -start; while (ptr < 0) { if (text[ptr] == '\"') nwc = !nwc; ptr++; } if (nwc && *text) matches = completion_matches(text, commands_matching); return matches; } void readline_getcommands(FILE * in, FILE * out) { while ((stateflag & ST_INTERACTIVE) && !feof(in)) { char *buf; rl_instream = in; rl_outstream = out; rl_readline_name = "v9t9"; rl_basic_word_break_characters = "\t\n\"\\'`@$<>=;|&{(,"; rl_attempted_completion_function = readline_completion; buf = readline("Enter a command> "); if (buf) { if (*buf) add_history(buf); command_parse_text(buf); free(buf); } else fprintf(out, "\n"); } } #else // !HAVE_READLINE void readline_getcommands(FILE * in, FILE * out) { while ((stateflag & ST_INTERACTIVE) && !feof(in)) { char buf[1024]; fprintf(out, "Enter a command> "); fgets(buf, sizeof(buf), in); if (*buf) command_parse_text(buf); else command_parse_text("Die\n"); } } #endif