1 ////////////////////////////////////////////////////////////////////
2 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
3 // All rights reserved
4 // This file was released under the GPLv2 on June 2015.
5 ////////////////////////////////////////////////////////////////////
6 
7 #ifndef _GETOPT_H
8 #define _GETOPT_H
9 
10 #ifdef  __cplusplus
11 extern "C" {
12 #endif
13 
14 #define BAD_OPTION '\0'
15 
16 typedef struct _optarg_ctx {
17     /* For communication from `getopt' to the caller.
18        When `getopt' finds an option that takes an argument,
19        the argument value is returned here.
20        Also, when `ordering' is RETURN_IN_ORDER,
21        each non-option ARGV-element is returned here.  */
22 
23     WCHAR* optarg;
24 
25     /* Index in ARGV of the next element to be scanned.
26        This is used for communication to and from the caller
27        and for communication between successive calls to `getopt'.
28 
29        On entry to `getopt', zero means this is the first call; initialize.
30 
31        When `getopt' returns EOF, this is the index of the first of the
32        non-option elements that the caller should itself scan.
33 
34        Otherwise, `optind' communicates from one call to the next
35        how much of ARGV has been scanned so far.  */
36 
37     int optind;
38 
39     /* The next char to be scanned in the option-element
40        in which the last option character we returned was found.
41        This allows us to pick up the scan where we left off.
42 
43        If this is zero, or a null string, it means resume the scan
44        by advancing to the next ARGV-element.  */
45 
46     WCHAR *nextchar;
47 
48     /* Callers store zero here to inhibit the error message
49        for unrecognized options.  */
50 
51     int opterr;
52 
53     /* Set to an option character which was unrecognized.
54        This must be initialized on some systems to avoid linking in the
55        system's own getopt implementation.  */
56 
57     int optopt;
58 
59     /* Describe the part of ARGV that contains non-options that have
60        been skipped.  `first_nonopt' is the index in ARGV of the first of them;
61        `last_nonopt' is the index after the last of them.  */
62 
63     int first_nonopt;
64     int last_nonopt;
65 
66     /* Exchange two adjacent subsequences of ARGV.
67        One subsequence is elements [first_nonopt,last_nonopt)
68        which contains all the non-options that have been skipped so far.
69        The other is elements [last_nonopt,optind), which contains all
70        the options processed since those non-options were skipped.
71 
72        `first_nonopt' and `last_nonopt' are relocated so that they describe
73        the new indices of the non-options in ARGV after they are moved.
74 
75        To perform the swap, we first reverse the order of all elements. So
76        all options now come before all non options, but they are in the
77        wrong order. So we put back the options and non options in original
78        order by reversing them again. For example:
79            original input:      a b c -x -y
80            reverse all:         -y -x c b a
81            reverse options:     -x -y c b a
82            reverse non options: -x -y a b c
83     */
84 
85 } optarg_ctx, *P_optarg_ctx;
86 
87 /* Describe the long-named options requested by the application.
88    The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
89    of `struct option' terminated by an element containing a name which is
90    zero.
91 
92    The field `has_arg' is:
93    no_argument          (or 0) if the option does not take an argument,
94    required_argument    (or 1) if the option requires an argument,
95    optional_argument    (or 2) if the option takes an optional argument.
96 
97    If the field `flag' is not NULL, it points to a variable that is set
98    to the value given in the field `val' when the option is found, but
99    left unchanged if the option is not found.
100 
101    To have a long-named option do something other than set an `int' to
102    a compiled-in constant, such as set a value from `optarg', set the
103    option's `flag' field to zero and its `val' field to a nonzero
104    value (the equivalent single-letter option character, if there is
105    one).  For long options that have a zero `flag' field, `getopt'
106    returns the contents of the `val' field.  */
107 
108 struct option
109 {
110   WCHAR *name;
111   /* has_arg can't be an enum because some compilers complain about
112      type mismatches in all the code that assumes it is an int.  */
113   int has_arg;
114   int *flag;
115   int val;
116 };
117 
118 extern void getopt_init(optarg_ctx* o);
119 
120 /* Names for the values of the `has_arg' field of `struct option'.  */
121 
122 #define no_argument             0
123 #define required_argument       1
124 #define optional_argument       2
125 
126 extern int getopt (optarg_ctx* o, int argc, WCHAR *const *argv, const WCHAR *shortopts);
127 extern int getopt_long (optarg_ctx* o, int argc, WCHAR *const *argv, const WCHAR *shortopts,
128                         const struct option *longopts, int *longind);
129 extern int getopt_long_only (optarg_ctx* o, int argc, WCHAR *const *argv,
130                              const WCHAR *shortopts,
131                              const struct option *longopts, int *longind);
132 
133 /* Internal only.  Users should not call this directly.  */
134 extern int _getopt_internal (optarg_ctx* o, int argc, WCHAR *const *argv,
135                              const WCHAR *shortopts,
136                              const struct option *longopts, int *longind,
137                              int long_only);
138 
139 #ifdef  __cplusplus
140 }
141 #endif
142 
143 #endif /* _GETOPT_H */
144