9
9
10
10
struct _args {
11
11
FILE * rfp ;
12
- char * cmdline ;
12
+ char * cmdline ;
13
13
mrb_bool fname : 1 ;
14
14
mrb_bool mrbfile : 1 ;
15
15
mrb_bool check_syntax : 1 ;
16
16
mrb_bool verbose : 1 ;
17
17
mrb_bool debug : 1 ;
18
18
int argc ;
19
- char * * argv ;
19
+ char * * argv ;
20
20
int libc ;
21
21
char * * libv ;
22
22
};
23
23
24
+ struct options {
25
+ int argc ;
26
+ char * * argv ;
27
+ char * program ;
28
+ char * opt ;
29
+ char short_opt [2 ];
30
+ };
31
+
24
32
static void
25
33
usage (const char * name )
26
34
{
@@ -44,6 +52,51 @@ usage(const char *name)
44
52
printf (" %s\n" , * p ++ );
45
53
}
46
54
55
+ static void
56
+ options_init (struct options * opts , int argc , char * * argv )
57
+ {
58
+ opts -> argc = argc ;
59
+ opts -> argv = argv ;
60
+ opts -> program = * argv ;
61
+ * opts -> short_opt = 0 ;
62
+ }
63
+
64
+ static const char *
65
+ options_opt (struct options * opts )
66
+ {
67
+ if (* opts -> short_opt && * ++ opts -> opt ) {
68
+ short_opt :
69
+ opts -> short_opt [0 ] = * opts -> opt ;
70
+ opts -> short_opt [1 ] = 0 ;
71
+ return opts -> short_opt ;
72
+ }
73
+ while (++ opts -> argv , -- opts -> argc ) {
74
+ opts -> opt = * opts -> argv ;
75
+ if (!opts -> opt [0 ] || opts -> opt [0 ] != '-' || !opts -> opt [1 ]) return NULL ;
76
+ if (opts -> opt [1 ] == '-' ) {
77
+ opts -> opt += 2 ;
78
+ * opts -> short_opt = 0 ;
79
+ return opts -> opt ;
80
+ }
81
+ else {
82
+ ++ opts -> opt ;
83
+ goto short_opt ;
84
+ }
85
+ }
86
+ return NULL ;
87
+ }
88
+
89
+ static const char *
90
+ options_arg (struct options * opts )
91
+ {
92
+ if (* opts -> short_opt && opts -> opt [1 ]) {
93
+ * opts -> short_opt = 0 ;
94
+ return opts -> opt + 1 ;
95
+ }
96
+ -- opts -> argc , ++ opts -> argv ;
97
+ return opts -> argc ? * opts -> argv : NULL ;
98
+ }
99
+
47
100
static char *
48
101
dup_arg_item (mrb_state * mrb , const char * item )
49
102
{
@@ -56,40 +109,24 @@ dup_arg_item(mrb_state *mrb, const char *item)
56
109
static int
57
110
parse_args (mrb_state * mrb , int argc , char * * argv , struct _args * args )
58
111
{
59
- char * * origargv = argv ;
60
112
static const struct _args args_zero = { 0 };
113
+ struct options opts [1 ];
114
+ const char * opt , * item ;
61
115
62
116
* args = args_zero ;
63
-
64
- for (argc -- ,argv ++ ; argc > 0 ; argc -- ,argv ++ ) {
65
- char * item ;
66
- if (argv [0 ][0 ] != '-' ) break ;
67
-
68
- if (strlen (* argv ) <= 1 ) {
69
- argc -- ; argv ++ ;
70
- args -> rfp = stdin ;
71
- break ;
72
- }
73
-
74
- item = argv [0 ] + 1 ;
75
- switch (* item ++ ) {
76
- case 'b' :
117
+ options_init (opts , argc , argv );
118
+ while ((opt = options_opt (opts ))) {
119
+ if (strcmp (opt , "b" ) == 0 ) {
77
120
args -> mrbfile = TRUE;
78
- break ;
79
- case 'c' :
121
+ }
122
+ else if ( strcmp ( opt , "c" ) == 0 ) {
80
123
args -> check_syntax = TRUE;
81
- break ;
82
- case 'd' :
124
+ }
125
+ else if ( strcmp ( opt , "d" ) == 0 ) {
83
126
args -> debug = TRUE;
84
- break ;
85
- case 'e' :
86
- if (item [0 ]) {
87
- goto append_cmdline ;
88
- }
89
- else if (argc > 1 ) {
90
- argc -- ; argv ++ ;
91
- item = argv [0 ];
92
- append_cmdline :
127
+ }
128
+ else if (strcmp (opt , "e" ) == 0 ) {
129
+ if ((item = options_arg (opts ))) {
93
130
if (!args -> cmdline ) {
94
131
args -> cmdline = dup_arg_item (mrb , item );
95
132
}
@@ -106,59 +143,60 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
106
143
}
107
144
}
108
145
else {
109
- fprintf (stderr , "%s: No code specified for -e\n" , * origargv );
146
+ fprintf (stderr , "%s: No code specified for -e\n" , opts -> program );
110
147
return EXIT_FAILURE ;
111
148
}
112
- break ;
113
- case 'h' :
114
- usage (* origargv );
149
+ }
150
+ else if ( strcmp ( opt , "h" ) == 0 ) {
151
+ usage (opts -> program );
115
152
exit (EXIT_SUCCESS );
116
- case 'r' :
117
- if (! item [ 0 ] ) {
118
- if (argc <= 1 ) {
119
- fprintf ( stderr , "%s: No library specified for -r\n" , * origargv );
120
- return EXIT_FAILURE ;
153
+ }
154
+ else if (strcmp ( opt , "r" ) == 0 ) {
155
+ if (( item = options_arg ( opts )) ) {
156
+ if ( args -> libc == 0 ) {
157
+ args -> libv = ( char * * ) mrb_malloc ( mrb , sizeof ( char * )) ;
121
158
}
122
- argc -- ; argv ++ ;
123
- item = argv [0 ];
124
- }
125
- if (args -> libc == 0 ) {
126
- args -> libv = (char * * )mrb_malloc (mrb , sizeof (char * ));
159
+ else {
160
+ args -> libv = (char * * )mrb_realloc (mrb , args -> libv , sizeof (char * ) * (args -> libc + 1 ));
161
+ }
162
+ args -> libv [args -> libc ++ ] = dup_arg_item (mrb , item );
127
163
}
128
164
else {
129
- args -> libv = (char * * )mrb_realloc (mrb , args -> libv , sizeof (char * ) * (args -> libc + 1 ));
165
+ fprintf (stderr , "%s: No library specified for -r\n" , opts -> program );
166
+ return EXIT_FAILURE ;
130
167
}
131
- args -> libv [args -> libc ++ ] = dup_arg_item (mrb , item );
132
- break ;
133
- case 'v' :
168
+ }
169
+ else if (strcmp (opt , "v" ) == 0 ) {
134
170
if (!args -> verbose ) mrb_show_version (mrb );
135
171
args -> verbose = TRUE;
172
+ }
173
+ else if (strcmp (opt , "version" ) == 0 ) {
174
+ mrb_show_version (mrb );
175
+ exit (EXIT_SUCCESS );
176
+ }
177
+ else if (strcmp (opt , "verbose" ) == 0 ) {
178
+ args -> verbose = TRUE;
136
179
break ;
137
- case '-' :
138
- if (strcmp ((* argv ) + 2 , "version" ) == 0 ) {
139
- mrb_show_version (mrb );
140
- exit (EXIT_SUCCESS );
141
- }
142
- else if (strcmp ((* argv ) + 2 , "verbose" ) == 0 ) {
143
- args -> verbose = TRUE;
144
- break ;
145
- }
146
- else if (strcmp ((* argv ) + 2 , "copyright" ) == 0 ) {
147
- mrb_show_copyright (mrb );
148
- exit (EXIT_SUCCESS );
149
- }
150
- default :
151
- fprintf (stderr , "%s: invalid option %s (-h will show valid options)\n" , * origargv , * argv );
180
+ }
181
+ else if (strcmp (opt , "copyright" ) == 0 ) {
182
+ mrb_show_copyright (mrb );
183
+ exit (EXIT_SUCCESS );
184
+ }
185
+ else {
186
+ fprintf (stderr , "%s: invalid option %s%s (-h will show valid options)\n" ,
187
+ opts -> program , opt [1 ] ? "--" : "-" , opt );
152
188
return EXIT_FAILURE ;
153
189
}
154
190
}
155
191
156
- if (args -> rfp == NULL && args -> cmdline == NULL ) {
192
+ if (args -> cmdline == NULL ) {
193
+ argc = opts -> argc ; argv = opts -> argv ;
157
194
if (* argv == NULL ) args -> rfp = stdin ;
158
195
else {
159
- args -> rfp = fopen (argv [0 ], args -> mrbfile ? "rb" : "r" );
196
+ args -> rfp = strcmp (argv [0 ], "-" ) == 0 ?
197
+ stdin : fopen (argv [0 ], args -> mrbfile ? "rb" : "r" );
160
198
if (args -> rfp == NULL ) {
161
- fprintf (stderr , "%s: Cannot open program file: %s\n" , * origargv , * argv );
199
+ fprintf (stderr , "%s: Cannot open program file: %s\n" , opts -> program , argv [ 0 ] );
162
200
return EXIT_FAILURE ;
163
201
}
164
202
args -> fname = TRUE;
0 commit comments