~ubuntu-branches/ubuntu/karmic/gnupg2/karmic-updates

« back to all changes in this revision

Viewing changes to jnlib/argparse.c

  • Committer: Bazaar Package Importer
  • Author(s): Eric Dorland
  • Date: 2009-03-08 22:46:47 UTC
  • mfrom: (1.1.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20090308224647-gq17gatcl71lrc2k
Tags: 2.0.11-1
* New upstream release. (Closes: #496663)
* debian/control: Make the description a little more distinctive than
  gnupg v1's. Thanks Jari Aalto. (Closes: #496323)

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
 *
7
7
 * JNLIB is free software; you can redistribute it and/or modify it
8
8
 * under the terms of the GNU Lesser General Public License as
9
 
 * published by the Free Software Foundation; either version 3 of
 
9
 * published by the Free Software Foundation; either version 2.1 of
10
10
 * the License, or (at your option) any later version.
11
11
 *
12
12
 * JNLIB is distributed in the hope that it will be useful, but
18
18
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19
19
 */
20
20
 
 
21
#ifdef HAVE_CONFIG_H
21
22
#include <config.h>
 
23
#endif
 
24
 
22
25
#include <stdio.h>
23
26
#include <stdlib.h>
24
27
#include <ctype.h>
34
37
#include "argparse.h"
35
38
 
36
39
 
 
40
 
37
41
/*********************************
38
42
 * @Summary arg_parse
39
43
 *  #include <wk/lib.h>
172
176
      
173
177
      if (filename)
174
178
        {
175
 
          if ( arg->r_opt == -6 )
 
179
          if ( arg->r_opt == ARGPARSE_UNEXPECTED_ARG )
176
180
            s = _("argument not expected");
177
 
          else if ( arg->r_opt == -5 )
 
181
          else if ( arg->r_opt == ARGPARSE_READ_ERROR )
178
182
            s = _("read error");
179
 
          else if ( arg->r_opt == -4 )
 
183
          else if ( arg->r_opt == ARGPARSE_KEYWORD_TOO_LONG )
180
184
            s = _("keyword too long");
181
 
          else if ( arg->r_opt == -3 )
 
185
          else if ( arg->r_opt == ARGPARSE_MISSING_ARG )
182
186
            s = _("missing argument");
183
 
          else if ( arg->r_opt == -7 )
 
187
          else if ( arg->r_opt == ARGPARSE_INVALID_COMMAND )
184
188
            s = _("invalid command");
185
 
          else if ( arg->r_opt == -10 )
 
189
          else if ( arg->r_opt == ARGPARSE_INVALID_ALIAS )
186
190
            s = _("invalid alias definition");
 
191
          else if ( arg->r_opt == ARGPARSE_OUT_OF_CORE )
 
192
            s = _("out of core");
187
193
          else
188
194
            s = _("invalid option");
189
195
          jnlib_log_error ("%s:%u: %s\n", filename, *lineno, s);
192
198
        {
193
199
          s = arg->internal.last? arg->internal.last:"[??]";
194
200
            
195
 
          if ( arg->r_opt == -3 )
 
201
          if ( arg->r_opt == ARGPARSE_MISSING_ARG )
196
202
            jnlib_log_error (_("missing argument for option \"%.50s\"\n"), s);
197
 
          else if ( arg->r_opt == -6 )
 
203
          else if ( arg->r_opt == ARGPARSE_UNEXPECTED_ARG )
198
204
            jnlib_log_error (_("option \"%.50s\" does not expect an "
199
205
                               "argument\n"), s );
200
 
          else if ( arg->r_opt == -7 )
 
206
          else if ( arg->r_opt == ARGPARSE_INVALID_COMMAND )
201
207
            jnlib_log_error (_("invalid command \"%.50s\"\n"), s);
202
 
          else if ( arg->r_opt == -8 )
 
208
          else if ( arg->r_opt == ARGPARSE_AMBIGUOUS_OPTION )
203
209
            jnlib_log_error (_("option \"%.50s\" is ambiguous\n"), s);
204
 
          else if ( arg->r_opt == -9 )
 
210
          else if ( arg->r_opt == ARGPARSE_AMBIGUOUS_OPTION )
205
211
            jnlib_log_error (_("command \"%.50s\" is ambiguous\n"),s );
 
212
          else if ( arg->r_opt == ARGPARSE_OUT_OF_CORE )
 
213
            jnlib_log_error ("%s\n", _("out of core\n"));
206
214
          else
207
215
            jnlib_log_error (_("invalid option \"%.50s\"\n"), s);
208
216
        }
224
232
     * and fix the probelms IRIX has with (ALIAS_DEV)arg..
225
233
     * used as lvalue
226
234
     */
 
235
  (void)arg;
 
236
  (void)name;
 
237
  (void)value;
227
238
#if 0
228
239
    ALIAS_DEF a = jnlib_xmalloc( sizeof *a );
229
240
    a->name = name;
251
262
 * Note: Abbreviation of options is here not allowed.
252
263
 */
253
264
int
254
 
optfile_parse( FILE *fp, const char *filename, unsigned *lineno,
 
265
optfile_parse (FILE *fp, const char *filename, unsigned *lineno,
255
266
               ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
256
267
{
257
 
    int state, i, c;
258
 
    int idx=0;
259
 
    char keyword[100];
260
 
    char *buffer = NULL;
261
 
    size_t buflen = 0;
262
 
    int inverse=0;
263
 
    int in_alias=0;
264
 
 
265
 
    if( !fp ) /* same as arg_parse() in this case */
266
 
        return arg_parse( arg, opts );
267
 
 
268
 
    initialize( arg, filename, lineno );
269
 
 
270
 
    /* find the next keyword */
271
 
    state = i = 0;
272
 
    for(;;) {
273
 
        c=getc(fp);
274
 
        if( c == '\n' || c== EOF ) {
275
 
            if( c != EOF )
276
 
                ++*lineno;
277
 
            if( state == -1 )
278
 
                break;
279
 
            else if( state == 2 ) {
280
 
                keyword[i] = 0;
281
 
                for(i=0; opts[i].short_opt; i++ )
282
 
                    if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) )
283
 
                        break;
284
 
                idx = i;
285
 
                arg->r_opt = opts[idx].short_opt;
286
 
                if( inverse ) /* this does not have an effect, hmmm */
287
 
                    arg->r_opt = -arg->r_opt;
288
 
                if( !opts[idx].short_opt )   /* unknown command/option */
289
 
                    arg->r_opt = (opts[idx].flags & 256)? -7:-2;
290
 
                else if( !(opts[idx].flags & 7) ) /* does not take an arg */
291
 
                    arg->r_type = 0;           /* okay */
292
 
                else if( (opts[idx].flags & 8) )  /* argument is optional */
293
 
                    arg->r_type = 0;           /* okay */
294
 
                else                           /* required argument */
295
 
                    arg->r_opt = -3;           /* error */
296
 
                break;
297
 
            }
298
 
            else if( state == 3 ) {            /* no argument found */
299
 
                if( in_alias )
300
 
                    arg->r_opt = -3;           /* error */
301
 
                else if( !(opts[idx].flags & 7) ) /* does not take an arg */
302
 
                    arg->r_type = 0;           /* okay */
303
 
                else if( (opts[idx].flags & 8) )  /* no optional argument */
304
 
                    arg->r_type = 0;           /* okay */
305
 
                else                           /* no required argument */
306
 
                    arg->r_opt = -3;           /* error */
307
 
                break;
308
 
            }
309
 
            else if( state == 4 ) {     /* have an argument */
310
 
                if( in_alias ) {
311
 
                    if( !buffer )
312
 
                        arg->r_opt = -6;
313
 
                    else {
314
 
                        char *p;
315
 
 
316
 
                        buffer[i] = 0;
317
 
                        p = strpbrk( buffer, " \t" );
318
 
                        if( p ) {
319
 
                            *p++ = 0;
320
 
                            trim_spaces( p );
321
 
                        }
322
 
                        if( !p || !*p ) {
323
 
                            jnlib_free( buffer );
324
 
                            arg->r_opt = -10;
325
 
                        }
326
 
                        else {
327
 
                            store_alias( arg, buffer, p );
328
 
                        }
 
268
  int state, i, c;
 
269
  int idx=0;
 
270
  char keyword[100];
 
271
  char *buffer = NULL;
 
272
  size_t buflen = 0;
 
273
  int in_alias=0;
 
274
  
 
275
  if (!fp) /* Divert to to arg_parse() in this case.  */
 
276
    return arg_parse (arg, opts);
 
277
  
 
278
  initialize (arg, filename, lineno);
 
279
 
 
280
  /* Find the next keyword.  */
 
281
  state = i = 0;
 
282
  for (;;)
 
283
    {
 
284
      c = getc (fp);
 
285
      if (c == '\n' || c== EOF )
 
286
        {
 
287
          if ( c != EOF )
 
288
            ++*lineno;
 
289
          if (state == -1)
 
290
            break;
 
291
          else if (state == 2)
 
292
            {
 
293
              keyword[i] = 0;
 
294
              for (i=0; opts[i].short_opt; i++ )
 
295
                {
 
296
                  if (opts[i].long_opt && !strcmp (opts[i].long_opt, keyword))
 
297
                    break;
 
298
                }
 
299
              idx = i;
 
300
              arg->r_opt = opts[idx].short_opt;
 
301
              if (!opts[idx].short_opt )
 
302
                arg->r_opt = ((opts[idx].flags & ARGPARSE_OPT_COMMAND)
 
303
                              ? ARGPARSE_INVALID_COMMAND
 
304
                              : ARGPARSE_INVALID_OPTION);
 
305
              else if (!(opts[idx].flags & 7)) 
 
306
                arg->r_type = 0; /* Does not take an arg. */
 
307
              else if ((opts[idx].flags & 8) )  
 
308
                arg->r_type = 0; /* Arg is optional.  */
 
309
              else
 
310
                arg->r_opt = ARGPARSE_MISSING_ARG;
 
311
 
 
312
              break;
 
313
            }
 
314
          else if (state == 3)
 
315
            {   
 
316
              /* No argument found.  */
 
317
              if (in_alias)
 
318
                arg->r_opt = ARGPARSE_MISSING_ARG;
 
319
              else if (!(opts[idx].flags & 7)) 
 
320
                arg->r_type = 0; /* Does not take an arg. */
 
321
              else if ((opts[idx].flags & 8))  
 
322
                arg->r_type = 0; /* No optional argument. */
 
323
              else
 
324
                arg->r_opt = ARGPARSE_MISSING_ARG;
 
325
 
 
326
              break;
 
327
            }
 
328
          else if (state == 4)
 
329
            {
 
330
              /* Has an argument. */
 
331
              if (in_alias) 
 
332
                {
 
333
                  if (!buffer)
 
334
                    arg->r_opt = ARGPARSE_UNEXPECTED_ARG;
 
335
                  else 
 
336
                    {
 
337
                      char *p;
 
338
                      
 
339
                      buffer[i] = 0;
 
340
                      p = strpbrk (buffer, " \t");
 
341
                      if (p)
 
342
                        {
 
343
                          *p++ = 0;
 
344
                          trim_spaces (p);
 
345
                        }
 
346
                      if (!p || !*p)
 
347
                        {
 
348
                          jnlib_free (buffer);
 
349
                          arg->r_opt = ARGPARSE_INVALID_ALIAS;
 
350
                        }
 
351
                      else
 
352
                        {
 
353
                          store_alias (arg, buffer, p);
 
354
                        }
329
355
                    }
330
356
                }
331
 
                else if( !(opts[idx].flags & 7) )  /* does not take an arg */
332
 
                    arg->r_opt = -6;        /* error */
333
 
                else {
334
 
                    char *p;
335
 
                    if( !buffer ) {
336
 
                        keyword[i] = 0;
337
 
                        buffer = jnlib_xstrdup(keyword);
338
 
                    }
339
 
                    else
340
 
                        buffer[i] = 0;
 
357
              else if (!(opts[idx].flags & 7))
 
358
                arg->r_opt = ARGPARSE_UNEXPECTED_ARG;
 
359
              else
 
360
                {
 
361
                  char *p;
341
362
 
342
 
                    trim_spaces( buffer );
343
 
                    p = buffer;
344
 
                    if( *p == '"' ) { /* remove quotes */
345
 
                        p++;
346
 
                        if( *p && p[strlen(p)-1] == '"' )
347
 
                            p[strlen(p)-1] = 0;
 
363
                  if (!buffer)
 
364
                    {
 
365
                      keyword[i] = 0;
 
366
                      buffer = jnlib_strdup (keyword);
 
367
                      if (!buffer)
 
368
                        arg->r_opt = ARGPARSE_OUT_OF_CORE;
348
369
                    }
349
 
                    if( !set_opt_arg(arg, opts[idx].flags, p) )
 
370
                  else
 
371
                    buffer[i] = 0;
 
372
                  
 
373
                  if (buffer)
 
374
                    {
 
375
                      trim_spaces (buffer);
 
376
                      p = buffer;
 
377
                      if (*p == '"')
 
378
                        { 
 
379
                          /* Remove quotes. */
 
380
                          p++;
 
381
                          if (*p && p[strlen(p)-1] == '\"' )
 
382
                            p[strlen(p)-1] = 0;
 
383
                        }
 
384
                      if (!set_opt_arg (arg, opts[idx].flags, p))
350
385
                        jnlib_free(buffer);
351
 
                }
352
 
                break;
353
 
            }
354
 
            else if( c == EOF ) {
355
 
                if( ferror(fp) )
356
 
                    arg->r_opt = -5;   /* read error */
357
 
                else
358
 
                    arg->r_opt = 0;    /* eof */
359
 
                break;
360
 
            }
361
 
            state = 0;
362
 
            i = 0;
363
 
        }
364
 
        else if( state == -1 )
365
 
            ; /* skip */
366
 
        else if( !state && isspace(c) )
367
 
            ; /* skip leading white space */
368
 
        else if( !state && c == '#' )
369
 
            state = 1;  /* start of a comment */
370
 
        else if( state == 1 )
371
 
            ; /* skip comments */
372
 
        else if( state == 2 && isspace(c) ) {
373
 
            keyword[i] = 0;
374
 
            for(i=0; opts[i].short_opt; i++ )
375
 
                if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) )
376
 
                    break;
377
 
            idx = i;
378
 
            arg->r_opt = opts[idx].short_opt;
379
 
            if( !opts[idx].short_opt ) {
380
 
                if( !strcmp( keyword, "alias" ) ) {
381
 
                    in_alias = 1;
382
 
                    state = 3;
383
 
                }
384
 
                else {
385
 
                    arg->r_opt = (opts[idx].flags & 256)? -7:-2;
386
 
                    state = -1;        /* skip rest of line and leave */
387
 
                }
388
 
            }
389
 
            else
390
 
                state = 3;
391
 
        }
392
 
        else if( state == 3 ) { /* skip leading spaces of the argument */
393
 
            if( !isspace(c) ) {
394
 
                i = 0;
395
 
                keyword[i++] = c;
396
 
                state = 4;
397
 
            }
398
 
        }
399
 
        else if( state == 4 ) { /* collect the argument */
400
 
            if( buffer ) {
401
 
                if( i < buflen-1 )
402
 
                    buffer[i++] = c;
403
 
                else {
404
 
                    buflen += 50;
405
 
                    buffer = jnlib_xrealloc(buffer, buflen);
406
 
                    buffer[i++] = c;
407
 
                }
408
 
            }
409
 
            else if( i < DIM(keyword)-1 )
410
 
                keyword[i++] = c;
411
 
            else {
412
 
                buflen = DIM(keyword)+50;
413
 
                buffer = jnlib_xmalloc(buflen);
414
 
                memcpy(buffer, keyword, i);
415
 
                buffer[i++] = c;
416
 
            }
417
 
        }
418
 
        else if( i >= DIM(keyword)-1 ) {
419
 
            arg->r_opt = -4;   /* keyword to long */
420
 
            state = -1;        /* skip rest of line and leave */
421
 
        }
422
 
        else {
423
 
            keyword[i++] = c;
424
 
            state = 2;
425
 
        }
 
386
                    }
 
387
                }
 
388
              break;
 
389
            }
 
390
          else if (c == EOF)
 
391
            {
 
392
              if (ferror (fp))
 
393
                arg->r_opt = ARGPARSE_READ_ERROR;
 
394
              else
 
395
                arg->r_opt = 0; /* EOF. */
 
396
              break;
 
397
            }
 
398
          state = 0;
 
399
          i = 0;
 
400
        }
 
401
      else if (state == -1)
 
402
        ; /* Skip. */
 
403
      else if (state == 0 && isascii (c) && isspace(c))
 
404
        ; /* Skip leading white space.  */
 
405
      else if (state == 0 && c == '#' )
 
406
        state = 1;      /* Start of a comment.  */
 
407
      else if (state == 1)
 
408
        ; /* Skip comments. */
 
409
      else if (state == 2 && isascii (c) && isspace(c))
 
410
        {
 
411
          /* Check keyword.  */
 
412
          keyword[i] = 0;
 
413
          for (i=0; opts[i].short_opt; i++ )
 
414
            if (opts[i].long_opt && !strcmp (opts[i].long_opt, keyword))
 
415
              break;
 
416
          idx = i;
 
417
          arg->r_opt = opts[idx].short_opt;
 
418
          if (!opts[idx].short_opt)
 
419
            {
 
420
              if (!strcmp (keyword, "alias"))
 
421
                {
 
422
                  in_alias = 1;
 
423
                  state = 3;
 
424
                }
 
425
              else 
 
426
                {
 
427
                  arg->r_opt = ((opts[idx].flags & ARGPARSE_OPT_COMMAND)
 
428
                                ? ARGPARSE_INVALID_COMMAND
 
429
                                : ARGPARSE_INVALID_OPTION);
 
430
                  state = -1; /* Skip rest of line and leave.  */
 
431
                }
 
432
            }
 
433
          else
 
434
            state = 3;
 
435
        }
 
436
      else if (state == 3)
 
437
        {
 
438
          /* Skip leading spaces of the argument.  */
 
439
          if (!isascii (c) || !isspace(c))
 
440
            {
 
441
              i = 0;
 
442
              keyword[i++] = c;
 
443
              state = 4;
 
444
            }
 
445
        }
 
446
      else if (state == 4)
 
447
        { 
 
448
          /* Collect the argument. */
 
449
          if (buffer)
 
450
            {
 
451
              if (i < buflen-1)
 
452
                buffer[i++] = c;
 
453
              else 
 
454
                {
 
455
                  char *tmp;
 
456
                  size_t tmplen = buflen + 50;
 
457
 
 
458
                  tmp = jnlib_realloc (buffer, tmplen);
 
459
                  if (tmp)
 
460
                    {
 
461
                      buflen = tmplen;
 
462
                      buffer = tmp;
 
463
                      buffer[i++] = c;
 
464
                    }
 
465
                  else
 
466
                    {
 
467
                      jnlib_free (buffer);
 
468
                      arg->r_opt = ARGPARSE_OUT_OF_CORE;
 
469
                      break;
 
470
                    }
 
471
                }
 
472
            }
 
473
          else if (i < DIM(keyword)-1)
 
474
            keyword[i++] = c;
 
475
          else 
 
476
            {
 
477
              size_t tmplen = DIM(keyword) + 50;
 
478
              buffer = jnlib_malloc (tmplen);
 
479
              if (buffer)
 
480
                {
 
481
                  buflen = tmplen;
 
482
                  memcpy(buffer, keyword, i);
 
483
                  buffer[i++] = c;
 
484
                }
 
485
              else
 
486
                {
 
487
                  arg->r_opt = ARGPARSE_OUT_OF_CORE;
 
488
                  break;
 
489
                }
 
490
            }
 
491
        }
 
492
      else if (i >= DIM(keyword)-1)
 
493
        {
 
494
          arg->r_opt = ARGPARSE_KEYWORD_TOO_LONG;
 
495
          state = -1; /* Skip rest of line and leave.  */
 
496
        }
 
497
      else 
 
498
        {
 
499
          keyword[i++] = c;
 
500
          state = 2;
 
501
        }
426
502
    }
427
 
 
428
 
    return arg->r_opt;
 
503
  
 
504
  return arg->r_opt;
429
505
}
430
506
 
431
507
 
437
513
    int i;
438
514
    size_t n;
439
515
 
 
516
    (void)arg;
 
517
 
440
518
    /* Would be better if we can do a binary search, but it is not
441
519
       possible to reorder our option table because we would mess
442
520
       up our help strings - What we can do is: Build a nice option
479
557
int
480
558
arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
481
559
{
482
 
    int idx;
483
 
    int argc;
484
 
    char **argv;
485
 
    char *s, *s2;
486
 
    int i;
487
 
 
488
 
    initialize( arg, NULL, NULL );
489
 
    argc = *arg->argc;
490
 
    argv = *arg->argv;
491
 
    idx = arg->internal.idx;
492
 
 
493
 
    if( !idx && argc && !(arg->flags & (1<<4)) ) { /* skip the first entry */
494
 
        argc--; argv++; idx++;
495
 
    }
496
 
 
497
 
  next_one:
498
 
    if( !argc ) { /* no more args */
499
 
        arg->r_opt = 0;
500
 
        goto leave; /* ready */
501
 
    }
502
 
 
503
 
    s = *argv;
504
 
    arg->internal.last = s;
505
 
 
506
 
    if( arg->internal.stopped && (arg->flags & (1<<1)) ) {
507
 
        arg->r_opt = -1;  /* not an option but a argument */
508
 
        arg->r_type = 2;
509
 
        arg->r.ret_str = s;
510
 
        argc--; argv++; idx++; /* set to next one */
511
 
    }
512
 
    else if( arg->internal.stopped ) { /* ready */
513
 
        arg->r_opt = 0;
514
 
        goto leave;
515
 
    }
516
 
    else if( *s == '-' && s[1] == '-' ) { /* long option */
517
 
        char *argpos;
518
 
 
519
 
        arg->internal.inarg = 0;
520
 
        if( !s[2] && !(arg->flags & (1<<3)) ) { /* stop option processing */
521
 
            arg->internal.stopped = 1;
522
 
            argc--; argv++; idx++;
523
 
            goto next_one;
524
 
        }
525
 
 
526
 
        argpos = strchr( s+2, '=' );
527
 
        if( argpos )
528
 
            *argpos = 0;
529
 
        i = find_long_option( arg, opts, s+2 );
530
 
        if( argpos )
531
 
            *argpos = '=';
532
 
 
533
 
        if( i < 0 && !strcmp( "help", s+2) )
534
 
            show_help(opts, arg->flags);
535
 
        else if( i < 0 && !strcmp( "version", s+2) ) {
536
 
            if( !(arg->flags & (1<<6)) ) {
537
 
                show_version();
538
 
                exit(0);
539
 
            }
540
 
        }
541
 
        else if( i < 0 && !strcmp( "warranty", s+2) ) {
542
 
            puts( strusage(16) );
543
 
            exit(0);
544
 
        }
545
 
        else if( i < 0 && !strcmp( "dump-options", s+2) ) {
546
 
            for(i=0; opts[i].short_opt; i++ ) {
547
 
                if( opts[i].long_opt )
548
 
                    printf( "--%s\n", opts[i].long_opt );
549
 
            }
550
 
            fputs("--dump-options\n--help\n--version\n--warranty\n", stdout );
551
 
            exit(0);
552
 
        }
553
 
 
554
 
        if( i == -2 ) /* ambiguous option */
555
 
            arg->r_opt = -8;
556
 
        else if( i == -1 ) {
557
 
            arg->r_opt = -2;
558
 
            arg->r.ret_str = s+2;
559
 
        }
560
 
        else
561
 
            arg->r_opt = opts[i].short_opt;
562
 
        if( i < 0 )
563
 
            ;
564
 
        else if( (opts[i].flags & 7) ) {
565
 
            if( argpos ) {
566
 
                s2 = argpos+1;
567
 
                if( !*s2 )
568
 
                    s2 = NULL;
569
 
            }
570
 
            else
571
 
                s2 = argv[1];
572
 
            if( !s2 && (opts[i].flags & 8) ) { /* no argument but it is okay*/
573
 
                arg->r_type = 0;               /* because it is optional */
574
 
            }
575
 
            else if( !s2 ) {
576
 
                arg->r_opt = -3; /* missing argument */
577
 
            }
578
 
            else if( !argpos && *s2 == '-' && (opts[i].flags & 8) ) {
579
 
                /* the argument is optional and the next seems to be
580
 
                 * an option. We do not check this possible option
581
 
                 * but assume no argument */
582
 
                arg->r_type = 0;
583
 
            }
584
 
            else {
585
 
                set_opt_arg(arg, opts[i].flags, s2);
586
 
                if( !argpos ) {
587
 
                    argc--; argv++; idx++; /* skip one */
 
560
  int idx;
 
561
  int argc;
 
562
  char **argv;
 
563
  char *s, *s2;
 
564
  int i;
 
565
  
 
566
  initialize( arg, NULL, NULL );
 
567
  argc = *arg->argc;
 
568
  argv = *arg->argv;
 
569
  idx = arg->internal.idx;
 
570
 
 
571
  if (!idx && argc && !(arg->flags & ARGPARSE_FLAG_ARG0))
 
572
    {
 
573
      /* Skip the first argument.  */
 
574
      argc--; argv++; idx++;
 
575
    }
 
576
  
 
577
 next_one:
 
578
  if (!argc) 
 
579
    { 
 
580
      /* No more args.  */
 
581
      arg->r_opt = 0;
 
582
      goto leave; /* Ready. */
 
583
    }
 
584
 
 
585
  s = *argv;
 
586
  arg->internal.last = s;
 
587
 
 
588
  if (arg->internal.stopped && (arg->flags & ARGPARSE_FLAG_ALL)) 
 
589
    {
 
590
      arg->r_opt = ARGPARSE_IS_ARG;  /* Not an option but an argument.  */
 
591
      arg->r_type = 2;
 
592
      arg->r.ret_str = s;
 
593
      argc--; argv++; idx++; /* set to next one */
 
594
    }
 
595
  else if( arg->internal.stopped ) 
 
596
    {
 
597
      arg->r_opt = 0;
 
598
      goto leave; /* Ready.  */
 
599
    }
 
600
  else if ( *s == '-' && s[1] == '-' )
 
601
    {
 
602
      /* Long option.  */
 
603
      char *argpos;
 
604
      
 
605
      arg->internal.inarg = 0;
 
606
      if (!s[2] && !(arg->flags & ARGPARSE_FLAG_NOSTOP))
 
607
        { 
 
608
          /* Stop option processing.  */
 
609
          arg->internal.stopped = 1;
 
610
          argc--; argv++; idx++;
 
611
          goto next_one;
 
612
        }
 
613
 
 
614
      argpos = strchr( s+2, '=' );
 
615
      if ( argpos )
 
616
        *argpos = 0;
 
617
      i = find_long_option ( arg, opts, s+2 );
 
618
      if ( argpos )
 
619
        *argpos = '=';
 
620
 
 
621
      if ( i < 0 && !strcmp ( "help", s+2) )
 
622
        show_help (opts, arg->flags);
 
623
      else if ( i < 0 && !strcmp ( "version", s+2) )
 
624
        {
 
625
          if (!(arg->flags & ARGPARSE_FLAG_NOVERSION))
 
626
            {
 
627
              show_version ();
 
628
              exit(0);
 
629
            }
 
630
        }
 
631
      else if ( i < 0 && !strcmp( "warranty", s+2))
 
632
        {
 
633
          puts ( strusage (16) );
 
634
          exit (0);
 
635
        }
 
636
      else if ( i < 0 && !strcmp( "dump-options", s+2) )
 
637
        {
 
638
          for (i=0; opts[i].short_opt; i++ )
 
639
            {
 
640
              if ( opts[i].long_opt )
 
641
                printf ("--%s\n", opts[i].long_opt);
 
642
            }
 
643
          fputs ("--dump-options\n--help\n--version\n--warranty\n", stdout);
 
644
          exit (0);
 
645
        }
 
646
      
 
647
      if ( i == -2 )
 
648
        arg->r_opt = ARGPARSE_AMBIGUOUS_OPTION;
 
649
      else if ( i == -1 )
 
650
        {
 
651
          arg->r_opt = ARGPARSE_INVALID_OPTION;
 
652
          arg->r.ret_str = s+2;
 
653
        }
 
654
      else
 
655
        arg->r_opt = opts[i].short_opt;
 
656
      if ( i < 0 )
 
657
        ;
 
658
      else if ( (opts[i].flags & 0x07) )
 
659
        {
 
660
          if ( argpos )
 
661
            {
 
662
              s2 = argpos+1;
 
663
              if ( !*s2 )
 
664
                s2 = NULL;
 
665
            }
 
666
          else
 
667
            s2 = argv[1];
 
668
          if ( !s2 && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) )
 
669
            {
 
670
              arg->r_type = ARGPARSE_TYPE_NONE; /* Argument is optional.  */
 
671
            }
 
672
          else if ( !s2 )
 
673
            {
 
674
              arg->r_opt = ARGPARSE_MISSING_ARG;
 
675
            }
 
676
          else if ( !argpos && *s2 == '-' 
 
677
                    && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) ) 
 
678
            {
 
679
              /* The argument is optional and the next seems to be an
 
680
                 option.  We do not check this possible option but
 
681
                 assume no argument */
 
682
              arg->r_type = ARGPARSE_TYPE_NONE;
 
683
            }
 
684
          else 
 
685
            {
 
686
              set_opt_arg (arg, opts[i].flags, s2);
 
687
              if ( !argpos ) 
 
688
                {
 
689
                  argc--; argv++; idx++; /* Skip one.  */
588
690
                }
589
691
            }
590
692
        }
591
 
        else { /* does not take an argument */
592
 
            if( argpos )
593
 
                arg->r_type = -6; /* argument not expected */
594
 
            else
595
 
                arg->r_type = 0;
 
693
      else
 
694
        { 
 
695
          /* Does not take an argument. */
 
696
          if ( argpos )
 
697
            arg->r_type = ARGPARSE_UNEXPECTED_ARG; 
 
698
          else
 
699
            arg->r_type = 0;
596
700
        }
597
 
        argc--; argv++; idx++; /* set to next one */
 
701
      argc--; argv++; idx++; /* Set to next one.  */
598
702
    }
599
 
    else if( (*s == '-' && s[1]) || arg->internal.inarg ) { /* short option */
 
703
    else if ( (*s == '-' && s[1]) || arg->internal.inarg ) 
 
704
      {
 
705
        /* Short option.  */
600
706
        int dash_kludge = 0;
 
707
 
601
708
        i = 0;
602
 
        if( !arg->internal.inarg ) {
 
709
        if ( !arg->internal.inarg ) 
 
710
          {
603
711
            arg->internal.inarg++;
604
 
            if( arg->flags & (1<<5) ) {
605
 
                for(i=0; opts[i].short_opt; i++ )
606
 
                    if( opts[i].long_opt && !strcmp( opts[i].long_opt, s+1)) {
607
 
                        dash_kludge=1;
608
 
                        break;
 
712
            if ( (arg->flags & ARGPARSE_FLAG_ONEDASH) )
 
713
              {
 
714
                for (i=0; opts[i].short_opt; i++ )
 
715
                  if ( opts[i].long_opt && !strcmp (opts[i].long_opt, s+1))
 
716
                    {
 
717
                      dash_kludge = 1;
 
718
                      break;
609
719
                    }
610
 
            }
611
 
        }
 
720
              }
 
721
          }
612
722
        s += arg->internal.inarg;
613
723
 
614
 
        if( !dash_kludge ) {
615
 
            for(i=0; opts[i].short_opt; i++ )
616
 
                if( opts[i].short_opt == *s )
617
 
                    break;
618
 
        }
619
 
 
620
 
        if( !opts[i].short_opt && ( *s == 'h' || *s == '?' ) )
621
 
            show_help(opts, arg->flags);
 
724
        if (!dash_kludge )
 
725
          {
 
726
            for (i=0; opts[i].short_opt; i++ )
 
727
              if ( opts[i].short_opt == *s )
 
728
                break;
 
729
          }
 
730
        
 
731
        if ( !opts[i].short_opt && ( *s == 'h' || *s == '?' ) )
 
732
          show_help (opts, arg->flags);
622
733
 
623
734
        arg->r_opt = opts[i].short_opt;
624
 
        if( !opts[i].short_opt ) {
625
 
            arg->r_opt = (opts[i].flags & 256)? -7:-2;
626
 
            arg->internal.inarg++; /* point to the next arg */
 
735
        if (!opts[i].short_opt )
 
736
          {
 
737
            arg->r_opt = (opts[i].flags & ARGPARSE_OPT_COMMAND)?
 
738
              ARGPARSE_INVALID_COMMAND:ARGPARSE_INVALID_OPTION;
 
739
            arg->internal.inarg++; /* Point to the next arg.  */
627
740
            arg->r.ret_str = s;
628
 
        }
629
 
        else if( (opts[i].flags & 7) ) {
630
 
            if( s[1] && !dash_kludge ) {
 
741
          }
 
742
        else if ( (opts[i].flags & 7) )
 
743
          {
 
744
            if ( s[1] && !dash_kludge )
 
745
              {
631
746
                s2 = s+1;
632
 
                set_opt_arg(arg, opts[i].flags, s2);
633
 
            }
634
 
            else {
 
747
                set_opt_arg (arg, opts[i].flags, s2);
 
748
              }
 
749
            else
 
750
              {
635
751
                s2 = argv[1];
636
 
                if( !s2 && (opts[i].flags & 8) ) { /* no argument but it is okay*/
637
 
                    arg->r_type = 0;               /* because it is optional */
638
 
                }
639
 
                else if( !s2 ) {
640
 
                    arg->r_opt = -3; /* missing argument */
641
 
                }
642
 
                else if( *s2 == '-' && s2[1] && (opts[i].flags & 8) ) {
643
 
                    /* the argument is optional and the next seems to be
644
 
                     * an option. We do not check this possible option
645
 
                     * but assume no argument */
646
 
                    arg->r_type = 0;
647
 
                }
648
 
                else {
649
 
                    set_opt_arg(arg, opts[i].flags, s2);
650
 
                    argc--; argv++; idx++; /* skip one */
651
 
                }
652
 
            }
653
 
            s = "x"; /* so that !s[1] yields false */
654
 
        }
655
 
        else { /* does not take an argument */
656
 
            arg->r_type = 0;
657
 
            arg->internal.inarg++; /* point to the next arg */
658
 
        }
659
 
        if( !s[1] || dash_kludge ) { /* no more concatenated short options */
 
752
                if ( !s2 && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) )
 
753
                  {
 
754
                    arg->r_type = ARGPARSE_TYPE_NONE;
 
755
                  }
 
756
                else if ( !s2 )
 
757
                  {
 
758
                    arg->r_opt = ARGPARSE_MISSING_ARG;
 
759
                  }
 
760
                else if ( *s2 == '-' && s2[1]
 
761
                          && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) )
 
762
                  {
 
763
                    /* The argument is optional and the next seems to
 
764
                       be an option.  We do not check this possible
 
765
                       option but assume no argument.  */
 
766
                    arg->r_type = ARGPARSE_TYPE_NONE;
 
767
                  }
 
768
                else
 
769
                  {
 
770
                    set_opt_arg (arg, opts[i].flags, s2);
 
771
                    argc--; argv++; idx++; /* Skip one.  */
 
772
                  }
 
773
              }
 
774
            s = "x"; /* This is so that !s[1] yields false.  */
 
775
          }
 
776
        else
 
777
          {
 
778
            /* Does not take an argument.  */
 
779
            arg->r_type = ARGPARSE_TYPE_NONE;
 
780
            arg->internal.inarg++; /* Point to the next arg.  */
 
781
          }
 
782
        if ( !s[1] || dash_kludge )
 
783
          {
 
784
            /* No more concatenated short options.  */
660
785
            arg->internal.inarg = 0;
661
786
            argc--; argv++; idx++;
662
 
        }
663
 
    }
664
 
    else if( arg->flags & (1<<2) ) {
665
 
        arg->r_opt = -1;  /* not an option but a argument */
666
 
        arg->r_type = 2;
667
 
        arg->r.ret_str = s;
668
 
        argc--; argv++; idx++; /* set to next one */
669
 
    }
670
 
    else {
671
 
        arg->internal.stopped = 1; /* stop option processing */
672
 
        goto next_one;
 
787
          }
 
788
      }
 
789
  else if ( arg->flags & ARGPARSE_FLAG_MIXED )
 
790
    {
 
791
      arg->r_opt = ARGPARSE_IS_ARG;
 
792
      arg->r_type = 2;
 
793
      arg->r.ret_str = s;
 
794
      argc--; argv++; idx++; /* Set to next one.  */
 
795
    }
 
796
  else
 
797
    {
 
798
      arg->internal.stopped = 1; /* Stop option processing.  */
 
799
      goto next_one;
673
800
    }
674
801
 
675
 
  leave:
676
 
    *arg->argc = argc;
677
 
    *arg->argv = argv;
678
 
    arg->internal.idx = idx;
679
 
    return arg->r_opt;
 
802
 leave:
 
803
  *arg->argc = argc;
 
804
  *arg->argv = argv;
 
805
  arg->internal.idx = idx;
 
806
  return arg->r_opt;
680
807
}
681
808
 
682
809
 
684
811
static int
685
812
set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s)
686
813
{
687
 
    int base = (flags & 16)? 0 : 10;
 
814
  int base = (flags & 16)? 0 : 10;
688
815
 
689
 
    switch( arg->r_type = (flags & 7) ) {
690
 
      case 1: /* takes int argument */
691
 
        arg->r.ret_int = (int)strtol(s,NULL,base);
692
 
        return 0;
693
 
      case 3: /* takes long argument   */
694
 
        arg->r.ret_long= strtol(s,NULL,base);
695
 
        return 0;
696
 
      case 4: /* takes ulong argument  */
697
 
        arg->r.ret_ulong= strtoul(s,NULL,base);
698
 
        return 0;
699
 
      case 2: /* takes string argument */
700
 
      default:
701
 
        arg->r.ret_str = s;
702
 
        return 1;
 
816
  switch ( (arg->r_type = (flags & 7)) )
 
817
    {
 
818
    case ARGPARSE_TYPE_INT:
 
819
      arg->r.ret_int = (int)strtol(s,NULL,base);
 
820
      return 0;
 
821
    case ARGPARSE_TYPE_LONG:
 
822
      arg->r.ret_long= strtol(s,NULL,base);
 
823
      return 0;
 
824
    case ARGPARSE_TYPE_ULONG:
 
825
      arg->r.ret_ulong= strtoul(s,NULL,base);
 
826
      return 0;
 
827
    case ARGPARSE_TYPE_STRING:
 
828
    default:
 
829
      arg->r.ret_str = s;
 
830
      return 1;
703
831
    }
704
832
}
705
833
 
731
859
  return n;
732
860
}
733
861
 
 
862
 
734
863
/****************
735
864
 * Print formatted help. The description string has some special
736
865
 * meanings:
743
872
 *    bar and the next one as arguments of the long option.
744
873
 */
745
874
static void
746
 
show_help( ARGPARSE_OPTS *opts, unsigned flags )
 
875
show_help (ARGPARSE_OPTS *opts, unsigned int flags)
747
876
{
748
 
    const char *s;
 
877
  const char *s;
 
878
  
 
879
  show_version ();
 
880
  putchar ('\n');
 
881
  s = strusage(41);
 
882
  puts (s);
 
883
  if ( opts[0].description )
 
884
    {
 
885
      /* Auto format the option description.  */
 
886
      int i,j, indent;
749
887
 
750
 
    show_version();
751
 
    putchar('\n');
752
 
    s = strusage(41);
753
 
    puts(s);
754
 
    if( opts[0].description ) { /* auto format the option description */
755
 
        int i,j, indent;
756
 
        /* get max. length of long options */
757
 
        for(i=indent=0; opts[i].short_opt; i++ ) {
758
 
            if( opts[i].long_opt )
759
 
                if( !opts[i].description || *opts[i].description != '@' )
760
 
                    if( (j=long_opt_strlen(opts+i)) > indent && j < 35 )
761
 
                         indent = j;
 
888
      /* Get max. length of long options.  */
 
889
      for (i=indent=0; opts[i].short_opt; i++ )
 
890
        {
 
891
          if ( opts[i].long_opt )
 
892
            if ( !opts[i].description || *opts[i].description != '@' )
 
893
              if ( (j=long_opt_strlen(opts+i)) > indent && j < 35 )
 
894
                indent = j;
762
895
        }
763
 
        /* example: " -v, --verbose   Viele Sachen ausgeben" */
764
 
        indent += 10;
765
 
        if( *opts[0].description != '@' )
766
 
            puts("Options:");
767
 
        for(i=0; opts[i].short_opt; i++ ) {
768
 
            s = _( opts[i].description );
769
 
            if( s && *s== '@' && !s[1] ) /* hide this line */
770
 
                continue;
771
 
            if( s && *s == '@' ) { /* unindented comment only line */
772
 
                for(s++; *s; s++ ) {
773
 
                    if( *s == '\n' ) {
774
 
                        if( s[1] )
775
 
                            putchar('\n');
776
 
                    }
777
 
                    else
778
 
                        putchar(*s);
779
 
                }
780
 
                putchar('\n');
781
 
                continue;
782
 
            }
783
 
 
784
 
            j = 3;
785
 
            if( opts[i].short_opt < 256 ) {
786
 
                printf(" -%c", opts[i].short_opt );
787
 
                if( !opts[i].long_opt ) {
788
 
                    if(s && *s == '|' ) {
789
 
                        putchar(' '); j++;
790
 
                        for(s++ ; *s && *s != '|'; s++, j++ )
791
 
                            putchar(*s);
792
 
                        if( *s )
793
 
                            s++;
794
 
                    }
795
 
                }
796
 
            }
797
 
            else
798
 
                fputs("   ", stdout);
799
 
            if( opts[i].long_opt ) {
800
 
                j += printf("%c --%s", opts[i].short_opt < 256?',':' ',
801
 
                                       opts[i].long_opt );
802
 
                if(s && *s == '|' ) {
803
 
                    if( *++s != '=' ) {
804
 
                        putchar(' ');
805
 
                        j++;
806
 
                    }
807
 
                    for( ; *s && *s != '|'; s++, j++ )
808
 
                        putchar(*s);
809
 
                    if( *s )
810
 
                        s++;
811
 
                }
812
 
                fputs("   ", stdout);
813
 
                j += 3;
814
 
            }
815
 
            for(;j < indent; j++ )
816
 
                putchar(' ');
817
 
            if( s ) {
818
 
                if( *s && j > indent ) {
819
 
                    putchar('\n');
820
 
                    for(j=0;j < indent; j++ )
821
 
                        putchar(' ');
822
 
                }
823
 
                for(; *s; s++ ) {
824
 
                    if( *s == '\n' ) {
825
 
                        if( s[1] ) {
826
 
                            putchar('\n');
827
 
                            for(j=0;j < indent; j++ )
828
 
                                putchar(' ');
 
896
 
 
897
      /* Example: " -v, --verbose   Viele Sachen ausgeben" */
 
898
      indent += 10;
 
899
      if ( *opts[0].description != '@' )
 
900
        puts ("Options:");
 
901
      for (i=0; opts[i].short_opt; i++ )
 
902
        {
 
903
          s = _( opts[i].description );
 
904
          if ( s && *s== '@' && !s[1] ) /* Hide this line.  */
 
905
            continue;
 
906
          if ( s && *s == '@' )  /* Unindented comment only line.  */
 
907
            { 
 
908
              for (s++; *s; s++ ) 
 
909
                {
 
910
                  if ( *s == '\n' )
 
911
                    {
 
912
                      if( s[1] )
 
913
                        putchar('\n');
 
914
                    }
 
915
                  else
 
916
                    putchar(*s);
 
917
                }
 
918
              putchar('\n');
 
919
              continue;
 
920
            }
 
921
 
 
922
          j = 3;
 
923
          if ( opts[i].short_opt < 256 )
 
924
            {
 
925
              printf (" -%c", opts[i].short_opt);
 
926
              if ( !opts[i].long_opt ) 
 
927
                {
 
928
                  if (s && *s == '|' ) 
 
929
                    {
 
930
                      putchar (' '); j++;
 
931
                      for (s++ ; *s && *s != '|'; s++, j++ )
 
932
                        putchar (*s);
 
933
                      if ( *s )
 
934
                        s++;
 
935
                    }
 
936
                }
 
937
            }
 
938
          else
 
939
            fputs("   ", stdout);
 
940
          if ( opts[i].long_opt ) 
 
941
            {
 
942
              j += printf ("%c --%s", opts[i].short_opt < 256?',':' ',
 
943
                           opts[i].long_opt );
 
944
              if (s && *s == '|' ) 
 
945
                {
 
946
                  if ( *++s != '=' )
 
947
                    {
 
948
                      putchar(' ');
 
949
                      j++;
 
950
                    }
 
951
                  for ( ; *s && *s != '|'; s++, j++ )
 
952
                    putchar(*s);
 
953
                  if ( *s )
 
954
                    s++;
 
955
                }
 
956
              fputs ("   ", stdout);
 
957
              j += 3;
 
958
            }
 
959
          for (;j < indent; j++ )
 
960
            putchar(' ');
 
961
          if ( s )
 
962
            {
 
963
              if ( *s && j > indent )
 
964
                {
 
965
                  putchar('\n');
 
966
                  for (j=0;j < indent; j++ )
 
967
                    putchar (' ');
 
968
                }
 
969
              for (; *s; s++ )
 
970
                {
 
971
                  if ( *s == '\n' )
 
972
                    {
 
973
                      if ( s[1] ) 
 
974
                        {
 
975
                          putchar ('\n');
 
976
                          for (j=0; j < indent; j++ )
 
977
                            putchar (' ');
829
978
                        }
830
979
                    }
831
 
                    else
832
 
                        putchar(*s);
 
980
                  else
 
981
                    putchar (*s);
833
982
                }
834
983
            }
835
 
            putchar('\n');
 
984
          putchar ('\n');
836
985
        }
837
 
        if( flags & 32 )
838
 
            puts("\n(A single dash may be used instead of the double ones)");
839
 
    }
840
 
    if( (s=strusage(19)) ) {  /* bug reports to ... */
841
 
        char *s2;
842
 
 
843
 
        putchar('\n');
844
 
        s2 = strstr (s, "@EMAIL@");
845
 
        if (s2)
846
 
          {
847
 
            if (s2-s)
848
 
              fwrite (s, s2-s, 1, stdout);
849
 
            fputs (PACKAGE_BUGREPORT, stdout);
850
 
            s2 += 7;
851
 
            if (*s2)
852
 
              fputs (s2, stdout);
853
 
          }
854
 
        else
855
 
          fputs(s, stdout);
856
 
    }
857
 
    fflush(stdout);
858
 
    exit(0);
 
986
        if ( (flags & ARGPARSE_FLAG_ONEDASH) )
 
987
            puts ("\n(A single dash may be used instead of the double ones)");
 
988
    }
 
989
  if ( (s=strusage(19)) )
 
990
    { 
 
991
      /* bug reports to ... */
 
992
      char *s2;
 
993
      
 
994
      putchar('\n');
 
995
      s2 = strstr (s, "@EMAIL@");
 
996
      if (s2)
 
997
        {
 
998
          if (s2-s)
 
999
            fwrite (s, s2-s, 1, stdout);
 
1000
#ifdef PACKAGE_BUGREPORT
 
1001
          fputs (PACKAGE_BUGREPORT, stdout);
 
1002
#else
 
1003
          fputs ("bug@example.org", stdout);
 
1004
#endif
 
1005
          s2 += 7;
 
1006
          if (*s2)
 
1007
            fputs (s2, stdout);
 
1008
        }
 
1009
      else
 
1010
        fputs(s, stdout);
 
1011
    }
 
1012
  fflush(stdout);
 
1013
  exit(0);
859
1014
}
860
1015
 
861
1016
static void
862
 
show_version()
 
1017
show_version ()
863
1018
{
864
1019
  const char *s;
865
1020
  int i;
889
1044
  for (i=30; i < 40; i++ )
890
1045
    if ( (s=strusage (i)) )
891
1046
      fputs (s, stdout);
892
 
  fflush(stdout);
 
1047
  fflush (stdout);
893
1048
}
894
1049
 
895
1050
 
896
1051
void
897
1052
usage (int level)
898
1053
{
 
1054
  const char *p;
 
1055
 
899
1056
  if (!level)
900
1057
    {
901
1058
      fprintf(stderr,"%s %s; %s\n", strusage(11), strusage(13), strusage (14));
903
1060
    }
904
1061
  else if (level == 1)
905
1062
    {
906
 
      fputs (strusage (40), stderr);
 
1063
      p = strusage (40);
 
1064
      fputs (p, stderr);
 
1065
      if (*p && p[strlen(p)] != '\n')
 
1066
        putc ('\n', stderr);
907
1067
      exit (2);
908
1068
    }
909
1069
  else if (level == 2) 
935
1095
const char *
936
1096
strusage( int level )
937
1097
{
938
 
    const char *p = strusage_handler? strusage_handler(level) : NULL;
939
 
 
940
 
    if( p )
941
 
        return p;
942
 
 
943
 
    switch( level ) {
944
 
      case 10: p = ("License GPLv3+: GNU GPL version 3 or later "
945
 
                    "<http://gnu.org/licenses/gpl.html>");
946
 
        break;
947
 
      case 11: p = "foo"; break;
948
 
      case 13: p = "0.0"; break;
949
 
      case 14: p = "Copyright (C) 2008 Free Software Foundation, Inc."; break;
950
 
      case 15: p =
 
1098
  const char *p = strusage_handler? strusage_handler(level) : NULL;
 
1099
  
 
1100
  if ( p )
 
1101
    return p;
 
1102
  
 
1103
  switch ( level )
 
1104
    {
 
1105
    case 10: p = ("License GPLv3+: GNU GPL version 3 or later "
 
1106
                  "<http://gnu.org/licenses/gpl.html>");
 
1107
      break;
 
1108
    case 11: p = "foo"; break;
 
1109
    case 13: p = "0.0"; break;
 
1110
    case 14: p = "Copyright (C) 2009 Free Software Foundation, Inc."; break;
 
1111
    case 15: p =
951
1112
"This is free software: you are free to change and redistribute it.\n"
952
1113
"There is NO WARRANTY, to the extent permitted by law.\n";
953
 
        break;
954
 
      case 16:  p =
 
1114
      break;
 
1115
    case 16: p =
955
1116
"This is free software; you can redistribute it and/or modify\n"
956
1117
"it under the terms of the GNU General Public License as published by\n"
957
1118
"the Free Software Foundation; either version 3 of the License, or\n"
962
1123
"GNU General Public License for more details.\n\n"
963
1124
"You should have received a copy of the GNU General Public License\n"
964
1125
"along with this software.  If not, see <http://www.gnu.org/licenses/>.\n";
965
 
        break;
966
 
      case 40: /* short and long usage */
967
 
      case 41: p = ""; break;
 
1126
      break;
 
1127
    case 40: /* short and long usage */
 
1128
    case 41: p = ""; break;
968
1129
    }
969
 
 
970
 
    return p;
 
1130
  
 
1131
  return p;
971
1132
}
972
1133
 
973
1134
void
974
 
set_strusage( const char *(*f)( int ) )
 
1135
set_strusage ( const char *(*f)( int ) )
975
1136
{
976
 
    strusage_handler = f;
 
1137
  strusage_handler = f;
977
1138
}
978
1139
 
979
1140
 
991
1152
int
992
1153
main(int argc, char **argv)
993
1154
{
994
 
    ARGPARSE_OPTS opts[] = {
995
 
    { 'v', "verbose",   0 , "Laut sein"},
996
 
    { 'e', "echo"   ,   0 , ("Zeile ausgeben, damit wir sehen, was wir ein"
997
 
                             " gegeben haben")},
998
 
    { 'd', "debug",     0 , "Debug\nfalls mal etwas\nschief geht"},
999
 
    { 'o', "output",    2   },
1000
 
    { 'c', "cross-ref", 2|8, "cross-reference erzeugen\n" },
 
1155
  ARGPARSE_OPTS opts[] = {
 
1156
    ARGPARSE_x('v', "verbose", NONE, 0, "Laut sein"),
 
1157
    ARGPARSE_s_n('e', "echo"   , ("Zeile ausgeben, damit wir sehen, "
 
1158
                                  "was wir ein gegeben haben")),
 
1159
    ARGPARSE_s_n('d', "debug", "Debug\nfalls mal etwas\nschief geht"),
 
1160
    ARGPARSE_s_s('o', "output", 0 ),
 
1161
    ARGPARSE_o_s('c', "cross-ref", "cross-reference erzeugen\n" ),
1001
1162
    /* Note that on a non-utf8 terminal the ß might garble the output. */
1002
 
    { 's', "street",  0,     "|Straße|set the name of the street to Straße" },
1003
 
    { 'm', "my-option", 1|8 },
1004
 
    { 500, "a-long-option", 0 },
1005
 
    {0} };
1006
 
    ARGPARSE_ARGS pargs = { &argc, &argv, 2|4|32 };
 
1163
    ARGPARSE_s_n('s', "street","|Straße|set the name of the street to Straße"),
 
1164
    ARGPARSE_o_i('m', "my-option", 0),
 
1165
    ARGPARSE_s_n(500, "a-long-option", 0 ),
 
1166
    ARGPARSE_end
 
1167
  };
 
1168
  ARGPARSE_ARGS pargs = { &argc, &argv, 2|4|32 };
1007
1169
    int i;
1008
1170
 
1009
1171
    while( arg_parse ( &pargs, opts) ) {
1016
1178
          case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break;
1017
1179
          case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break;
1018
1180
          case 500: opt.a_long_one++;  break;
1019
 
          default : pargs.err = 1; break; /* force warning output */
 
1181
          default : pargs.err = ARGPARSE_PRINT_WARNING; break; 
1020
1182
        }
1021
1183
    }
1022
1184
    for(i=0; i < argc; i++ )