]> git.datanom.net - caldav.git/blobdiff - test-app/cmdline-parser.c
First complete version
[caldav.git] / test-app / cmdline-parser.c
diff --git a/test-app/cmdline-parser.c b/test-app/cmdline-parser.c
new file mode 100644 (file)
index 0000000..747e3d7
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ * cmdline-parser.c
+ *
+ * Copyright 2017 Michael Rasmussen <mir@datanom.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <glib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "cmdline-parser.h"
+#include "caldav.h"
+
+static const gchar* help[] = {
+       "Usage: test-app [Options] -o operation -p password -u username URL",
+       "",
+       "a|data     Use this option to insert calendar data from file.",
+       "           As an alternative use redirect IO with <.",
+       "d|debug    Print a lot of debug information to STDOUT",
+       "e|etag     ETag to use for update and delete",
+       "f|finish   End time interval in ISO 8601 local time. 2017-01-13T13:13:13",
+       "h|help     Show this help info.",
+       "r|href     HREFs to use for getobjects. Each href on a separate line.",
+       "           As an alternative use redirect IO with <.",
+       "s|start    Start time interval in ISO 8601 local time. 2017-01-13T13:13:13",
+       NULL
+};
+
+static void show_help() {
+       for (int i = 0; help[i]; i++) {
+               printf("%s\n", help[i]);
+       }
+}
+
+static void get_operation(const gchar* op, Operation* o) {
+       if (o) {
+               if (g_strcmp0("CALENDARINFO", op) == 0) {
+                       *o = CALENDARINFO;
+               } else if (g_strcmp0("GETOBJECTS", op) == 0) {
+                       *o = GETOBJECTS;
+               } else if (g_strcmp0("GETALLOBJECTS", op) == 0) {
+                       *o = GETALLOBJECTS;
+               } else if (g_strcmp0("SIMPLEGET", op) == 0) {
+                       *o = SIMPLEGET;
+               } else if (g_strcmp0("CHANGEINFO", op) == 0) {
+                       *o = CHANGEINFO;
+               } else if (g_strcmp0("UPDATEOBJECTS", op) == 0) {
+                       *o = UPDATEOBJECTS;
+               } else if (g_strcmp0("ADDOBJECTS", op) == 0) {
+                       *o = ADDOBJECTS;
+               } else if (g_strcmp0("DELETEOBJECTS", op) == 0) {
+                       *o = DELETEOBJECTS;
+               } else if (g_strcmp0("DISCOVER", op) == 0) {
+                       *o = DISCOVER;
+               } else if (g_strcmp0("OPTIONSINFO", op) == 0) {
+                       *o = OPTIONSINFO;
+               } else if (g_strcmp0("FREEBUSY", op) == 0) {
+                       *o = FREEBUSY;
+               } else {
+                       *o = UNKNOWN;
+               }
+       }
+}
+
+static gboolean invalid_test_case(Runtime* test) {
+       gboolean invalid = TRUE;
+       gboolean error = FALSE;
+
+       if (test) {
+               if (!test->username) {
+                       printf("Missing username\n");
+                       error = TRUE;
+               }
+               if (!test->password) {
+                       printf("Missing password\n");
+                       error = TRUE;
+               }
+               if (!test->url) {
+                       printf("Missing URL\n");
+                       error = TRUE;
+               }
+               if (!test->operation) {
+                       printf("Missing operation\n");
+                       error = TRUE;
+               }
+               invalid = (error) ? TRUE : FALSE;
+       }
+
+       return invalid;
+}
+
+#define BUF_SIZE 1024
+static gchar* read_stream(FILE* stream) {
+       gchar buffer[BUF_SIZE];
+       size_t size = 1;
+       gchar* content = g_malloc0(sizeof(gchar) * BUF_SIZE);
+
+       while (fgets(buffer, BUF_SIZE, stream) != NULL) {
+               size += strlen(buffer);
+               content = g_realloc(content, size);
+               g_strlcat(content, buffer, size);
+       }
+
+       return content;
+}
+
+static GSList* parse_input(const gchar* input) {
+       GSList* list = NULL;
+
+       gchar** strings = g_strsplit(input, "\n", 0);
+       for (gchar** h = strings; *h; ++h) {
+               if (g_strcmp0(*h, "") != 0) {
+                       HrefData* hd = href_data_new(*h, NULL);
+                       list = g_slist_append(list, hd);
+               }
+       }
+       g_strfreev(strings);
+
+       return list;
+}
+
+Runtime* parse_cmdline(int argc, char **argv) {
+       int opt = 0;
+       int debug_flag = 0;
+       Runtime* test = runtime_new();
+       Operation* op = g_new(Operation, 1);
+       FILE* stream = NULL;
+
+       struct option long_options[] = {
+               {"data",      required_argument, 0,           'a'},
+               {"etag",      required_argument, 0,           'e'},
+               {"finish",    required_argument, 0,           'f'},
+               {"debug",     no_argument,       &debug_flag,  1 },
+               {"help",      no_argument,       0,           'h'},
+               {"operation", required_argument, 0,           'o'},
+               {"password",  required_argument, 0,           'p'},
+               {"href",      required_argument, 0,           'r'},
+               {"start",     required_argument, 0,           's'},
+               {"username",  required_argument, 0,           'u'},
+               {0,           0,                 0,            0 }
+       };
+
+       int option_index = 0;
+       while ((opt = getopt_long(argc, argv, "a:de:f:h:o:p:rs:u:",
+                                       long_options, &option_index)) != -1) {
+               switch (opt) {
+                       case 'a': {
+                               stream = fopen(optarg, "r");
+                               if (!stream) {
+                                       perror("File");
+                                       runtime_free(test);
+                                       exit(EXIT_FAILURE);
+                               }
+                               break;
+                       }
+
+                       case 'd':
+                               debug_flag = 1;
+                               break;
+
+                       case 'e':
+                               test->etag = g_strdup(optarg);
+                               break;
+
+                       case 'f':
+                               test->finish = get_date_time_from_string(optarg);
+                               break;
+
+                       case 'h':
+                               runtime_free(test);
+                               show_help();
+                               exit(EXIT_SUCCESS);
+
+                       case 'o':
+                               get_operation(optarg, op);
+                               if (op && *op != UNKNOWN) {
+                                       test->operation = op;
+                               } else {
+                                       runtime_free(test);
+                                       fprintf(stderr, "%s: Invalid operation\n", optarg);
+                                       show_help();
+                                       exit(EXIT_FAILURE);
+                               }
+                               break;
+
+                       case 'p':
+                               test->password = g_strdup(optarg);
+                               break;
+
+                       case 'r': {
+                               stream = fopen(optarg, "r");
+                               if (!stream) {
+                                       perror("File");
+                                       runtime_free(test);
+                                       exit(EXIT_FAILURE);
+                               }
+                               break;
+                       }
+
+                       case 's':
+                               test->start = get_date_time_from_string(optarg);
+                               break;
+
+                       case 'u':
+                               test->username = g_strdup(optarg);
+                               break;
+
+                       case ':':
+                               /* missing option argument */
+                               runtime_free(test);
+                               printf("%s: option '-%c' requires an argument\n", argv[0], optopt);
+                               show_help();
+                               exit(EXIT_FAILURE);
+
+                       case '?':
+                       default:
+                               /* invalid option */
+                               runtime_free(test);
+                               fprintf(stderr, "%s: option '-%c' is invalid: ignored\n", argv[0], optopt);
+                               show_help();
+                               exit(EXIT_FAILURE);
+               }
+       }
+
+       if (optind + 1 < argc) {
+               runtime_free(test);
+               printf("Only one URL allowed\n");
+               show_help();
+               exit(EXIT_FAILURE);
+       }
+
+       test->url= g_strdup(argv[optind]);
+
+       if (invalid_test_case(test)) {
+               runtime_free(test);
+               show_help();
+               exit(EXIT_FAILURE);
+       }
+
+       if (*test->operation == ADDOBJECTS || *test->operation == UPDATEOBJECTS) {
+               struct stat sb;
+               if (fstat(fileno(stdin), &sb) == -1) {
+                       if (!stream) {
+                               perror("Stat");
+                               runtime_free(test);
+                               exit(EXIT_FAILURE);
+                       }
+               } else {
+                       if (stream && sb.st_size > 0) {
+                               fprintf(stderr, "Error: Option --data or --href active. Cannot redirect STDIN\n");
+                               runtime_free(test);
+                               exit(EXIT_FAILURE);
+                       } else {
+                               stream = (stream) ? stream : stdin;
+                       }
+               }
+
+               gchar* text = read_stream(stream);
+
+               switch (*test->operation) {
+                       case GETOBJECTS:
+                               test->hrefs = parse_input(text);
+                               g_free(text);
+                               break;
+                       case UPDATEOBJECTS:
+                       case ADDOBJECTS:
+                               test->component = text;
+                               break;
+                       default:
+                               fprintf(stderr, "%i: Input not allowed\n", *test->operation);
+                               runtime_free(test);
+                               g_free(text);
+                               exit(EXIT_FAILURE);
+               }
+       }
+
+       test->debug = (debug_flag) ? TRUE : FALSE;
+
+       return test;
+}
+
This page took 0.040105 seconds and 5 git commands to generate.