~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.1.0/pjlib-util/src/pjlib-util/getopt.c

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2015-01-07 14:51:16 UTC
  • mfrom: (4.3.5 sid)
  • Revision ID: package-import@ubuntu.com-20150107145116-yxnafinf4lrdvrmx
Tags: 1.4.1-0.1ubuntu1
* Merge with Debian, remaining changes:
 - Drop soprano, nepomuk build-dep
* Drop ubuntu patches, now upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: getopt.c 3550 2011-05-05 05:33:27Z nanang $ */
2
 
/* 
3
 
 * pj_getopt entry points
4
 
 *
5
 
 * modified by Mike Borella <mike_borella@mw.3com.com>
6
 
 */
7
 
 
8
 
#include <pjlib-util/getopt.h>
9
 
#include <pj/string.h>
10
 
 
11
 
/* Internal only.  Users should not call this directly.  */
12
 
static
13
 
int _getopt_internal (int argc, char *const *argv,
14
 
                      const char *shortopts,
15
 
                      const struct pj_getopt_option *longopts, int *longind,
16
 
                      int long_only);
17
 
 
18
 
/* pj_getopt_long and pj_getopt_long_only entry points for GNU pj_getopt.
19
 
   Copyright (C) 1987,88,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
20
 
   This file is part of the GNU C Library.
21
 
 
22
 
   The GNU C Library is free software; you can redistribute it and/or
23
 
   modify it under the terms of the GNU Library General Public License as
24
 
   published by the Free Software Foundation; either version 2 of the
25
 
   License, or (at your option) any later version.
26
 
 
27
 
   The GNU C Library is distributed in the hope that it will be useful,
28
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
29
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
30
 
   Library General Public License for more details.
31
 
 
32
 
   You should have received a copy of the GNU Library General Public
33
 
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
34
 
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
35
 
   Boston, MA 02111-1307, USA.  */
36
 
 
37
 
 
38
 
/* Comment out all this code if we are using the GNU C Library, and are not
39
 
   actually compiling the library itself.  This code is part of the GNU C
40
 
   Library, but also included in many other GNU distributions.  Compiling
41
 
   and linking in this code is a waste when using the GNU C library
42
 
   (especially if it is a shared library).  Rather than having every GNU
43
 
   program understand `configure --with-gnu-libc' and omit the object files,
44
 
   it is simpler to just do this in the source for each such file.  */
45
 
 
46
 
#   define GETOPT_INTERFACE_VERSION 2
47
 
 
48
 
 
49
 
int
50
 
pj_getopt_long (int argc, char *const *argv, const char *options, 
51
 
             const struct pj_getopt_option *long_options, int *opt_index)
52
 
{
53
 
  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
54
 
}
55
 
 
56
 
/* Like pj_getopt_long, but '-' as well as '--' can indicate a long option.
57
 
   If an option that starts with '-' (not '--') doesn't match a long option,
58
 
   but does match a short option, it is parsed as a short option
59
 
   instead.  */
60
 
 
61
 
int
62
 
pj_getopt (int argc, char * const * argv, const char * optstring)
63
 
{
64
 
  return _getopt_internal (argc, argv, optstring,
65
 
                           (const struct pj_getopt_option *) 0,
66
 
                           (int *) 0,
67
 
                           0);
68
 
}
69
 
 
70
 
 
71
 
#define _(msgid)        (msgid)
72
 
 
73
 
/* This version of `pj_getopt' appears to the caller like standard Unix `pj_getopt'
74
 
   but it behaves differently for the user, since it allows the user
75
 
   to intersperse the options with the other arguments.
76
 
 
77
 
   As `pj_getopt' works, it permutes the elements of ARGV so that,
78
 
   when it is done, all the options precede everything else.  Thus
79
 
   all application programs are extended to handle flexible argument order.
80
 
 
81
 
   Setting the environment variable POSIXLY_CORRECT disables permutation.
82
 
   Then the behavior is completely standard.
83
 
 
84
 
   GNU application programs can use a third alternative mode in which
85
 
   they can distinguish the relative order of options and other arguments.  */
86
 
 
87
 
/* For communication from `pj_getopt' to the caller.
88
 
   When `pj_getopt' finds an option that takes an argument,
89
 
   the argument value is returned here.
90
 
   Also, when `ordering' is RETURN_IN_ORDER,
91
 
   each non-option ARGV-element is returned here.  */
92
 
 
93
 
char *pj_optarg = NULL;
94
 
 
95
 
/* Index in ARGV of the next element to be scanned.
96
 
   This is used for communication to and from the caller
97
 
   and for communication between successive calls to `pj_getopt'.
98
 
 
99
 
   On entry to `pj_getopt', zero means this is the first call; initialize.
100
 
 
101
 
   When `pj_getopt' returns -1, this is the index of the first of the
102
 
   non-option elements that the caller should itself scan.
103
 
 
104
 
   Otherwise, `pj_optind' communicates from one call to the next
105
 
   how much of ARGV has been scanned so far.  */
106
 
 
107
 
/* 1003.2 says this must be 1 before any call.  */
108
 
int pj_optind = 1;
109
 
 
110
 
/* Formerly, initialization of pj_getopt depended on pj_optind==0, which
111
 
   causes problems with re-calling pj_getopt as programs generally don't
112
 
   know that. */
113
 
 
114
 
int __getopt_initialized = 0;
115
 
 
116
 
/* The next char to be scanned in the option-element
117
 
   in which the last option character we returned was found.
118
 
   This allows us to pick up the scan where we left off.
119
 
 
120
 
   If this is zero, or a null string, it means resume the scan
121
 
   by advancing to the next ARGV-element.  */
122
 
 
123
 
static char *nextchar;
124
 
 
125
 
/* Set to an option character which was unrecognized.
126
 
   This must be initialized on some systems to avoid linking in the
127
 
   system's own pj_getopt implementation.  */
128
 
 
129
 
int pj_optopt = '?';
130
 
 
131
 
/* Describe how to deal with options that follow non-option ARGV-elements.
132
 
 
133
 
   If the caller did not specify anything,
134
 
   the default is REQUIRE_ORDER if the environment variable
135
 
   POSIXLY_CORRECT is defined, PERMUTE otherwise.
136
 
 
137
 
   REQUIRE_ORDER means don't recognize them as options;
138
 
   stop option processing when the first non-option is seen.
139
 
   This is what Unix does.
140
 
   This mode of operation is selected by either setting the environment
141
 
   variable POSIXLY_CORRECT, or using `+' as the first character
142
 
   of the list of option characters.
143
 
 
144
 
   PERMUTE is the default.  We permute the contents of ARGV as we scan,
145
 
   so that eventually all the non-options are at the end.  This allows options
146
 
   to be given in any order, even with programs that were not written to
147
 
   expect this.
148
 
 
149
 
   RETURN_IN_ORDER is an option available to programs that were written
150
 
   to expect options and other ARGV-elements in any order and that care about
151
 
   the ordering of the two.  We describe each non-option ARGV-element
152
 
   as if it were the argument of an option with character code 1.
153
 
   Using `-' as the first character of the list of option characters
154
 
   selects this mode of operation.
155
 
 
156
 
   The special argument `--' forces an end of option-scanning regardless
157
 
   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
158
 
   `--' can cause `pj_getopt' to return -1 with `pj_optind' != ARGC.  */
159
 
 
160
 
static enum
161
 
{
162
 
  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
163
 
} ordering;
164
 
 
165
 
/* Value of POSIXLY_CORRECT environment variable.  */
166
 
static char *posixly_correct;
167
 
 
168
 
static char *
169
 
my_index (const char *str, int chr)
170
 
{
171
 
  while (*str)
172
 
    {
173
 
      if (*str == chr)
174
 
        return (char *) str;
175
 
      str++;
176
 
    }
177
 
  return 0;
178
 
}
179
 
 
180
 
 
181
 
/* Handle permutation of arguments.  */
182
 
 
183
 
/* Describe the part of ARGV that contains non-options that have
184
 
   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
185
 
   `last_nonopt' is the index after the last of them.  */
186
 
 
187
 
static int first_nonopt;
188
 
static int last_nonopt;
189
 
 
190
 
#   define SWAP_FLAGS(ch1, ch2)
191
 
 
192
 
/* Exchange two adjacent subsequences of ARGV.
193
 
   One subsequence is elements [first_nonopt,last_nonopt)
194
 
   which contains all the non-options that have been skipped so far.
195
 
   The other is elements [last_nonopt,pj_optind), which contains all
196
 
   the options processed since those non-options were skipped.
197
 
 
198
 
   `first_nonopt' and `last_nonopt' are relocated so that they describe
199
 
   the new indices of the non-options in ARGV after they are moved.  */
200
 
 
201
 
static void
202
 
exchange (char **argv)
203
 
{
204
 
  int bottom = first_nonopt;
205
 
  int middle = last_nonopt;
206
 
  int top = pj_optind;
207
 
  char *tem;
208
 
 
209
 
  /* Exchange the shorter segment with the far end of the longer segment.
210
 
     That puts the shorter segment into the right place.
211
 
     It leaves the longer segment in the right place overall,
212
 
     but it consists of two parts that need to be swapped next.  */
213
 
 
214
 
  while (top > middle && middle > bottom)
215
 
    {
216
 
      if (top - middle > middle - bottom)
217
 
        {
218
 
          /* Bottom segment is the short one.  */
219
 
          int len = middle - bottom;
220
 
          register int i;
221
 
 
222
 
          /* Swap it with the top part of the top segment.  */
223
 
          for (i = 0; i < len; i++)
224
 
            {
225
 
              tem = argv[bottom + i];
226
 
              argv[bottom + i] = argv[top - (middle - bottom) + i];
227
 
              argv[top - (middle - bottom) + i] = tem;
228
 
              SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
229
 
            }
230
 
          /* Exclude the moved bottom segment from further swapping.  */
231
 
          top -= len;
232
 
        }
233
 
      else
234
 
        {
235
 
          /* Top segment is the short one.  */
236
 
          int len = top - middle;
237
 
          register int i;
238
 
 
239
 
          /* Swap it with the bottom part of the bottom segment.  */
240
 
          for (i = 0; i < len; i++)
241
 
            {
242
 
              tem = argv[bottom + i];
243
 
              argv[bottom + i] = argv[middle + i];
244
 
              argv[middle + i] = tem;
245
 
              SWAP_FLAGS (bottom + i, middle + i);
246
 
            }
247
 
          /* Exclude the moved top segment from further swapping.  */
248
 
          bottom += len;
249
 
        }
250
 
    }
251
 
 
252
 
  /* Update records for the slots the non-options now occupy.  */
253
 
 
254
 
  first_nonopt += (pj_optind - last_nonopt);
255
 
  last_nonopt = pj_optind;
256
 
}
257
 
 
258
 
/* Initialize the internal data when the first call is made.  */
259
 
 
260
 
static const char *_getopt_initialize (int argc, char *const *argv, 
261
 
                                       const char *optstring)
262
 
{
263
 
    PJ_UNUSED_ARG(argc);
264
 
    PJ_UNUSED_ARG(argv);
265
 
 
266
 
  /* Start processing options with ARGV-element 1 (since ARGV-element 0
267
 
     is the program name); the sequence of previously skipped
268
 
     non-option ARGV-elements is empty.  */
269
 
 
270
 
  first_nonopt = last_nonopt = pj_optind;
271
 
 
272
 
  nextchar = NULL;
273
 
 
274
 
  //posixly_correct = getenv ("POSIXLY_CORRECT");
275
 
  posixly_correct = NULL;
276
 
 
277
 
  /* Determine how to handle the ordering of options and nonoptions.  */
278
 
 
279
 
  if (optstring[0] == '-')
280
 
    {
281
 
      ordering = RETURN_IN_ORDER;
282
 
      ++optstring;
283
 
    }
284
 
  else if (optstring[0] == '+')
285
 
    {
286
 
      ordering = REQUIRE_ORDER;
287
 
      ++optstring;
288
 
    }
289
 
  else if (posixly_correct != NULL)
290
 
    ordering = REQUIRE_ORDER;
291
 
  else
292
 
    ordering = PERMUTE;
293
 
 
294
 
  return optstring;
295
 
}
296
 
 
297
 
/* Scan elements of ARGV (whose length is ARGC) for option characters
298
 
   given in OPTSTRING.
299
 
 
300
 
   If an element of ARGV starts with '-', and is not exactly "-" or "--",
301
 
   then it is an option element.  The characters of this element
302
 
   (aside from the initial '-') are option characters.  If `pj_getopt'
303
 
   is called repeatedly, it returns successively each of the option characters
304
 
   from each of the option elements.
305
 
 
306
 
   If `pj_getopt' finds another option character, it returns that character,
307
 
   updating `pj_optind' and `nextchar' so that the next call to `pj_getopt' can
308
 
   resume the scan with the following option character or ARGV-element.
309
 
 
310
 
   If there are no more option characters, `pj_getopt' returns -1.
311
 
   Then `pj_optind' is the index in ARGV of the first ARGV-element
312
 
   that is not an option.  (The ARGV-elements have been permuted
313
 
   so that those that are not options now come last.)
314
 
 
315
 
   OPTSTRING is a string containing the legitimate option characters.
316
 
   If an option character is seen that is not listed in OPTSTRING,
317
 
   return '?' after printing an error message.  If you set `pj_opterr' to
318
 
   zero, the error message is suppressed but we still return '?'.
319
 
 
320
 
   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
321
 
   so the following text in the same ARGV-element, or the text of the following
322
 
   ARGV-element, is returned in `pj_optarg'.  Two colons mean an option that
323
 
   wants an optional arg; if there is text in the current ARGV-element,
324
 
   it is returned in `pj_optarg', otherwise `pj_optarg' is set to zero.
325
 
 
326
 
   If OPTSTRING starts with `-' or `+', it requests different methods of
327
 
   handling the non-option ARGV-elements.
328
 
   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
329
 
 
330
 
   Long-named options begin with `--' instead of `-'.
331
 
   Their names may be abbreviated as long as the abbreviation is unique
332
 
   or is an exact match for some defined option.  If they have an
333
 
   argument, it follows the option name in the same ARGV-element, separated
334
 
   from the option name by a `=', or else the in next ARGV-element.
335
 
   When `pj_getopt' finds a long-named option, it returns 0 if that option's
336
 
   `flag' field is nonzero, the value of the option's `val' field
337
 
   if the `flag' field is zero.
338
 
 
339
 
   The elements of ARGV aren't really const, because we permute them.
340
 
   But we pretend they're const in the prototype to be compatible
341
 
   with other systems.
342
 
 
343
 
   LONGOPTS is a vector of `struct pj_getopt_option' terminated by an
344
 
   element containing a name which is zero.
345
 
 
346
 
   LONGIND returns the index in LONGOPT of the long-named option found.
347
 
   It is only valid when a long-named option has been found by the most
348
 
   recent call.
349
 
 
350
 
   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
351
 
   long-named options.  */
352
 
 
353
 
static int
354
 
_getopt_internal (int argc, char *const *argv, const char *optstring, 
355
 
                  const struct pj_getopt_option *longopts, int *longind, 
356
 
                  int long_only)
357
 
{
358
 
  pj_optarg = NULL;
359
 
 
360
 
  if (pj_optind == 0 || !__getopt_initialized)
361
 
    {
362
 
      if (pj_optind == 0)
363
 
        pj_optind = 1;  /* Don't scan ARGV[0], the program name.  */
364
 
      optstring = _getopt_initialize (argc, argv, optstring);
365
 
      __getopt_initialized = 1;
366
 
    }
367
 
 
368
 
  /* Test whether ARGV[pj_optind] points to a non-option argument.
369
 
     Either it does not have option syntax, or there is an environment flag
370
 
     from the shell indicating it is not an option.  The later information
371
 
     is only used when the used in the GNU libc.  */
372
 
#define NONOPTION_P (argv[pj_optind][0] != '-' || argv[pj_optind][1] == '\0')
373
 
 
374
 
  if (nextchar == NULL || *nextchar == '\0')
375
 
    {
376
 
      /* Advance to the next ARGV-element.  */
377
 
 
378
 
      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
379
 
         moved back by the user (who may also have changed the arguments).  */
380
 
      if (last_nonopt > pj_optind)
381
 
        last_nonopt = pj_optind;
382
 
      if (first_nonopt > pj_optind)
383
 
        first_nonopt = pj_optind;
384
 
 
385
 
      if (ordering == PERMUTE)
386
 
        {
387
 
          /* If we have just processed some options following some non-options,
388
 
             exchange them so that the options come first.  */
389
 
 
390
 
          if (first_nonopt != last_nonopt && last_nonopt != pj_optind)
391
 
            exchange ((char **) argv);
392
 
          else if (last_nonopt != pj_optind)
393
 
            first_nonopt = pj_optind;
394
 
 
395
 
          /* Skip any additional non-options
396
 
             and extend the range of non-options previously skipped.  */
397
 
 
398
 
          while (pj_optind < argc && NONOPTION_P)
399
 
            pj_optind++;
400
 
          last_nonopt = pj_optind;
401
 
        }
402
 
 
403
 
      /* The special ARGV-element `--' means premature end of options.
404
 
         Skip it like a null option,
405
 
         then exchange with previous non-options as if it were an option,
406
 
         then skip everything else like a non-option.  */
407
 
 
408
 
      if (pj_optind != argc && !pj_ansi_strcmp(argv[pj_optind], "--"))
409
 
        {
410
 
          pj_optind++;
411
 
 
412
 
          if (first_nonopt != last_nonopt && last_nonopt != pj_optind)
413
 
            exchange ((char **) argv);
414
 
          else if (first_nonopt == last_nonopt)
415
 
            first_nonopt = pj_optind;
416
 
          last_nonopt = argc;
417
 
 
418
 
          pj_optind = argc;
419
 
        }
420
 
 
421
 
      /* If we have done all the ARGV-elements, stop the scan
422
 
         and back over any non-options that we skipped and permuted.  */
423
 
 
424
 
      if (pj_optind == argc)
425
 
        {
426
 
          /* Set the next-arg-index to point at the non-options
427
 
             that we previously skipped, so the caller will digest them.  */
428
 
          if (first_nonopt != last_nonopt)
429
 
            pj_optind = first_nonopt;
430
 
          return -1;
431
 
        }
432
 
 
433
 
      /* If we have come to a non-option and did not permute it,
434
 
         either stop the scan or describe it to the caller and pass it by.  */
435
 
 
436
 
      if (NONOPTION_P)
437
 
        {
438
 
          if (ordering == REQUIRE_ORDER)
439
 
            return -1;
440
 
          pj_optarg = argv[pj_optind++];
441
 
          return 1;
442
 
        }
443
 
 
444
 
      /* We have found another option-ARGV-element.
445
 
         Skip the initial punctuation.  */
446
 
 
447
 
      nextchar = (argv[pj_optind] + 1
448
 
                  + (longopts != NULL && argv[pj_optind][1] == '-'));
449
 
    }
450
 
 
451
 
  /* Decode the current option-ARGV-element.  */
452
 
 
453
 
  /* Check whether the ARGV-element is a long option.
454
 
 
455
 
     If long_only and the ARGV-element has the form "-f", where f is
456
 
     a valid short option, don't consider it an abbreviated form of
457
 
     a long option that starts with f.  Otherwise there would be no
458
 
     way to give the -f short option.
459
 
 
460
 
     On the other hand, if there's a long option "fubar" and
461
 
     the ARGV-element is "-fu", do consider that an abbreviation of
462
 
     the long option, just like "--fu", and not "-f" with arg "u".
463
 
 
464
 
     This distinction seems to be the most useful approach.  */
465
 
 
466
 
  if (longopts != NULL
467
 
      && (argv[pj_optind][1] == '-'
468
 
          || (long_only && (argv[pj_optind][2] || !my_index (optstring, argv[pj_optind][1])))))
469
 
    {
470
 
      char *nameend;
471
 
      const struct pj_getopt_option *p;
472
 
      const struct pj_getopt_option *pfound = NULL;
473
 
      int exact = 0;
474
 
      int ambig = 0;
475
 
      int indfound = -1;
476
 
      int option_index;
477
 
 
478
 
      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
479
 
        /* Do nothing.  */ ;
480
 
 
481
 
      /* Test all long options for either exact match
482
 
         or abbreviated matches.  */
483
 
      for (p = longopts, option_index = 0; p->name; p++, option_index++)
484
 
        if (!strncmp (p->name, nextchar, nameend - nextchar))
485
 
          {
486
 
            if ((unsigned int) (nameend - nextchar)
487
 
                == (unsigned int) strlen (p->name))
488
 
              {
489
 
                /* Exact match found.  */
490
 
                pfound = p;
491
 
                indfound = option_index;
492
 
                exact = 1;
493
 
                break;
494
 
              }
495
 
            else if (pfound == NULL)
496
 
              {
497
 
                /* First nonexact match found.  */
498
 
                pfound = p;
499
 
                indfound = option_index;
500
 
              }
501
 
            else
502
 
              /* Second or later nonexact match found.  */
503
 
              ambig = 1;
504
 
          }
505
 
 
506
 
      if (ambig && !exact)
507
 
        {
508
 
          nextchar += strlen (nextchar);
509
 
          pj_optind++;
510
 
          pj_optopt = 0;
511
 
          return '?';
512
 
        }
513
 
 
514
 
      if (pfound != NULL)
515
 
        {
516
 
          option_index = indfound;
517
 
          pj_optind++;
518
 
          if (*nameend)
519
 
            {
520
 
              /* Don't test has_arg with >, because some C compilers don't
521
 
                 allow it to be used on enums.  */
522
 
              if (pfound->has_arg)
523
 
                pj_optarg = nameend + 1;
524
 
              else
525
 
                {
526
 
                  nextchar += strlen (nextchar);
527
 
 
528
 
                  pj_optopt = pfound->val;
529
 
                  return '?';
530
 
                }
531
 
            }
532
 
          else if (pfound->has_arg == 1)
533
 
            {
534
 
              if (pj_optind < argc)
535
 
                pj_optarg = argv[pj_optind++];
536
 
              else
537
 
                {
538
 
                  nextchar += strlen (nextchar);
539
 
                  pj_optopt = pfound->val;
540
 
                  return optstring[0] == ':' ? ':' : '?';
541
 
                }
542
 
            }
543
 
          nextchar += strlen (nextchar);
544
 
          if (longind != NULL)
545
 
            *longind = option_index;
546
 
          if (pfound->flag)
547
 
            {
548
 
              *(pfound->flag) = pfound->val;
549
 
              return 0;
550
 
            }
551
 
          return pfound->val;
552
 
        }
553
 
 
554
 
      /* Can't find it as a long option.  If this is not pj_getopt_long_only,
555
 
         or the option starts with '--' or is not a valid short
556
 
         option, then it's an error.
557
 
         Otherwise interpret it as a short option.  */
558
 
      if (!long_only || argv[pj_optind][1] == '-'
559
 
          || my_index (optstring, *nextchar) == NULL)
560
 
        {
561
 
          nextchar = (char *) "";
562
 
          pj_optind++;
563
 
          pj_optopt = 0;
564
 
          return '?';
565
 
        }
566
 
    }
567
 
 
568
 
  /* Look at and handle the next short option-character.  */
569
 
 
570
 
  {
571
 
    char c = *nextchar++;
572
 
    char *temp = my_index (optstring, c);
573
 
 
574
 
    /* Increment `pj_optind' when we start to process its last character.  */
575
 
    if (*nextchar == '\0')
576
 
      ++pj_optind;
577
 
 
578
 
    if (temp == NULL || c == ':')
579
 
      {
580
 
        pj_optopt = c;
581
 
        return '?';
582
 
      }
583
 
    /* Convenience. Treat POSIX -W foo same as long option --foo */
584
 
    if (temp[0] == 'W' && temp[1] == ';')
585
 
      {
586
 
        char *nameend;
587
 
        const struct pj_getopt_option *p;
588
 
        const struct pj_getopt_option *pfound = NULL;
589
 
        int exact = 0;
590
 
        int ambig = 0;
591
 
        int indfound = 0;
592
 
        int option_index;
593
 
 
594
 
        /* This is an option that requires an argument.  */
595
 
        if (*nextchar != '\0')
596
 
          {
597
 
            pj_optarg = nextchar;
598
 
            /* If we end this ARGV-element by taking the rest as an arg,
599
 
               we must advance to the next element now.  */
600
 
            pj_optind++;
601
 
          }
602
 
        else if (pj_optind == argc)
603
 
          {
604
 
            pj_optopt = c;
605
 
            if (optstring[0] == ':')
606
 
              c = ':';
607
 
            else
608
 
              c = '?';
609
 
            return c;
610
 
          }
611
 
        else
612
 
          /* We already incremented `pj_optind' once;
613
 
             increment it again when taking next ARGV-elt as argument.  */
614
 
          pj_optarg = argv[pj_optind++];
615
 
 
616
 
        /* pj_optarg is now the argument, see if it's in the
617
 
           table of longopts.  */
618
 
 
619
 
        for (nextchar = nameend = pj_optarg; *nameend && *nameend != '='; nameend++)
620
 
          /* Do nothing.  */ ;
621
 
 
622
 
        /* Test all long options for either exact match
623
 
           or abbreviated matches.  */
624
 
        for (p = longopts, option_index = 0; p->name; p++, option_index++)
625
 
          if (!strncmp (p->name, nextchar, nameend - nextchar))
626
 
            {
627
 
              if ((unsigned int) (nameend - nextchar) == strlen (p->name))
628
 
                {
629
 
                  /* Exact match found.  */
630
 
                  pfound = p;
631
 
                  indfound = option_index;
632
 
                  exact = 1;
633
 
                  break;
634
 
                }
635
 
              else if (pfound == NULL)
636
 
                {
637
 
                  /* First nonexact match found.  */
638
 
                  pfound = p;
639
 
                  indfound = option_index;
640
 
                }
641
 
              else
642
 
                /* Second or later nonexact match found.  */
643
 
                ambig = 1;
644
 
            }
645
 
        if (ambig && !exact)
646
 
          {
647
 
            nextchar += strlen (nextchar);
648
 
            pj_optind++;
649
 
            return '?';
650
 
          }
651
 
        if (pfound != NULL)
652
 
          {
653
 
            option_index = indfound;
654
 
            if (*nameend)
655
 
              {
656
 
                /* Don't test has_arg with >, because some C compilers don't
657
 
                   allow it to be used on enums.  */
658
 
                if (pfound->has_arg)
659
 
                  pj_optarg = nameend + 1;
660
 
                else
661
 
                  {
662
 
                    nextchar += strlen (nextchar);
663
 
                    return '?';
664
 
                  }
665
 
              }
666
 
            else if (pfound->has_arg == 1)
667
 
              {
668
 
                if (pj_optind < argc)
669
 
                  pj_optarg = argv[pj_optind++];
670
 
                else
671
 
                  {
672
 
                    nextchar += strlen (nextchar);
673
 
                    return optstring[0] == ':' ? ':' : '?';
674
 
                  }
675
 
              }
676
 
            nextchar += strlen (nextchar);
677
 
            if (longind != NULL)
678
 
              *longind = option_index;
679
 
            if (pfound->flag)
680
 
              {
681
 
                *(pfound->flag) = pfound->val;
682
 
                return 0;
683
 
              }
684
 
            return pfound->val;
685
 
          }
686
 
          nextchar = NULL;
687
 
          return 'W';   /* Let the application handle it.   */
688
 
      }
689
 
    if (temp[1] == ':')
690
 
      {
691
 
        if (temp[2] == ':')
692
 
          {
693
 
            /* This is an option that accepts an argument optionally.  */
694
 
            if (*nextchar != '\0')
695
 
              {
696
 
                pj_optarg = nextchar;
697
 
                pj_optind++;
698
 
              }
699
 
            else
700
 
              pj_optarg = NULL;
701
 
            nextchar = NULL;
702
 
          }
703
 
        else
704
 
          {
705
 
            /* This is an option that requires an argument.  */
706
 
            if (*nextchar != '\0')
707
 
              {
708
 
                pj_optarg = nextchar;
709
 
                /* If we end this ARGV-element by taking the rest as an arg,
710
 
                   we must advance to the next element now.  */
711
 
                pj_optind++;
712
 
              }
713
 
            else if (pj_optind == argc)
714
 
              {
715
 
                pj_optopt = c;
716
 
                if (optstring[0] == ':')
717
 
                  c = ':';
718
 
                else
719
 
                  c = '?';
720
 
              }
721
 
            else
722
 
              /* We already incremented `pj_optind' once;
723
 
                 increment it again when taking next ARGV-elt as argument.  */
724
 
              pj_optarg = argv[pj_optind++];
725
 
            nextchar = NULL;
726
 
          }
727
 
      }
728
 
    return c;
729
 
  }
730
 
}
731