int i;
int num_expansions;
char const *expansions[CMD_MAX_ARGV];
- char *p;
+ char *p, **argv;
fr_cmd_info_t info;
info.argc = 0;
info.max_argc = CMD_MAX_ARGV;
- info.argv = talloc_zero_array(ctx, char *, CMD_MAX_ARGV);
+ info.argv = talloc_zero_array(ctx, char const *, CMD_MAX_ARGV);
info.box = talloc_zero_array(ctx, fr_value_box_t *, CMD_MAX_ARGV);
- info.argc = fr_dict_str_to_argv(input, info.argv, CMD_MAX_ARGV);
+ memcpy(&argv, &info.argv, sizeof(argv)); /* const issues */
+ info.argc = fr_dict_str_to_argv(input, argv, CMD_MAX_ARGV);
if (info.argc <= 0) {
snprintf(output, outlen, "Failed splitting input");
return;
#define MATCHED_WORD ((!*p || isspace((int) *p)) && !*q)
#define MATCHED_START ((text + start) >= word) && ((text + start) <= p)
-static char *skip_word(char *text)
+static char const *skip_word(char const *text)
{
char quote;
- char *word = text;
+ char const *word = text;
if ((*word != '"') && (*word != '\'')) {
while (*word && !isspace((int) *word)) word++;
* commands. So we MUST re-parse the ENTIRE input every time.
*/
static int syntax_str_to_argv(int start_argc, fr_cmd_argv_t *start, fr_cmd_info_t *info,
- char **text, bool *runnable)
+ char const **text, bool *runnable)
{
int argc = start_argc;
int rcode;
bool child_done;
- char *word, *my_word, *p;
- char const *q;
+ char const *word, *my_word, *p, *q;
fr_cmd_argv_t *argv = start;
fr_cmd_argv_t *child;
* Parse / check data types.
*/
if (argv->type < FR_TYPE_FIXED) {
- size_t len;
- char quote;
+ size_t len, offset;
+ char quote, *str;
fr_type_t type;
p = skip_word(word);
return -1;
}
- /*
- * Strings MAY be quoted.
- */
- if ((argv->type == FR_TYPE_STRING) &&
- ((*word == '"') || (*word == '\''))) {
- quote = *word;
- p = word + 1;
- while (*p && !isspace((int) *p)) {
- if (*p == quote) {
- break;
- }
-
- if (*p == '\\') {
- if (p[1]) goto invalid;
- p++;
- }
-
- p++;
- }
-
- if (*p != quote) goto invalid;
-
- word++;
- len = p - word;
- p++;
+ p = skip_word(word);
+ if (!p) goto invalid;
+ len = p - word;
+ if ((*word == '"') || (*word == '\'')) {
+ quote = *word;
+ offset = 1;
} else {
- p = word;
quote = 0;
- while (*p && !isspace((int) *p)) p++;
- len = p - word;
+ offset = 0;
}
type = argv->type;
rcode = fr_value_box_from_str(info->box[argc], info->box[argc],
&type, NULL,
- word, len, quote, false);
+ word + offset, len - (offset << 1), quote, false);
if (rcode < 0) return -1;
/*
* The called function MUST check box[i]
* for the actual value.
*/
- if (quote) { /* account for quotes */
- word--;
- len += 2;
- }
-
- info->argv[argc] = talloc_memdup(info->argv, word, len + 1);
- info->argv[argc][len] = '\0';
+ info->argv[argc] = str = talloc_memdup(info->argv, word + offset, len + 1);
+ str[len] = '\0';
word = p;
argc++;
* - <0 on error.
* - total number of arguments in the argv[] array. Always >= argc.
*/
-int fr_command_str_to_argv(fr_cmd_t *head, fr_cmd_info_t *info, char *text)
+int fr_command_str_to_argv(fr_cmd_t *head, fr_cmd_info_t *info, char const *text)
{
int argc, rcode;
- char *word, *p;
- char const *q;
+ char const *word, *p, *q;
fr_cmd_t *cmd;
if ((info->argc < 0) || (info->max_argc <= 0) || !text || !head) {
for (i = new_argc; i < info->argc; i++) {
if (info->box && info->box[i]) {
fr_value_box_clear(info->box[i]);
- talloc_free(info->argv[i]);
+ talloc_const_free(info->argv[i]);
}
if (info->cmd && info->cmd[i]) info->cmd[i] = NULL;
info->argv[i] = NULL;
info->argc = 0;
info->max_argc = CMD_MAX_ARGV;
- info->argv = talloc_zero_array(ctx, char *, CMD_MAX_ARGV);
+ info->argv = talloc_zero_array(ctx, char const *, CMD_MAX_ARGV);
info->box = talloc_zero_array(ctx, fr_value_box_t *, CMD_MAX_ARGV);
info->cmd = talloc_zero_array(ctx, fr_cmd_t *, CMD_MAX_ARGV);
}
}
/*
- * Skip data types (for now)
+ * Check data types.
*/
if (argv->type < FR_TYPE_FIXED) {
- while (*word && !isspace((int) *word)) word++;
+ p = skip_word(word);
- if (!*word) return count;
+ if (!p || !*p) return count;
- *word_p = word;
+ if (MATCHED_START) {
+ // @todo call tab expand callback
+ rad_assert(0 == 1);
+ }
+
+ *word_p = p;
continue;
}
int argc; //!< current argument count
int max_argc; //!< maximum number of arguments
bool runnable; //!< is the command runnable?
- char **argv; //!< text version of commands
+ char const **argv; //!< text version of commands
fr_value_box_t **box; //!< value_box version of commands.
fr_cmd_t **cmd; //!< cached commands at each offset
} fr_cmd_info_t;
char const *fr_command_help(fr_cmd_t *head, int argc, char *argv[]);
int fr_command_run(FILE *fp, FILE *fp_err, fr_cmd_info_t *info, bool read_only);
void fr_command_debug(FILE *fp, fr_cmd_t *head);
-int fr_command_str_to_argv(fr_cmd_t *head, fr_cmd_info_t *info, char *str);
+int fr_command_str_to_argv(fr_cmd_t *head, fr_cmd_info_t *info, char const *str);
int fr_command_clear(int new_argc, fr_cmd_info_t *info) CC_HINT(nonnull);