1 /* getopt_long and getopt_long_only entry points for GNU getopt.
2 
3    Copyright 2008, 2010 Karl Berry.
4    Copyright (C) 1987,88,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
5 
6    The original version of this file was part of the GNU C Library.
7    It has been modified for use with libkpathsea.
8 
9    This library is free software; you can redistribute it and/or
10    modify it under the terms of the GNU Lesser General Public
11    License as published by the Free Software Foundation; either
12    version 2.1 of the License, or (at your option) any later version.
13 
14    This library is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    Lesser General Public License for more details.
18 
19    You should have received a copy of the GNU Lesser General Public License
20    along with this library; if not, see <http://www.gnu.org/licenses/>.  */
21 
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include "getopt.h"
28 
29 #include <stdio.h>
30 
31 /* Comment out all this code if we are using the GNU C Library, and are not
32    actually compiling the library itself.  This code is part of the GNU C
33    Library, but also included in many other GNU distributions.  Compiling
34    and linking in this code is a waste when using the GNU C library
35    (especially if it is a shared library).  Rather than having every GNU
36    program understand `configure --with-gnu-libc' and omit the object files,
37    it is simpler to just do this in the source for each such file.  */
38 
39 #define GETOPT_INTERFACE_VERSION 2
40 #if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2
41 #include <gnu-versions.h>
42 #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
43 #define ELIDE_CODE
44 #endif
45 #endif
46 
47 #ifndef ELIDE_CODE
48 
49 
50 /* This needs to come after some library #include
51    to get __GNU_LIBRARY__ defined.  */
52 #ifdef __GNU_LIBRARY__
53 #include <stdlib.h>
54 #endif
55 
56 #ifndef NULL
57 #define NULL 0
58 #endif
59 
getopt_long(int argc,char * const * argv,const char * options,const struct option * long_options,int * opt_index)60 int getopt_long(
61      int argc,
62      char *const *argv,
63      const char *options,
64      const struct option *long_options,
65      int *opt_index
66 ){
67   return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
68 }
69 
70 /* Like getopt_long, but '-' as well as '--' can indicate a long option.
71    If an option that starts with '-' (not '--') doesn't match a long option,
72    but does match a short option, it is parsed as a short option
73    instead.  */
74 
getopt_long_only(int argc,char * const * argv,const char * options,const struct option * long_options,int * opt_index)75 int getopt_long_only(
76      int argc,
77      char *const *argv,
78      const char *options,
79      const struct option *long_options,
80      int *opt_index
81 ){
82   return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
83 }
84 
85 
86 #endif  /* Not ELIDE_CODE.  */
87 
88 #ifdef TEST
89 
90 #include <stdio.h>
91 
main(int argc,char ** argv)92 int main(int argc, char **argv)
93 {
94   int c;
95   int digit_optind = 0;
96 
97   while (1)
98     {
99       int this_option_optind = optind ? optind : 1;
100       int option_index = 0;
101       static struct option long_options[] =
102       {
103         {"add", 1, 0, 0},
104         {"append", 0, 0, 0},
105         {"delete", 1, 0, 0},
106         {"verbose", 0, 0, 0},
107         {"create", 0, 0, 0},
108         {"file", 1, 0, 0},
109         {0, 0, 0, 0}
110       };
111 
112       c = getopt_long (argc, argv, "abc:d:0123456789",
113                        long_options, &option_index);
114       if (c == -1)
115         break;
116 
117       switch (c)
118         {
119         case 0:
120           printf ("option %s", long_options[option_index].name);
121           if (optarg)
122             printf (" with arg %s", optarg);
123           printf ("\n");
124           break;
125 
126         case '0':
127         case '1':
128         case '2':
129         case '3':
130         case '4':
131         case '5':
132         case '6':
133         case '7':
134         case '8':
135         case '9':
136           if (digit_optind != 0 && digit_optind != this_option_optind)
137             printf ("digits occur in two different argv-elements.\n");
138           digit_optind = this_option_optind;
139           printf ("option %c\n", c);
140           break;
141 
142         case 'a':
143           printf ("option a\n");
144           break;
145 
146         case 'b':
147           printf ("option b\n");
148           break;
149 
150         case 'c':
151           printf ("option c with value `%s'\n", optarg);
152           break;
153 
154         case 'd':
155           printf ("option d with value `%s'\n", optarg);
156           break;
157 
158         case '?':
159           break;
160 
161         default:
162           printf ("?? getopt returned character code 0%o ??\n", c);
163         }
164     }
165 
166   if (optind < argc)
167     {
168       printf ("non-option ARGV-elements: ");
169       while (optind < argc)
170         printf ("%s ", argv[optind++]);
171       printf ("\n");
172     }
173 
174   exit (0);
175 }
176 
177 #endif /* TEST */
178