155682Smarkm/* 2233294Sstas * Copyright (c) 1997 - 2002 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 555682Smarkm * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 955682Smarkm * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1655682Smarkm * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 2055682Smarkm * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include <config.h> 3555682Smarkm 3655682Smarkm#include <stdio.h> 3772445Sassar#include <stdlib.h> 3872445Sassar#include <string.h> 39178825Sdfr#include "roken.h" 4055682Smarkm#include "getarg.h" 4155682Smarkm 4255682Smarkm#define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag) 4355682Smarkm 4455682Smarkmstatic size_t 45233294Sstasprint_arg (char *string, 46233294Sstas size_t len, 47233294Sstas int mdoc, 48233294Sstas int longp, 49233294Sstas struct getargs *arg, 50233294Sstas char *(i18n)(const char *)) 5155682Smarkm{ 5255682Smarkm const char *s; 5355682Smarkm 5455682Smarkm *string = '\0'; 5555682Smarkm 5655682Smarkm if (ISFLAG(*arg) || (!longp && arg->type == arg_counter)) 5755682Smarkm return 0; 5855682Smarkm 5955682Smarkm if(mdoc){ 6055682Smarkm if(longp) 6155682Smarkm strlcat(string, "= Ns", len); 6255682Smarkm strlcat(string, " Ar ", len); 6372445Sassar } else { 6455682Smarkm if (longp) 6555682Smarkm strlcat (string, "=", len); 6655682Smarkm else 6755682Smarkm strlcat (string, " ", len); 6872445Sassar } 6955682Smarkm 7055682Smarkm if (arg->arg_help) 71233294Sstas s = (*i18n)(arg->arg_help); 7255682Smarkm else if (arg->type == arg_integer || arg->type == arg_counter) 7355682Smarkm s = "integer"; 7455682Smarkm else if (arg->type == arg_string) 7555682Smarkm s = "string"; 7672445Sassar else if (arg->type == arg_strings) 7772445Sassar s = "strings"; 7855682Smarkm else if (arg->type == arg_double) 7955682Smarkm s = "float"; 8055682Smarkm else 8155682Smarkm s = "<undefined>"; 8255682Smarkm 8355682Smarkm strlcat(string, s, len); 8455682Smarkm return 1 + strlen(s); 8555682Smarkm} 8655682Smarkm 8755682Smarkmstatic void 8855682Smarkmmandoc_template(struct getargs *args, 8955682Smarkm size_t num_args, 9055682Smarkm const char *progname, 91233294Sstas const char *extra_string, 92233294Sstas char *(i18n)(const char *)) 9355682Smarkm{ 94233294Sstas size_t i; 9555682Smarkm char timestr[64], cmd[64]; 9655682Smarkm char buf[128]; 9755682Smarkm const char *p; 9855682Smarkm time_t t; 9955682Smarkm 10055682Smarkm printf(".\\\" Things to fix:\n"); 10155682Smarkm printf(".\\\" * correct section, and operating system\n"); 10255682Smarkm printf(".\\\" * remove Op from mandatory flags\n"); 10355682Smarkm printf(".\\\" * use better macros for arguments (like .Pa for files)\n"); 10455682Smarkm printf(".\\\"\n"); 10555682Smarkm t = time(NULL); 10655682Smarkm strftime(timestr, sizeof(timestr), "%B %e, %Y", localtime(&t)); 10755682Smarkm printf(".Dd %s\n", timestr); 10855682Smarkm p = strrchr(progname, '/'); 10955682Smarkm if(p) p++; else p = progname; 11055682Smarkm strlcpy(cmd, p, sizeof(cmd)); 11155682Smarkm strupr(cmd); 112233294Sstas 11355682Smarkm printf(".Dt %s SECTION\n", cmd); 11455682Smarkm printf(".Os OPERATING_SYSTEM\n"); 11555682Smarkm printf(".Sh NAME\n"); 11655682Smarkm printf(".Nm %s\n", p); 117233294Sstas printf(".Nd in search of a description\n"); 11855682Smarkm printf(".Sh SYNOPSIS\n"); 11955682Smarkm printf(".Nm\n"); 12055682Smarkm for(i = 0; i < num_args; i++){ 12155682Smarkm /* we seem to hit a limit on number of arguments if doing 12255682Smarkm short and long flags with arguments -- split on two lines */ 123233294Sstas if(ISFLAG(args[i]) || 12455682Smarkm args[i].short_name == 0 || args[i].long_name == NULL) { 12555682Smarkm printf(".Op "); 12655682Smarkm 12755682Smarkm if(args[i].short_name) { 128233294Sstas print_arg(buf, sizeof(buf), 1, 0, args + i, i18n); 12955682Smarkm printf("Fl %c%s", args[i].short_name, buf); 13055682Smarkm if(args[i].long_name) 13155682Smarkm printf(" | "); 13255682Smarkm } 13355682Smarkm if(args[i].long_name) { 134233294Sstas print_arg(buf, sizeof(buf), 1, 1, args + i, i18n); 135233294Sstas printf("Fl Fl %s%s%s", 13657419Smarkm args[i].type == arg_negative_flag ? "no-" : "", 13757419Smarkm args[i].long_name, buf); 13855682Smarkm } 13955682Smarkm printf("\n"); 14055682Smarkm } else { 141233294Sstas print_arg(buf, sizeof(buf), 1, 0, args + i, i18n); 14255682Smarkm printf(".Oo Fl %c%s \\*(Ba Xo\n", args[i].short_name, buf); 143233294Sstas print_arg(buf, sizeof(buf), 1, 1, args + i, i18n); 144233294Sstas printf(".Fl Fl %s%s\n.Xc\n.Oc\n", args[i].long_name, buf); 14555682Smarkm } 14655682Smarkm /* 14755682Smarkm if(args[i].type == arg_strings) 14855682Smarkm fprintf (stderr, "..."); 14955682Smarkm */ 15055682Smarkm } 15155682Smarkm if (extra_string && *extra_string) 15255682Smarkm printf (".Ar %s\n", extra_string); 15355682Smarkm printf(".Sh DESCRIPTION\n"); 15455682Smarkm printf("Supported options:\n"); 15555682Smarkm printf(".Bl -tag -width Ds\n"); 15655682Smarkm for(i = 0; i < num_args; i++){ 15755682Smarkm printf(".It Xo\n"); 15855682Smarkm if(args[i].short_name){ 15955682Smarkm printf(".Fl %c", args[i].short_name); 160233294Sstas print_arg(buf, sizeof(buf), 1, 0, args + i, i18n); 16155682Smarkm printf("%s", buf); 16255682Smarkm if(args[i].long_name) 163102644Snectar printf(" ,"); 16455682Smarkm printf("\n"); 16555682Smarkm } 16655682Smarkm if(args[i].long_name){ 167233294Sstas printf(".Fl Fl %s%s", 16857419Smarkm args[i].type == arg_negative_flag ? "no-" : "", 16957419Smarkm args[i].long_name); 170233294Sstas print_arg(buf, sizeof(buf), 1, 1, args + i, i18n); 17155682Smarkm printf("%s\n", buf); 17255682Smarkm } 17355682Smarkm printf(".Xc\n"); 17455682Smarkm if(args[i].help) 17555682Smarkm printf("%s\n", args[i].help); 17655682Smarkm /* 17755682Smarkm if(args[i].type == arg_strings) 17855682Smarkm fprintf (stderr, "..."); 17955682Smarkm */ 18055682Smarkm } 18155682Smarkm printf(".El\n"); 18255682Smarkm printf(".\\\".Sh ENVIRONMENT\n"); 18355682Smarkm printf(".\\\".Sh FILES\n"); 18455682Smarkm printf(".\\\".Sh EXAMPLES\n"); 18555682Smarkm printf(".\\\".Sh DIAGNOSTICS\n"); 18655682Smarkm printf(".\\\".Sh SEE ALSO\n"); 18755682Smarkm printf(".\\\".Sh STANDARDS\n"); 18855682Smarkm printf(".\\\".Sh HISTORY\n"); 18955682Smarkm printf(".\\\".Sh AUTHORS\n"); 19055682Smarkm printf(".\\\".Sh BUGS\n"); 19155682Smarkm} 19255682Smarkm 19355682Smarkmstatic int 19455682Smarkmcheck_column(FILE *f, int col, int len, int columns) 19555682Smarkm{ 19655682Smarkm if(col + len > columns) { 19755682Smarkm fprintf(f, "\n"); 19855682Smarkm col = fprintf(f, " "); 19955682Smarkm } 20055682Smarkm return col; 20155682Smarkm} 20255682Smarkm 203233294Sstasstatic char * 204233294Sstasbuiltin_i18n(const char *str) 205233294Sstas{ 206233294Sstas return rk_UNCONST(str); 207233294Sstas} 208233294Sstas 209233294SstasROKEN_LIB_FUNCTION void ROKEN_LIB_CALL 21055682Smarkmarg_printusage (struct getargs *args, 21155682Smarkm size_t num_args, 21255682Smarkm const char *progname, 21355682Smarkm const char *extra_string) 21455682Smarkm{ 215233294Sstas arg_printusage_i18n(args, num_args, "Usage", 216233294Sstas progname, extra_string, builtin_i18n); 217233294Sstas} 218233294Sstas 219233294SstasROKEN_LIB_FUNCTION void ROKEN_LIB_CALL 220233294Sstasarg_printusage_i18n (struct getargs *args, 221233294Sstas size_t num_args, 222233294Sstas const char *usage, 223233294Sstas const char *progname, 224233294Sstas const char *extra_string, 225233294Sstas char *(*i18n)(const char *)) 226233294Sstas{ 227233294Sstas size_t i, max_len = 0; 22855682Smarkm char buf[128]; 22955682Smarkm int col = 0, columns; 23055682Smarkm 23155682Smarkm if (progname == NULL) 23278527Sassar progname = getprogname(); 23355682Smarkm 234233294Sstas if (i18n == NULL) 235233294Sstas i18n = builtin_i18n; 236233294Sstas 23755682Smarkm if(getenv("GETARGMANDOC")){ 238233294Sstas mandoc_template(args, num_args, progname, extra_string, i18n); 23955682Smarkm return; 24055682Smarkm } 241233294Sstas if(get_window_size(2, NULL, &columns) == -1) 24255682Smarkm columns = 80; 24355682Smarkm col = 0; 244233294Sstas col += fprintf (stderr, "%s: %s", usage, progname); 24578527Sassar buf[0] = '\0'; 24655682Smarkm for (i = 0; i < num_args; ++i) { 24778527Sassar if(args[i].short_name && ISFLAG(args[i])) { 24878527Sassar char s[2]; 24978527Sassar if(buf[0] == '\0') 25078527Sassar strlcpy(buf, "[-", sizeof(buf)); 25178527Sassar s[0] = args[i].short_name; 25278527Sassar s[1] = '\0'; 25378527Sassar strlcat(buf, s, sizeof(buf)); 25478527Sassar } 25578527Sassar } 25678527Sassar if(buf[0] != '\0') { 25778527Sassar strlcat(buf, "]", sizeof(buf)); 25878527Sassar col = check_column(stderr, col, strlen(buf) + 1, columns); 25978527Sassar col += fprintf(stderr, " %s", buf); 26078527Sassar } 26178527Sassar 26278527Sassar for (i = 0; i < num_args; ++i) { 26355682Smarkm size_t len = 0; 26455682Smarkm 26555682Smarkm if (args[i].long_name) { 26655682Smarkm buf[0] = '\0'; 26755682Smarkm strlcat(buf, "[--", sizeof(buf)); 26855682Smarkm len += 2; 26955682Smarkm if(args[i].type == arg_negative_flag) { 27055682Smarkm strlcat(buf, "no-", sizeof(buf)); 27155682Smarkm len += 3; 27255682Smarkm } 27355682Smarkm strlcat(buf, args[i].long_name, sizeof(buf)); 27455682Smarkm len += strlen(args[i].long_name); 275233294Sstas len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf), 276233294Sstas 0, 1, &args[i], i18n); 27755682Smarkm strlcat(buf, "]", sizeof(buf)); 27855682Smarkm if(args[i].type == arg_strings) 27955682Smarkm strlcat(buf, "...", sizeof(buf)); 28055682Smarkm col = check_column(stderr, col, strlen(buf) + 1, columns); 28155682Smarkm col += fprintf(stderr, " %s", buf); 28255682Smarkm } 28378527Sassar if (args[i].short_name && !ISFLAG(args[i])) { 28455682Smarkm snprintf(buf, sizeof(buf), "[-%c", args[i].short_name); 28555682Smarkm len += 2; 286233294Sstas len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf), 287233294Sstas 0, 0, &args[i], i18n); 28855682Smarkm strlcat(buf, "]", sizeof(buf)); 28955682Smarkm if(args[i].type == arg_strings) 29055682Smarkm strlcat(buf, "...", sizeof(buf)); 29155682Smarkm col = check_column(stderr, col, strlen(buf) + 1, columns); 29255682Smarkm col += fprintf(stderr, " %s", buf); 29355682Smarkm } 29455682Smarkm if (args[i].long_name && args[i].short_name) 29555682Smarkm len += 2; /* ", " */ 29655682Smarkm max_len = max(max_len, len); 29755682Smarkm } 29855682Smarkm if (extra_string) { 299233294Sstas check_column(stderr, col, strlen(extra_string) + 1, columns); 30055682Smarkm fprintf (stderr, " %s\n", extra_string); 30155682Smarkm } else 30255682Smarkm fprintf (stderr, "\n"); 30355682Smarkm for (i = 0; i < num_args; ++i) { 30455682Smarkm if (args[i].help) { 30555682Smarkm size_t count = 0; 30655682Smarkm 30755682Smarkm if (args[i].short_name) { 30855682Smarkm count += fprintf (stderr, "-%c", args[i].short_name); 309233294Sstas print_arg (buf, sizeof(buf), 0, 0, &args[i], i18n); 31055682Smarkm count += fprintf(stderr, "%s", buf); 31155682Smarkm } 31255682Smarkm if (args[i].short_name && args[i].long_name) 31355682Smarkm count += fprintf (stderr, ", "); 31455682Smarkm if (args[i].long_name) { 31555682Smarkm count += fprintf (stderr, "--"); 31655682Smarkm if (args[i].type == arg_negative_flag) 31755682Smarkm count += fprintf (stderr, "no-"); 31855682Smarkm count += fprintf (stderr, "%s", args[i].long_name); 319233294Sstas print_arg (buf, sizeof(buf), 0, 1, &args[i], i18n); 32055682Smarkm count += fprintf(stderr, "%s", buf); 32155682Smarkm } 32255682Smarkm while(count++ <= max_len) 32355682Smarkm putc (' ', stderr); 324233294Sstas fprintf (stderr, "%s\n", (*i18n)(args[i].help)); 32555682Smarkm } 32655682Smarkm } 32755682Smarkm} 32855682Smarkm 329178825Sdfrstatic int 33055682Smarkmadd_string(getarg_strings *s, char *value) 33155682Smarkm{ 332178825Sdfr char **strings; 333178825Sdfr 334178825Sdfr strings = realloc(s->strings, (s->num_strings + 1) * sizeof(*s->strings)); 335178825Sdfr if (strings == NULL) { 336178825Sdfr free(s->strings); 337178825Sdfr s->strings = NULL; 338178825Sdfr s->num_strings = 0; 339178825Sdfr return ENOMEM; 340178825Sdfr } 341178825Sdfr s->strings = strings; 34255682Smarkm s->strings[s->num_strings] = value; 34355682Smarkm s->num_strings++; 344178825Sdfr return 0; 34555682Smarkm} 34655682Smarkm 34755682Smarkmstatic int 34855682Smarkmarg_match_long(struct getargs *args, size_t num_args, 349102644Snectar char *argv, int argc, char **rargv, int *goptind) 35055682Smarkm{ 351233294Sstas size_t i; 352102644Snectar char *goptarg = NULL; 35355682Smarkm int negate = 0; 35455682Smarkm int partial_match = 0; 35555682Smarkm struct getargs *partial = NULL; 35655682Smarkm struct getargs *current = NULL; 35755682Smarkm int argv_len; 35855682Smarkm char *p; 359102644Snectar int p_len; 36055682Smarkm 36155682Smarkm argv_len = strlen(argv); 36255682Smarkm p = strchr (argv, '='); 36355682Smarkm if (p != NULL) 36455682Smarkm argv_len = p - argv; 36555682Smarkm 36655682Smarkm for (i = 0; i < num_args; ++i) { 36755682Smarkm if(args[i].long_name) { 36855682Smarkm int len = strlen(args[i].long_name); 369102644Snectar p = argv; 370102644Snectar p_len = argv_len; 37155682Smarkm negate = 0; 37255682Smarkm 37355682Smarkm for (;;) { 37455682Smarkm if (strncmp (args[i].long_name, p, p_len) == 0) { 37555682Smarkm if(p_len == len) 37655682Smarkm current = &args[i]; 37755682Smarkm else { 37855682Smarkm ++partial_match; 37955682Smarkm partial = &args[i]; 38055682Smarkm } 381102644Snectar goptarg = p + p_len; 38255682Smarkm } else if (ISFLAG(args[i]) && strncmp (p, "no-", 3) == 0) { 38355682Smarkm negate = !negate; 38455682Smarkm p += 3; 38555682Smarkm p_len -= 3; 38655682Smarkm continue; 38755682Smarkm } 38855682Smarkm break; 38955682Smarkm } 39055682Smarkm if (current) 39155682Smarkm break; 39255682Smarkm } 39355682Smarkm } 39455682Smarkm if (current == NULL) { 39555682Smarkm if (partial_match == 1) 39655682Smarkm current = partial; 39755682Smarkm else 39855682Smarkm return ARG_ERR_NO_MATCH; 39955682Smarkm } 400233294Sstas 401102644Snectar if(*goptarg == '\0' 40255682Smarkm && !ISFLAG(*current) 40355682Smarkm && current->type != arg_collect 40455682Smarkm && current->type != arg_counter) 40555682Smarkm return ARG_ERR_NO_MATCH; 40655682Smarkm switch(current->type){ 40755682Smarkm case arg_integer: 40855682Smarkm { 40955682Smarkm int tmp; 410102644Snectar if(sscanf(goptarg + 1, "%d", &tmp) != 1) 41155682Smarkm return ARG_ERR_BAD_ARG; 41255682Smarkm *(int*)current->value = tmp; 41355682Smarkm return 0; 41455682Smarkm } 41555682Smarkm case arg_string: 41655682Smarkm { 417102644Snectar *(char**)current->value = goptarg + 1; 41855682Smarkm return 0; 41955682Smarkm } 42055682Smarkm case arg_strings: 42155682Smarkm { 422178825Sdfr return add_string((getarg_strings*)current->value, goptarg + 1); 42355682Smarkm } 42455682Smarkm case arg_flag: 42555682Smarkm case arg_negative_flag: 42655682Smarkm { 42755682Smarkm int *flag = current->value; 428102644Snectar if(*goptarg == '\0' || 429233294Sstas strcmp(goptarg + 1, "yes") == 0 || 430102644Snectar strcmp(goptarg + 1, "true") == 0){ 43155682Smarkm *flag = !negate; 43255682Smarkm return 0; 433102644Snectar } else if (*goptarg && strcmp(goptarg + 1, "maybe") == 0) { 434233294Sstas *flag = rk_random() & 1; 43555682Smarkm } else { 43655682Smarkm *flag = negate; 43755682Smarkm return 0; 43855682Smarkm } 43955682Smarkm return ARG_ERR_BAD_ARG; 44055682Smarkm } 44155682Smarkm case arg_counter : 44255682Smarkm { 44355682Smarkm int val; 44455682Smarkm 445102644Snectar if (*goptarg == '\0') 44655682Smarkm val = 1; 447102644Snectar else if(sscanf(goptarg + 1, "%d", &val) != 1) 44890926Snectar return ARG_ERR_BAD_ARG; 44955682Smarkm *(int *)current->value += val; 45055682Smarkm return 0; 45155682Smarkm } 45255682Smarkm case arg_double: 45355682Smarkm { 45455682Smarkm double tmp; 455102644Snectar if(sscanf(goptarg + 1, "%lf", &tmp) != 1) 45655682Smarkm return ARG_ERR_BAD_ARG; 45755682Smarkm *(double*)current->value = tmp; 45855682Smarkm return 0; 45955682Smarkm } 46055682Smarkm case arg_collect:{ 46155682Smarkm struct getarg_collect_info *c = current->value; 462102644Snectar int o = argv - rargv[*goptind]; 463102644Snectar return (*c->func)(FALSE, argc, rargv, goptind, &o, c->data); 46455682Smarkm } 46555682Smarkm 46655682Smarkm default: 46755682Smarkm abort (); 468233294Sstas UNREACHABLE(return 0); 46955682Smarkm } 47055682Smarkm} 47155682Smarkm 47255682Smarkmstatic int 47355682Smarkmarg_match_short (struct getargs *args, size_t num_args, 474102644Snectar char *argv, int argc, char **rargv, int *goptind) 47555682Smarkm{ 476233294Sstas size_t j, k; 47755682Smarkm 478102644Snectar for(j = 1; j > 0 && j < strlen(rargv[*goptind]); j++) { 47955682Smarkm for(k = 0; k < num_args; k++) { 480102644Snectar char *goptarg; 48155682Smarkm 48255682Smarkm if(args[k].short_name == 0) 48355682Smarkm continue; 48455682Smarkm if(argv[j] == args[k].short_name) { 48555682Smarkm if(args[k].type == arg_flag) { 48655682Smarkm *(int*)args[k].value = 1; 48755682Smarkm break; 48855682Smarkm } 48955682Smarkm if(args[k].type == arg_negative_flag) { 49055682Smarkm *(int*)args[k].value = 0; 49155682Smarkm break; 492233294Sstas } 49355682Smarkm if(args[k].type == arg_counter) { 49455682Smarkm ++*(int *)args[k].value; 49555682Smarkm break; 49655682Smarkm } 49755682Smarkm if(args[k].type == arg_collect) { 49855682Smarkm struct getarg_collect_info *c = args[k].value; 499233294Sstas int a = (int)j; 50055682Smarkm 501233294Sstas if((*c->func)(TRUE, argc, rargv, goptind, &a, c->data)) 50255682Smarkm return ARG_ERR_BAD_ARG; 503233294Sstas j = a; 50455682Smarkm break; 50555682Smarkm } 50655682Smarkm 50755682Smarkm if(argv[j + 1]) 508102644Snectar goptarg = &argv[j + 1]; 50955682Smarkm else { 510102644Snectar ++*goptind; 511102644Snectar goptarg = rargv[*goptind]; 51255682Smarkm } 513102644Snectar if(goptarg == NULL) { 514102644Snectar --*goptind; 51555682Smarkm return ARG_ERR_NO_ARG; 51672445Sassar } 51755682Smarkm if(args[k].type == arg_integer) { 51855682Smarkm int tmp; 519102644Snectar if(sscanf(goptarg, "%d", &tmp) != 1) 52055682Smarkm return ARG_ERR_BAD_ARG; 52155682Smarkm *(int*)args[k].value = tmp; 52255682Smarkm return 0; 52355682Smarkm } else if(args[k].type == arg_string) { 524102644Snectar *(char**)args[k].value = goptarg; 52555682Smarkm return 0; 52655682Smarkm } else if(args[k].type == arg_strings) { 527178825Sdfr return add_string((getarg_strings*)args[k].value, goptarg); 52855682Smarkm } else if(args[k].type == arg_double) { 52955682Smarkm double tmp; 530102644Snectar if(sscanf(goptarg, "%lf", &tmp) != 1) 53155682Smarkm return ARG_ERR_BAD_ARG; 53255682Smarkm *(double*)args[k].value = tmp; 53355682Smarkm return 0; 53455682Smarkm } 53555682Smarkm return ARG_ERR_BAD_ARG; 53655682Smarkm } 53755682Smarkm } 53855682Smarkm if (k == num_args) 53955682Smarkm return ARG_ERR_NO_MATCH; 54055682Smarkm } 54155682Smarkm return 0; 54255682Smarkm} 54355682Smarkm 544233294SstasROKEN_LIB_FUNCTION int ROKEN_LIB_CALL 545233294Sstasgetarg(struct getargs *args, size_t num_args, 546102644Snectar int argc, char **argv, int *goptind) 54755682Smarkm{ 54855682Smarkm int i; 54955682Smarkm int ret = 0; 55055682Smarkm 551233294Sstas rk_random_init(); 552102644Snectar (*goptind)++; 553102644Snectar for(i = *goptind; i < argc; i++) { 55455682Smarkm if(argv[i][0] != '-') 55555682Smarkm break; 55655682Smarkm if(argv[i][1] == '-'){ 55755682Smarkm if(argv[i][2] == 0){ 55855682Smarkm i++; 55955682Smarkm break; 56055682Smarkm } 561233294Sstas ret = arg_match_long (args, num_args, argv[i] + 2, 56255682Smarkm argc, argv, &i); 56355682Smarkm } else { 56455682Smarkm ret = arg_match_short (args, num_args, argv[i], 56555682Smarkm argc, argv, &i); 56655682Smarkm } 56755682Smarkm if(ret) 56855682Smarkm break; 56955682Smarkm } 570102644Snectar *goptind = i; 57155682Smarkm return ret; 57255682Smarkm} 57355682Smarkm 574233294SstasROKEN_LIB_FUNCTION void ROKEN_LIB_CALL 57578527Sassarfree_getarg_strings (getarg_strings *s) 57678527Sassar{ 57778527Sassar free (s->strings); 57878527Sassar} 57978527Sassar 58055682Smarkm#if TEST 58155682Smarkmint foo_flag = 2; 58255682Smarkmint flag1 = 0; 58355682Smarkmint flag2 = 0; 58455682Smarkmint bar_int; 58555682Smarkmchar *baz_string; 58655682Smarkm 58755682Smarkmstruct getargs args[] = { 58855682Smarkm { NULL, '1', arg_flag, &flag1, "one", NULL }, 58955682Smarkm { NULL, '2', arg_flag, &flag2, "two", NULL }, 59055682Smarkm { "foo", 'f', arg_negative_flag, &foo_flag, "foo", NULL }, 59155682Smarkm { "bar", 'b', arg_integer, &bar_int, "bar", "seconds"}, 59255682Smarkm { "baz", 'x', arg_string, &baz_string, "baz", "name" }, 59355682Smarkm}; 59455682Smarkm 59555682Smarkmint main(int argc, char **argv) 59655682Smarkm{ 597102644Snectar int goptind = 0; 598102644Snectar while(getarg(args, 5, argc, argv, &goptind)) 599102644Snectar printf("Bad arg: %s\n", argv[goptind]); 600233294Sstas printf("flag1 = %d\n", flag1); 601233294Sstas printf("flag2 = %d\n", flag2); 602233294Sstas printf("foo_flag = %d\n", foo_flag); 60355682Smarkm printf("bar_int = %d\n", bar_int); 60455682Smarkm printf("baz_flag = %s\n", baz_string); 60555682Smarkm arg_printusage (args, 5, argv[0], "nothing here"); 60655682Smarkm} 60755682Smarkm#endif 608