11#ifndef KETOPT_H
22#define KETOPT_H
33
4+ #include <string.h> /* for strchr() and strncmp() */
5+
46#define ko_no_argument 0
57#define ko_required_argument 1
68#define ko_optional_argument 2
@@ -20,11 +22,16 @@ typedef struct {
2022 int val ;
2123} ko_longopt_t ;
2224
23- #ifdef __cplusplus
24- extern "C" {
25- #endif
25+ static ketopt_t KETOPT_INIT = { 1 , 0 , 0 , -1 , 1 , 0 , 0 };
2626
27- extern ketopt_t KETOPT_INIT ;
27+ static void ketopt_permute (char * argv [], int j , int n ) /* move argv[j] over n elements to the left */
28+ {
29+ int k ;
30+ char * p = argv [j ];
31+ for (k = 0 ; k < n ; ++ k )
32+ argv [j - k ] = argv [j - k - 1 ];
33+ argv [j - k ] = p ;
34+ }
2835
2936/**
3037 * Parse command-line options and arguments
@@ -46,10 +53,64 @@ extern ketopt_t KETOPT_INIT;
4653 * argv[] is fully processed; '?' for an unknown option or an ambiguous
4754 * long option; ':' if an option argument is missing
4855 */
49- int ketopt (ketopt_t * s , int argc , char * argv [], int permute , const char * ostr , const ko_longopt_t * longopts );
50-
51- #ifdef __cplusplus
56+ static int ketopt (ketopt_t * s , int argc , char * argv [], int permute , const char * ostr , const ko_longopt_t * longopts )
57+ {
58+ int opt = -1 , i0 , j ;
59+ if (permute ) {
60+ while (s -> i < argc && (argv [s -> i ][0 ] != '-' || argv [s -> i ][1 ] == '\0' ))
61+ ++ s -> i , ++ s -> n_args ;
62+ }
63+ s -> arg = 0 , s -> longidx = -1 , i0 = s -> i ;
64+ if (s -> i >= argc || argv [s -> i ][0 ] != '-' || argv [s -> i ][1 ] == '\0' ) {
65+ s -> ind = s -> i - s -> n_args ;
66+ return -1 ;
67+ }
68+ if (argv [s -> i ][0 ] == '-' && argv [s -> i ][1 ] == '-' ) { /* "--" or a long option */
69+ if (argv [s -> i ][2 ] == '\0' ) { /* a bare "--" */
70+ ketopt_permute (argv , s -> i , s -> n_args );
71+ ++ s -> i , s -> ind = s -> i - s -> n_args ;
72+ return -1 ;
73+ }
74+ s -> opt = 0 , opt = '?' , s -> pos = -1 ;
75+ if (longopts ) { /* parse long options */
76+ int k , n_matches = 0 ;
77+ const ko_longopt_t * o = 0 ;
78+ for (j = 2 ; argv [s -> i ][j ] != '\0' && argv [s -> i ][j ] != '=' ; ++ j ) {} /* find the end of the option name */
79+ for (k = 0 ; longopts [k ].name != 0 ; ++ k )
80+ if (strncmp (& argv [s -> i ][2 ], longopts [k ].name , j - 2 ) == 0 )
81+ ++ n_matches , o = & longopts [k ];
82+ if (n_matches == 1 ) {
83+ s -> opt = opt = o -> val , s -> longidx = o - longopts ;
84+ if (argv [s -> i ][j ] == '=' ) s -> arg = & argv [s -> i ][j + 1 ];
85+ if (o -> has_arg == 1 && argv [s -> i ][j ] == '\0' ) {
86+ if (s -> i < argc - 1 ) s -> arg = argv [++ s -> i ];
87+ else opt = ':' ; /* missing option argument */
88+ }
89+ }
90+ }
91+ } else { /* a short option */
92+ char * p ;
93+ if (s -> pos == 0 ) s -> pos = 1 ;
94+ opt = s -> opt = argv [s -> i ][s -> pos ++ ];
95+ p = strchr (ostr , opt );
96+ if (p == 0 ) {
97+ opt = '?' ; /* unknown option */
98+ } else if (p [1 ] == ':' ) {
99+ if (argv [s -> i ][s -> pos ] == 0 ) {
100+ if (s -> i < argc - 1 ) s -> arg = argv [++ s -> i ];
101+ else opt = ':' ; /* missing option argument */
102+ } else s -> arg = & argv [s -> i ][s -> pos ];
103+ s -> pos = -1 ;
104+ }
105+ }
106+ if (s -> pos < 0 || argv [s -> i ][s -> pos ] == 0 ) {
107+ ++ s -> i , s -> pos = 0 ;
108+ if (s -> n_args > 0 ) /* permute */
109+ for (j = i0 ; j < s -> i ; ++ j )
110+ ketopt_permute (argv , j , s -> n_args );
111+ }
112+ s -> ind = s -> i - s -> n_args ;
113+ return opt ;
52114}
53- #endif
54115
55116#endif
0 commit comments