diff options
Diffstat (limited to 'src/actionparser.c')
-rw-r--r-- | src/actionparser.c | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/src/actionparser.c b/src/actionparser.c new file mode 100644 index 0000000..33e8ccc --- /dev/null +++ b/src/actionparser.c @@ -0,0 +1,241 @@ +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "actionparser.h" + +/* -------------------------------------------------------------------------- + * The following code is resposinble for parsing the command line arguments + * and report any errors that might come up. + * -------------------------------------------------------------------------- */ + +/* accepted commands */ +/* [0] is the count */ +const char* const strINIT[] = {"2", "init", "-i"}; +const char* const strADD[] = {"2", "add", "-a"}; +const char* const strDEL[] = {"2", "del", "-d"}; +const char* const strEDIT[] = {"3", "edit", "e", "-e"}; +const char* const strLIST[] = {"3", "list", "ls", "-ls"}; +const char* const strSEARCH[] = {"3", "search", "s", "-s"}; +const char* const strHELP[] = {"4", "help", "?", "-h", "--help"}; + +/* Number of opts */ +static int optNum; +/* holds the list of the opts + as given by the user */ +static char **opts; +/* points to the current token */ +static char *token; +/* points to the position + * to be read */ +static int pos = 0; + +/* Reads the next token and returns it's position + * Returns -1 otherwise */ +int nextToken() { + if (pos < optNum) { + token = opts[pos]; + return pos++; + } + else { + token = ""; + return -1; + } +} + +void getOpt(int position, UserOpt *opt) { + // get arg + nextToken(); + + // allocate memory + opt->argv[position] = (char *)malloc((strlen(token)+1)*sizeof(char)); + strcpy(opt->argv[position], token); +} + +/* When starting to parse the action, + * `pos` should be at 2 + * like so "ck ACTION ..." + * ^ */ +int parseINIT(UserOpt *opt) { + // if db exists init should fail before checking for args + + // INIT expects 2 arguments + // starting from 0 + opt->argc = 2; + if (optNum != pos /* already consumed */ + opt->argc) { + opt->err = PERR_INIT_WRONG; + return -1; + } + + for (int i = 0; i < opt->argc; i++) { + getOpt(i, opt); + } + return 1; +} + +int parseADD(UserOpt *opt) { + // ADD expects 2 to 4 arguments + if (optNum <= pos + 1 + || optNum > pos + 4) { + opt->err = PERR_ADD_WRONG; + return -1; + } + return 1; +} + +int parseDEL(UserOpt *opt) { +} +int parseEDIT(UserOpt *opt) { +} +int parseLIST(UserOpt *opt) { +} +int parseSEARCH(UserOpt *opt) { +} +int parseHELP(UserOpt *opt) { +} + + +int parseVals(UserOpt *opt) { + switch (opt->action) { +#define X(ACTION) \ + case CKA_##ACTION: \ + return parse##ACTION(opt); + CK_ACTIONS +#undef X + default: + // can't end up here, but it prevents a compiler warning + opt->err = PERR_UNKONW_ACTION; + return -1; + break; + } + return 1; +} + +CkAction determineAction() { + int i = 0; +#define X(ACTION) \ + for (i = 1; i < atoi(str##ACTION[0]) + 1; i++) { \ + if (strcmp(token, str##ACTION[i]) == 0) { \ + return CKA_##ACTION; \ + } \ + } + CK_ACTIONS +#undef X + return -1; +} + +UserOpt initUserOpt() { + UserOpt uo; + uo.action = -1; + uo.err = PERR_NOERR; + uo.argc = 0; + for (int i = 0; i < 10; i++) { + uo.argv[i] = NULL; + } + return uo; +} + +ParseResult parseAction(int argc, char* argv[], UserOpt *opt) { + *opt = initUserOpt(); + if (argc < 2) { + return OPR_HELP; + } + opts = argv; + optNum = argc; + + // skip the program nake + nextToken(); + + // get action + nextToken(); + opt->action = determineAction(); + if (opt->action == -1) { + opt->err = PERR_UNKONW_ACTION; + return OPR_ERR; + } + if (opt->action == CKA_HELP) { + return OPR_HELP; + } + + // parse values + if (!parseVals(opt)) { + return OPR_ERR; + } + + if (opt->err == PERR_NOERR) { + return OPR_OK; + } + else { + return OPR_ERR; + } +} + +const char * getPossibleActionName(const char* const strAction[]) { + char *names; + size_t size = 2; // first chars "{ " + for (int i = 1; i < atoi(strAction[0]) + 1; i++) { + size += strlen(strAction[i]) + 2; // comma and space for each entry and " }" for the last one + } + if ((names = malloc(size)) != NULL) { + strcpy(names, "{ "); + int i = 1; + for (; i < atoi(strAction[0]); i++) { + strcat(names, strAction[i]); + strcat(names, ", "); + } + // last one + strcat(names, strAction[atoi(strAction[0])]); + strcat(names, " }"); + return names; + } + return NULL; +} + +void printParserError(UserOpt *opt) { + char *errStr = NULL; + switch (opt->err) { + case PERR_NOERR: + return; + case PERR_UNKONW_ACTION: + asprintf(&errStr, "Unknown action: %s", token); + break; + case PERR_INIT_WRONG: + asprintf(&errStr, "Initialize database\nUsage: %s VC_dir SCRT_dir DB_dir", getPossibleActionName(strINIT)); + break; + case PERR_ADD_WRONG: + asprintf(&errStr, "Add config (new or existing)\nUsage: %s ProgramName ConfigPath [-s](secret) [-p](primary)", getPossibleActionName(strADD)); + break; + case PERR_DEL_WRONG: + asprintf(&errStr, "Delete config or program\nUsage: %s ProgramName ConfigPath [-s](secret) [-p](primary)", getPossibleActionName(strDEL)); + break; + case PERR_EDIT_WRONG: + asprintf(&errStr, "Edit config\nUsage: add ProgramName ConfigPath [-s](secret) [-p](primary)"); + break; + case PERR_LIST_WRONG: + asprintf(&errStr, "Usage: add ProgramName ConfigPath [-s](secret) [-p](primary)"); + break; + case PERR_SEARCH_WRONG: + asprintf(&errStr, "Usage: add ProgramName ConfigPath [-s](secret) [-p](primary)"); + break; + case PERR_HELP_WRONG: + asprintf(&errStr, "Usage: add ProgramName ConfigPath [-s](secret) [-p](primary)"); + break; + } + printf("Parsing error\n%s\n", errStr); + exit(1); +} + +void printParserHelp() { + printf("ck - the config keeper"); + printf("\n----------------------"); + printf("\n----------------------\n"); + printf("Usage:\n"); + printf("Initialize: \t%s\n", getPossibleActionName(strINIT)); + printf("Add config: \t%s\n", getPossibleActionName(strADD)); + printf("Delete config: \t%s\n", getPossibleActionName(strDEL)); + printf("Edit config: \t%s\n", getPossibleActionName(strEDIT)); + printf("List configs: \t%s\n", getPossibleActionName(strLIST)); + printf("Search: \t%s\n", getPossibleActionName(strSEARCH)); + printf("Print this: \t%s\n", getPossibleActionName(strHELP)); + exit(0); +} |