99
1010struct _args {
1111 FILE * rfp ;
12- char * cmdline ;
12+ char * cmdline ;
1313 mrb_bool fname : 1 ;
1414 mrb_bool mrbfile : 1 ;
1515 mrb_bool check_syntax : 1 ;
1616 mrb_bool verbose : 1 ;
1717 mrb_bool debug : 1 ;
1818 int argc ;
19- char * * argv ;
19+ char * * argv ;
2020 int libc ;
2121 char * * libv ;
2222};
2323
24+ struct options {
25+ int argc ;
26+ char * * argv ;
27+ char * program ;
28+ char * opt ;
29+ char short_opt [2 ];
30+ };
31+
2432static void
2533usage (const char * name )
2634{
@@ -44,6 +52,51 @@ usage(const char *name)
4452 printf (" %s\n" , * p ++ );
4553}
4654
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+
47100static char *
48101dup_arg_item (mrb_state * mrb , const char * item )
49102{
@@ -56,40 +109,24 @@ dup_arg_item(mrb_state *mrb, const char *item)
56109static int
57110parse_args (mrb_state * mrb , int argc , char * * argv , struct _args * args )
58111{
59- char * * origargv = argv ;
60112 static const struct _args args_zero = { 0 };
113+ struct options opts [1 ];
114+ const char * opt , * item ;
61115
62116 * 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 ) {
77120 args -> mrbfile = TRUE;
78- break ;
79- case 'c' :
121+ }
122+ else if ( strcmp ( opt , "c" ) == 0 ) {
80123 args -> check_syntax = TRUE;
81- break ;
82- case 'd' :
124+ }
125+ else if ( strcmp ( opt , "d" ) == 0 ) {
83126 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 ))) {
93130 if (!args -> cmdline ) {
94131 args -> cmdline = dup_arg_item (mrb , item );
95132 }
@@ -106,59 +143,60 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
106143 }
107144 }
108145 else {
109- fprintf (stderr , "%s: No code specified for -e\n" , * origargv );
146+ fprintf (stderr , "%s: No code specified for -e\n" , opts -> program );
110147 return EXIT_FAILURE ;
111148 }
112- break ;
113- case 'h' :
114- usage (* origargv );
149+ }
150+ else if ( strcmp ( opt , "h" ) == 0 ) {
151+ usage (opts -> program );
115152 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 * )) ;
121158 }
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 );
127163 }
128164 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 ;
130167 }
131- args -> libv [args -> libc ++ ] = dup_arg_item (mrb , item );
132- break ;
133- case 'v' :
168+ }
169+ else if (strcmp (opt , "v" ) == 0 ) {
134170 if (!args -> verbose ) mrb_show_version (mrb );
135171 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;
136179 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 );
152188 return EXIT_FAILURE ;
153189 }
154190 }
155191
156- if (args -> rfp == NULL && args -> cmdline == NULL ) {
192+ if (args -> cmdline == NULL ) {
193+ argc = opts -> argc ; argv = opts -> argv ;
157194 if (* argv == NULL ) args -> rfp = stdin ;
158195 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" );
160198 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 ] );
162200 return EXIT_FAILURE ;
163201 }
164202 args -> fname = TRUE;
0 commit comments