/* * Copyright (c) 2015 Peter Rosin * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include "confuse.h" static cfg_t *cfg; static int cmdc; static char **cmdv; static int cmdv_max; static int reserve_cmdv(int cmdc) { int cmd_max = cmdv_max; char **tmp; if (cmdc < cmd_max) return 0; do cmd_max += 10; while (cmdc >= cmd_max); tmp = realloc(cmdv, cmd_max * sizeof(*tmp)); if (!tmp) return -1; cmdv = tmp; cmdv_max = cmd_max; return 0; } static int split_cmd(char *cmd) { char *out = cmd; int arg; cmdc = 0; for (;;) { char ch; arg = 0; while (*cmd == ' ') ++cmd; next_char: ch = *cmd++; if (ch == '"' || ch == '\'') { char end = ch; if (!arg) { if (reserve_cmdv(cmdc + 1)) return -1; cmdv[cmdc++] = out; arg = 1; } while (*cmd && *cmd != end) *out++ = *cmd++; if (!*cmd++) return -1; goto next_char; } if (ch && ch != ' ') { if (!arg) { if (reserve_cmdv(cmdc + 1)) return -1; cmdv[cmdc++] = out; arg = 1; } *out++ = ch; goto next_char; } *out++ = 0; if (!ch) break; } return cmdc; } static char *input_cmd(void) { int ch; char *cmd = malloc(128); int len = 128; int pos = 0; if (!cmd) return NULL; for (;;) { ch = fgetc(stdin); if (ch < 0) break; switch (ch) { case '\r': case '\n': ch = 0; /* fall through */ default: if (pos == len) { char *tmp = realloc(cmd, len * 2); if (!tmp) goto cleanup; cmd = tmp; len *= 2; } cmd[pos++] = ch; if (!ch) return cmd; } } cleanup: free(cmd); return NULL; } static const char *help(int argc, char *argv[]) { return "Available commands:\n" "\n" "help\n" "set