X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fcommand.c;h=0e5d9d6376f8b4a55a9a31e5e4d9114b3df3f381;hb=1195caf0c998e80d3e7195a0452a14e7b4194077;hp=071c7e4e9ecb89942d1a3394c229a4019357126f;hpb=97d6c6f6b1922621ca013668eba9a9a9f71d60fe;p=pspp diff --git a/src/command.c b/src/command.c index 071c7e4e9e..0e5d9d6376 100644 --- a/src/command.c +++ b/src/command.c @@ -14,8 +14,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ #include #include "error.h" @@ -25,7 +25,9 @@ #include #include #include "alloc.h" +#include "dictionary.h" #include "error.h" +#include "glob.h" #include "getline.h" #include "lexer.h" #include "main.h" @@ -62,22 +64,67 @@ struct command int (*func) (void); /* Function to call. */ int skip_entire_name; /* If zero, we don't skip the final token in the command name. */ + short debug; /* Set if this cmd available only in test mode*/ }; /* Define the command array. */ #define DEFCMD(NAME, T1, T2, T3, T4, FUNC) \ - {NAME, {T1, T2, T3, T4}, FUNC, 1}, + {NAME, {T1, T2, T3, T4}, FUNC, 1, 0}, +#define DBGCMD(NAME, T1, T2, T3, T4, FUNC) \ + {NAME, {T1, T2, T3, T4}, FUNC, 1, 1}, #define SPCCMD(NAME, T1, T2, T3, T4, FUNC) \ - {NAME, {T1, T2, T3, T4}, FUNC, 0}, -#define UNIMPL(NAME, T1, T2, T3, T4) \ - {NAME, {T1, T2, T3, T4}, NULL, 1}, + {NAME, {T1, T2, T3, T4}, FUNC, 0, 0}, +#define UNIMPL(NAME, T1, T2, T3, T4, DESC) \ + {NAME, {T1, T2, T3, T4}, NULL, 1, 0}, static const struct command commands[] = { #include "command.def" }; #undef DEFCMD +#undef DBGCMD #undef UNIMPL + +/* Complete the line using the name of a command, + * based upon the current prg_state + */ +char * +pspp_completion_function (const char *text, int state) +{ + static int skip=0; + const struct command *cmd = 0; + + for(;;) + { + if ( state + skip >= sizeof(commands)/ sizeof(struct command)) + { + skip = 0; + return 0; + } + + cmd = &commands[state + skip]; + + if ( cmd->transition[pgm_state] == STATE_ERROR || ( cmd->debug && ! test_mode ) ) + { + skip++; + continue; + } + + if ( text == 0 || 0 == strncasecmp (cmd->name, text, strlen(text))) + { + break; + } + + skip++; + } + + + return xstrdup(cmd->name); + +} + + + #define COMMAND_CNT (sizeof commands / sizeof *commands) /* Command parser. */ @@ -136,7 +183,7 @@ cmd_parse (void) return CMD_SUCCESS; /* Parse comments. */ - if ((token == T_ID && !strcmp (tokid, "COMMENT")) + if ((token == T_ID && !strcasecmp (tokid, "COMMENT")) || token == T_EXP || token == '*' || token == '[') { lex_skip_comment (); @@ -234,7 +281,7 @@ match_strings (const char *a, size_t a_len, while (a_len > 0 && b_len > 0) { /* Mismatch always returns zero. */ - if (*a++ != *b++) + if (toupper ((unsigned char) *a++) != toupper ((unsigned char) *b++)) return 0; /* Advance. */ @@ -293,9 +340,15 @@ conflicting_3char_prefixes (const char *a, const char *b) bw = find_word (b, &bw_len); assert (aw != NULL && bw != NULL); + /* Words that are the same don't conflict. */ + if (aw_len == bw_len && !mm_case_compare (aw, bw, aw_len)) + return 0; + + /* Words that are otherwise the same in the first three letters + do conflict. */ return ((aw_len > 3 && bw_len > 3) || (aw_len == 3 && bw_len > 3) - || (bw_len == 3 && aw_len > 3)) && !memcmp (aw, bw, 3); + || (bw_len == 3 && aw_len > 3)) && !mm_case_compare (aw, bw, 3); } /* Returns nonzero if CMD can be confused with another command @@ -337,7 +390,7 @@ cmd_match_words (const struct command *cmd, word != NULL && word_idx < word_cnt; word = find_word (word + word_len, &word_len), word_idx++) if (word_len != strlen (words[word_idx]) - || memcmp (word, words[word_idx], word_len)) + || mm_case_compare (word, words[word_idx], word_len)) { size_t match_chars = match_strings (word, word_len, words[word_idx], @@ -480,7 +533,7 @@ parse_command_name (void) assert (word_cnt < sizeof words / sizeof *words); if (token == T_ID) - words[word_cnt++] = xstrdup (ds_value (&tokstr)); + words[word_cnt++] = xstrdup (ds_c_str (&tokstr)); else words[word_cnt++] = xstrdup ("-"); @@ -495,6 +548,8 @@ parse_command_name (void) { if (command->skip_entire_name) lex_get (); + if ( command->debug & !test_mode ) + goto error; free_words (words, word_cnt); return command; } @@ -538,10 +593,14 @@ parse_command_name (void) free (words[word_cnt]); } + if ( command->debug && !test_mode ) + goto error; + free_words (words, word_cnt); return command; } +error: unknown_command_error (words, word_cnt); free_words (words, word_cnt); return NULL; @@ -626,10 +685,10 @@ cmd_erase (void) if (!lex_force_string ()) return CMD_FAILURE; - if (remove (ds_value (&tokstr)) == -1) + if (remove (ds_c_str (&tokstr)) == -1) { msg (SW, _("Error removing `%s': %s."), - ds_value (&tokstr), strerror (errno)); + ds_c_str (&tokstr), strerror (errno)); return CMD_FAILURE; } @@ -707,7 +766,7 @@ run_command (void) lex_get (); if (!lex_force_string ()) return CMD_FAILURE; - cmd = ds_value (&tokstr); + cmd = ds_c_str (&tokstr); string = 1; } else @@ -765,11 +824,11 @@ cmd_host (void) /* Make sure that the system has a command interpreter, then run a command. */ if (system (NULL) != 0) - success = run_command (); + code = run_command (); else { msg (SE, _("No operating system support for this command.")); - success = CMD_FAILURE; + code = CMD_FAILURE; } #endif /* !unix */