Thu, 28 Nov 2024 17:20:19 +0100
fix crash in printxmldoc, fixes #514
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2018 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "sopt.h" #include <cx/hash_map.h> void cmd_args_free(CmdArgs *args) { if(args) { cxMapDestroy(args->options); free(args->argv); free(args); } } static void cmd_map_put(CxMap *map, const char *key, const void *value) { cxMapPut(map, key, (void*)value); } CmdArgs* cmd_parse_args(int argc, char **argv) { CmdArgs *a = malloc(sizeof(CmdArgs)); a->options = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); a->argv = calloc(argc, sizeof(char*)); a->argc = 0; const char *NOARG = ""; char *option = NULL; char optchar = 0; for(int i=0;i<argc;i++) { char *arg = argv[i]; size_t len = strlen(arg); if(len > 1 && arg[0] == '-') { for(int c=1;c<len;c++) { switch(arg[c]) { default: { fprintf(stderr, "Unknown option -%c\n\n", arg[c]); cmd_args_free(a); return NULL; } case 'c': { cmd_map_put(a->options, "conflict", NOARG); break; } case 'l': { cmd_map_put(a->options, "lock", NOARG); break; } case 'd': { cmd_map_put(a->options, "nolock", NOARG); break; } case 'r': { cmd_map_put(a->options, "remove", NOARG); break; } case 'v': { cmd_map_put(a->options, "verbose", NOARG); break; } case 's': { option = "syncdir"; optchar = 's'; break; } case 't': { option = "tags"; optchar = 't'; break; } case 'V': { option = "version"; optchar = 'V'; break; } case 'R': { cmd_map_put(a->options, "restore-removed", NOARG); break; } case 'M': { cmd_map_put(a->options, "restore-modified", NOARG); break; } case 'S': { cmd_map_put(a->options, "snapshot", NOARG); } } } } else if(option) { cmd_map_put(a->options, option, arg); option = NULL; } else { a->argv[a->argc++] = arg; } } return a; } char* cmd_getoption(CmdArgs *arg, const char *name) { return cxMapGet(arg->options, cx_hash_key_str(name)); }