aboutsummaryrefslogtreecommitdiffstats
path: root/src/actionparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/actionparser.c')
-rw-r--r--src/actionparser.c241
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);
+}