libusb 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. data/.gitignore +8 -0
  2. data/.travis.yml +10 -0
  3. data/.yardopts +6 -1
  4. data/Gemfile +16 -0
  5. data/{History.txt → History.md} +28 -16
  6. data/README.md +144 -0
  7. data/Rakefile +28 -24
  8. data/ext/extconf.rb +33 -0
  9. data/ext/libusbx-1.0.14/AUTHORS +50 -0
  10. data/ext/libusbx-1.0.14/COPYING +504 -0
  11. data/ext/libusbx-1.0.14/ChangeLog +139 -0
  12. data/ext/libusbx-1.0.14/INSTALL +234 -0
  13. data/ext/libusbx-1.0.14/Makefile.am +23 -0
  14. data/ext/libusbx-1.0.14/Makefile.in +803 -0
  15. data/ext/libusbx-1.0.14/NEWS +2 -0
  16. data/ext/libusbx-1.0.14/PORTING +94 -0
  17. data/ext/libusbx-1.0.14/README +28 -0
  18. data/ext/libusbx-1.0.14/THANKS +7 -0
  19. data/ext/libusbx-1.0.14/TODO +2 -0
  20. data/ext/libusbx-1.0.14/aclocal.m4 +9480 -0
  21. data/ext/libusbx-1.0.14/compile +143 -0
  22. data/ext/libusbx-1.0.14/config.guess +1501 -0
  23. data/ext/libusbx-1.0.14/config.h.in +116 -0
  24. data/ext/libusbx-1.0.14/config.sub +1705 -0
  25. data/ext/libusbx-1.0.14/configure +14818 -0
  26. data/ext/libusbx-1.0.14/configure.ac +230 -0
  27. data/ext/libusbx-1.0.14/depcomp +630 -0
  28. data/ext/libusbx-1.0.14/doc/Makefile.am +9 -0
  29. data/ext/libusbx-1.0.14/doc/Makefile.in +380 -0
  30. data/ext/libusbx-1.0.14/doc/doxygen.cfg.in +1288 -0
  31. data/ext/libusbx-1.0.14/examples/Makefile.am +18 -0
  32. data/ext/libusbx-1.0.14/examples/Makefile.in +596 -0
  33. data/ext/libusbx-1.0.14/examples/dpfp.c +506 -0
  34. data/ext/libusbx-1.0.14/examples/dpfp_threaded.c +544 -0
  35. data/ext/libusbx-1.0.14/examples/ezusb.c +616 -0
  36. data/ext/libusbx-1.0.14/examples/ezusb.h +107 -0
  37. data/ext/libusbx-1.0.14/examples/fxload.c +261 -0
  38. data/ext/libusbx-1.0.14/examples/getopt/getopt.c +1060 -0
  39. data/ext/libusbx-1.0.14/examples/getopt/getopt.h +180 -0
  40. data/ext/libusbx-1.0.14/examples/getopt/getopt1.c +188 -0
  41. data/ext/libusbx-1.0.14/examples/listdevs.c +63 -0
  42. data/ext/libusbx-1.0.14/examples/xusb.c +1036 -0
  43. data/ext/libusbx-1.0.14/install-sh +520 -0
  44. data/ext/libusbx-1.0.14/libusb-1.0.pc.in +11 -0
  45. data/ext/libusbx-1.0.14/libusb/Makefile.am +56 -0
  46. data/ext/libusbx-1.0.14/libusb/Makefile.in +721 -0
  47. data/ext/libusbx-1.0.14/libusb/core.c +1951 -0
  48. data/ext/libusbx-1.0.14/libusb/descriptor.c +731 -0
  49. data/ext/libusbx-1.0.14/libusb/io.c +2450 -0
  50. data/ext/libusbx-1.0.14/libusb/libusb-1.0.def +126 -0
  51. data/ext/libusbx-1.0.14/libusb/libusb-1.0.rc +59 -0
  52. data/ext/libusbx-1.0.14/libusb/libusb.h +1506 -0
  53. data/ext/libusbx-1.0.14/libusb/libusbi.h +910 -0
  54. data/ext/libusbx-1.0.14/libusb/os/darwin_usb.c +1807 -0
  55. data/ext/libusbx-1.0.14/libusb/os/darwin_usb.h +169 -0
  56. data/ext/libusbx-1.0.14/libusb/os/linux_usbfs.c +2569 -0
  57. data/ext/libusbx-1.0.14/libusb/os/linux_usbfs.h +149 -0
  58. data/ext/libusbx-1.0.14/libusb/os/openbsd_usb.c +727 -0
  59. data/ext/libusbx-1.0.14/libusb/os/poll_posix.h +10 -0
  60. data/ext/libusbx-1.0.14/libusb/os/poll_windows.c +747 -0
  61. data/ext/libusbx-1.0.14/libusb/os/poll_windows.h +114 -0
  62. data/ext/libusbx-1.0.14/libusb/os/threads_posix.c +80 -0
  63. data/ext/libusbx-1.0.14/libusb/os/threads_posix.h +50 -0
  64. data/ext/libusbx-1.0.14/libusb/os/threads_windows.c +211 -0
  65. data/ext/libusbx-1.0.14/libusb/os/threads_windows.h +87 -0
  66. data/ext/libusbx-1.0.14/libusb/os/windows_usb.c +4369 -0
  67. data/ext/libusbx-1.0.14/libusb/os/windows_usb.h +979 -0
  68. data/ext/libusbx-1.0.14/libusb/sync.c +321 -0
  69. data/ext/libusbx-1.0.14/libusb/version.h +18 -0
  70. data/ext/libusbx-1.0.14/libusb/version_nano.h +1 -0
  71. data/ext/libusbx-1.0.14/ltmain.sh +9636 -0
  72. data/ext/libusbx-1.0.14/missing +376 -0
  73. data/lib/libusb.rb +2 -3
  74. data/lib/libusb/call.rb +49 -7
  75. data/lib/libusb/compat.rb +15 -9
  76. data/lib/libusb/configuration.rb +15 -3
  77. data/lib/libusb/constants.rb +19 -6
  78. data/lib/libusb/context.rb +181 -3
  79. data/lib/libusb/dev_handle.rb +91 -40
  80. data/lib/libusb/endpoint.rb +41 -14
  81. data/lib/libusb/eventmachine.rb +183 -0
  82. data/lib/libusb/transfer.rb +21 -8
  83. data/lib/libusb/version_gem.rb +19 -0
  84. data/lib/libusb/{version.rb → version_struct.rb} +0 -0
  85. data/libusb.gemspec +31 -0
  86. data/test/test_libusb_compat.rb +1 -1
  87. data/test/test_libusb_compat_mass_storage.rb +2 -2
  88. data/test/test_libusb_descriptors.rb +1 -1
  89. data/test/test_libusb_event_machine.rb +118 -0
  90. data/test/test_libusb_iso_transfer.rb +6 -1
  91. data/test/test_libusb_mass_storage.rb +9 -3
  92. data/test/test_libusb_mass_storage2.rb +1 -1
  93. data/test/test_libusb_structs.rb +45 -0
  94. data/test/test_libusb_threads.rb +89 -0
  95. data/test/test_libusb_version.rb +4 -0
  96. metadata +109 -44
  97. data/.autotest +0 -23
  98. data/.gemtest +0 -0
  99. data/Manifest.txt +0 -3
  100. data/README.rdoc +0 -115
  101. data/test/test_libusb_keyboard.rb +0 -50
@@ -0,0 +1,107 @@
1
+ #ifndef __ezusb_H
2
+ #define __ezusb_H
3
+ /*
4
+ * Copyright © 2001 Stephen Williams (steve@icarus.com)
5
+ * Copyright © 2002 David Brownell (dbrownell@users.sourceforge.net)
6
+ *
7
+ * This source code is free software; you can redistribute it
8
+ * and/or modify it in source code form under the terms of the GNU
9
+ * General Public License as published by the Free Software
10
+ * Foundation; either version 2 of the License, or (at your option)
11
+ * any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program; if not, write to the Free Software
20
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21
+ */
22
+ #if !defined(_MSC_VER)
23
+ #include <stdbool.h>
24
+ #else
25
+ #define __attribute__(x)
26
+ #if !defined(bool)
27
+ #define bool int
28
+ #endif
29
+ #if !defined(true)
30
+ #define true (1 == 1)
31
+ #endif
32
+ #if !defined(false)
33
+ #define false (!true)
34
+ #endif
35
+ #if defined(_PREFAST_)
36
+ #pragma warning(disable:28193)
37
+ #endif
38
+ #endif
39
+
40
+ #define FX_TYPE_UNDEFINED -1
41
+ #define FX_TYPE_AN21 0 /* Original AnchorChips parts */
42
+ #define FX_TYPE_FX1 1 /* Updated Cypress versions */
43
+ #define FX_TYPE_FX2 2 /* USB 2.0 versions */
44
+ #define FX_TYPE_FX2LP 3 /* Updated FX2 */
45
+ #define FX_TYPE_MAX 4
46
+ #define FX_TYPE_NAMES { "an21", "fx", "fx2", "fx2lp" }
47
+
48
+ #define IMG_TYPE_UNDEFINED -1
49
+ #define IMG_TYPE_HEX 0 /* Intel HEX */
50
+ #define IMG_TYPE_IIC 1 /* Cypress 8051 IIC */
51
+ #define IMG_TYPE_BIX 2 /* Cypress 8051 BIX */
52
+ #define IMG_TYPE_MAX 3
53
+ #define IMG_TYPE_NAMES { "Intel HEX", "Cypress 8051 IIC", "Cypress 8051 BIX" }
54
+
55
+ /*
56
+ * Automatically identified devices (VID, PID, type, designation).
57
+ * TODO: Could use some validation. Also where's the FX2?
58
+ */
59
+ typedef struct {
60
+ uint16_t vid;
61
+ uint16_t pid;
62
+ int type;
63
+ const char* designation;
64
+ } fx_known_device;
65
+
66
+ #define FX_KNOWN_DEVICES { \
67
+ { 0x0547, 0x2122, FX_TYPE_AN21, "Cypress EZ-USB (2122S)" },\
68
+ { 0x0547, 0x2125, FX_TYPE_AN21, "Cypress EZ-USB (2121S/2125S)" },\
69
+ { 0x0547, 0x2126, FX_TYPE_AN21, "Cypress EZ-USB (2126S)" },\
70
+ { 0x0547, 0x2131, FX_TYPE_AN21, "Cypress EZ-USB (2131Q/2131S/2135S)" },\
71
+ { 0x0547, 0x2136, FX_TYPE_AN21, "Cypress EZ-USB (2136S)" },\
72
+ { 0x0547, 0x2225, FX_TYPE_AN21, "Cypress EZ-USB (2225)" },\
73
+ { 0x0547, 0x2226, FX_TYPE_AN21, "Cypress EZ-USB (2226)" },\
74
+ { 0x0547, 0x2235, FX_TYPE_AN21, "Cypress EZ-USB (2235)" },\
75
+ { 0x0547, 0x2236, FX_TYPE_AN21, "Cypress EZ-USB (2236)" },\
76
+ { 0x04b4, 0x6473, FX_TYPE_FX1, "Cypress EZ-USB FX1" },\
77
+ { 0x04b4, 0x8613, FX_TYPE_FX2LP, "Cypress EZ-USB FX2LP (68013A/68014A/68015A/68016A)" }, \
78
+ }
79
+
80
+ /*
81
+ * This function uploads the firmware from the given file into RAM.
82
+ * Stage == 0 means this is a single stage load (or the first of
83
+ * two stages). Otherwise it's the second of two stages; the
84
+ * caller having preloaded the second stage loader.
85
+ *
86
+ * The target processor is reset at the end of this upload.
87
+ */
88
+ extern int ezusb_load_ram(libusb_device_handle *device,
89
+ const char *path, int fx_type, int img_type, int stage);
90
+
91
+ /*
92
+ * This function uploads the firmware from the given file into EEPROM.
93
+ * This uses the right CPUCS address to terminate the EEPROM load with
94
+ * a reset command where FX parts behave differently than FX2 ones.
95
+ * The configuration byte is as provided here (zero for an21xx parts)
96
+ * and the EEPROM type is set so that the microcontroller will boot
97
+ * from it.
98
+ *
99
+ * The caller must have preloaded a second stage loader that knows
100
+ * how to respond to the EEPROM write request.
101
+ */
102
+ extern int ezusb_load_eeprom(libusb_device_handle *device,
103
+ const char *path, int fx_type, int img_type, int config);
104
+
105
+ /* boolean flag, says whether to write extra messages to stderr */
106
+ extern int verbose;
107
+ #endif
@@ -0,0 +1,261 @@
1
+ /*
2
+ * Copyright © 2001 Stephen Williams (steve@icarus.com)
3
+ * Copyright © 2001-2002 David Brownell (dbrownell@users.sourceforge.net)
4
+ * Copyright © 2008 Roger Williams (rawqux@users.sourceforge.net)
5
+ * Copyright © 2012 Pete Batard (pete@akeo.ie)
6
+ *
7
+ * This source code is free software; you can redistribute it
8
+ * and/or modify it in source code form under the terms of the GNU
9
+ * General Public License as published by the Free Software
10
+ * Foundation; either version 2 of the License, or (at your option)
11
+ * any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program; if not, write to the Free Software
20
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21
+ */
22
+
23
+ /*
24
+ * This program supports uploading firmware into a target USB device.
25
+ *
26
+ * -I <path> -- Upload this firmware
27
+ * -t <type> -- uController type: an21, fx, fx2, fx2lp
28
+ *
29
+ * -D <vid:pid> -- Use this device, instead of $DEVICE
30
+ *
31
+ * -V -- Print version ID for program
32
+ */
33
+ #include <stdlib.h>
34
+ #include <stdio.h>
35
+ #include <string.h>
36
+ #include <stdint.h>
37
+ #include <stdarg.h>
38
+ #include <sys/types.h>
39
+ #include <getopt.h>
40
+
41
+ #include <libusb.h>
42
+ #include "ezusb.h"
43
+
44
+ #if !defined(_WIN32) || defined(__CYGWIN__ )
45
+ #include <syslog.h>
46
+ static bool dosyslog = false;
47
+ #include <strings.h>
48
+ #define _stricmp strcasecmp
49
+ #endif
50
+
51
+ #ifndef FXLOAD_VERSION
52
+ #define FXLOAD_VERSION (__DATE__ " (development)")
53
+ #endif
54
+
55
+ #ifndef ARRAYSIZE
56
+ #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
57
+ #endif
58
+
59
+ void logerror(const char *format, ...)
60
+ __attribute__ ((format (__printf__, 1, 2)));
61
+
62
+ void logerror(const char *format, ...)
63
+ {
64
+ va_list ap;
65
+ va_start(ap, format);
66
+
67
+ #if !defined(_WIN32) || defined(__CYGWIN__ )
68
+ if (dosyslog)
69
+ vsyslog(LOG_ERR, format, ap);
70
+ else
71
+ #endif
72
+ vfprintf(stderr, format, ap);
73
+ va_end(ap);
74
+ }
75
+
76
+ #define FIRMWARE 0
77
+ #define LOADER 1
78
+ int main(int argc, char*argv[])
79
+ {
80
+ fx_known_device known_device[] = FX_KNOWN_DEVICES;
81
+ const char *path[] = { NULL, NULL };
82
+ const char *device_id = getenv("DEVICE");
83
+ const char *type = NULL;
84
+ const char *fx_name[FX_TYPE_MAX] = FX_TYPE_NAMES;
85
+ const char *ext, *img_name[] = IMG_TYPE_NAMES;
86
+ int fx_type = FX_TYPE_UNDEFINED, img_type[ARRAYSIZE(path)];
87
+ int i, j, opt, status;
88
+ unsigned vid = 0, pid = 0;
89
+ libusb_device *dev, **devs;
90
+ libusb_device_handle *device = NULL;
91
+ struct libusb_device_descriptor desc;
92
+
93
+ while ((opt = getopt(argc, argv, "vV?D:I:c:s:t:")) != EOF)
94
+ switch (opt) {
95
+
96
+ case 'D':
97
+ device_id = optarg;
98
+ break;
99
+
100
+ case 'I':
101
+ path[FIRMWARE] = optarg;
102
+ break;
103
+
104
+ case 'V':
105
+ puts(FXLOAD_VERSION);
106
+ return 0;
107
+
108
+ case 't':
109
+ type = optarg;
110
+ break;
111
+
112
+ case 'v':
113
+ verbose++;
114
+ break;
115
+
116
+ case '?':
117
+ default:
118
+ goto usage;
119
+
120
+ }
121
+
122
+ if (path[FIRMWARE] == NULL) {
123
+ logerror("no firmware specified!\n");
124
+ usage:
125
+ fprintf(stderr, "\nusage: %s [-vV] [-t type] [-D vid:pid] -I firmware\n", argv[0]);
126
+ fprintf(stderr, " type: one of an21, fx, fx2, fx2lp\n");
127
+ return -1;
128
+ }
129
+
130
+ if ((device_id != NULL) && (sscanf(device_id, "%x:%x" , &vid, &pid) != 2 )) {
131
+ fputs ("please specify VID & PID as \"vid:pid\" in hexadecimal format\n", stderr);
132
+ return -1;
133
+ }
134
+
135
+ /* determine the target type */
136
+ if (type != NULL) {
137
+ for (i=0; i<FX_TYPE_MAX; i++) {
138
+ if (strcmp(type, fx_name[i]) == 0) {
139
+ fx_type = i;
140
+ break;
141
+ }
142
+ }
143
+ if (i >= FX_TYPE_MAX) {
144
+ logerror("illegal microcontroller type: %s\n", type);
145
+ goto usage;
146
+ }
147
+ }
148
+
149
+ /* open the device using libusbx */
150
+ status = libusb_init(NULL);
151
+ if (status < 0) {
152
+ logerror("libusb_init() failed: %s\n", libusb_error_name(status));
153
+ return -1;
154
+ }
155
+ libusb_set_debug(NULL, verbose);
156
+
157
+ /* try to pick up missing parameters from known devices */
158
+ if ((type == NULL) || (device_id == NULL)) {
159
+ if (libusb_get_device_list(NULL, &devs) < 0) {
160
+ logerror("libusb_get_device_list() failed: %s\n", libusb_error_name(status));
161
+ goto err;
162
+ }
163
+ for (i=0; (dev=devs[i]) != NULL; i++) {
164
+ status = libusb_get_device_descriptor(dev, &desc);
165
+ if (status >= 0) {
166
+ if (verbose >= 2)
167
+ logerror("trying to match against %04x:%04x\n", desc.idVendor, desc.idProduct);
168
+ for (j=0; j<ARRAYSIZE(known_device); j++) {
169
+ if ((desc.idVendor == known_device[j].vid)
170
+ && (desc.idProduct == known_device[j].pid)) {
171
+ if ((type == NULL) && (device_id == NULL)) {
172
+ fx_type = known_device[j].type;
173
+ vid = desc.idVendor;
174
+ pid = desc.idProduct;
175
+ break;
176
+ } else if ((type == NULL) && (vid == desc.idVendor)
177
+ && (pid == desc.idProduct)) {
178
+ fx_type = known_device[j].type;
179
+ break;
180
+ } else if ((device_id == NULL)
181
+ && (fx_type == known_device[j].type)) {
182
+ vid = desc.idVendor;
183
+ pid = desc.idProduct;
184
+ break;
185
+ }
186
+ }
187
+ }
188
+ if (j < ARRAYSIZE(known_device)) {
189
+ if (verbose)
190
+ logerror("found device '%s' [%04x:%04x]\n",
191
+ known_device[j].designation, vid, pid);
192
+ break;
193
+ }
194
+ }
195
+ }
196
+ if (dev == NULL) {
197
+ libusb_free_device_list(devs, 1);
198
+ logerror("could not find a known device - please specify type and/or vid:pid\n");
199
+ goto usage;
200
+ }
201
+ status = libusb_open(dev, &device);
202
+ if (status < 0) {
203
+ logerror("libusb_open() failed: %s\n", libusb_error_name(status));
204
+ goto err;
205
+ }
206
+ libusb_free_device_list(devs, 1);
207
+ } else {
208
+ device = libusb_open_device_with_vid_pid(NULL, (uint16_t)vid, (uint16_t)pid);
209
+ if (device == NULL) {
210
+ logerror("libusb_open() failed\n");
211
+ goto err;
212
+ }
213
+ }
214
+ /* We need to claim the first interface */
215
+ status = libusb_claim_interface(device, 0);
216
+ #if defined(__linux__)
217
+ if (status != LIBUSB_SUCCESS) {
218
+ /* Maybe we need to detach the driver */
219
+ libusb_detach_kernel_driver(device, 0);
220
+ status = libusb_claim_interface(device, 0);
221
+ }
222
+ #endif
223
+ if (status != LIBUSB_SUCCESS) {
224
+ logerror("libusb_claim_interface failed: %s\n", libusb_error_name(status));
225
+ goto err;
226
+ }
227
+
228
+ if (verbose)
229
+ logerror("microcontroller type: %s\n", fx_name[fx_type]);
230
+
231
+ for (i=0; i<ARRAYSIZE(path); i++) {
232
+ if (path[i] != NULL) {
233
+ ext = path[i] + strlen(path[i]) - 4;
234
+ if ((_stricmp(ext, ".hex") == 0) || (strcmp(ext, ".ihx") == 0))
235
+ img_type[i] = IMG_TYPE_HEX;
236
+ else if (_stricmp(ext, ".iic") == 0)
237
+ img_type[i] = IMG_TYPE_IIC;
238
+ else if (_stricmp(ext, ".bix") == 0)
239
+ img_type[i] = IMG_TYPE_BIX;
240
+ else {
241
+ logerror("%s is not a recognized image type\n", path[i]);
242
+ goto err;
243
+ }
244
+ }
245
+ if (verbose && path[i] != NULL)
246
+ logerror("%s: type %s\n", path[i], img_name[img_type[i]]);
247
+ }
248
+
249
+ /* single stage, put into internal memory */
250
+ if (verbose)
251
+ logerror("single stage: load on-chip memory\n");
252
+ status = ezusb_load_ram(device, path[FIRMWARE], fx_type, img_type[FIRMWARE], 0);
253
+
254
+ libusb_release_interface(device, 0);
255
+ libusb_close(device);
256
+ libusb_exit(NULL);
257
+ return status;
258
+ err:
259
+ libusb_exit(NULL);
260
+ return -1;
261
+ }
@@ -0,0 +1,1060 @@
1
+ /* Getopt for GNU.
2
+ NOTE: getopt is now part of the C library, so if you don't know what
3
+ "Keep this file name-space clean" means, talk to drepper@gnu.org
4
+ before changing it!
5
+ Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
6
+ Free Software Foundation, Inc.
7
+ This file is part of the GNU C Library.
8
+
9
+ The GNU C 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
+ The GNU C 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
20
+ License along with the GNU C Library; if not, write to the Free
21
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22
+ 02111-1307 USA. */
23
+
24
+ /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
25
+ Ditto for AIX 3.2 and <stdlib.h>. */
26
+ #ifndef _NO_PROTO
27
+ # define _NO_PROTO
28
+ #endif
29
+
30
+ #ifdef HAVE_CONFIG_H
31
+ # include <config.h>
32
+ #endif
33
+
34
+ #if !defined __STDC__ || !__STDC__
35
+ /* This is a separate conditional since some stdc systems
36
+ reject `defined (const)'. */
37
+ # ifndef const
38
+ # define const
39
+ # endif
40
+ #endif
41
+
42
+ #include <stdio.h>
43
+
44
+ /* Comment out all this code if we are using the GNU C Library, and are not
45
+ actually compiling the library itself. This code is part of the GNU C
46
+ Library, but also included in many other GNU distributions. Compiling
47
+ and linking in this code is a waste when using the GNU C library
48
+ (especially if it is a shared library). Rather than having every GNU
49
+ program understand `configure --with-gnu-libc' and omit the object files,
50
+ it is simpler to just do this in the source for each such file. */
51
+
52
+ #define GETOPT_INTERFACE_VERSION 2
53
+ #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
54
+ # include <gnu-versions.h>
55
+ # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
56
+ # define ELIDE_CODE
57
+ # endif
58
+ #endif
59
+
60
+ #ifndef ELIDE_CODE
61
+
62
+
63
+ /* This needs to come after some library #include
64
+ to get __GNU_LIBRARY__ defined. */
65
+ #ifdef __GNU_LIBRARY__
66
+ /* Don't include stdlib.h for non-GNU C libraries because some of them
67
+ contain conflicting prototypes for getopt. */
68
+ # include <stdlib.h>
69
+ # include <unistd.h>
70
+ #endif /* GNU C library. */
71
+
72
+ #ifdef VMS
73
+ # include <unixlib.h>
74
+ # if HAVE_STRING_H - 0
75
+ # include <string.h>
76
+ # endif
77
+ #endif
78
+
79
+ #ifndef _
80
+ /* This is for other GNU distributions with internationalized messages. */
81
+ # if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
82
+ # include <libintl.h>
83
+ # ifndef _
84
+ # define _(msgid) gettext (msgid)
85
+ # endif
86
+ # else
87
+ # define _(msgid) (msgid)
88
+ # endif
89
+ #endif
90
+
91
+ /* This version of `getopt' appears to the caller like standard Unix `getopt'
92
+ but it behaves differently for the user, since it allows the user
93
+ to intersperse the options with the other arguments.
94
+
95
+ As `getopt' works, it permutes the elements of ARGV so that,
96
+ when it is done, all the options precede everything else. Thus
97
+ all application programs are extended to handle flexible argument order.
98
+
99
+ Setting the environment variable POSIXLY_CORRECT disables permutation.
100
+ Then the behavior is completely standard.
101
+
102
+ GNU application programs can use a third alternative mode in which
103
+ they can distinguish the relative order of options and other arguments. */
104
+
105
+ #include "getopt.h"
106
+
107
+ /* For communication from `getopt' to the caller.
108
+ When `getopt' finds an option that takes an argument,
109
+ the argument value is returned here.
110
+ Also, when `ordering' is RETURN_IN_ORDER,
111
+ each non-option ARGV-element is returned here. */
112
+
113
+ char *optarg;
114
+
115
+ /* Index in ARGV of the next element to be scanned.
116
+ This is used for communication to and from the caller
117
+ and for communication between successive calls to `getopt'.
118
+
119
+ On entry to `getopt', zero means this is the first call; initialize.
120
+
121
+ When `getopt' returns -1, this is the index of the first of the
122
+ non-option elements that the caller should itself scan.
123
+
124
+ Otherwise, `optind' communicates from one call to the next
125
+ how much of ARGV has been scanned so far. */
126
+
127
+ /* 1003.2 says this must be 1 before any call. */
128
+ int optind = 1;
129
+
130
+ /* Formerly, initialization of getopt depended on optind==0, which
131
+ causes problems with re-calling getopt as programs generally don't
132
+ know that. */
133
+
134
+ int __getopt_initialized;
135
+
136
+ /* The next char to be scanned in the option-element
137
+ in which the last option character we returned was found.
138
+ This allows us to pick up the scan where we left off.
139
+
140
+ If this is zero, or a null string, it means resume the scan
141
+ by advancing to the next ARGV-element. */
142
+
143
+ static char *nextchar;
144
+
145
+ /* Callers store zero here to inhibit the error message
146
+ for unrecognized options. */
147
+
148
+ int opterr = 1;
149
+
150
+ /* Set to an option character which was unrecognized.
151
+ This must be initialized on some systems to avoid linking in the
152
+ system's own getopt implementation. */
153
+
154
+ int optopt = '?';
155
+
156
+ /* Describe how to deal with options that follow non-option ARGV-elements.
157
+
158
+ If the caller did not specify anything,
159
+ the default is REQUIRE_ORDER if the environment variable
160
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
161
+
162
+ REQUIRE_ORDER means don't recognize them as options;
163
+ stop option processing when the first non-option is seen.
164
+ This is what Unix does.
165
+ This mode of operation is selected by either setting the environment
166
+ variable POSIXLY_CORRECT, or using `+' as the first character
167
+ of the list of option characters.
168
+
169
+ PERMUTE is the default. We permute the contents of ARGV as we scan,
170
+ so that eventually all the non-options are at the end. This allows options
171
+ to be given in any order, even with programs that were not written to
172
+ expect this.
173
+
174
+ RETURN_IN_ORDER is an option available to programs that were written
175
+ to expect options and other ARGV-elements in any order and that care about
176
+ the ordering of the two. We describe each non-option ARGV-element
177
+ as if it were the argument of an option with character code 1.
178
+ Using `-' as the first character of the list of option characters
179
+ selects this mode of operation.
180
+
181
+ The special argument `--' forces an end of option-scanning regardless
182
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
183
+ `--' can cause `getopt' to return -1 with `optind' != ARGC. */
184
+
185
+ static enum
186
+ {
187
+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
188
+ } ordering;
189
+
190
+ /* Value of POSIXLY_CORRECT environment variable. */
191
+ static char *posixly_correct;
192
+
193
+ #ifdef __GNU_LIBRARY__
194
+ /* We want to avoid inclusion of string.h with non-GNU libraries
195
+ because there are many ways it can cause trouble.
196
+ On some systems, it contains special magic macros that don't work
197
+ in GCC. */
198
+ # include <string.h>
199
+ # define my_index strchr
200
+ #else
201
+
202
+ # if HAVE_STRING_H
203
+ # include <string.h>
204
+ # else
205
+ # include <strings.h>
206
+ # endif
207
+
208
+ /* Avoid depending on library functions or files
209
+ whose names are inconsistent. */
210
+
211
+ #ifndef getenv
212
+ #ifdef _MSC_VER
213
+ // DDK will complain if you don't use the stdlib defined getenv
214
+ #include <stdlib.h>
215
+ #else
216
+ extern char *getenv ();
217
+ #endif
218
+ #endif
219
+
220
+ static char *
221
+ my_index (str, chr)
222
+ const char *str;
223
+ int chr;
224
+ {
225
+ while (*str)
226
+ {
227
+ if (*str == chr)
228
+ return (char *) str;
229
+ str++;
230
+ }
231
+ return 0;
232
+ }
233
+
234
+ /* If using GCC, we can safely declare strlen this way.
235
+ If not using GCC, it is ok not to declare it. */
236
+ #ifdef __GNUC__
237
+ /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
238
+ That was relevant to code that was here before. */
239
+ # if (!defined __STDC__ || !__STDC__) && !defined strlen
240
+ /* gcc with -traditional declares the built-in strlen to return int,
241
+ and has done so at least since version 2.4.5. -- rms. */
242
+ extern int strlen (const char *);
243
+ # endif /* not __STDC__ */
244
+ #endif /* __GNUC__ */
245
+
246
+ #endif /* not __GNU_LIBRARY__ */
247
+
248
+ /* Handle permutation of arguments. */
249
+
250
+ /* Describe the part of ARGV that contains non-options that have
251
+ been skipped. `first_nonopt' is the index in ARGV of the first of them;
252
+ `last_nonopt' is the index after the last of them. */
253
+
254
+ static int first_nonopt;
255
+ static int last_nonopt;
256
+
257
+ #ifdef _LIBC
258
+ /* Stored original parameters.
259
+ XXX This is no good solution. We should rather copy the args so
260
+ that we can compare them later. But we must not use malloc(3). */
261
+ extern int __libc_argc;
262
+ extern char **__libc_argv;
263
+
264
+ /* Bash 2.0 gives us an environment variable containing flags
265
+ indicating ARGV elements that should not be considered arguments. */
266
+
267
+ # ifdef USE_NONOPTION_FLAGS
268
+ /* Defined in getopt_init.c */
269
+ extern char *__getopt_nonoption_flags;
270
+
271
+ static int nonoption_flags_max_len;
272
+ static int nonoption_flags_len;
273
+ # endif
274
+
275
+ # ifdef USE_NONOPTION_FLAGS
276
+ # define SWAP_FLAGS(ch1, ch2) \
277
+ if (nonoption_flags_len > 0) \
278
+ { \
279
+ char __tmp = __getopt_nonoption_flags[ch1]; \
280
+ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
281
+ __getopt_nonoption_flags[ch2] = __tmp; \
282
+ }
283
+ # else
284
+ # define SWAP_FLAGS(ch1, ch2)
285
+ # endif
286
+ #else /* !_LIBC */
287
+ # define SWAP_FLAGS(ch1, ch2)
288
+ #endif /* _LIBC */
289
+
290
+ /* Exchange two adjacent subsequences of ARGV.
291
+ One subsequence is elements [first_nonopt,last_nonopt)
292
+ which contains all the non-options that have been skipped so far.
293
+ The other is elements [last_nonopt,optind), which contains all
294
+ the options processed since those non-options were skipped.
295
+
296
+ `first_nonopt' and `last_nonopt' are relocated so that they describe
297
+ the new indices of the non-options in ARGV after they are moved. */
298
+
299
+ #if defined __STDC__ && __STDC__
300
+ static void exchange (char **);
301
+ #endif
302
+
303
+ static void
304
+ exchange (argv)
305
+ char **argv;
306
+ {
307
+ int bottom = first_nonopt;
308
+ int middle = last_nonopt;
309
+ int top = optind;
310
+ char *tem;
311
+
312
+ /* Exchange the shorter segment with the far end of the longer segment.
313
+ That puts the shorter segment into the right place.
314
+ It leaves the longer segment in the right place overall,
315
+ but it consists of two parts that need to be swapped next. */
316
+
317
+ #if defined _LIBC && defined USE_NONOPTION_FLAGS
318
+ /* First make sure the handling of the `__getopt_nonoption_flags'
319
+ string can work normally. Our top argument must be in the range
320
+ of the string. */
321
+ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
322
+ {
323
+ /* We must extend the array. The user plays games with us and
324
+ presents new arguments. */
325
+ char *new_str = malloc (top + 1);
326
+ if (new_str == NULL)
327
+ nonoption_flags_len = nonoption_flags_max_len = 0;
328
+ else
329
+ {
330
+ memset (__mempcpy (new_str, __getopt_nonoption_flags,
331
+ nonoption_flags_max_len),
332
+ '\0', top + 1 - nonoption_flags_max_len);
333
+ nonoption_flags_max_len = top + 1;
334
+ __getopt_nonoption_flags = new_str;
335
+ }
336
+ }
337
+ #endif
338
+
339
+ while (top > middle && middle > bottom)
340
+ {
341
+ if (top - middle > middle - bottom)
342
+ {
343
+ /* Bottom segment is the short one. */
344
+ int len = middle - bottom;
345
+ register int i;
346
+
347
+ /* Swap it with the top part of the top segment. */
348
+ for (i = 0; i < len; i++)
349
+ {
350
+ tem = argv[bottom + i];
351
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
352
+ argv[top - (middle - bottom) + i] = tem;
353
+ SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
354
+ }
355
+ /* Exclude the moved bottom segment from further swapping. */
356
+ top -= len;
357
+ }
358
+ else
359
+ {
360
+ /* Top segment is the short one. */
361
+ int len = top - middle;
362
+ register int i;
363
+
364
+ /* Swap it with the bottom part of the bottom segment. */
365
+ for (i = 0; i < len; i++)
366
+ {
367
+ tem = argv[bottom + i];
368
+ argv[bottom + i] = argv[middle + i];
369
+ argv[middle + i] = tem;
370
+ SWAP_FLAGS (bottom + i, middle + i);
371
+ }
372
+ /* Exclude the moved top segment from further swapping. */
373
+ bottom += len;
374
+ }
375
+ }
376
+
377
+ /* Update records for the slots the non-options now occupy. */
378
+
379
+ first_nonopt += (optind - last_nonopt);
380
+ last_nonopt = optind;
381
+ }
382
+
383
+ /* Initialize the internal data when the first call is made. */
384
+
385
+ #if defined __STDC__ && __STDC__
386
+ static const char *_getopt_initialize (int, char *const *, const char *);
387
+ #endif
388
+ static const char *
389
+ _getopt_initialize (argc, argv, optstring)
390
+ int argc;
391
+ char *const *argv;
392
+ const char *optstring;
393
+ {
394
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
395
+ is the program name); the sequence of previously skipped
396
+ non-option ARGV-elements is empty. */
397
+
398
+ first_nonopt = last_nonopt = optind;
399
+
400
+ nextchar = NULL;
401
+
402
+ posixly_correct = getenv ("POSIXLY_CORRECT");
403
+
404
+ /* Determine how to handle the ordering of options and nonoptions. */
405
+
406
+ if (optstring[0] == '-')
407
+ {
408
+ ordering = RETURN_IN_ORDER;
409
+ ++optstring;
410
+ }
411
+ else if (optstring[0] == '+')
412
+ {
413
+ ordering = REQUIRE_ORDER;
414
+ ++optstring;
415
+ }
416
+ else if (posixly_correct != NULL)
417
+ ordering = REQUIRE_ORDER;
418
+ else
419
+ ordering = PERMUTE;
420
+
421
+ #if defined _LIBC && defined USE_NONOPTION_FLAGS
422
+ if (posixly_correct == NULL
423
+ && argc == __libc_argc && argv == __libc_argv)
424
+ {
425
+ if (nonoption_flags_max_len == 0)
426
+ {
427
+ if (__getopt_nonoption_flags == NULL
428
+ || __getopt_nonoption_flags[0] == '\0')
429
+ nonoption_flags_max_len = -1;
430
+ else
431
+ {
432
+ const char *orig_str = __getopt_nonoption_flags;
433
+ int len = nonoption_flags_max_len = strlen (orig_str);
434
+ if (nonoption_flags_max_len < argc)
435
+ nonoption_flags_max_len = argc;
436
+ __getopt_nonoption_flags =
437
+ (char *) malloc (nonoption_flags_max_len);
438
+ if (__getopt_nonoption_flags == NULL)
439
+ nonoption_flags_max_len = -1;
440
+ else
441
+ memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
442
+ '\0', nonoption_flags_max_len - len);
443
+ }
444
+ }
445
+ nonoption_flags_len = nonoption_flags_max_len;
446
+ }
447
+ else
448
+ nonoption_flags_len = 0;
449
+ #endif
450
+
451
+ return optstring;
452
+ }
453
+
454
+ /* Scan elements of ARGV (whose length is ARGC) for option characters
455
+ given in OPTSTRING.
456
+
457
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
458
+ then it is an option element. The characters of this element
459
+ (aside from the initial '-') are option characters. If `getopt'
460
+ is called repeatedly, it returns successively each of the option characters
461
+ from each of the option elements.
462
+
463
+ If `getopt' finds another option character, it returns that character,
464
+ updating `optind' and `nextchar' so that the next call to `getopt' can
465
+ resume the scan with the following option character or ARGV-element.
466
+
467
+ If there are no more option characters, `getopt' returns -1.
468
+ Then `optind' is the index in ARGV of the first ARGV-element
469
+ that is not an option. (The ARGV-elements have been permuted
470
+ so that those that are not options now come last.)
471
+
472
+ OPTSTRING is a string containing the legitimate option characters.
473
+ If an option character is seen that is not listed in OPTSTRING,
474
+ return '?' after printing an error message. If you set `opterr' to
475
+ zero, the error message is suppressed but we still return '?'.
476
+
477
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
478
+ so the following text in the same ARGV-element, or the text of the following
479
+ ARGV-element, is returned in `optarg'. Two colons mean an option that
480
+ wants an optional arg; if there is text in the current ARGV-element,
481
+ it is returned in `optarg', otherwise `optarg' is set to zero.
482
+
483
+ If OPTSTRING starts with `-' or `+', it requests different methods of
484
+ handling the non-option ARGV-elements.
485
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
486
+
487
+ Long-named options begin with `--' instead of `-'.
488
+ Their names may be abbreviated as long as the abbreviation is unique
489
+ or is an exact match for some defined option. If they have an
490
+ argument, it follows the option name in the same ARGV-element, separated
491
+ from the option name by a `=', or else the in next ARGV-element.
492
+ When `getopt' finds a long-named option, it returns 0 if that option's
493
+ `flag' field is nonzero, the value of the option's `val' field
494
+ if the `flag' field is zero.
495
+
496
+ The elements of ARGV aren't really const, because we permute them.
497
+ But we pretend they're const in the prototype to be compatible
498
+ with other systems.
499
+
500
+ LONGOPTS is a vector of `struct option' terminated by an
501
+ element containing a name which is zero.
502
+
503
+ LONGIND returns the index in LONGOPT of the long-named option found.
504
+ It is only valid when a long-named option has been found by the most
505
+ recent call.
506
+
507
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
508
+ long-named options. */
509
+
510
+ int
511
+ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
512
+ int argc;
513
+ char *const *argv;
514
+ const char *optstring;
515
+ const struct option *longopts;
516
+ int *longind;
517
+ int long_only;
518
+ {
519
+ int print_errors = opterr;
520
+ if (optstring[0] == ':')
521
+ print_errors = 0;
522
+
523
+ if (argc < 1)
524
+ return -1;
525
+
526
+ optarg = NULL;
527
+
528
+ if (optind == 0 || !__getopt_initialized)
529
+ {
530
+ if (optind == 0)
531
+ optind = 1; /* Don't scan ARGV[0], the program name. */
532
+ optstring = _getopt_initialize (argc, argv, optstring);
533
+ __getopt_initialized = 1;
534
+ }
535
+
536
+ /* Test whether ARGV[optind] points to a non-option argument.
537
+ Either it does not have option syntax, or there is an environment flag
538
+ from the shell indicating it is not an option. The later information
539
+ is only used when the used in the GNU libc. */
540
+ #if defined _LIBC && defined USE_NONOPTION_FLAGS
541
+ # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
542
+ || (optind < nonoption_flags_len \
543
+ && __getopt_nonoption_flags[optind] == '1'))
544
+ #else
545
+ # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
546
+ #endif
547
+
548
+ if (nextchar == NULL || *nextchar == '\0')
549
+ {
550
+ /* Advance to the next ARGV-element. */
551
+
552
+ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
553
+ moved back by the user (who may also have changed the arguments). */
554
+ if (last_nonopt > optind)
555
+ last_nonopt = optind;
556
+ if (first_nonopt > optind)
557
+ first_nonopt = optind;
558
+
559
+ if (ordering == PERMUTE)
560
+ {
561
+ /* If we have just processed some options following some non-options,
562
+ exchange them so that the options come first. */
563
+
564
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
565
+ exchange ((char **) argv);
566
+ else if (last_nonopt != optind)
567
+ first_nonopt = optind;
568
+
569
+ /* Skip any additional non-options
570
+ and extend the range of non-options previously skipped. */
571
+
572
+ while (optind < argc && NONOPTION_P)
573
+ optind++;
574
+ last_nonopt = optind;
575
+ }
576
+
577
+ /* The special ARGV-element `--' means premature end of options.
578
+ Skip it like a null option,
579
+ then exchange with previous non-options as if it were an option,
580
+ then skip everything else like a non-option. */
581
+
582
+ if (optind != argc && !strcmp (argv[optind], "--"))
583
+ {
584
+ optind++;
585
+
586
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
587
+ exchange ((char **) argv);
588
+ else if (first_nonopt == last_nonopt)
589
+ first_nonopt = optind;
590
+ last_nonopt = argc;
591
+
592
+ optind = argc;
593
+ }
594
+
595
+ /* If we have done all the ARGV-elements, stop the scan
596
+ and back over any non-options that we skipped and permuted. */
597
+
598
+ if (optind == argc)
599
+ {
600
+ /* Set the next-arg-index to point at the non-options
601
+ that we previously skipped, so the caller will digest them. */
602
+ if (first_nonopt != last_nonopt)
603
+ optind = first_nonopt;
604
+ return -1;
605
+ }
606
+
607
+ /* If we have come to a non-option and did not permute it,
608
+ either stop the scan or describe it to the caller and pass it by. */
609
+
610
+ if (NONOPTION_P)
611
+ {
612
+ if (ordering == REQUIRE_ORDER)
613
+ return -1;
614
+ optarg = argv[optind++];
615
+ return 1;
616
+ }
617
+
618
+ /* We have found another option-ARGV-element.
619
+ Skip the initial punctuation. */
620
+
621
+ nextchar = (argv[optind] + 1
622
+ + (longopts != NULL && argv[optind][1] == '-'));
623
+ }
624
+
625
+ /* Decode the current option-ARGV-element. */
626
+
627
+ /* Check whether the ARGV-element is a long option.
628
+
629
+ If long_only and the ARGV-element has the form "-f", where f is
630
+ a valid short option, don't consider it an abbreviated form of
631
+ a long option that starts with f. Otherwise there would be no
632
+ way to give the -f short option.
633
+
634
+ On the other hand, if there's a long option "fubar" and
635
+ the ARGV-element is "-fu", do consider that an abbreviation of
636
+ the long option, just like "--fu", and not "-f" with arg "u".
637
+
638
+ This distinction seems to be the most useful approach. */
639
+
640
+ if (longopts != NULL
641
+ && (argv[optind][1] == '-'
642
+ || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
643
+ {
644
+ char *nameend;
645
+ const struct option *p;
646
+ const struct option *pfound = NULL;
647
+ int exact = 0;
648
+ int ambig = 0;
649
+ int indfound = -1;
650
+ int option_index;
651
+
652
+ for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
653
+ /* Do nothing. */ ;
654
+
655
+ /* Test all long options for either exact match
656
+ or abbreviated matches. */
657
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
658
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
659
+ {
660
+ if ((unsigned int) (nameend - nextchar)
661
+ == (unsigned int) strlen (p->name))
662
+ {
663
+ /* Exact match found. */
664
+ pfound = p;
665
+ indfound = option_index;
666
+ exact = 1;
667
+ break;
668
+ }
669
+ else if (pfound == NULL)
670
+ {
671
+ /* First nonexact match found. */
672
+ pfound = p;
673
+ indfound = option_index;
674
+ }
675
+ else if (long_only
676
+ || pfound->has_arg != p->has_arg
677
+ || pfound->flag != p->flag
678
+ || pfound->val != p->val)
679
+ /* Second or later nonexact match found. */
680
+ ambig = 1;
681
+ }
682
+
683
+ if (ambig && !exact)
684
+ {
685
+ if (print_errors)
686
+ fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
687
+ argv[0], argv[optind]);
688
+ nextchar += strlen (nextchar);
689
+ optind++;
690
+ optopt = 0;
691
+ return '?';
692
+ }
693
+
694
+ if (pfound != NULL)
695
+ {
696
+ option_index = indfound;
697
+ optind++;
698
+ if (*nameend)
699
+ {
700
+ /* Don't test has_arg with >, because some C compilers don't
701
+ allow it to be used on enums. */
702
+ if (pfound->has_arg)
703
+ optarg = nameend + 1;
704
+ else
705
+ {
706
+ if (print_errors)
707
+ {
708
+ if (argv[optind - 1][1] == '-')
709
+ /* --option */
710
+ fprintf (stderr,
711
+ _("%s: option `--%s' doesn't allow an argument\n"),
712
+ argv[0], pfound->name);
713
+ else
714
+ /* +option or -option */
715
+ fprintf (stderr,
716
+ _("%s: option `%c%s' doesn't allow an argument\n"),
717
+ argv[0], argv[optind - 1][0], pfound->name);
718
+ }
719
+
720
+ nextchar += strlen (nextchar);
721
+
722
+ optopt = pfound->val;
723
+ return '?';
724
+ }
725
+ }
726
+ else if (pfound->has_arg == 1)
727
+ {
728
+ if (optind < argc)
729
+ optarg = argv[optind++];
730
+ else
731
+ {
732
+ if (print_errors)
733
+ fprintf (stderr,
734
+ _("%s: option `%s' requires an argument\n"),
735
+ argv[0], argv[optind - 1]);
736
+ nextchar += strlen (nextchar);
737
+ optopt = pfound->val;
738
+ return optstring[0] == ':' ? ':' : '?';
739
+ }
740
+ }
741
+ nextchar += strlen (nextchar);
742
+ if (longind != NULL)
743
+ *longind = option_index;
744
+ if (pfound->flag)
745
+ {
746
+ *(pfound->flag) = pfound->val;
747
+ return 0;
748
+ }
749
+ return pfound->val;
750
+ }
751
+
752
+ /* Can't find it as a long option. If this is not getopt_long_only,
753
+ or the option starts with '--' or is not a valid short
754
+ option, then it's an error.
755
+ Otherwise interpret it as a short option. */
756
+ if (!long_only || argv[optind][1] == '-'
757
+ || my_index (optstring, *nextchar) == NULL)
758
+ {
759
+ if (print_errors)
760
+ {
761
+ if (argv[optind][1] == '-')
762
+ /* --option */
763
+ fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
764
+ argv[0], nextchar);
765
+ else
766
+ /* +option or -option */
767
+ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
768
+ argv[0], argv[optind][0], nextchar);
769
+ }
770
+ nextchar = (char *) "";
771
+ optind++;
772
+ optopt = 0;
773
+ return '?';
774
+ }
775
+ }
776
+
777
+ /* Look at and handle the next short option-character. */
778
+
779
+ {
780
+ char c = *nextchar++;
781
+ char *temp = my_index (optstring, c);
782
+
783
+ /* Increment `optind' when we start to process its last character. */
784
+ if (*nextchar == '\0')
785
+ ++optind;
786
+
787
+ if (temp == NULL || c == ':')
788
+ {
789
+ if (print_errors)
790
+ {
791
+ if (posixly_correct)
792
+ /* 1003.2 specifies the format of this message. */
793
+ fprintf (stderr, _("%s: illegal option -- %c\n"),
794
+ argv[0], c);
795
+ else
796
+ fprintf (stderr, _("%s: invalid option -- %c\n"),
797
+ argv[0], c);
798
+ }
799
+ optopt = c;
800
+ return '?';
801
+ }
802
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
803
+ if (temp[0] == 'W' && temp[1] == ';')
804
+ {
805
+ char *nameend;
806
+ const struct option *p;
807
+ const struct option *pfound = NULL;
808
+ int exact = 0;
809
+ int ambig = 0;
810
+ int indfound = 0;
811
+ int option_index;
812
+
813
+ /* This is an option that requires an argument. */
814
+ if (*nextchar != '\0')
815
+ {
816
+ optarg = nextchar;
817
+ /* If we end this ARGV-element by taking the rest as an arg,
818
+ we must advance to the next element now. */
819
+ optind++;
820
+ }
821
+ else if (optind == argc)
822
+ {
823
+ if (print_errors)
824
+ {
825
+ /* 1003.2 specifies the format of this message. */
826
+ fprintf (stderr, _("%s: option requires an argument -- %c\n"),
827
+ argv[0], c);
828
+ }
829
+ optopt = c;
830
+ if (optstring[0] == ':')
831
+ c = ':';
832
+ else
833
+ c = '?';
834
+ return c;
835
+ }
836
+ else
837
+ /* We already incremented `optind' once;
838
+ increment it again when taking next ARGV-elt as argument. */
839
+ optarg = argv[optind++];
840
+
841
+ /* optarg is now the argument, see if it's in the
842
+ table of longopts. */
843
+
844
+ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
845
+ /* Do nothing. */ ;
846
+
847
+ /* Test all long options for either exact match
848
+ or abbreviated matches. */
849
+ for (p = longopts, option_index = 0; p != NULL && p->name; p++, option_index++)
850
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
851
+ {
852
+ if ((unsigned int) (nameend - nextchar) == strlen (p->name))
853
+ {
854
+ /* Exact match found. */
855
+ pfound = p;
856
+ indfound = option_index;
857
+ exact = 1;
858
+ break;
859
+ }
860
+ else if (pfound == NULL)
861
+ {
862
+ /* First nonexact match found. */
863
+ pfound = p;
864
+ indfound = option_index;
865
+ }
866
+ else
867
+ /* Second or later nonexact match found. */
868
+ ambig = 1;
869
+ }
870
+ if (ambig && !exact)
871
+ {
872
+ if (print_errors)
873
+ fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
874
+ argv[0], argv[optind]);
875
+ nextchar += strlen (nextchar);
876
+ optind++;
877
+ return '?';
878
+ }
879
+ if (pfound != NULL)
880
+ {
881
+ option_index = indfound;
882
+ if (*nameend)
883
+ {
884
+ /* Don't test has_arg with >, because some C compilers don't
885
+ allow it to be used on enums. */
886
+ if (pfound->has_arg)
887
+ optarg = nameend + 1;
888
+ else
889
+ {
890
+ if (print_errors)
891
+ fprintf (stderr, _("\
892
+ %s: option `-W %s' doesn't allow an argument\n"),
893
+ argv[0], pfound->name);
894
+
895
+ nextchar += strlen (nextchar);
896
+ return '?';
897
+ }
898
+ }
899
+ else if (pfound->has_arg == 1)
900
+ {
901
+ if (optind < argc)
902
+ optarg = argv[optind++];
903
+ else
904
+ {
905
+ if (print_errors)
906
+ fprintf (stderr,
907
+ _("%s: option `%s' requires an argument\n"),
908
+ argv[0], argv[optind - 1]);
909
+ nextchar += strlen (nextchar);
910
+ return optstring[0] == ':' ? ':' : '?';
911
+ }
912
+ }
913
+ nextchar += strlen (nextchar);
914
+ if (longind != NULL)
915
+ *longind = option_index;
916
+ if (pfound->flag)
917
+ {
918
+ *(pfound->flag) = pfound->val;
919
+ return 0;
920
+ }
921
+ return pfound->val;
922
+ }
923
+ nextchar = NULL;
924
+ return 'W'; /* Let the application handle it. */
925
+ }
926
+ if (temp[1] == ':')
927
+ {
928
+ if (temp[2] == ':')
929
+ {
930
+ /* This is an option that accepts an argument optionally. */
931
+ if (*nextchar != '\0')
932
+ {
933
+ optarg = nextchar;
934
+ optind++;
935
+ }
936
+ else
937
+ optarg = NULL;
938
+ nextchar = NULL;
939
+ }
940
+ else
941
+ {
942
+ /* This is an option that requires an argument. */
943
+ if (*nextchar != '\0')
944
+ {
945
+ optarg = nextchar;
946
+ /* If we end this ARGV-element by taking the rest as an arg,
947
+ we must advance to the next element now. */
948
+ optind++;
949
+ }
950
+ else if (optind == argc)
951
+ {
952
+ if (print_errors)
953
+ {
954
+ /* 1003.2 specifies the format of this message. */
955
+ fprintf (stderr,
956
+ _("%s: option requires an argument -- %c\n"),
957
+ argv[0], c);
958
+ }
959
+ optopt = c;
960
+ if (optstring[0] == ':')
961
+ c = ':';
962
+ else
963
+ c = '?';
964
+ }
965
+ else
966
+ /* We already incremented `optind' once;
967
+ increment it again when taking next ARGV-elt as argument. */
968
+ optarg = argv[optind++];
969
+ nextchar = NULL;
970
+ }
971
+ }
972
+ return c;
973
+ }
974
+ }
975
+
976
+ int
977
+ getopt (argc, argv, optstring)
978
+ int argc;
979
+ char *const *argv;
980
+ const char *optstring;
981
+ {
982
+ return _getopt_internal (argc, argv, optstring,
983
+ (const struct option *) 0,
984
+ (int *) 0,
985
+ 0);
986
+ }
987
+
988
+ #endif /* Not ELIDE_CODE. */
989
+
990
+ #ifdef TEST
991
+
992
+ /* Compile with -DTEST to make an executable for use in testing
993
+ the above definition of `getopt'. */
994
+
995
+ int
996
+ main (argc, argv)
997
+ int argc;
998
+ char **argv;
999
+ {
1000
+ int c;
1001
+ int digit_optind = 0;
1002
+
1003
+ while (1)
1004
+ {
1005
+ int this_option_optind = optind ? optind : 1;
1006
+
1007
+ c = getopt (argc, argv, "abc:d:0123456789");
1008
+ if (c == -1)
1009
+ break;
1010
+
1011
+ switch (c)
1012
+ {
1013
+ case '0':
1014
+ case '1':
1015
+ case '2':
1016
+ case '3':
1017
+ case '4':
1018
+ case '5':
1019
+ case '6':
1020
+ case '7':
1021
+ case '8':
1022
+ case '9':
1023
+ if (digit_optind != 0 && digit_optind != this_option_optind)
1024
+ printf ("digits occur in two different argv-elements.\n");
1025
+ digit_optind = this_option_optind;
1026
+ printf ("option %c\n", c);
1027
+ break;
1028
+
1029
+ case 'a':
1030
+ printf ("option a\n");
1031
+ break;
1032
+
1033
+ case 'b':
1034
+ printf ("option b\n");
1035
+ break;
1036
+
1037
+ case 'c':
1038
+ printf ("option c with value `%s'\n", optarg);
1039
+ break;
1040
+
1041
+ case '?':
1042
+ break;
1043
+
1044
+ default:
1045
+ printf ("?? getopt returned character code 0%o ??\n", c);
1046
+ }
1047
+ }
1048
+
1049
+ if (optind < argc)
1050
+ {
1051
+ printf ("non-option ARGV-elements: ");
1052
+ while (optind < argc)
1053
+ printf ("%s ", argv[optind++]);
1054
+ printf ("\n");
1055
+ }
1056
+
1057
+ exit (0);
1058
+ }
1059
+
1060
+ #endif /* TEST */