UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2018 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 33 #include "sopt.h" 34 35 #include <cx/hash_map.h> 36 37 void cmd_args_free(CmdArgs *args) { 38 if(args) { 39 cxMapDestroy(args->options); 40 free(args->argv); 41 free(args); 42 } 43 } 44 45 static void cmd_map_put(CxMap *map, const char *key, const void *value) { 46 cxMapPut(map, key, (void*)value); 47 } 48 49 CmdArgs* cmd_parse_args(int argc, char **argv) { 50 CmdArgs *a = malloc(sizeof(CmdArgs)); 51 a->options = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); 52 a->argv = calloc(argc, sizeof(char*)); 53 a->argc = 0; 54 55 const char *NOARG = ""; 56 57 char *option = NULL; 58 char optchar = 0; 59 for(int i=0;i<argc;i++) { 60 char *arg = argv[i]; 61 size_t len = strlen(arg); 62 if(len > 1 && arg[0] == '-') { 63 for(int c=1;c<len;c++) { 64 switch(arg[c]) { 65 default: { 66 fprintf(stderr, "Unknown option -%c\n\n", arg[c]); 67 cmd_args_free(a); 68 return NULL; 69 } 70 case 'c': { 71 cmd_map_put(a->options, "conflict", NOARG); 72 break; 73 } 74 case 'l': { 75 cmd_map_put(a->options, "lock", NOARG); 76 break; 77 } 78 case 'd': { 79 cmd_map_put(a->options, "nolock", NOARG); 80 break; 81 } 82 case 'r': { 83 cmd_map_put(a->options, "remove", NOARG); 84 break; 85 } 86 case 'v': { 87 cmd_map_put(a->options, "verbose", NOARG); 88 break; 89 } 90 case 's': { 91 option = "syncdir"; 92 optchar = 's'; 93 break; 94 } 95 case 't': { 96 option = "tags"; 97 optchar = 't'; 98 break; 99 } 100 case 'V': { 101 option = "version"; 102 optchar = 'V'; 103 break; 104 } 105 case 'R': { 106 cmd_map_put(a->options, "restore-removed", NOARG); 107 break; 108 } 109 case 'M': { 110 cmd_map_put(a->options, "restore-modified", NOARG); 111 break; 112 } 113 case 'S': { 114 cmd_map_put(a->options, "snapshot", NOARG); 115 } 116 } 117 } 118 } else if(option) { 119 cmd_map_put(a->options, option, arg); 120 option = NULL; 121 } else { 122 a->argv[a->argc++] = arg; 123 } 124 } 125 126 return a; 127 } 128 129 char* cmd_getoption(CmdArgs *arg, const char *name) { 130 return cxMapGet(arg->options, cx_hash_key_str(name)); 131 } 132