[BACK]Return to getarg.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / asn1_compile

Annotation of src/usr.bin/asn1_compile/getarg.c, Revision 1.1

1.1     ! hin         1: /*
        !             2:  * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
        !             3:  * (Royal Institute of Technology, Stockholm, Sweden).
        !             4:  * 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
        !             8:  * are met:
        !             9:  *
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  *
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            16:  *
        !            17:  * 3. Neither the name of the Institute nor the names of its contributors
        !            18:  *    may be used to endorse or promote products derived from this software
        !            19:  *    without specific prior written permission.
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
        !            22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
        !            25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            31:  * SUCH DAMAGE.
        !            32:  */
        !            33:
        !            34: #ifdef HAVE_CONFIG_H
        !            35: #include <config.h>
        !            36: RCSID("$KTH: getarg.c,v 1.46 2002/08/20 16:23:07 joda Exp $");
        !            37: #endif
        !            38:
        !            39: #include <stdio.h>
        !            40: #include <stdlib.h>
        !            41: #include <string.h>
        !            42: #include "getarg.h"
        !            43:
        !            44: #define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag)
        !            45:
        !            46: extern char *__progname;
        !            47:
        !            48: static size_t
        !            49: print_arg (char *string, size_t len, int mdoc, int longp, struct getargs *arg)
        !            50: {
        !            51:     const char *s;
        !            52:
        !            53:     *string = '\0';
        !            54:
        !            55:     if (ISFLAG(*arg) || (!longp && arg->type == arg_counter))
        !            56:        return 0;
        !            57:
        !            58:     if(mdoc){
        !            59:        if(longp)
        !            60:            strlcat(string, "= Ns", len);
        !            61:        strlcat(string, " Ar ", len);
        !            62:     } else {
        !            63:        if (longp)
        !            64:            strlcat (string, "=", len);
        !            65:        else
        !            66:            strlcat (string, " ", len);
        !            67:     }
        !            68:
        !            69:     if (arg->arg_help)
        !            70:        s = arg->arg_help;
        !            71:     else if (arg->type == arg_integer || arg->type == arg_counter)
        !            72:        s = "integer";
        !            73:     else if (arg->type == arg_string)
        !            74:        s = "string";
        !            75:     else if (arg->type == arg_strings)
        !            76:        s = "strings";
        !            77:     else if (arg->type == arg_double)
        !            78:        s = "float";
        !            79:     else
        !            80:        s = "<undefined>";
        !            81:
        !            82:     strlcat(string, s, len);
        !            83:     return 1 + strlen(s);
        !            84: }
        !            85:
        !            86: #if 0
        !            87: static void
        !            88: mandoc_template(struct getargs *args,
        !            89:                size_t num_args,
        !            90:                const char *progname,
        !            91:                const char *extra_string)
        !            92: {
        !            93:     int i;
        !            94:     char timestr[64], cmd[64];
        !            95:     char buf[128];
        !            96:     const char *p;
        !            97:     time_t t;
        !            98:
        !            99:     printf(".\\\" Things to fix:\n");
        !           100:     printf(".\\\"   * correct section, and operating system\n");
        !           101:     printf(".\\\"   * remove Op from mandatory flags\n");
        !           102:     printf(".\\\"   * use better macros for arguments (like .Pa for files)\n");
        !           103:     printf(".\\\"\n");
        !           104:     t = time(NULL);
        !           105:     strftime(timestr, sizeof(timestr), "%B %e, %Y", localtime(&t));
        !           106:     printf(".Dd %s\n", timestr);
        !           107:     p = strrchr(progname, '/');
        !           108:     if(p) p++; else p = progname;
        !           109:     strlcpy(cmd, p, sizeof(cmd));
        !           110:     strupr(cmd);
        !           111:
        !           112:     printf(".Dt %s SECTION\n", cmd);
        !           113:     printf(".Os OPERATING_SYSTEM\n");
        !           114:     printf(".Sh NAME\n");
        !           115:     printf(".Nm %s\n", p);
        !           116:     printf(".Nd\n");
        !           117:     printf("in search of a description\n");
        !           118:     printf(".Sh SYNOPSIS\n");
        !           119:     printf(".Nm\n");
        !           120:     for(i = 0; i < num_args; i++){
        !           121:        /* we seem to hit a limit on number of arguments if doing
        !           122:            short and long flags with arguments -- split on two lines */
        !           123:        if(ISFLAG(args[i]) ||
        !           124:           args[i].short_name == 0 || args[i].long_name == NULL) {
        !           125:            printf(".Op ");
        !           126:
        !           127:            if(args[i].short_name) {
        !           128:                print_arg(buf, sizeof(buf), 1, 0, args + i);
        !           129:                printf("Fl %c%s", args[i].short_name, buf);
        !           130:                if(args[i].long_name)
        !           131:                    printf(" | ");
        !           132:            }
        !           133:            if(args[i].long_name) {
        !           134:                print_arg(buf, sizeof(buf), 1, 1, args + i);
        !           135:                printf("Fl -%s%s%s",
        !           136:                       args[i].type == arg_negative_flag ? "no-" : "",
        !           137:                       args[i].long_name, buf);
        !           138:            }
        !           139:            printf("\n");
        !           140:        } else {
        !           141:            print_arg(buf, sizeof(buf), 1, 0, args + i);
        !           142:            printf(".Oo Fl %c%s \\*(Ba Xo\n", args[i].short_name, buf);
        !           143:            print_arg(buf, sizeof(buf), 1, 1, args + i);
        !           144:            printf(".Fl -%s%s\n.Xc\n.Oc\n", args[i].long_name, buf);
        !           145:        }
        !           146:     /*
        !           147:            if(args[i].type == arg_strings)
        !           148:                fprintf (stderr, "...");
        !           149:                */
        !           150:     }
        !           151:     if (extra_string && *extra_string)
        !           152:        printf (".Ar %s\n", extra_string);
        !           153:     printf(".Sh DESCRIPTION\n");
        !           154:     printf("Supported options:\n");
        !           155:     printf(".Bl -tag -width Ds\n");
        !           156:     for(i = 0; i < num_args; i++){
        !           157:        printf(".It Xo\n");
        !           158:        if(args[i].short_name){
        !           159:            printf(".Fl %c", args[i].short_name);
        !           160:            print_arg(buf, sizeof(buf), 1, 0, args + i);
        !           161:            printf("%s", buf);
        !           162:            if(args[i].long_name)
        !           163:                printf(" ,");
        !           164:            printf("\n");
        !           165:        }
        !           166:        if(args[i].long_name){
        !           167:            printf(".Fl -%s%s",
        !           168:                   args[i].type == arg_negative_flag ? "no-" : "",
        !           169:                   args[i].long_name);
        !           170:            print_arg(buf, sizeof(buf), 1, 1, args + i);
        !           171:            printf("%s\n", buf);
        !           172:        }
        !           173:        printf(".Xc\n");
        !           174:        if(args[i].help)
        !           175:            printf("%s\n", args[i].help);
        !           176:     /*
        !           177:            if(args[i].type == arg_strings)
        !           178:                fprintf (stderr, "...");
        !           179:                */
        !           180:     }
        !           181:     printf(".El\n");
        !           182:     printf(".\\\".Sh ENVIRONMENT\n");
        !           183:     printf(".\\\".Sh FILES\n");
        !           184:     printf(".\\\".Sh EXAMPLES\n");
        !           185:     printf(".\\\".Sh DIAGNOSTICS\n");
        !           186:     printf(".\\\".Sh SEE ALSO\n");
        !           187:     printf(".\\\".Sh STANDARDS\n");
        !           188:     printf(".\\\".Sh HISTORY\n");
        !           189:     printf(".\\\".Sh AUTHORS\n");
        !           190:     printf(".\\\".Sh BUGS\n");
        !           191: }
        !           192: #endif
        !           193:
        !           194: static int
        !           195: check_column(FILE *f, int col, int len, int columns)
        !           196: {
        !           197:     if(col + len > columns) {
        !           198:        fprintf(f, "\n");
        !           199:        col = fprintf(f, "  ");
        !           200:     }
        !           201:     return col;
        !           202: }
        !           203:
        !           204: void
        !           205: arg_printusage (struct getargs *args,
        !           206:                size_t num_args,
        !           207:                const char *progname,
        !           208:                const char *extra_string)
        !           209: {
        !           210:     int i;
        !           211:     size_t max_len = 0;
        !           212:     char buf[128];
        !           213:     int col = 0, columns;
        !           214: #if 0
        !           215:     struct winsize ws;
        !           216: #endif
        !           217:
        !           218:     if (progname == NULL)
        !           219:        progname = __progname;
        !           220:
        !           221: #if 0
        !           222:     if(getenv("GETARGMANDOC")){
        !           223:        mandoc_template(args, num_args, progname, extra_string);
        !           224:        return;
        !           225:     }
        !           226: #endif
        !           227: #if 0
        !           228:     if(get_window_size(2, &ws) == 0)
        !           229:        columns = ws.ws_col;
        !           230:     else
        !           231: #endif
        !           232:        columns = 80;
        !           233:     col = 0;
        !           234:     col += fprintf (stderr, "Usage: %s", progname);
        !           235:     buf[0] = '\0';
        !           236:     for (i = 0; i < num_args; ++i) {
        !           237:        if(args[i].short_name && ISFLAG(args[i])) {
        !           238:            char s[2];
        !           239:            if(buf[0] == '\0')
        !           240:                strlcpy(buf, "[-", sizeof(buf));
        !           241:            s[0] = args[i].short_name;
        !           242:            s[1] = '\0';
        !           243:            strlcat(buf, s, sizeof(buf));
        !           244:        }
        !           245:     }
        !           246:     if(buf[0] != '\0') {
        !           247:        strlcat(buf, "]", sizeof(buf));
        !           248:        col = check_column(stderr, col, strlen(buf) + 1, columns);
        !           249:        col += fprintf(stderr, " %s", buf);
        !           250:     }
        !           251:
        !           252:     for (i = 0; i < num_args; ++i) {
        !           253:        size_t len = 0;
        !           254:
        !           255:        if (args[i].long_name) {
        !           256:            buf[0] = '\0';
        !           257:            strlcat(buf, "[--", sizeof(buf));
        !           258:            len += 2;
        !           259:            if(args[i].type == arg_negative_flag) {
        !           260:                strlcat(buf, "no-", sizeof(buf));
        !           261:                len += 3;
        !           262:            }
        !           263:            strlcat(buf, args[i].long_name, sizeof(buf));
        !           264:            len += strlen(args[i].long_name);
        !           265:            len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf),
        !           266:                             0, 1, &args[i]);
        !           267:            strlcat(buf, "]", sizeof(buf));
        !           268:            if(args[i].type == arg_strings)
        !           269:                strlcat(buf, "...", sizeof(buf));
        !           270:            col = check_column(stderr, col, strlen(buf) + 1, columns);
        !           271:            col += fprintf(stderr, " %s", buf);
        !           272:        }
        !           273:        if (args[i].short_name && !ISFLAG(args[i])) {
        !           274:            snprintf(buf, sizeof(buf), "[-%c", args[i].short_name);
        !           275:            len += 2;
        !           276:            len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf),
        !           277:                             0, 0, &args[i]);
        !           278:            strlcat(buf, "]", sizeof(buf));
        !           279:            if(args[i].type == arg_strings)
        !           280:                strlcat(buf, "...", sizeof(buf));
        !           281:            col = check_column(stderr, col, strlen(buf) + 1, columns);
        !           282:            col += fprintf(stderr, " %s", buf);
        !           283:        }
        !           284:        if (args[i].long_name && args[i].short_name)
        !           285:            len += 2; /* ", " */
        !           286: #if 0
        !           287:        max_len = max(max_len, len);
        !           288: #else
        !           289:        if(len > max_len)
        !           290:            max_len = len;
        !           291: #endif
        !           292:     }
        !           293:     if (extra_string) {
        !           294:        col = check_column(stderr, col, strlen(extra_string) + 1, columns);
        !           295:        fprintf (stderr, " %s\n", extra_string);
        !           296:     } else
        !           297:        fprintf (stderr, "\n");
        !           298:     for (i = 0; i < num_args; ++i) {
        !           299:        if (args[i].help) {
        !           300:            size_t count = 0;
        !           301:
        !           302:            if (args[i].short_name) {
        !           303:                count += fprintf (stderr, "-%c", args[i].short_name);
        !           304:                print_arg (buf, sizeof(buf), 0, 0, &args[i]);
        !           305:                count += fprintf(stderr, "%s", buf);
        !           306:            }
        !           307:            if (args[i].short_name && args[i].long_name)
        !           308:                count += fprintf (stderr, ", ");
        !           309:            if (args[i].long_name) {
        !           310:                count += fprintf (stderr, "--");
        !           311:                if (args[i].type == arg_negative_flag)
        !           312:                    count += fprintf (stderr, "no-");
        !           313:                count += fprintf (stderr, "%s", args[i].long_name);
        !           314:                print_arg (buf, sizeof(buf), 0, 1, &args[i]);
        !           315:                count += fprintf(stderr, "%s", buf);
        !           316:            }
        !           317:            while(count++ <= max_len)
        !           318:                putc (' ', stderr);
        !           319:            fprintf (stderr, "%s\n", args[i].help);
        !           320:        }
        !           321:     }
        !           322: }
        !           323:
        !           324: static void
        !           325: add_string(getarg_strings *s, char *value)
        !           326: {
        !           327:     s->strings = realloc(s->strings, (s->num_strings + 1) * sizeof(*s->strings));
        !           328:     s->strings[s->num_strings] = value;
        !           329:     s->num_strings++;
        !           330: }
        !           331:
        !           332: static int
        !           333: arg_match_long(struct getargs *args, size_t num_args,
        !           334:               char *argv, int argc, char **rargv, int *goptind)
        !           335: {
        !           336:     int i;
        !           337:     char *goptarg = NULL;
        !           338:     int negate = 0;
        !           339:     int partial_match = 0;
        !           340:     struct getargs *partial = NULL;
        !           341:     struct getargs *current = NULL;
        !           342:     int argv_len;
        !           343:     char *p;
        !           344:     int p_len;
        !           345:
        !           346:     argv_len = strlen(argv);
        !           347:     p = strchr (argv, '=');
        !           348:     if (p != NULL)
        !           349:        argv_len = p - argv;
        !           350:
        !           351:     for (i = 0; i < num_args; ++i) {
        !           352:        if(args[i].long_name) {
        !           353:            int len = strlen(args[i].long_name);
        !           354:            p = argv;
        !           355:            p_len = argv_len;
        !           356:            negate = 0;
        !           357:
        !           358:            for (;;) {
        !           359:                if (strncmp (args[i].long_name, p, p_len) == 0) {
        !           360:                    if(p_len == len)
        !           361:                        current = &args[i];
        !           362:                    else {
        !           363:                        ++partial_match;
        !           364:                        partial = &args[i];
        !           365:                    }
        !           366:                    goptarg  = p + p_len;
        !           367:                } else if (ISFLAG(args[i]) && strncmp (p, "no-", 3) == 0) {
        !           368:                    negate = !negate;
        !           369:                    p += 3;
        !           370:                    p_len -= 3;
        !           371:                    continue;
        !           372:                }
        !           373:                break;
        !           374:            }
        !           375:            if (current)
        !           376:                break;
        !           377:        }
        !           378:     }
        !           379:     if (current == NULL) {
        !           380:        if (partial_match == 1)
        !           381:            current = partial;
        !           382:        else
        !           383:            return ARG_ERR_NO_MATCH;
        !           384:     }
        !           385:
        !           386:     if(*goptarg == '\0'
        !           387:        && !ISFLAG(*current)
        !           388:        && current->type != arg_collect
        !           389:        && current->type != arg_counter)
        !           390:        return ARG_ERR_NO_MATCH;
        !           391:     switch(current->type){
        !           392:     case arg_integer:
        !           393:     {
        !           394:        int tmp;
        !           395:        if(sscanf(goptarg + 1, "%d", &tmp) != 1)
        !           396:            return ARG_ERR_BAD_ARG;
        !           397:        *(int*)current->value = tmp;
        !           398:        return 0;
        !           399:     }
        !           400:     case arg_string:
        !           401:     {
        !           402:        *(char**)current->value = goptarg + 1;
        !           403:        return 0;
        !           404:     }
        !           405:     case arg_strings:
        !           406:     {
        !           407:        add_string((getarg_strings*)current->value, goptarg + 1);
        !           408:        return 0;
        !           409:     }
        !           410:     case arg_flag:
        !           411:     case arg_negative_flag:
        !           412:     {
        !           413:        int *flag = current->value;
        !           414:        if(*goptarg == '\0' ||
        !           415:           strcmp(goptarg + 1, "yes") == 0 ||
        !           416:           strcmp(goptarg + 1, "true") == 0){
        !           417:            *flag = !negate;
        !           418:            return 0;
        !           419:        } else if (*goptarg && strcmp(goptarg + 1, "maybe") == 0) {
        !           420: #ifdef HAVE_RANDOM
        !           421:            *flag = random() & 1;
        !           422: #else
        !           423:            *flag = rand() & 1;
        !           424: #endif
        !           425:        } else {
        !           426:            *flag = negate;
        !           427:            return 0;
        !           428:        }
        !           429:        return ARG_ERR_BAD_ARG;
        !           430:     }
        !           431:     case arg_counter :
        !           432:     {
        !           433:        int val;
        !           434:
        !           435:        if (*goptarg == '\0')
        !           436:            val = 1;
        !           437:        else if(sscanf(goptarg + 1, "%d", &val) != 1)
        !           438:            return ARG_ERR_BAD_ARG;
        !           439:        *(int *)current->value += val;
        !           440:        return 0;
        !           441:     }
        !           442:     case arg_double:
        !           443:     {
        !           444:        double tmp;
        !           445:        if(sscanf(goptarg + 1, "%lf", &tmp) != 1)
        !           446:            return ARG_ERR_BAD_ARG;
        !           447:        *(double*)current->value = tmp;
        !           448:        return 0;
        !           449:     }
        !           450:     case arg_collect:{
        !           451:        struct getarg_collect_info *c = current->value;
        !           452:        int o = argv - rargv[*goptind];
        !           453:        return (*c->func)(FALSE, argc, rargv, goptind, &o, c->data);
        !           454:     }
        !           455:
        !           456:     default:
        !           457:        abort ();
        !           458:     }
        !           459: }
        !           460:
        !           461: static int
        !           462: arg_match_short (struct getargs *args, size_t num_args,
        !           463:                 char *argv, int argc, char **rargv, int *goptind)
        !           464: {
        !           465:     int j, k;
        !           466:
        !           467:     for(j = 1; j > 0 && j < strlen(rargv[*goptind]); j++) {
        !           468:        for(k = 0; k < num_args; k++) {
        !           469:            char *goptarg;
        !           470:
        !           471:            if(args[k].short_name == 0)
        !           472:                continue;
        !           473:            if(argv[j] == args[k].short_name) {
        !           474:                if(args[k].type == arg_flag) {
        !           475:                    *(int*)args[k].value = 1;
        !           476:                    break;
        !           477:                }
        !           478:                if(args[k].type == arg_negative_flag) {
        !           479:                    *(int*)args[k].value = 0;
        !           480:                    break;
        !           481:                }
        !           482:                if(args[k].type == arg_counter) {
        !           483:                    ++*(int *)args[k].value;
        !           484:                    break;
        !           485:                }
        !           486:                if(args[k].type == arg_collect) {
        !           487:                    struct getarg_collect_info *c = args[k].value;
        !           488:
        !           489:                    if((*c->func)(TRUE, argc, rargv, goptind, &j, c->data))
        !           490:                        return ARG_ERR_BAD_ARG;
        !           491:                    break;
        !           492:                }
        !           493:
        !           494:                if(argv[j + 1])
        !           495:                    goptarg = &argv[j + 1];
        !           496:                else {
        !           497:                    ++*goptind;
        !           498:                    goptarg = rargv[*goptind];
        !           499:                }
        !           500:                if(goptarg == NULL) {
        !           501:                    --*goptind;
        !           502:                    return ARG_ERR_NO_ARG;
        !           503:                }
        !           504:                if(args[k].type == arg_integer) {
        !           505:                    int tmp;
        !           506:                    if(sscanf(goptarg, "%d", &tmp) != 1)
        !           507:                        return ARG_ERR_BAD_ARG;
        !           508:                    *(int*)args[k].value = tmp;
        !           509:                    return 0;
        !           510:                } else if(args[k].type == arg_string) {
        !           511:                    *(char**)args[k].value = goptarg;
        !           512:                    return 0;
        !           513:                } else if(args[k].type == arg_strings) {
        !           514:                    add_string((getarg_strings*)args[k].value, goptarg);
        !           515:                    return 0;
        !           516:                } else if(args[k].type == arg_double) {
        !           517:                    double tmp;
        !           518:                    if(sscanf(goptarg, "%lf", &tmp) != 1)
        !           519:                        return ARG_ERR_BAD_ARG;
        !           520:                    *(double*)args[k].value = tmp;
        !           521:                    return 0;
        !           522:                }
        !           523:                return ARG_ERR_BAD_ARG;
        !           524:            }
        !           525:        }
        !           526:        if (k == num_args)
        !           527:            return ARG_ERR_NO_MATCH;
        !           528:     }
        !           529:     return 0;
        !           530: }
        !           531:
        !           532: int
        !           533: getarg(struct getargs *args, size_t num_args,
        !           534:        int argc, char **argv, int *goptind)
        !           535: {
        !           536:     int i;
        !           537:     int ret = 0;
        !           538:
        !           539: #if defined(HAVE_SRANDOMDEV)
        !           540:     srandomdev();
        !           541: #elif defined(HAVE_RANDOM)
        !           542:     srandom(time(NULL));
        !           543: #else
        !           544:     srand (time(NULL));
        !           545: #endif
        !           546:     (*goptind)++;
        !           547:     for(i = *goptind; i < argc; i++) {
        !           548:        if(argv[i][0] != '-')
        !           549:            break;
        !           550:        if(argv[i][1] == '-'){
        !           551:            if(argv[i][2] == 0){
        !           552:                i++;
        !           553:                break;
        !           554:            }
        !           555:            ret = arg_match_long (args, num_args, argv[i] + 2,
        !           556:                                  argc, argv, &i);
        !           557:        } else {
        !           558:            ret = arg_match_short (args, num_args, argv[i],
        !           559:                                   argc, argv, &i);
        !           560:        }
        !           561:        if(ret)
        !           562:            break;
        !           563:     }
        !           564:     *goptind = i;
        !           565:     return ret;
        !           566: }
        !           567:
        !           568: void
        !           569: free_getarg_strings (getarg_strings *s)
        !           570: {
        !           571:     free (s->strings);
        !           572: }
        !           573:
        !           574: #if TEST
        !           575: int foo_flag = 2;
        !           576: int flag1 = 0;
        !           577: int flag2 = 0;
        !           578: int bar_int;
        !           579: char *baz_string;
        !           580:
        !           581: struct getargs args[] = {
        !           582:     { NULL, '1', arg_flag, &flag1, "one", NULL },
        !           583:     { NULL, '2', arg_flag, &flag2, "two", NULL },
        !           584:     { "foo", 'f', arg_negative_flag, &foo_flag, "foo", NULL },
        !           585:     { "bar", 'b', arg_integer, &bar_int, "bar", "seconds"},
        !           586:     { "baz", 'x', arg_string, &baz_string, "baz", "name" },
        !           587: };
        !           588:
        !           589: int main(int argc, char **argv)
        !           590: {
        !           591:     int goptind = 0;
        !           592:     while(getarg(args, 5, argc, argv, &goptind))
        !           593:        printf("Bad arg: %s\n", argv[goptind]);
        !           594:     printf("flag1 = %d\n", flag1);
        !           595:     printf("flag2 = %d\n", flag2);
        !           596:     printf("foo_flag = %d\n", foo_flag);
        !           597:     printf("bar_int = %d\n", bar_int);
        !           598:     printf("baz_flag = %s\n", baz_string);
        !           599:     arg_printusage (args, 5, argv[0], "nothing here");
        !           600: }
        !           601: #endif