return ERROR_OK;
}
+/* Avoid evaluating this each time we add a command. Reduces overhead from O(n^2) to O(n).
+ * Makes a difference on ARM7 types machines and is not observable on GHz machines.
+ */
+static int unique_length_dirty=1;
+
command_t* register_command(command_context_t *context, command_t *parent, char *name, int (*handler)(struct command_context_s *context, char* name, char** args, int argc), enum command_mode mode, char *help)
{
command_t *c, *p;
+ unique_length_dirty=1;
if (!context || !name)
return NULL;
}
}
- /* update unique lengths */
- build_unique_lengths(context, (parent) ? parent : context->commands);
-
return c;
}
int unregister_command(command_context_t *context, char *name)
{
+ unique_length_dirty=1;
+
command_t *c, *p = NULL, *c2;
if ((!context) || (!name))
/* we're inside a word or quote, and reached its end*/
if (word_start)
{
- int len = p - word_start;
-
- /* copy the word */
- memcpy(words[nwords] = malloc(len + 1), word_start, len);
- /* add terminating NUL */
- words[nwords++][len] = 0;
+ int len;
+ char *word_end=p;
+
+ /* This will handle extra whitespace within quotes */
+ while (isspace(*word_start)&&(word_start<word_end))
+ word_start++;
+ while (isspace(*(word_end-1))&&(word_start<word_end))
+ word_end--;
+ len = word_end - word_start;
+
+ if (len>0)
+ {
+ /* copy the word */
+ memcpy(words[nwords] = malloc(len + 1), word_start, len);
+ /* add terminating NUL */
+ words[nwords++][len] = 0;
+ }
}
-
/* we're done parsing the line */
if (!*p)
break;
/* skip over trailing quote or whitespace*/
if (inquote || isspace(*p))
p++;
-
+ while (isspace(*p))
+ p++;
+
inquote = 0;
word_start = 0;
}
{
/* increase buffer until it fits the whole string */
if (!(p = realloc(buffer, size += 4096)))
+ {
+ /* gotta free up */
+ if (buffer)
+ free(buffer);
return;
+ }
buffer = p;
}
/* vsnprintf failed */
if (n < 0)
+ {
+ if (buffer)
+ free(buffer);
return;
+ }
p = buffer;
{
command_t *c;
+ if (unique_length_dirty)
+ {
+ unique_length_dirty=0;
+ /* update unique lengths */
+ build_unique_lengths(context, context->commands);
+ }
+
for (c = commands; c; c = c->next)
{
if (strncasecmp(c->name, words[start_word], c->unique_len))
if (!*line)
return ERROR_OK;
+ /* ignore comments */
+ if (*line && (line[0] == '#'))
+ return ERROR_OK;
+
if (context->echo)
{
command_print(context, "%s", line);
int command_run_file(command_context_t *context, FILE *file, enum command_mode mode)
{
- int retval;
+ int retval = ERROR_OK;
int old_command_mode;
- char buffer[4096];
+ char *buffer=malloc(4096);
+ if (buffer==NULL)
+ {
+ return ERROR_INVALID_ARGUMENTS;
+ }
old_command_mode = context->mode;
context->mode = mode;
break;
/* run line */
- if (command_run_line(context, cmd) == ERROR_COMMAND_CLOSE_CONNECTION)
+ if ((retval = command_run_line(context, cmd)) == ERROR_COMMAND_CLOSE_CONNECTION)
break;
}
context->mode = old_command_mode;
+
+
+ free(buffer);
return retval;
}
int command_done(command_context_t *context)
{
free(context);
+ context = NULL;
return ERROR_OK;
}