├── .gitignore
├── LICENSE
├── README.md
├── appveyor.yml
├── article.md
├── getopt.c
├── getopt.h
├── getopt.sln
└── getopt.vcxproj
/.gitignore:
--------------------------------------------------------------------------------
1 | Win32/
2 | x64/
3 | .vs/
4 | *.user
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | getopt port for Visual C++
2 | ==========================
3 |
4 | [](https://ci.appveyor.com/project/qmfrederik/getopt/branch/master)
5 |
6 | This repository contains a port of getopt which can be used with Visual C++. It is intended to be used with vcpkg.
7 |
8 | The Visual C++ port was originally done by Ludvik Jerabek, and described in the [Full getopt Port for Unicode and Multibyte Microsoft Visual C, C++, or MFC Projects](https://www.codeproject.com/Articles/157001/Full-getopt-Port-for-Unicode-and-Multibyte-Microso/)
9 | article. This repository contains a copy of that code and the article.
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | build_script:
2 | - msbuild getopt.sln /p:Configuration=Debug /p:Platform=Win32 /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
3 | - msbuild getopt.sln /p:Configuration=Debug /p:Platform=x64 /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
4 | - msbuild getopt.sln /p:Configuration=Release /p:Platform=Win32 /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
5 | - msbuild getopt.sln /p:Configuration=Release /p:Platform=x64 /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
6 |
--------------------------------------------------------------------------------
/article.md:
--------------------------------------------------------------------------------
1 | Full getopt Port for Unicode and Multibyte Microsoft Visual C, C++, or MFC Projects
2 | ===================================================================================
3 |
4 | Ludvik Jerabek, 15 Oct 2012
5 |
6 | Originally published at https://www.codeproject.com/Articles/157001/Full-getopt-Port-for-Unicode-and-Multibyte-Microso/
7 |
8 |
9 | Introduction
10 | ------------
11 |
12 | This software was written after hours of searching for a robust Microsoft C and C++ implementation of getopt,
13 | which led to devoid results.
14 |
15 | This software is a modification of the Free Software Foundation, Inc. getopt library for parsing command line arguments
16 | and its purpose is to provide a Microsoft Visual C friendly derivative. The source code provides functionality for both
17 | Unicode and Multibyte builds and supports `getopt`, `getopt_long`, and `getopt_long_only`. Additionally the code supports the
18 | `POSIXLY_CORRECT` environment flag. The library uses the `_UNICODE` preprocessor directive when defining the `getopt`, `getopt_long`,
19 | and `getopt_long_only` functions. These functions are mapped back to `getopt_a`\`getopt_w`, `getopt_long_a`\`getopt_long_w`, and
20 | `getopt_long_only_a`\`getopt_long_only_w` respectively. This improvement was made to allow a single DLL to be used in both
21 | multibyte and Unicode projects.
22 |
23 | The original GNU code used several header and implementation files containing numerous preprocessor directives specific
24 | to Linux environments which have been removed. After removing unneeded dependencies, it was condensed into a single
25 | header and implementation file which can be compiled into a DLL, LIB, or directly included into any Visual C, C++, or MFC
26 | project. The getopt library can be used by proprietary software, however; certain measures need to be taken to ensure
27 | proprietary code adheres to the Lesser GNU Public License for non-derivative works. Please refer to the licensing section
28 | of this article for more details on how this software is licensed.
29 |
30 | For the sake of brevity, this article doesn't discuss how to use the `getopt` functions. Anyone new to using the `getopt`
31 | functions should refer to the GNU tutorial for using getopt.
32 |
33 | Licensing
34 | ---------
35 |
36 | Since `getopt` is licensed under LGPL, it is free to use in proprietary software under some restrictions.
37 | When using this library as part of a proprietary software solution, it is important that the library is used as
38 | a dynamically linked library (DLL) and is not statically linked or directly compiled into proprietary source code.
39 | Static linkage requires that your software be released GPL. Therefore, by keeping the library separately referenced
40 | via Dynamic Link Library (DLL), allows the DLL to be modified and updated without changing the proprietary software
41 | which utilizes the library; under this condition proprietary software is said to "use" the library. Thus, it is not
42 | considered to be a derivative work and can be distributed freely under any license.
43 |
44 | Preprocessor Definitions
45 | ------------------------
46 |
47 | Compiling `getopt` as a Dynamic Link Library (DLL) requires the preprocessor definition of `EXPORTS_GETOPT`.
48 | The definition of `EXPORTS_GETOPT` sets the internal preprocessor definition `_GETOPT_API` to the value `__declspec(dllexport)`.
49 | Compiling getopt as a Static Library (LIB) or directly including the source and header file within a project requires the
50 | preprocessor definition of `STATIC_GETOPT`. The definition of `STATIC_GETOPT` clears the value of the internal preprocessor definition
51 | of `_GETOPT_API`. Compiling software to use _getopt.dll_ requires that no library specific preprocessor definitions be used.
52 | When no library specific preprocessor definitions are used the value assigned to the internal preprocessor definition `_GETOPT_API` is `__declspec(dllimport)`.
53 |
54 | The code segment below demonstrates the logic outlined above:
55 |
56 | ```c
57 | #if defined(EXPORTS_GETOPT) && defined(STATIC_GETOPT)
58 | #error "The preprocessor definitions of EXPORTS_GETOPT
59 | and STATIC_GETOPT can only be used individually"
60 | #elif defined(STATIC_GETOPT)
61 | #pragma message("Warning static builds of getopt violate the Lesser GNU Public License")
62 | #define _GETOPT_API
63 | #elif defined(EXPORTS_GETOPT)
64 | #pragma message("Exporting getopt library")
65 | #define _GETOPT_API __declspec(dllexport)
66 | #else
67 | #pragma message("Importing getopt library")
68 | #define _GETOPT_API __declspec(dllimport)
69 | #endif
70 | ```
71 |
72 | The following code segment located in _getopt.h_ is responsible for mapping the correct version of the `getopt`, `getopt_long`,
73 | and `getopt_long_only` functions. The `getopt` functions appended with `_a` to denote ANSI characters using the char type and
74 | Unicode functions are appended with `_w` to denote wide characters using the `wchar_t` type.
75 |
76 | ```c
77 | #ifdef _UNICODE
78 | #define getopt getopt_w
79 | #define getopt_long getopt_long_w
80 | #define getopt_long_only getopt_long_only_w
81 | #define option option_w
82 | #define optarg optarg_w
83 | #else
84 | #define getopt getopt_a
85 | #define getopt_long getopt_long_a
86 | #define getopt_long_only getopt_long_only_a
87 | #define option option_a
88 | #define optarg optarg_a
89 | #endif
90 | ```
91 |
92 | Using the Code
93 | ---------------
94 |
95 | The code is used identical to GNU `getopt`.
96 |
97 | ```c
98 | #include
99 | #include
100 | #include "tchar.h"
101 | #include "getopt.h"
102 |
103 | int _tmain(int argc, TCHAR** argv)
104 | {
105 | static int verbose_flag;
106 | int c;
107 |
108 | while (1)
109 | {
110 | static struct option long_options[] =
111 | {
112 | {_T("verbose"), ARG_NONE, &verbose_flag, 1},
113 | {_T("brief"), ARG_NONE, &verbose_flag, 0},
114 | {_T("add"), ARG_NONE, 0, _T('a')},
115 | {_T("append"), ARG_NONE, 0, _T('b')},
116 | {_T("delete"), ARG_REQ, 0, _T('d')},
117 | {_T("create"), ARG_REQ, 0, _T('c')},
118 | {_T("file"), ARG_REQ, 0 , _T('f')},
119 | { ARG_NULL , ARG_NULL , ARG_NULL , ARG_NULL }
120 | };
121 |
122 | int option_index = 0;
123 | c = getopt_long(argc, argv, _T("abc:d:f:"), long_options, &option_index);
124 |
125 | // Check for end of operation or error
126 | if (c == -1)
127 | break;
128 |
129 | // Handle options
130 | switch (c)
131 | {
132 | case 0:
133 | /* If this option set a flag, do nothing else now. */
134 | if (long_options[option_index].flag != 0)
135 | break;
136 | _tprintf (_T("option %s"), long_options[option_index].name);
137 | if (optarg)
138 | _tprintf (_T(" with arg %s"), optarg);
139 | _tprintf (_T("\n"));
140 | break;
141 |
142 | case _T('a'):
143 | _tprintf(_T("option -a\n"));
144 | break;
145 |
146 | case _T('b'):
147 | _tprintf(_T("option -b\n"));
148 | break;
149 |
150 | case _T('c'):
151 | _tprintf (_T("option -c with value `%s'\n"), optarg);
152 | break;
153 |
154 | case _T('d'):
155 | _tprintf (_T("option -d with value `%s'\n"), optarg);
156 | break;
157 |
158 | case _T('f'):
159 | _tprintf (_T("option -f with value `%s'\n"), optarg);
160 | break;
161 |
162 | case '?':
163 | /* getopt_long already printed an error message. */
164 | break;
165 |
166 | default:
167 | abort();
168 | }
169 | }
170 |
171 | if (verbose_flag)
172 | _tprintf (_T("verbose flag is set\n"));
173 |
174 |
175 | if (optind < argc)
176 | {
177 | _tprintf (_T("non-option ARGV-elements: "));
178 | while (optind < argc) _tprintf (_T("%s "), argv[optind++]);
179 | _tprintf (_T("\n"));
180 | }
181 | return 0;
182 | }
183 | ```
184 |
185 | Using this Code with C++ Precompiled Headers
186 | --------------------------------------------
187 |
188 | When using this code statically within a C++ project with precompiled headers, it is necessary to rename `getopt.c`
189 | to `getopt.cpp` in order to circumvent the following compiler error:
190 |
191 | ```
192 | "C1853 - Precompiled header file is from a previous version of the compiler,
193 | or the precompiled header is C++ and you are using it from C (or vice versa)."
194 | ```
195 |
196 | Additionally precompiled header file must be added as the first include of the `getopt.c` or `getopt.cpp` file.
197 | For example, if you are using _stdafx.h_ as the precompiled header, the following would be expected:
198 |
199 | ```
200 | // File comments removed
201 | #include "stdafx.h"
202 | #define _CRT_SECURE_NO_WARNINGS
203 | #include
204 | #include
205 | #include "getopt.h"
206 | ```
207 |
208 | History
209 | -------
210 |
211 | - 02/03/2011 - Initial release
212 | - 02/20/2011 - Fixed L4 compiler warnings
213 | - 07/05/2011 - Added no_argument, required_argument, optional_argument def
214 | - 08/05/2011 - Fixed non-argument runtime bug which caused runtime exception
215 | - 08/09/2011 - Added code to export functions for DLL and LIB
216 | - 02/15/2012 - Fixed _GETOPT_THROW definition missing in implementation file
217 | - 08/03/2012 - Created separate functions for char and wchar_t characters so single DLL can do both Unicode and ANSI
218 | - 10/15/2012 - Modified to match latest GNU features
219 | - 06/19/2015 - Fixed maximum option limitation caused by option_a (255) and option_w (65535) structure val variable
220 |
221 | License
222 | -------
223 |
224 | This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)
--------------------------------------------------------------------------------
/getopt.c:
--------------------------------------------------------------------------------
1 | /* Getopt for Microsoft C
2 | This code is a modification of the Free Software Foundation, Inc.
3 | Getopt library for parsing command line argument the purpose was
4 | to provide a Microsoft Visual C friendly derivative. This code
5 | provides functionality for both Unicode and Multibyte builds.
6 |
7 | Date: 02/03/2011 - Ludvik Jerabek - Initial Release
8 | Version: 1.0
9 | Comment: Supports getopt, getopt_long, and getopt_long_only
10 | and POSIXLY_CORRECT environment flag
11 | License: LGPL
12 |
13 | Revisions:
14 |
15 | 02/03/2011 - Ludvik Jerabek - Initial Release
16 | 02/20/2011 - Ludvik Jerabek - Fixed compiler warnings at Level 4
17 | 07/05/2011 - Ludvik Jerabek - Added no_argument, required_argument, optional_argument defs
18 | 08/03/2011 - Ludvik Jerabek - Fixed non-argument runtime bug which caused runtime exception
19 | 08/09/2011 - Ludvik Jerabek - Added code to export functions for DLL and LIB
20 | 02/15/2012 - Ludvik Jerabek - Fixed _GETOPT_THROW definition missing in implementation file
21 | 08/01/2012 - Ludvik Jerabek - Created separate functions for char and wchar_t characters so single dll can do both unicode and ansi
22 | 10/15/2012 - Ludvik Jerabek - Modified to match latest GNU features
23 | 06/19/2015 - Ludvik Jerabek - Fixed maximum option limitation caused by option_a (255) and option_w (65535) structure val variable
24 |
25 | **DISCLAIMER**
26 | THIS MATERIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
27 | EITHER EXPRESS OR IMPLIED, INCLUDING, BUT Not LIMITED TO, THE
28 | IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
29 | PURPOSE, OR NON-INFRINGEMENT. SOME JURISDICTIONS DO NOT ALLOW THE
30 | EXCLUSION OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY NOT
31 | APPLY TO YOU. IN NO EVENT WILL I BE LIABLE TO ANY PARTY FOR ANY
32 | DIRECT, INDIRECT, SPECIAL OR OTHER CONSEQUENTIAL DAMAGES FOR ANY
33 | USE OF THIS MATERIAL INCLUDING, WITHOUT LIMITATION, ANY LOST
34 | PROFITS, BUSINESS INTERRUPTION, LOSS OF PROGRAMS OR OTHER DATA ON
35 | YOUR INFORMATION HANDLING SYSTEM OR OTHERWISE, EVEN If WE ARE
36 | EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
37 | */
38 | #define _CRT_SECURE_NO_WARNINGS
39 | #include
40 | #include
41 | #include
42 | #include "getopt.h"
43 |
44 | #ifdef __cplusplus
45 | #define _GETOPT_THROW throw()
46 | #else
47 | #define _GETOPT_THROW
48 | #endif
49 |
50 | int optind = 1;
51 | int opterr = 1;
52 | int optopt = '?';
53 | enum ENUM_ORDERING { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER };
54 |
55 | //
56 | //
57 | // Ansi structures and functions follow
58 | //
59 | //
60 |
61 | static struct _getopt_data_a
62 | {
63 | int optind;
64 | int opterr;
65 | int optopt;
66 | char *optarg;
67 | int __initialized;
68 | char *__nextchar;
69 | enum ENUM_ORDERING __ordering;
70 | int __posixly_correct;
71 | int __first_nonopt;
72 | int __last_nonopt;
73 | } getopt_data_a;
74 | char *optarg_a;
75 |
76 | static void exchange_a(char **argv, struct _getopt_data_a *d)
77 | {
78 | int bottom = d->__first_nonopt;
79 | int middle = d->__last_nonopt;
80 | int top = d->optind;
81 | char *tem;
82 | while (top > middle && middle > bottom)
83 | {
84 | if (top - middle > middle - bottom)
85 | {
86 | int len = middle - bottom;
87 | register int i;
88 | for (i = 0; i < len; i++)
89 | {
90 | tem = argv[bottom + i];
91 | argv[bottom + i] = argv[top - (middle - bottom) + i];
92 | argv[top - (middle - bottom) + i] = tem;
93 | }
94 | top -= len;
95 | }
96 | else
97 | {
98 | int len = top - middle;
99 | register int i;
100 | for (i = 0; i < len; i++)
101 | {
102 | tem = argv[bottom + i];
103 | argv[bottom + i] = argv[middle + i];
104 | argv[middle + i] = tem;
105 | }
106 | bottom += len;
107 | }
108 | }
109 | d->__first_nonopt += (d->optind - d->__last_nonopt);
110 | d->__last_nonopt = d->optind;
111 | }
112 | static const char *_getopt_initialize_a (const char *optstring, struct _getopt_data_a *d, int posixly_correct)
113 | {
114 | d->__first_nonopt = d->__last_nonopt = d->optind;
115 | d->__nextchar = NULL;
116 | d->__posixly_correct = posixly_correct | !!getenv("POSIXLY_CORRECT");
117 | if (optstring[0] == '-')
118 | {
119 | d->__ordering = RETURN_IN_ORDER;
120 | ++optstring;
121 | }
122 | else if (optstring[0] == '+')
123 | {
124 | d->__ordering = REQUIRE_ORDER;
125 | ++optstring;
126 | }
127 | else if (d->__posixly_correct)
128 | d->__ordering = REQUIRE_ORDER;
129 | else
130 | d->__ordering = PERMUTE;
131 | return optstring;
132 | }
133 | int _getopt_internal_r_a (int argc, char *const *argv, const char *optstring, const struct option_a *longopts, int *longind, int long_only, struct _getopt_data_a *d, int posixly_correct)
134 | {
135 | int print_errors = d->opterr;
136 | if (argc < 1)
137 | return -1;
138 | d->optarg = NULL;
139 | if (d->optind == 0 || !d->__initialized)
140 | {
141 | if (d->optind == 0)
142 | d->optind = 1;
143 | optstring = _getopt_initialize_a (optstring, d, posixly_correct);
144 | d->__initialized = 1;
145 | }
146 | else if (optstring[0] == '-' || optstring[0] == '+')
147 | optstring++;
148 | if (optstring[0] == ':')
149 | print_errors = 0;
150 | if (d->__nextchar == NULL || *d->__nextchar == '\0')
151 | {
152 | if (d->__last_nonopt > d->optind)
153 | d->__last_nonopt = d->optind;
154 | if (d->__first_nonopt > d->optind)
155 | d->__first_nonopt = d->optind;
156 | if (d->__ordering == PERMUTE)
157 | {
158 | if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind)
159 | exchange_a ((char **) argv, d);
160 | else if (d->__last_nonopt != d->optind)
161 | d->__first_nonopt = d->optind;
162 | while (d->optind < argc && (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0'))
163 | d->optind++;
164 | d->__last_nonopt = d->optind;
165 | }
166 | if (d->optind != argc && !strcmp(argv[d->optind], "--"))
167 | {
168 | d->optind++;
169 | if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind)
170 | exchange_a((char **) argv, d);
171 | else if (d->__first_nonopt == d->__last_nonopt)
172 | d->__first_nonopt = d->optind;
173 | d->__last_nonopt = argc;
174 | d->optind = argc;
175 | }
176 | if (d->optind == argc)
177 | {
178 | if (d->__first_nonopt != d->__last_nonopt)
179 | d->optind = d->__first_nonopt;
180 | return -1;
181 | }
182 | if ((argv[d->optind][0] != '-' || argv[d->optind][1] == '\0'))
183 | {
184 | if (d->__ordering == REQUIRE_ORDER)
185 | return -1;
186 | d->optarg = argv[d->optind++];
187 | return 1;
188 | }
189 | d->__nextchar = (argv[d->optind] + 1 + (longopts != NULL && argv[d->optind][1] == '-'));
190 | }
191 | if (longopts != NULL && (argv[d->optind][1] == '-' || (long_only && (argv[d->optind][2] || !strchr(optstring, argv[d->optind][1])))))
192 | {
193 | char *nameend;
194 | unsigned int namelen;
195 | const struct option_a *p;
196 | const struct option_a *pfound = NULL;
197 | struct option_list
198 | {
199 | const struct option_a *p;
200 | struct option_list *next;
201 | } *ambig_list = NULL;
202 | int exact = 0;
203 | int indfound = -1;
204 | int option_index;
205 | for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++);
206 | namelen = (unsigned int)(nameend - d->__nextchar);
207 | for (p = longopts, option_index = 0; p->name; p++, option_index++)
208 | if (!strncmp(p->name, d->__nextchar, namelen))
209 | {
210 | if (namelen == (unsigned int)strlen(p->name))
211 | {
212 | pfound = p;
213 | indfound = option_index;
214 | exact = 1;
215 | break;
216 | }
217 | else if (pfound == NULL)
218 | {
219 | pfound = p;
220 | indfound = option_index;
221 | }
222 | else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val)
223 | {
224 | struct option_list *newp = (struct option_list*)alloca(sizeof(*newp));
225 | newp->p = p;
226 | newp->next = ambig_list;
227 | ambig_list = newp;
228 | }
229 | }
230 | if (ambig_list != NULL && !exact)
231 | {
232 | if (print_errors)
233 | {
234 | struct option_list first;
235 | first.p = pfound;
236 | first.next = ambig_list;
237 | ambig_list = &first;
238 | fprintf (stderr, "%s: option '%s' is ambiguous; possibilities:", argv[0], argv[d->optind]);
239 | do
240 | {
241 | fprintf (stderr, " '--%s'", ambig_list->p->name);
242 | ambig_list = ambig_list->next;
243 | }
244 | while (ambig_list != NULL);
245 | fputc ('\n', stderr);
246 | }
247 | d->__nextchar += strlen(d->__nextchar);
248 | d->optind++;
249 | d->optopt = 0;
250 | return '?';
251 | }
252 | if (pfound != NULL)
253 | {
254 | option_index = indfound;
255 | d->optind++;
256 | if (*nameend)
257 | {
258 | if (pfound->has_arg)
259 | d->optarg = nameend + 1;
260 | else
261 | {
262 | if (print_errors)
263 | {
264 | if (argv[d->optind - 1][1] == '-')
265 | {
266 | fprintf(stderr, "%s: option '--%s' doesn't allow an argument\n",argv[0], pfound->name);
267 | }
268 | else
269 | {
270 | fprintf(stderr, "%s: option '%c%s' doesn't allow an argument\n",argv[0], argv[d->optind - 1][0],pfound->name);
271 | }
272 | }
273 | d->__nextchar += strlen(d->__nextchar);
274 | d->optopt = pfound->val;
275 | return '?';
276 | }
277 | }
278 | else if (pfound->has_arg == 1)
279 | {
280 | if (d->optind < argc)
281 | d->optarg = argv[d->optind++];
282 | else
283 | {
284 | if (print_errors)
285 | {
286 | fprintf(stderr,"%s: option '--%s' requires an argument\n",argv[0], pfound->name);
287 | }
288 | d->__nextchar += strlen(d->__nextchar);
289 | d->optopt = pfound->val;
290 | return optstring[0] == ':' ? ':' : '?';
291 | }
292 | }
293 | d->__nextchar += strlen(d->__nextchar);
294 | if (longind != NULL)
295 | *longind = option_index;
296 | if (pfound->flag)
297 | {
298 | *(pfound->flag) = pfound->val;
299 | return 0;
300 | }
301 | return pfound->val;
302 | }
303 | if (!long_only || argv[d->optind][1] == '-' || strchr(optstring, *d->__nextchar) == NULL)
304 | {
305 | if (print_errors)
306 | {
307 | if (argv[d->optind][1] == '-')
308 | {
309 | fprintf(stderr, "%s: unrecognized option '--%s'\n",argv[0], d->__nextchar);
310 | }
311 | else
312 | {
313 | fprintf(stderr, "%s: unrecognized option '%c%s'\n",argv[0], argv[d->optind][0], d->__nextchar);
314 | }
315 | }
316 | d->__nextchar = (char *)"";
317 | d->optind++;
318 | d->optopt = 0;
319 | return '?';
320 | }
321 | }
322 | {
323 | char c = *d->__nextchar++;
324 | char *temp = (char*)strchr(optstring, c);
325 | if (*d->__nextchar == '\0')
326 | ++d->optind;
327 | if (temp == NULL || c == ':' || c == ';')
328 | {
329 | if (print_errors)
330 | {
331 | fprintf(stderr, "%s: invalid option -- '%c'\n", argv[0], c);
332 | }
333 | d->optopt = c;
334 | return '?';
335 | }
336 | if (temp[0] == 'W' && temp[1] == ';')
337 | {
338 | char *nameend;
339 | const struct option_a *p;
340 | const struct option_a *pfound = NULL;
341 | int exact = 0;
342 | int ambig = 0;
343 | int indfound = 0;
344 | int option_index;
345 | if (longopts == NULL)
346 | goto no_longs;
347 | if (*d->__nextchar != '\0')
348 | {
349 | d->optarg = d->__nextchar;
350 | d->optind++;
351 | }
352 | else if (d->optind == argc)
353 | {
354 | if (print_errors)
355 | {
356 | fprintf(stderr,"%s: option requires an argument -- '%c'\n",argv[0], c);
357 | }
358 | d->optopt = c;
359 | if (optstring[0] == ':')
360 | c = ':';
361 | else
362 | c = '?';
363 | return c;
364 | }
365 | else
366 | d->optarg = argv[d->optind++];
367 | for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '='; nameend++);
368 | for (p = longopts, option_index = 0; p->name; p++, option_index++)
369 | if (!strncmp(p->name, d->__nextchar, nameend - d->__nextchar))
370 | {
371 | if ((unsigned int) (nameend - d->__nextchar) == strlen(p->name))
372 | {
373 | pfound = p;
374 | indfound = option_index;
375 | exact = 1;
376 | break;
377 | }
378 | else if (pfound == NULL)
379 | {
380 | pfound = p;
381 | indfound = option_index;
382 | }
383 | else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val)
384 | ambig = 1;
385 | }
386 | if (ambig && !exact)
387 | {
388 | if (print_errors)
389 | {
390 | fprintf(stderr, "%s: option '-W %s' is ambiguous\n",argv[0], d->optarg);
391 | }
392 | d->__nextchar += strlen(d->__nextchar);
393 | d->optind++;
394 | return '?';
395 | }
396 | if (pfound != NULL)
397 | {
398 | option_index = indfound;
399 | if (*nameend)
400 | {
401 | if (pfound->has_arg)
402 | d->optarg = nameend + 1;
403 | else
404 | {
405 | if (print_errors)
406 | {
407 | fprintf(stderr, "%s: option '-W %s' doesn't allow an argument\n",argv[0], pfound->name);
408 | }
409 | d->__nextchar += strlen(d->__nextchar);
410 | return '?';
411 | }
412 | }
413 | else if (pfound->has_arg == 1)
414 | {
415 | if (d->optind < argc)
416 | d->optarg = argv[d->optind++];
417 | else
418 | {
419 | if (print_errors)
420 | {
421 | fprintf(stderr, "%s: option '-W %s' requires an argument\n",argv[0], pfound->name);
422 | }
423 | d->__nextchar += strlen(d->__nextchar);
424 | return optstring[0] == ':' ? ':' : '?';
425 | }
426 | }
427 | else
428 | d->optarg = NULL;
429 | d->__nextchar += strlen(d->__nextchar);
430 | if (longind != NULL)
431 | *longind = option_index;
432 | if (pfound->flag)
433 | {
434 | *(pfound->flag) = pfound->val;
435 | return 0;
436 | }
437 | return pfound->val;
438 | }
439 | no_longs:
440 | d->__nextchar = NULL;
441 | return 'W';
442 | }
443 | if (temp[1] == ':')
444 | {
445 | if (temp[2] == ':')
446 | {
447 | if (*d->__nextchar != '\0')
448 | {
449 | d->optarg = d->__nextchar;
450 | d->optind++;
451 | }
452 | else
453 | d->optarg = NULL;
454 | d->__nextchar = NULL;
455 | }
456 | else
457 | {
458 | if (*d->__nextchar != '\0')
459 | {
460 | d->optarg = d->__nextchar;
461 | d->optind++;
462 | }
463 | else if (d->optind == argc)
464 | {
465 | if (print_errors)
466 | {
467 | fprintf(stderr,"%s: option requires an argument -- '%c'\n",argv[0], c);
468 | }
469 | d->optopt = c;
470 | if (optstring[0] == ':')
471 | c = ':';
472 | else
473 | c = '?';
474 | }
475 | else
476 | d->optarg = argv[d->optind++];
477 | d->__nextchar = NULL;
478 | }
479 | }
480 | return c;
481 | }
482 | }
483 | int _getopt_internal_a (int argc, char *const *argv, const char *optstring, const struct option_a *longopts, int *longind, int long_only, int posixly_correct)
484 | {
485 | int result;
486 | getopt_data_a.optind = optind;
487 | getopt_data_a.opterr = opterr;
488 | result = _getopt_internal_r_a (argc, argv, optstring, longopts,longind, long_only, &getopt_data_a,posixly_correct);
489 | optind = getopt_data_a.optind;
490 | optarg_a = getopt_data_a.optarg;
491 | optopt = getopt_data_a.optopt;
492 | return result;
493 | }
494 | int getopt_a (int argc, char *const *argv, const char *optstring) _GETOPT_THROW
495 | {
496 | return _getopt_internal_a (argc, argv, optstring, (const struct option_a *) 0, (int *) 0, 0, 0);
497 | }
498 | int getopt_long_a (int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index) _GETOPT_THROW
499 | {
500 | return _getopt_internal_a (argc, argv, options, long_options, opt_index, 0, 0);
501 | }
502 | int getopt_long_only_a (int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index) _GETOPT_THROW
503 | {
504 | return _getopt_internal_a (argc, argv, options, long_options, opt_index, 1, 0);
505 | }
506 | int _getopt_long_r_a (int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index, struct _getopt_data_a *d)
507 | {
508 | return _getopt_internal_r_a (argc, argv, options, long_options, opt_index,0, d, 0);
509 | }
510 | int _getopt_long_only_r_a (int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index, struct _getopt_data_a *d)
511 | {
512 | return _getopt_internal_r_a (argc, argv, options, long_options, opt_index, 1, d, 0);
513 | }
514 |
515 | //
516 | //
517 | // Unicode Structures and Functions
518 | //
519 | //
520 |
521 | static struct _getopt_data_w
522 | {
523 | int optind;
524 | int opterr;
525 | int optopt;
526 | wchar_t *optarg;
527 | int __initialized;
528 | wchar_t *__nextchar;
529 | enum ENUM_ORDERING __ordering;
530 | int __posixly_correct;
531 | int __first_nonopt;
532 | int __last_nonopt;
533 | } getopt_data_w;
534 | wchar_t *optarg_w;
535 |
536 | static void exchange_w(wchar_t **argv, struct _getopt_data_w *d)
537 | {
538 | int bottom = d->__first_nonopt;
539 | int middle = d->__last_nonopt;
540 | int top = d->optind;
541 | wchar_t *tem;
542 | while (top > middle && middle > bottom)
543 | {
544 | if (top - middle > middle - bottom)
545 | {
546 | int len = middle - bottom;
547 | register int i;
548 | for (i = 0; i < len; i++)
549 | {
550 | tem = argv[bottom + i];
551 | argv[bottom + i] = argv[top - (middle - bottom) + i];
552 | argv[top - (middle - bottom) + i] = tem;
553 | }
554 | top -= len;
555 | }
556 | else
557 | {
558 | int len = top - middle;
559 | register int i;
560 | for (i = 0; i < len; i++)
561 | {
562 | tem = argv[bottom + i];
563 | argv[bottom + i] = argv[middle + i];
564 | argv[middle + i] = tem;
565 | }
566 | bottom += len;
567 | }
568 | }
569 | d->__first_nonopt += (d->optind - d->__last_nonopt);
570 | d->__last_nonopt = d->optind;
571 | }
572 | static const wchar_t *_getopt_initialize_w (const wchar_t *optstring, struct _getopt_data_w *d, int posixly_correct)
573 | {
574 | d->__first_nonopt = d->__last_nonopt = d->optind;
575 | d->__nextchar = NULL;
576 | d->__posixly_correct = posixly_correct | !!_wgetenv(L"POSIXLY_CORRECT");
577 | if (optstring[0] == L'-')
578 | {
579 | d->__ordering = RETURN_IN_ORDER;
580 | ++optstring;
581 | }
582 | else if (optstring[0] == L'+')
583 | {
584 | d->__ordering = REQUIRE_ORDER;
585 | ++optstring;
586 | }
587 | else if (d->__posixly_correct)
588 | d->__ordering = REQUIRE_ORDER;
589 | else
590 | d->__ordering = PERMUTE;
591 | return optstring;
592 | }
593 | int _getopt_internal_r_w (int argc, wchar_t *const *argv, const wchar_t *optstring, const struct option_w *longopts, int *longind, int long_only, struct _getopt_data_w *d, int posixly_correct)
594 | {
595 | int print_errors = d->opterr;
596 | if (argc < 1)
597 | return -1;
598 | d->optarg = NULL;
599 | if (d->optind == 0 || !d->__initialized)
600 | {
601 | if (d->optind == 0)
602 | d->optind = 1;
603 | optstring = _getopt_initialize_w (optstring, d, posixly_correct);
604 | d->__initialized = 1;
605 | }
606 | else if (optstring[0] == L'-' || optstring[0] == L'+')
607 | optstring++;
608 | if (optstring[0] == L':')
609 | print_errors = 0;
610 | if (d->__nextchar == NULL || *d->__nextchar == L'\0')
611 | {
612 | if (d->__last_nonopt > d->optind)
613 | d->__last_nonopt = d->optind;
614 | if (d->__first_nonopt > d->optind)
615 | d->__first_nonopt = d->optind;
616 | if (d->__ordering == PERMUTE)
617 | {
618 | if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind)
619 | exchange_w((wchar_t **) argv, d);
620 | else if (d->__last_nonopt != d->optind)
621 | d->__first_nonopt = d->optind;
622 | while (d->optind < argc && (argv[d->optind][0] != L'-' || argv[d->optind][1] == L'\0'))
623 | d->optind++;
624 | d->__last_nonopt = d->optind;
625 | }
626 | if (d->optind != argc && !wcscmp(argv[d->optind], L"--"))
627 | {
628 | d->optind++;
629 | if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind)
630 | exchange_w((wchar_t **) argv, d);
631 | else if (d->__first_nonopt == d->__last_nonopt)
632 | d->__first_nonopt = d->optind;
633 | d->__last_nonopt = argc;
634 | d->optind = argc;
635 | }
636 | if (d->optind == argc)
637 | {
638 | if (d->__first_nonopt != d->__last_nonopt)
639 | d->optind = d->__first_nonopt;
640 | return -1;
641 | }
642 | if ((argv[d->optind][0] != L'-' || argv[d->optind][1] == L'\0'))
643 | {
644 | if (d->__ordering == REQUIRE_ORDER)
645 | return -1;
646 | d->optarg = argv[d->optind++];
647 | return 1;
648 | }
649 | d->__nextchar = (argv[d->optind] + 1 + (longopts != NULL && argv[d->optind][1] == L'-'));
650 | }
651 | if (longopts != NULL && (argv[d->optind][1] == L'-' || (long_only && (argv[d->optind][2] || !wcschr(optstring, argv[d->optind][1])))))
652 | {
653 | wchar_t *nameend;
654 | unsigned int namelen;
655 | const struct option_w *p;
656 | const struct option_w *pfound = NULL;
657 | struct option_list
658 | {
659 | const struct option_w *p;
660 | struct option_list *next;
661 | } *ambig_list = NULL;
662 | int exact = 0;
663 | int indfound = -1;
664 | int option_index;
665 | for (nameend = d->__nextchar; *nameend && *nameend != L'='; nameend++);
666 | namelen = (unsigned int)(nameend - d->__nextchar);
667 | for (p = longopts, option_index = 0; p->name; p++, option_index++)
668 | if (!wcsncmp(p->name, d->__nextchar, namelen))
669 | {
670 | if (namelen == (unsigned int)wcslen(p->name))
671 | {
672 | pfound = p;
673 | indfound = option_index;
674 | exact = 1;
675 | break;
676 | }
677 | else if (pfound == NULL)
678 | {
679 | pfound = p;
680 | indfound = option_index;
681 | }
682 | else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val)
683 | {
684 | struct option_list *newp = (struct option_list*)alloca(sizeof(*newp));
685 | newp->p = p;
686 | newp->next = ambig_list;
687 | ambig_list = newp;
688 | }
689 | }
690 | if (ambig_list != NULL && !exact)
691 | {
692 | if (print_errors)
693 | {
694 | struct option_list first;
695 | first.p = pfound;
696 | first.next = ambig_list;
697 | ambig_list = &first;
698 | fwprintf(stderr, L"%s: option '%s' is ambiguous; possibilities:", argv[0], argv[d->optind]);
699 | do
700 | {
701 | fwprintf (stderr, L" '--%s'", ambig_list->p->name);
702 | ambig_list = ambig_list->next;
703 | }
704 | while (ambig_list != NULL);
705 | fputwc (L'\n', stderr);
706 | }
707 | d->__nextchar += wcslen(d->__nextchar);
708 | d->optind++;
709 | d->optopt = 0;
710 | return L'?';
711 | }
712 | if (pfound != NULL)
713 | {
714 | option_index = indfound;
715 | d->optind++;
716 | if (*nameend)
717 | {
718 | if (pfound->has_arg)
719 | d->optarg = nameend + 1;
720 | else
721 | {
722 | if (print_errors)
723 | {
724 | if (argv[d->optind - 1][1] == L'-')
725 | {
726 | fwprintf(stderr, L"%s: option '--%s' doesn't allow an argument\n",argv[0], pfound->name);
727 | }
728 | else
729 | {
730 | fwprintf(stderr, L"%s: option '%c%s' doesn't allow an argument\n",argv[0], argv[d->optind - 1][0],pfound->name);
731 | }
732 | }
733 | d->__nextchar += wcslen(d->__nextchar);
734 | d->optopt = pfound->val;
735 | return L'?';
736 | }
737 | }
738 | else if (pfound->has_arg == 1)
739 | {
740 | if (d->optind < argc)
741 | d->optarg = argv[d->optind++];
742 | else
743 | {
744 | if (print_errors)
745 | {
746 | fwprintf(stderr,L"%s: option '--%s' requires an argument\n",argv[0], pfound->name);
747 | }
748 | d->__nextchar += wcslen(d->__nextchar);
749 | d->optopt = pfound->val;
750 | return optstring[0] == L':' ? L':' : L'?';
751 | }
752 | }
753 | d->__nextchar += wcslen(d->__nextchar);
754 | if (longind != NULL)
755 | *longind = option_index;
756 | if (pfound->flag)
757 | {
758 | *(pfound->flag) = pfound->val;
759 | return 0;
760 | }
761 | return pfound->val;
762 | }
763 | if (!long_only || argv[d->optind][1] == L'-' || wcschr(optstring, *d->__nextchar) == NULL)
764 | {
765 | if (print_errors)
766 | {
767 | if (argv[d->optind][1] == L'-')
768 | {
769 | fwprintf(stderr, L"%s: unrecognized option '--%s'\n",argv[0], d->__nextchar);
770 | }
771 | else
772 | {
773 | fwprintf(stderr, L"%s: unrecognized option '%c%s'\n",argv[0], argv[d->optind][0], d->__nextchar);
774 | }
775 | }
776 | d->__nextchar = (wchar_t *)L"";
777 | d->optind++;
778 | d->optopt = 0;
779 | return L'?';
780 | }
781 | }
782 | {
783 | wchar_t c = *d->__nextchar++;
784 | wchar_t *temp = (wchar_t*)wcschr(optstring, c);
785 | if (*d->__nextchar == L'\0')
786 | ++d->optind;
787 | if (temp == NULL || c == L':' || c == L';')
788 | {
789 | if (print_errors)
790 | {
791 | fwprintf(stderr, L"%s: invalid option -- '%c'\n", argv[0], c);
792 | }
793 | d->optopt = c;
794 | return L'?';
795 | }
796 | if (temp[0] == L'W' && temp[1] == L';')
797 | {
798 | wchar_t *nameend;
799 | const struct option_w *p;
800 | const struct option_w *pfound = NULL;
801 | int exact = 0;
802 | int ambig = 0;
803 | int indfound = 0;
804 | int option_index;
805 | if (longopts == NULL)
806 | goto no_longs;
807 | if (*d->__nextchar != L'\0')
808 | {
809 | d->optarg = d->__nextchar;
810 | d->optind++;
811 | }
812 | else if (d->optind == argc)
813 | {
814 | if (print_errors)
815 | {
816 | fwprintf(stderr,L"%s: option requires an argument -- '%c'\n",argv[0], c);
817 | }
818 | d->optopt = c;
819 | if (optstring[0] == L':')
820 | c = L':';
821 | else
822 | c = L'?';
823 | return c;
824 | }
825 | else
826 | d->optarg = argv[d->optind++];
827 | for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != L'='; nameend++);
828 | for (p = longopts, option_index = 0; p->name; p++, option_index++)
829 | if (!wcsncmp(p->name, d->__nextchar, nameend - d->__nextchar))
830 | {
831 | if ((unsigned int) (nameend - d->__nextchar) == wcslen(p->name))
832 | {
833 | pfound = p;
834 | indfound = option_index;
835 | exact = 1;
836 | break;
837 | }
838 | else if (pfound == NULL)
839 | {
840 | pfound = p;
841 | indfound = option_index;
842 | }
843 | else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val)
844 | ambig = 1;
845 | }
846 | if (ambig && !exact)
847 | {
848 | if (print_errors)
849 | {
850 | fwprintf(stderr, L"%s: option '-W %s' is ambiguous\n",argv[0], d->optarg);
851 | }
852 | d->__nextchar += wcslen(d->__nextchar);
853 | d->optind++;
854 | return L'?';
855 | }
856 | if (pfound != NULL)
857 | {
858 | option_index = indfound;
859 | if (*nameend)
860 | {
861 | if (pfound->has_arg)
862 | d->optarg = nameend + 1;
863 | else
864 | {
865 | if (print_errors)
866 | {
867 | fwprintf(stderr, L"%s: option '-W %s' doesn't allow an argument\n",argv[0], pfound->name);
868 | }
869 | d->__nextchar += wcslen(d->__nextchar);
870 | return L'?';
871 | }
872 | }
873 | else if (pfound->has_arg == 1)
874 | {
875 | if (d->optind < argc)
876 | d->optarg = argv[d->optind++];
877 | else
878 | {
879 | if (print_errors)
880 | {
881 | fwprintf(stderr, L"%s: option '-W %s' requires an argument\n",argv[0], pfound->name);
882 | }
883 | d->__nextchar += wcslen(d->__nextchar);
884 | return optstring[0] == L':' ? L':' : L'?';
885 | }
886 | }
887 | else
888 | d->optarg = NULL;
889 | d->__nextchar += wcslen(d->__nextchar);
890 | if (longind != NULL)
891 | *longind = option_index;
892 | if (pfound->flag)
893 | {
894 | *(pfound->flag) = pfound->val;
895 | return 0;
896 | }
897 | return pfound->val;
898 | }
899 | no_longs:
900 | d->__nextchar = NULL;
901 | return L'W';
902 | }
903 | if (temp[1] == L':')
904 | {
905 | if (temp[2] == L':')
906 | {
907 | if (*d->__nextchar != L'\0')
908 | {
909 | d->optarg = d->__nextchar;
910 | d->optind++;
911 | }
912 | else
913 | d->optarg = NULL;
914 | d->__nextchar = NULL;
915 | }
916 | else
917 | {
918 | if (*d->__nextchar != L'\0')
919 | {
920 | d->optarg = d->__nextchar;
921 | d->optind++;
922 | }
923 | else if (d->optind == argc)
924 | {
925 | if (print_errors)
926 | {
927 | fwprintf(stderr,L"%s: option requires an argument -- '%c'\n",argv[0], c);
928 | }
929 | d->optopt = c;
930 | if (optstring[0] == L':')
931 | c = L':';
932 | else
933 | c = L'?';
934 | }
935 | else
936 | d->optarg = argv[d->optind++];
937 | d->__nextchar = NULL;
938 | }
939 | }
940 | return c;
941 | }
942 | }
943 | int _getopt_internal_w (int argc, wchar_t *const *argv, const wchar_t *optstring, const struct option_w *longopts, int *longind, int long_only, int posixly_correct)
944 | {
945 | int result;
946 | getopt_data_w.optind = optind;
947 | getopt_data_w.opterr = opterr;
948 | result = _getopt_internal_r_w (argc, argv, optstring, longopts,longind, long_only, &getopt_data_w,posixly_correct);
949 | optind = getopt_data_w.optind;
950 | optarg_w = getopt_data_w.optarg;
951 | optopt = getopt_data_w.optopt;
952 | return result;
953 | }
954 | int getopt_w (int argc, wchar_t *const *argv, const wchar_t *optstring) _GETOPT_THROW
955 | {
956 | return _getopt_internal_w (argc, argv, optstring, (const struct option_w *) 0, (int *) 0, 0, 0);
957 | }
958 | int getopt_long_w (int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index) _GETOPT_THROW
959 | {
960 | return _getopt_internal_w (argc, argv, options, long_options, opt_index, 0, 0);
961 | }
962 | int getopt_long_only_w (int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index) _GETOPT_THROW
963 | {
964 | return _getopt_internal_w (argc, argv, options, long_options, opt_index, 1, 0);
965 | }
966 | int _getopt_long_r_w (int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index, struct _getopt_data_w *d)
967 | {
968 | return _getopt_internal_r_w (argc, argv, options, long_options, opt_index,0, d, 0);
969 | }
970 | int _getopt_long_only_r_w (int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index, struct _getopt_data_w *d)
971 | {
972 | return _getopt_internal_r_w (argc, argv, options, long_options, opt_index, 1, d, 0);
973 | }
--------------------------------------------------------------------------------
/getopt.h:
--------------------------------------------------------------------------------
1 | /* Getopt for Microsoft C
2 | This code is a modification of the Free Software Foundation, Inc.
3 | Getopt library for parsing command line argument the purpose was
4 | to provide a Microsoft Visual C friendly derivative. This code
5 | provides functionality for both Unicode and Multibyte builds.
6 |
7 | Date: 02/03/2011 - Ludvik Jerabek - Initial Release
8 | Version: 1.0
9 | Comment: Supports getopt, getopt_long, and getopt_long_only
10 | and POSIXLY_CORRECT environment flag
11 | License: LGPL
12 |
13 | Revisions:
14 |
15 | 02/03/2011 - Ludvik Jerabek - Initial Release
16 | 02/20/2011 - Ludvik Jerabek - Fixed compiler warnings at Level 4
17 | 07/05/2011 - Ludvik Jerabek - Added no_argument, required_argument, optional_argument defs
18 | 08/03/2011 - Ludvik Jerabek - Fixed non-argument runtime bug which caused runtime exception
19 | 08/09/2011 - Ludvik Jerabek - Added code to export functions for DLL and LIB
20 | 02/15/2012 - Ludvik Jerabek - Fixed _GETOPT_THROW definition missing in implementation file
21 | 08/01/2012 - Ludvik Jerabek - Created separate functions for char and wchar_t characters so single dll can do both unicode and ansi
22 | 10/15/2012 - Ludvik Jerabek - Modified to match latest GNU features
23 | 06/19/2015 - Ludvik Jerabek - Fixed maximum option limitation caused by option_a (255) and option_w (65535) structure val variable
24 |
25 | **DISCLAIMER**
26 | THIS MATERIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
27 | EITHER EXPRESS OR IMPLIED, INCLUDING, BUT Not LIMITED TO, THE
28 | IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
29 | PURPOSE, OR NON-INFRINGEMENT. SOME JURISDICTIONS DO NOT ALLOW THE
30 | EXCLUSION OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY NOT
31 | APPLY TO YOU. IN NO EVENT WILL I BE LIABLE TO ANY PARTY FOR ANY
32 | DIRECT, INDIRECT, SPECIAL OR OTHER CONSEQUENTIAL DAMAGES FOR ANY
33 | USE OF THIS MATERIAL INCLUDING, WITHOUT LIMITATION, ANY LOST
34 | PROFITS, BUSINESS INTERRUPTION, LOSS OF PROGRAMS OR OTHER DATA ON
35 | YOUR INFORMATION HANDLING SYSTEM OR OTHERWISE, EVEN If WE ARE
36 | EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
37 | */
38 | #ifndef __GETOPT_H_
39 | #define __GETOPT_H_
40 |
41 | #ifdef _GETOPT_API
42 | #undef _GETOPT_API
43 | #endif
44 |
45 | #if defined(EXPORTS_GETOPT) && defined(STATIC_GETOPT)
46 | #error "The preprocessor definitions of EXPORTS_GETOPT and STATIC_GETOPT can only be used individually"
47 | #elif defined(STATIC_GETOPT)
48 | #pragma message("Warning static builds of getopt violate the Lesser GNU Public License")
49 | #define _GETOPT_API
50 | #elif defined(EXPORTS_GETOPT)
51 | #pragma message("Exporting getopt library")
52 | #define _GETOPT_API __declspec(dllexport)
53 | #else
54 | #pragma message("Importing getopt library")
55 | #define _GETOPT_API __declspec(dllimport)
56 | #endif
57 |
58 | // Change behavior for C\C++
59 | #ifdef __cplusplus
60 | #define _BEGIN_EXTERN_C extern "C" {
61 | #define _END_EXTERN_C }
62 | #define _GETOPT_THROW throw()
63 | #else
64 | #define _BEGIN_EXTERN_C
65 | #define _END_EXTERN_C
66 | #define _GETOPT_THROW
67 | #endif
68 |
69 | // Standard GNU options
70 | #define null_argument 0 /*Argument Null*/
71 | #define no_argument 0 /*Argument Switch Only*/
72 | #define required_argument 1 /*Argument Required*/
73 | #define optional_argument 2 /*Argument Optional*/
74 |
75 | // Shorter Options
76 | #define ARG_NULL 0 /*Argument Null*/
77 | #define ARG_NONE 0 /*Argument Switch Only*/
78 | #define ARG_REQ 1 /*Argument Required*/
79 | #define ARG_OPT 2 /*Argument Optional*/
80 |
81 | #include
82 | #include
83 |
84 | _BEGIN_EXTERN_C
85 |
86 | extern _GETOPT_API int optind;
87 | extern _GETOPT_API int opterr;
88 | extern _GETOPT_API int optopt;
89 |
90 | // Ansi
91 | struct option_a
92 | {
93 | const char* name;
94 | int has_arg;
95 | int *flag;
96 | int val;
97 | };
98 | extern _GETOPT_API char *optarg_a;
99 | extern _GETOPT_API int getopt_a(int argc, char *const *argv, const char *optstring) _GETOPT_THROW;
100 | extern _GETOPT_API int getopt_long_a(int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index) _GETOPT_THROW;
101 | extern _GETOPT_API int getopt_long_only_a(int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index) _GETOPT_THROW;
102 |
103 | // Unicode
104 | struct option_w
105 | {
106 | const wchar_t* name;
107 | int has_arg;
108 | int *flag;
109 | int val;
110 | };
111 | extern _GETOPT_API wchar_t *optarg_w;
112 | extern _GETOPT_API int getopt_w(int argc, wchar_t *const *argv, const wchar_t *optstring) _GETOPT_THROW;
113 | extern _GETOPT_API int getopt_long_w(int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index) _GETOPT_THROW;
114 | extern _GETOPT_API int getopt_long_only_w(int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index) _GETOPT_THROW;
115 |
116 | _END_EXTERN_C
117 |
118 | #undef _BEGIN_EXTERN_C
119 | #undef _END_EXTERN_C
120 | #undef _GETOPT_THROW
121 | #undef _GETOPT_API
122 |
123 | #ifdef _UNICODE
124 | #define getopt getopt_w
125 | #define getopt_long getopt_long_w
126 | #define getopt_long_only getopt_long_only_w
127 | #define option option_w
128 | #define optarg optarg_w
129 | #else
130 | #define getopt getopt_a
131 | #define getopt_long getopt_long_a
132 | #define getopt_long_only getopt_long_only_a
133 | #define option option_a
134 | #define optarg optarg_a
135 | #endif
136 | #endif // __GETOPT_H_
137 |
--------------------------------------------------------------------------------
/getopt.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27705.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "getopt", "getopt.vcxproj", "{4BBAEAA1-9AD1-42D2-B6DC-7F73C4B3D238}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Win32 = Debug|Win32
11 | Debug|x64 = Debug|x64
12 | Release|Win32 = Release|Win32
13 | Release|x64 = Release|x64
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {4BBAEAA1-9AD1-42D2-B6DC-7F73C4B3D238}.Debug|Win32.ActiveCfg = Debug|Win32
17 | {4BBAEAA1-9AD1-42D2-B6DC-7F73C4B3D238}.Debug|Win32.Build.0 = Debug|Win32
18 | {4BBAEAA1-9AD1-42D2-B6DC-7F73C4B3D238}.Debug|x64.ActiveCfg = Debug|x64
19 | {4BBAEAA1-9AD1-42D2-B6DC-7F73C4B3D238}.Debug|x64.Build.0 = Debug|x64
20 | {4BBAEAA1-9AD1-42D2-B6DC-7F73C4B3D238}.Release|Win32.ActiveCfg = Release|Win32
21 | {4BBAEAA1-9AD1-42D2-B6DC-7F73C4B3D238}.Release|Win32.Build.0 = Release|Win32
22 | {4BBAEAA1-9AD1-42D2-B6DC-7F73C4B3D238}.Release|x64.ActiveCfg = Release|x64
23 | {4BBAEAA1-9AD1-42D2-B6DC-7F73C4B3D238}.Release|x64.Build.0 = Release|x64
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {4E6DE38C-035F-4DBE-9385-C35AC4C787ED}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/getopt.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Debug
10 | x64
11 |
12 |
13 | Release
14 | Win32
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | {4BBAEAA1-9AD1-42D2-B6DC-7F73C4B3D238}
23 | GetOptTest
24 | Win32Proj
25 |
26 |
27 |
28 | DynamicLibrary
29 | Unicode
30 | v140
31 |
32 |
33 | DynamicLibrary
34 | Unicode
35 | v140
36 |
37 |
38 | DynamicLibrary
39 | Unicode
40 | true
41 | v140
42 |
43 |
44 | DynamicLibrary
45 | Unicode
46 | true
47 | v140
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | <_ProjectFileVersion>10.0.30319.1
67 | $(SolutionDir)$(Platform)\$(Configuration)\
68 | $(SolutionDir)$(Platform)\$(Configuration)\
69 | false
70 | false
71 | true
72 | true
73 | getopt
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | MaxSpeed
82 | true
83 | WIN32;NDEBUG;_CONSOLE;EXPORTS_GETOPT;%(PreprocessorDefinitions)
84 | MultiThreadedDLL
85 | true
86 |
87 |
88 | Level3
89 | ProgramDatabase
90 |
91 |
92 | $(OutDir)\getopt.dll
93 | true
94 | Console
95 | true
96 | true
97 | MachineX86
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 | MaxSpeed
111 | true
112 | WIN32;NDEBUG;_CONSOLE;EXPORTS_GETOPT;%(PreprocessorDefinitions)
113 | MultiThreadedDLL
114 | true
115 |
116 |
117 | Level3
118 | ProgramDatabase
119 |
120 |
121 | $(OutDir)\getopt.dll
122 | true
123 | Console
124 | true
125 | true
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 | Disabled
139 | WIN32;_DEBUG;_CONSOLE;EXPORTS_GETOPT;%(PreprocessorDefinitions)
140 | true
141 | EnableFastChecks
142 | MultiThreadedDebugDLL
143 |
144 |
145 | Level4
146 | EditAndContinue
147 |
148 |
149 | $(OutDir)\getopt.dll
150 | true
151 | Console
152 | MachineX86
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 | Disabled
166 | WIN32;_DEBUG;_CONSOLE;EXPORTS_GETOPT;%(PreprocessorDefinitions)
167 | EnableFastChecks
168 | MultiThreadedDebugDLL
169 |
170 |
171 | Level4
172 | ProgramDatabase
173 |
174 |
175 | $(OutDir)\getopt.dll
176 | true
177 | Console
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
--------------------------------------------------------------------------------