chiark / gitweb /
Expunge revision histories in files.
[cfd] / mdwopt.c
1 /* -*-c-*-
2  *
3  * $Id: mdwopt.c,v 1.10 2004/04/08 01:36:24 mdw Exp $
4  *
5  * Options parsing, similar to GNU @getopt_long@
6  *
7  * (c) 1996 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------*
11  *
12  * This file is part of many programs.
13  *
14  * `mdwopt' is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Library General Public License as
16  * published by the Free Software Foundation; either version 2 of the
17  * License, or (at your option) any later version.
18  *
19  * `mdwopt' is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Library General Public License for more details.
23  *
24  * You should have received a copy of the GNU Library General Public
25  * License along with `mdwopt'; if not, write to the Free
26  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27  * MA 02111-1307, USA.
28  */
29
30 /*----- External dependencies ---------------------------------------------*/
31
32 #include <ctype.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #include "mdwopt.h"
38
39 /*----- Configuration things ----------------------------------------------*/
40
41 #if defined(__riscos)
42 #  define PATHSEP '.'
43 #elif defined(__OS2__) || defined(__MSDOS__) || defined(__WINNT__)
44 #  define PATHSEP '\\'
45 #else /* Assume a sane filing system */
46 #  define PATHSEP '/'
47 #endif
48
49 /*----- Global variables --------------------------------------------------*/
50
51 mdwopt_data mdwopt_global = {0, 0, 0, 1, 0, 0, 0, 0, 0};
52
53 enum {
54   ORD_PERMUTE = 0,                      /* Permute the options (default) */
55   ORD_RETURN = 1,                       /* Return non-option things */
56   ORD_POSIX = 2,                        /* Do POSIX-type hacking */
57   ORD_NEGATE = 4                        /* Magic negate-next-thing flag */
58 };
59
60 /*----- Word splitting ----------------------------------------------------*/
61
62 #ifdef BUILDING_MLIB
63 #  include "str.h"
64 #  define qword str_qword
65 #else
66
67 /* --- @qword@ --- *
68  *
69  * Arguments:   @char **pp@ = address of pointer into string
70  *              @unsigned f@ = various flags
71  *
72  * Returns:     Pointer to the next space-separated possibly-quoted word from
73  *              the string, or null.
74  *
75  * Use:         Fetches the next word from a string.  If the flag
76  *              @STRF_QUOTE@ is set, the `\' character acts as an escape, and
77  *              single and double quotes protect whitespace.
78  */
79
80 #define STRF_QUOTE 1u
81
82 static char *qword(char **pp, unsigned f)
83 {
84   char *p = *pp, *q, *qq;
85   int st = 0, pst = 0;
86
87   /* --- Preliminaries --- */
88
89   if (!p)
90     return (0);
91   while (isspace((unsigned char)*p))
92     p++;
93   if (!*p) {
94     *pp = 0;
95     return (0);
96   }
97
98   /* --- Main work --- */
99
100   for (q = qq = p; *q; q++) {
101     switch (st) {
102       case '\\':
103         *qq++ = *q;
104         st = pst;
105         break;
106       case '\'':
107       case '\"':
108         if (*q == st)
109           st = pst = 0;
110         else if (*q == '\\')
111           st = '\\';
112         else
113           *qq++ = *q;
114         break;
115       default:
116         if (isspace((unsigned char)*q)) {
117           do q++; while (*q && isspace((unsigned char)*q));
118           goto done;
119         } else if (!(f & STRF_QUOTE))
120           goto stdchar;
121         switch (*q) {
122           case '\\':
123             st = '\\';
124             break;
125           case '\'':
126           case '\"':
127             st = pst = *q;
128             break;
129           default:
130           stdchar:
131             *qq++ = *q;
132             break;
133         }
134     }
135   }
136
137   /* --- Finished --- */
138
139 done:
140   *pp = *q ? q : 0;
141   *qq++ = 0;
142   return (p);
143 }
144
145 #endif
146
147 /*----- Main code ---------------------------------------------------------*/
148
149 /* --- @nextword@ --- *
150  *
151  * Arguments:   @int argc@ = number of command line options
152  *              @char *argv[]@ = pointer to command line options
153  *              @mdwopt_data *data@ = pointer to persistent state
154  *
155  * Returns:     Pointer to the next word to handle, or 0
156  *
157  * Use:         Extracts the next word from the command line or environment
158  *              variable.
159  */
160
161 static char *nextword(int argc, char *const *argv, mdwopt_data *data)
162 {
163   if (data->ind == -1) {
164     char *p;
165     if ((p = qword(&data->env, STRF_QUOTE)) != 0)
166       return (p);
167     data->ind = 1;
168   }
169
170   if (data->next == argc)
171     return (0);
172   return (argv[data->next++]);
173 }
174
175 /* --- @permute@ --- *
176  *
177  * Arguments:   @char *argv[]@ = pointer to command line arguments
178  *              @mdwopt_data *data@ = pointer to persistent data
179  *
180  * Returns:     --
181  *
182  * Use:         Moves a command line option into the right place.
183  */
184
185 static void permute(char *const *argv, mdwopt_data *data)
186 {
187   char **v = (char **)argv;
188   if (data->ind != -1) {
189     int i = data->next - 1;
190     char *p = v[i];
191     while (i > data->ind) {
192       v[i] = v[i - 1];
193       i--;
194     }
195     v[i] = p;
196     data->ind++;
197   }
198 }
199
200 /* --- @findOpt@ --- *
201  *
202  * Arguments:   @int o@ = which option to search for
203  *              @const char *shortopt@ = short options string to search
204  *              @mdwopt_data *data@ = pointer to persistant state
205  *
206  * Returns:     Pointer to rest of short options string (including magic
207  *              characters)
208  *
209  * Use:         Looks up a short option in the given string.
210  */
211
212 static const char *findOpt(int o, const char *shortopt,
213                                mdwopt_data *data)
214 {
215   const char *p = shortopt;
216   for (;;) {
217     if (!*p)
218       return (0);
219
220     if (o != *p || (p[1] != '+' && data->order & ORD_NEGATE)) {
221       p++;
222       while (*p == '+')
223         p++;
224       while (*p == ':')
225         p++;
226     }
227     else
228       return (p + 1);
229   }
230 }
231
232 /* --- @mdwopt@ --- *
233  *
234  * Arguments:   @int argc@ = number of command line arguments
235  *              @char * const *argv@ = pointer to command line arguments
236  *              @const char *shortopt@ = pointer to short options information
237  *              @const struct option *longopts@ = pointer to long opts info
238  *              @int *longind@ = where to store matched longopt
239  *              @mdwopt_data *data@ = persistent state for the parser
240  *              @int flags@ = various useful flags
241  *
242  * Returns:     Value of option found next, or an error character, or
243  *              @EOF@ for the last thing.
244  *
245  * Use:         Reads options.  The routine should be more-or-less compatible
246  *              with standard getopts, although it provides many more
247  *              features even than the standard GNU implementation.
248  *
249  *              The precise manner of options parsing is determined by
250  *              various flag settings, which are described below.  By setting
251  *              flag values appropriately, you can achieve behaviour very
252  *              similar to most other getopt routines.
253  *
254  *
255  *          How options parsing appears to users
256  *
257  *              A command line consists of a number of `words' (which may
258  *              contain spaces, according to various shell quoting
259  *              conventions).  A word may be an option, an argument to an
260  *              option, or a non-option.  An option begins with a special
261  *              character, usually `%|-|%', although `%|+|%' is also used
262  *              sometimes.  As special exceptions, the word containing only a
263  *              `%|-|%' is considered to be a non-option, since it usually
264  *              represents standard input or output as a filename, and the
265  *              word containing a double-dash `%|--|%' is used to mark all
266  *              following words as being non-options regardless of their
267  *              initial character.
268  *
269  *              Traditionally, all words after the first non-option have been
270  *              considered to be non-options automatically, so that options
271  *              must be specified before filenames.  However, this
272  *              implementation can extract all the options from the command
273  *              line regardless of their position.  This can usually be
274  *              disabled by setting one of the environment variables
275  *              `%|POSIXLY_CORRECT|%' or `%|_POSIX_OPTION_ORDER|%'.
276  *
277  *              There are two different styles of options: `short' and
278  *              `long'.
279  *
280  *              Short options are the sort which Unix has known for ages: an
281  *              option is a single letter, preceded by a `%|-|%'.  Short
282  *              options can be joined together to save space (and possibly to
283  *              make silly words): e.g., instead of giving options
284  *              `%|-x -y|%', a user could write `%|-xy|%'.  Some short
285  *              options can have arguments, which appear after the option
286  *              letter, either immediately following, or in the next `word'
287  *              (so an option with an argument could be written as
288  *              `%|-o foo|%' or as `%|-ofoo|%').  Note that options with
289  *              optional arguments must be written in the second style.
290  *
291  *              When a short option controls a flag setting, it is sometimes
292  *              possible to explicitly turn the flag off, as well as turning
293  *              it on, (usually to override default options).  This is
294  *              usually done by using a `%|+|%' instead of a `%|-|%' to
295  *              introduce the option.
296  *
297  *              Long options, as popularized by the GNU utilities, are given
298  *              long-ish memorable names, preceded by a double-dash `%|--|%'.
299  *              Since their names are more than a single character, long
300  *              options can't be combined in the same way as short options.
301  *              Arguments to long options may be given either in the same
302  *              `word', separated from the option name by an equals sign, or
303  *              in the following `word'.
304  *
305  *              Long option names can be abbreviated if necessary, as long
306  *              as the abbreviation is unique.  This means that options can
307  *              have sensible and memorable names but still not require much
308  *              typing from an experienced user.
309  *
310  *              Like short options, long options can control flag settings.
311  *              The options to manipulate these settings come in pairs: an
312  *              option of the form `%|--set-flag|%' might set the flag, while
313  *              an option of the form `%|--no-set-flag|%' might clear it.
314  *
315  *              It is usual for applications to provide both short and long
316  *              options with identical behaviour.  Some applications with
317  *              lots of options may only provide long options (although they
318  *              will often be only two or three characters long).  In this
319  *              case, long options can be preceded with a single `%|-|%'
320  *              character, and negated by a `%|+|%' character.
321  *
322  *              Finally, some (older) programs accept arguments of the form
323  *              `%%@.{"-"<number>}%%', to set some numerical parameter,
324  *              typically a line count of some kind.
325  *
326  *
327  *          How programs parse options
328  *
329  *              An application parses its options by calling mdwopt
330  *              repeatedly.  Each time it is called, mdwopt returns a value
331  *              describing the option just read, and stores information about
332  *              the option in a data block.  The value %$-1$% is returned
333  *              when there are no more options to be read.  The `%|?|%'
334  *              character is returned when an error is encountered.
335  *
336  *              Before starting to parse options, the value @data->ind@ must
337  *              be set to 0 or 1. The value of @data->err@ can also be set,
338  *              to choose whether errors are reported by mdwopt.
339  *
340  *              The program's `@argc@' and `@argv@' arguments are passed to
341  *              the options parser, so that it can read the command line.  A
342  *              flags word is also passed, allowing the program fine control
343  *              over parsing.  The flags are described above.
344  *
345  *              Short options are described by a string, which once upon a
346  *              time just contained the permitted option characters.  Now the
347  *              options string begins with a collection of flag characters,
348  *              and various flag characters can be put after options
349  *              characters to change their properties.
350  *
351  *              If the first character of the short options string is
352  *              `%|+|%', `%|-|%' or `%|!|%', the order in which options are
353  *              read is modified, as follows:
354  *
355  *              `%|+|%' forces the POSIX order to be used. As soon as a non-
356  *                      option is found, mdwopt returns %$-1$%.
357  *
358  *              `%|-|%' makes mdwopt treat non-options as being `special'
359  *                      sorts of option. When a non-option word is found, the
360  *                      value 0 is returned, and the actual text of the word
361  *                      is stored as being the option's argument.
362  *
363  *              `%|!|%' forces the default order to be used.  The entire
364  *                      command line is scanned for options, which are
365  *                      returned in order.  However, during this process,
366  *                      the options are moved in the @argv@ array, so that
367  *                      they appear before the non- options.
368  *
369  *              A `%|:|%' character may be placed after the ordering flag (or
370  *              at the very beginning if no ordering flag is given) which
371  *              indicates that the character `%|:|%', rather than `%|?|%',
372  *              should be returned if a missing argument error is detected.
373  *
374  *              Each option in the string can be followed by a `%|+|%' sign,
375  *              indicating that it can be negated, a `%|:|%' sign indicating
376  *              that it requires an argument, or a `%|::|%' string,
377  *              indicating an optional argument.  Both `%|+|%' and `%|:|%' or
378  *              `%|::|%' may be given, although the `%|+|%' must come first.
379  *
380  *              If an option is found, the option character is returned to
381  *              the caller.  A pointer to an argument is stored in
382  *              @data->arg@, or @NULL@ is stored if there was no argument.
383  *              If a negated option was found, the option character is
384  *              returned ORred with @OPTF_NEGATED@ (bit 8 set).
385  *
386  *              Long options are described in a table.  Each entry in the
387  *              table is of type @struct option@, and the table is terminated
388  *              by an entry whose @name@ field is null.  Each option has
389  *              a flags word which, due to historical reasons, is called
390  *              @has_arg@.  This describes various properties of the option,
391  *              such as what sort of argument it takes, and whether it can
392  *              be negated.
393  *
394  *              When mdwopt finds a long option, it looks the name up in the
395  *              table. The index of the matching entry is stored in the
396  *              @longind@ variable, passed to mdwopt (unless @longind@ is 0):
397  *              a value of %$-1$% indicates that no long option was
398  *              found. The behaviour is then dependent on the values in the
399  *              table entry.  If @flag@ is nonzero, it points to an integer
400  *              to be modified by mdwopt.  Usually the value in the @val@
401  *              field is simply stored in the @flag@ variable. If the flag
402  *              @OPTF_SWITCH@ is set, however, the value is combined with
403  *              the existing value of the flags using a bitwise OR.  If
404  *              @OPTF_NEGATE@ is set, then the flag bit will be cleared if a
405  *              matching negated long option is found.  The value 0 is
406  *              returned.
407  *
408  *              If @flag@ is zero, the value in @val@ is returned by mdwopt,
409  *              possibly with bit 8 set if the option was negated.
410  *
411  *              Arguments for long options are stored in @data->arg@, as
412  *              before.
413  *
414  *              Numeric options, if enabled, cause the value `%|#|%' to be
415  *              returned, and the numeric value to be stored in @data->opt@.
416  *
417  *              If the flag @OPTF_ENVVAR@ is set on entry, options will be
418  *              extracted from an environment variable whose name is built by
419  *              capitalizing all the letters of the program's name.  (This
420  *              allows a user to have different default settings for a
421  *              program, by calling it through different symbolic links.)
422  */
423
424 int mdwopt(int argc, char *const *argv,
425            const char *shortopt,
426            const struct option *longopts, int *longind,
427            mdwopt_data *data, int flags)
428 {
429   /* --- Local variables --- */
430
431   char *p, *q, *r;
432   char *prefix;
433   int i;
434   char noarg = '?';
435
436   /* --- Sort out our data --- */
437
438   if (!data)
439     data = &mdwopt_global;
440
441   /* --- See if this is the first time --- */
442
443   if (data->ind == 0 || (data->ind == 1 && ~flags & OPTF_NOPROGNAME)) {
444
445     /* --- Sort out default returning order --- */
446
447     if (getenv("_POSIX_OPTION_ORDER") ||
448         getenv("POSIXLY_CORRECT"))
449       data->order = ORD_POSIX;
450     else
451       data->order = ORD_PERMUTE;
452
453     /* --- Now see what the caller actually wants --- */
454
455     switch (shortopt[0]) {
456       case '-':
457         data->order = ORD_RETURN;
458         break;
459       case '+':
460         data->order = ORD_POSIX;
461         break;
462       case '!':
463         data->order = ORD_PERMUTE;
464         break;
465     }
466
467     /* --- Now decide on the program's name --- */
468
469     if (~flags & OPTF_NOPROGNAME) {
470       p = q = (char *)argv[0];
471       while (*p) {
472         if (*p++ == PATHSEP)
473           q = p;
474       }
475       data->prog = q;
476
477       data->ind = data->next = 1;
478       data->list = 0;
479
480       /* --- See about environment variables --- *
481        *
482        * Be careful.  The program may be setuid, and an attacker might have
483        * given us a long name in @argv[0]@.  If the name is very long, don't
484        * support this option.
485        */
486
487       if (flags & OPTF_ENVVAR && strlen(data->prog) < 48) {
488
489         char buf[64];
490
491         /* --- For RISC OS, support a different format --- *
492          *
493          * Acorn's RISC OS tends to put settings in variables named
494          * `App$Options' rather than `APP'.  Under RISC OS, I'll support
495          * both methods, just to avoid confuddlement.
496          */
497
498 #ifdef __riscos
499         sprintf(buf, "%s$Options", data->prog);
500         p = getenv(buf);
501         if (!p) {
502 #endif
503
504           p = buf;
505           q = data->prog;
506           while (*q)
507             *p++ = toupper(*q++);
508           *p++ = 0;
509           p = getenv(buf);
510
511 #ifdef __riscos
512         }
513 #endif
514
515         /* --- Copy the options string into a buffer --- */
516
517         if (p) {
518           q = malloc(strlen(p) + 1);
519           if (!q) {
520             fprintf(stderr,
521                     "%s: Not enough memory to read settings in "
522                     "environment variable\n",
523                     data->prog);
524           } else {
525             strcpy(q, p);
526             data->ind = -1;
527             data->env = data->estart = q;
528           }
529         }
530
531       }
532     }
533     else
534       data->ind = data->next = 0;
535   }
536
537   /* --- Do some initial bodgery --- *
538    *
539    * The @shortopt@ string can have some interesting characters at the
540    * beginning.  We'll skip past them.
541    */
542
543   switch (shortopt[0]) {
544     case '+':
545     case '-':
546     case '!':
547       shortopt++;
548       break;
549   }
550
551   if (shortopt[0] == ':') {
552     noarg = shortopt[0];
553     shortopt++;
554   }
555
556   if (longind)
557     *longind = -1;
558   data->opt = -1;
559   data->arg = 0;
560
561   /* --- Now go off and search for an option --- */
562
563   if (!data->list || !*data->list) {
564     data->order &= 3;                   /* Clear negation flag */
565
566     /* --- Now we need to find the next option --- *
567      *
568      * Exactly how we do this depends on the settings of the order variable.
569      * We identify options as being things starting with `%|-|%', and which
570      * aren't equal to `%|-|%' or `%|--|%'.  We'll look for options until:
571      *
572      *   * We find something which isn't an option AND @order == ORD_POSIX@
573      *   * We find a `%|--|%'
574      *   * We reach the end of the list
575      *
576      * There are some added little wrinkles, which we'll meet as we go.
577      */
578
579     for (;;) {
580       p = nextword(argc, argv, data);
581       if (!p)
582         return (EOF);
583
584       /* --- See if we've found an option --- */
585
586       if ((p[0] == '-' || (p[0] == '+' && flags & OPTF_NEGATION)) &&
587           p[1] != 0) {
588         if (strcmp(p, "--") == 0) {
589           permute(argv, data);
590           return (EOF);
591         }
592         break;
593       }
594
595       /* --- Figure out how to proceed --- */
596
597       switch (data->order & 3) {
598         case ORD_POSIX:
599           return (EOF);
600           break;
601         case ORD_PERMUTE:
602           break;
603         case ORD_RETURN:
604           permute(argv, data);
605           data->arg = p;
606           return (0);
607       }
608     }
609
610     /* --- We found an option --- */
611
612     permute(argv, data);
613
614     /* --- Check for a numeric option --- *
615      *
616      * We only check the first character (or the second if the first is a
617      * sign).  This ought to be enough.
618      */
619
620     if (flags & OPTF_NUMBERS && (p[0] == '-' || flags & OPTF_NEGNUMBER)) {
621       if (((p[1] == '+' || p[1] == '-') && isdigit((unsigned char)p[2])) ||
622           isdigit((unsigned char)p[1])) {
623         data->opt = strtol(p + 1, &data->arg, 10);
624         while (isspace((unsigned char)data->arg[0]))
625           data->arg++;
626         if (!data->arg[0])
627           data->arg = 0;
628         return (p[0] == '-' ? '#' : '#' | OPTF_NEGATED);
629       }
630     }
631
632     /* --- Check for a long option --- */
633
634     if (p[0] == '+')
635       data->order |= ORD_NEGATE;
636
637     if (((p[0] == '-' && p[1] == '-') ||
638          (flags & OPTF_NOSHORTS && !findOpt(p[1], shortopt, data))) &&
639         (~flags & OPTF_NOLONGS))
640     {
641       int match = -1;
642
643       if (p[0] == '+') {
644         data->order |= ORD_NEGATE;
645         p++;
646         prefix = "+";
647       } else if (p[1] == '-') {
648         if ((flags & OPTF_NEGATION) && strncmp(p + 2, "no-", 3) == 0) {
649           p += 5;
650           prefix = "--no-";
651           data->order |= ORD_NEGATE;
652         } else {
653           p += 2;
654           prefix = "--";
655         }
656       } else {
657         if ((flags & OPTF_NEGATION) && strncmp(p + 1, "no-", 3) == 0) {
658           p += 4;
659           prefix = "-no-";
660           data->order |= ORD_NEGATE;
661         } else {
662           p++;
663           prefix = "-";
664         }
665       }
666
667       for (i = 0; longopts[i].name; i++) {
668         if ((data->order & ORD_NEGATE) &&
669             (~longopts[i].has_arg & OPTF_NEGATE))
670           continue;
671
672         r = (char *) longopts[i].name;
673         q = p;
674         for (;;) {
675           if (*q == 0 || *q == '=') {
676             if (*r == 0) {
677               match = i;
678               goto botched;
679             }
680             if (match == -1) {
681               match = i;
682               break;
683             } else {
684               match = -1;
685               goto botched;
686             }
687           }
688           else if (*q != *r)
689             break;
690           q++, r++;
691         }
692       }
693
694     botched:
695       if (match == -1) {
696         if (data->err) {
697           fprintf(stderr, "%s: unrecognized option `%s%s'\n",
698                   data->prog,
699                   prefix, p);
700         }
701         return ('?');
702       }
703
704       if (longind)
705         *longind = match;
706
707       /* --- Handle argument behaviour --- */
708
709       while (*p != 0 && *p != '=')
710         p++;
711       p = (*p ? p + 1 : 0);
712       q = (char *) longopts[match].name;
713
714       switch (longopts[match].has_arg & OPTF_ARG) {
715         case OPTF_NOARG:
716           if (p) {
717             if (data->err) {
718               fprintf(stderr,
719                       "%s: option `%s%s' does not accept arguments\n",
720                       data->prog,
721                       prefix, q);
722             }
723             return ('?');
724           }
725           break;
726
727         case OPTF_ARGREQ:
728           if (!p) {
729             p = nextword(argc, argv, data);
730
731             if (!p) {
732               if (data->err) {
733                 fprintf(stderr, "%s: option `%s%s' requires an argument\n",
734                         data->prog,
735                         prefix, q);
736               }
737               return (noarg);
738             }
739
740             permute(argv, data);
741           }
742           break;
743
744         case OPTF_ARGOPT:
745           /* Who cares? */
746           break;
747       }
748       data->arg = p;
749
750       /* --- Do correct things now we have a match --- */
751
752       if (longopts[match].flag) {
753         if (longopts[match].has_arg & OPTF_SWITCH) {
754           if (data->order & ORD_NEGATE)
755             *longopts[match].flag &= ~longopts[match].val;
756           else
757             *longopts[match].flag |= longopts[match].val;
758         } else {
759           if (data->order & ORD_NEGATE)
760             *longopts[match].flag = 0;
761           else
762             *longopts[match].flag = longopts[match].val;
763         }
764         return (0);
765       } else {
766         if (data->order & ORD_NEGATE)
767           return (longopts[match].val | OPTF_NEGATED);
768         else
769           return (longopts[match].val);
770       }
771     }
772
773     /* --- Do short options things --- */
774
775     else {
776       if (p[0] == '+')
777         data->order |= ORD_NEGATE;
778       data->list = p + 1;
779     }
780   }
781
782   /* --- Now process the short options --- */
783
784   i = *data->list++;
785   data->opt = i;
786
787   p = (char *) findOpt(i, shortopt, data);
788   if (!p) {
789     if (data->err) {
790       fprintf(stderr, "%s: unknown option `%c%c'\n",
791               data->prog,
792               data->order & ORD_NEGATE ? '+' : '-',
793               i);
794     }
795     return ('?');
796   }
797
798   data->opt = i;
799
800   /* --- Sort out an argument, if we expect one --- */
801
802   if (p[0] == ':') {
803     q = (data->list[0] ? data->list : 0);
804     data->list = 0;
805     if (p[1] != ':' && !q) {
806
807       /* --- Same code as before --- */
808
809       q = nextword(argc, argv, data);
810       if (!q) {
811         if (data->err) {
812           fprintf(stderr, "%s: option `%c%c' requires an argument\n",
813                   data->prog,
814                   data->order & ORD_NEGATE ? '+' : '-',
815                   i);
816         }
817         return (noarg);
818       }
819       permute(argv, data);
820     }
821
822     data->arg = q;
823   }
824   return ((data->order & ORD_NEGATE) ? i | OPTF_NEGATED : i);
825 }
826
827 /*----- That's all, folks -------------------------------------------------*/