~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): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

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