Wed, 20 May 2015 11:14:33 +0200
completed field list parser + error messages do now provide more context information based on the source string
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2015 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 "optparser.h" void cmd_args_free(CmdArgs *args) { ucx_map_free(args->options); free(args->argv); free(args); } CmdArgs* cmd_parse_args(int argc, char **argv) { CmdArgs *a = malloc(sizeof(CmdArgs)); a->options = ucx_map_new(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", arg[c]); cmd_args_free(a); return NULL; } case 'v': { ucx_map_cstr_put(a->options, "verbose", NOARG); break; } case 'k': { if(!option) { option = "key"; optchar = 'k'; } else { fprintf( stderr, "Missing argument for option -%c\n", optchar); cmd_args_free(a); return NULL; } break; } case 'p': { ucx_map_cstr_put(a->options, "plain", NOARG); break; } case 'c': { ucx_map_cstr_put(a->options, "crypt", NOARG); break; } case 'a': { ucx_map_cstr_put(a->options, "all", NOARG); break; } case 'l': { ucx_map_cstr_put(a->options, "list", NOARG); break; } case 't': { ucx_map_cstr_put(a->options, "type", NOARG); break; } case 'R': { ucx_map_cstr_put(a->options, "recursive", NOARG); break; } case 'o': { if(!option) { option = "output"; optchar = 'o'; } else { fprintf( stderr, "Missing argument for option -%c\n", optchar); cmd_args_free(a); return NULL; } break; } case 'u': { if(!option) { option = "update"; optchar = 'u'; } else { fprintf( stderr, "Missing argument for option -%c\n", optchar); cmd_args_free(a); return NULL; } break; } case 'n': { if(!option) { option = "namespace"; optchar = 'n'; } else { fprintf( stderr, "Missing argument for option -%c\n", optchar); cmd_args_free(a); return NULL; } break; } } } } else if(option) { ucx_map_cstr_put(a->options, option, arg); option = NULL; } else { a->argv[a->argc++] = arg; } } return a; } char* cmd_getoption(CmdArgs *arg, char *name) { return ucx_map_cstr_get(arg->options, name); }