projects
/
pspp
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Continue work on bug 12859, plus some code cleanup.
[pspp]
/
src
/
command.c
diff --git
a/src/command.c
b/src/command.c
index dff2ff4732d7a2e5792856188a0f162225907a63..3185446789b5073ae0b225ce2bdd855152214e3e 100644
(file)
--- 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
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., 5
9 Temple Place - Suite 330
, Boston, MA
- 0211
1-1307
, USA. */
+ Foundation, Inc., 5
1 Franklin Street, Fifth Floor
, Boston, MA
+ 0211
0-1301
, USA. */
#include <config.h>
#include "error.h"
#include <config.h>
#include "error.h"
@@
-25,7
+25,9
@@
#include <ctype.h>
#include <errno.h>
#include "alloc.h"
#include <ctype.h>
#include <errno.h>
#include "alloc.h"
+#include "dictionary.h"
#include "error.h"
#include "error.h"
+#include "glob.h"
#include "getline.h"
#include "lexer.h"
#include "main.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. */
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) \
};
/* 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) \
#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
static const struct command commands[] =
{
#include "command.def"
};
#undef DEFCMD
+#undef DBGCMD
#undef UNIMPL
#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)
\f
/* Command parser. */
#define COMMAND_CNT (sizeof commands / sizeof *commands)
\f
/* Command parser. */
@@
-87,7
+134,8
@@
static const struct command *parse_command_name (void);
/* Determines whether command C is appropriate to call in this
part of a FILE TYPE structure. */
static int
/* Determines whether command C is appropriate to call in this
part of a FILE TYPE structure. */
static int
-FILE_TYPE_okay (const struct command *c)
+FILE_TYPE_okay (const struct command *c UNUSED)
+#if 0
{
int okay = 0;
{
int okay = 0;
@@
-96,7
+144,6
@@
FILE_TYPE_okay (const struct command *c)
&& c->func != cmd_repeating_data
&& c->func != cmd_end_file_type)
msg (SE, _("%s not allowed inside FILE TYPE/END FILE TYPE."), c->name);
&& c->func != cmd_repeating_data
&& c->func != cmd_end_file_type)
msg (SE, _("%s not allowed inside FILE TYPE/END FILE TYPE."), c->name);
-#if 0
/* FIXME */
else if (c->func == cmd_repeating_data && fty.type == FTY_GROUPED)
msg (SE, _("%s not allowed inside FILE TYPE GROUPED/END FILE TYPE."),
/* FIXME */
else if (c->func == cmd_repeating_data && fty.type == FTY_GROUPED)
msg (SE, _("%s not allowed inside FILE TYPE GROUPED/END FILE TYPE."),
@@
-104,17
+151,19
@@
FILE_TYPE_okay (const struct command *c)
else if (!fty.had_rec_type && c->func != cmd_record_type)
msg (SE, _("RECORD TYPE must be the first command inside a "
"FILE TYPE structure."));
else if (!fty.had_rec_type && c->func != cmd_record_type)
msg (SE, _("RECORD TYPE must be the first command inside a "
"FILE TYPE structure."));
-#endif
else
okay = 1;
else
okay = 1;
-#if 0
if (c->func == cmd_record_type)
fty.had_rec_type = 1;
if (c->func == cmd_record_type)
fty.had_rec_type = 1;
-#endif
return okay;
}
return okay;
}
+#else
+{
+ return 1;
+}
+#endif
/* Parses an entire PSPP command. This includes everything from the
command name to the terminating dot. Does most of its work by
/* Parses an entire PSPP command. This includes everything from the
command name to the terminating dot. Does most of its work by
@@
-136,7
+185,7
@@
cmd_parse (void)
return CMD_SUCCESS;
/* Parse comments. */
return CMD_SUCCESS;
/* Parse comments. */
- if ((token == T_ID && !strcmp (tokid, "COMMENT"))
+ if ((token == T_ID && !strc
asec
mp (tokid, "COMMENT"))
|| token == T_EXP || token == '*' || token == '[')
{
lex_skip_comment ();
|| token == T_EXP || token == '*' || token == '[')
{
lex_skip_comment ();
@@
-234,7
+283,7
@@
match_strings (const char *a, size_t a_len,
while (a_len > 0 && b_len > 0)
{
/* Mismatch always returns zero. */
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. */
return 0;
/* Advance. */
@@
-294,14
+343,14
@@
conflicting_3char_prefixes (const char *a, const char *b)
assert (aw != NULL && bw != NULL);
/* Words that are the same don't conflict. */
assert (aw != NULL && bw != NULL);
/* Words that are the same don't conflict. */
- if (aw_len == bw_len && !
memcmp
(aw, bw, aw_len))
+ if (aw_len == bw_len && !
buf_compare_case
(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)
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)) && !
buf_compare_case
(aw, bw, 3);
}
/* Returns nonzero if CMD can be confused with another command
}
/* Returns nonzero if CMD can be confused with another command
@@
-343,7
+392,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])
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))
+ ||
buf_compare_case
(word, words[word_idx], word_len))
{
size_t match_chars = match_strings (word, word_len,
words[word_idx],
{
size_t match_chars = match_strings (word, word_len,
words[word_idx],
@@
-486,7
+535,7
@@
parse_command_name (void)
assert (word_cnt < sizeof words / sizeof *words);
if (token == T_ID)
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 ("-");
else
words[word_cnt++] = xstrdup ("-");
@@
-501,6
+550,8
@@
parse_command_name (void)
{
if (command->skip_entire_name)
lex_get ();
{
if (command->skip_entire_name)
lex_get ();
+ if ( command->debug & !test_mode )
+ goto error;
free_words (words, word_cnt);
return command;
}
free_words (words, word_cnt);
return command;
}
@@
-544,10
+595,14
@@
parse_command_name (void)
free (words[word_cnt]);
}
free (words[word_cnt]);
}
+ if ( command->debug && !test_mode )
+ goto error;
+
free_words (words, word_cnt);
return command;
}
free_words (words, word_cnt);
return command;
}
+error:
unknown_command_error (words, word_cnt);
free_words (words, word_cnt);
return NULL;
unknown_command_error (words, word_cnt);
free_words (words, word_cnt);
return NULL;
@@
-632,10
+687,10
@@
cmd_erase (void)
if (!lex_force_string ())
return CMD_FAILURE;
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."),
{
msg (SW, _("Error removing `%s': %s."),
- ds_
value
(&tokstr), strerror (errno));
+ ds_
c_str
(&tokstr), strerror (errno));
return CMD_FAILURE;
}
return CMD_FAILURE;
}
@@
-713,7
+768,7
@@
run_command (void)
lex_get ();
if (!lex_force_string ())
return CMD_FAILURE;
lex_get ();
if (!lex_force_string ())
return CMD_FAILURE;
- cmd = ds_
value
(&tokstr);
+ cmd = ds_
c_str
(&tokstr);
string = 1;
}
else
string = 1;
}
else
@@
-771,11
+826,11
@@
cmd_host (void)
/* Make sure that the system has a command interpreter, then run a
command. */
if (system (NULL) != 0)
/* 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."));
else
{
msg (SE, _("No operating system support for this command."));
-
success
= CMD_FAILURE;
+
code
= CMD_FAILURE;
}
#endif /* !unix */
}
#endif /* !unix */