ThiagoLelis-backgroundjob 1.0.4 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/lib/main/cast.rb CHANGED
@@ -1,100 +1,100 @@
1
- module Main
2
- module Cast
3
- def self.export m
4
- module_function m
5
- public m
6
- end
7
-
8
- List = []
9
-
10
- def self.cast m, &b
11
- define_method m, &b
12
- export m
13
- List << m.to_s
14
- end
15
-
16
- cast :boolean do |obj|
17
- case obj.to_s
18
- when %r/^(true|t|1)$/
19
- true
20
- when %r/^(false|f|0)$/
21
- false
22
- else
23
- !!obj
24
- end
25
- end
26
-
27
- cast :integer do |obj|
28
- Integer obj
29
- end
30
-
31
- cast :float do |obj|
32
- Float obj
33
- end
34
-
35
- cast :number do |obj|
36
- Float obj rescue Integer obj
37
- end
38
-
39
- cast :string do |obj|
40
- String obj
41
- end
42
-
43
- cast :symbol do |obj|
44
- String(obj).to_sym
45
- end
46
-
47
- cast :uri do |obj|
48
- require 'uri'
49
- ::URI.parse obj.to_s
50
- end
51
-
52
- cast :time do |obj|
53
- require 'time'
54
- ::Time.parse obj.to_s
55
- end
56
-
57
- cast :date do |obj|
58
- require 'date'
59
- ::Date.parse obj.to_s
60
- end
61
-
62
- cast :list do |*objs|
63
- [*objs].flatten.join(',').split(/,/)
64
- end
65
-
66
- # add list_of_xxx methods
67
- List.dup.each do |type|
68
- next if type.to_s =~ %r/list/
69
- m = "list_of_#{ type }"
70
- define_method m do |*objs|
71
- list(*objs).map{|obj| send type, obj}
72
- end
73
- export m
74
- List << m
75
- end
76
-
77
- # add list_of_xxx_from_file
78
- List.dup.each do |type|
79
- next if type.to_s =~ %r/list/
80
- m = "list_of_#{ type }"
81
- define_method m do |*objs|
82
- list(*objs).map{|obj| send type, obj}
83
- end
84
- export m
85
- List << m
86
- end
87
-
88
- def self.[] sym
89
- prefix = sym.to_s.downcase.to_sym
90
- candidates = List.select{|m| m =~ %r/^#{ prefix }/i}
91
- m = candidates.shift
92
- raise ArgumentError, "unsupported cast: #{ sym.inspect } (#{ List.join ',' })" unless
93
- m
94
- raise ArgumentError, "ambiguous cast: #{ sym.inspect } (#{ List.join ',' })" unless
95
- candidates.empty? or m.to_s == sym.to_s
96
- this = self
97
- lambda{|obj| method(m).call obj}
98
- end
99
- end
100
- end
1
+ module Main
2
+ module Cast
3
+ def self.export m
4
+ module_function m
5
+ public m
6
+ end
7
+
8
+ List = []
9
+
10
+ def self.cast m, &b
11
+ define_method m, &b
12
+ export m
13
+ List << m.to_s
14
+ end
15
+
16
+ cast :boolean do |obj|
17
+ case obj.to_s
18
+ when %r/^(true|t|1)$/
19
+ true
20
+ when %r/^(false|f|0)$/
21
+ false
22
+ else
23
+ !!obj
24
+ end
25
+ end
26
+
27
+ cast :integer do |obj|
28
+ Integer obj
29
+ end
30
+
31
+ cast :float do |obj|
32
+ Float obj
33
+ end
34
+
35
+ cast :number do |obj|
36
+ Float obj rescue Integer obj
37
+ end
38
+
39
+ cast :string do |obj|
40
+ String obj
41
+ end
42
+
43
+ cast :symbol do |obj|
44
+ String(obj).to_sym
45
+ end
46
+
47
+ cast :uri do |obj|
48
+ require 'uri'
49
+ ::URI.parse obj.to_s
50
+ end
51
+
52
+ cast :time do |obj|
53
+ require 'time'
54
+ ::Time.parse obj.to_s
55
+ end
56
+
57
+ cast :date do |obj|
58
+ require 'date'
59
+ ::Date.parse obj.to_s
60
+ end
61
+
62
+ cast :list do |*objs|
63
+ [*objs].flatten.join(',').split(/,/)
64
+ end
65
+
66
+ # add list_of_xxx methods
67
+ List.dup.each do |type|
68
+ next if type.to_s =~ %r/list/
69
+ m = "list_of_#{ type }"
70
+ define_method m do |*objs|
71
+ list(*objs).map{|obj| send type, obj}
72
+ end
73
+ export m
74
+ List << m
75
+ end
76
+
77
+ # add list_of_xxx_from_file
78
+ List.dup.each do |type|
79
+ next if type.to_s =~ %r/list/
80
+ m = "list_of_#{ type }"
81
+ define_method m do |*objs|
82
+ list(*objs).map{|obj| send type, obj}
83
+ end
84
+ export m
85
+ List << m
86
+ end
87
+
88
+ def self.[] sym
89
+ prefix = sym.to_s.downcase.to_sym
90
+ candidates = List.select{|m| m =~ %r/^#{ prefix }/i}
91
+ m = candidates.shift
92
+ raise ArgumentError, "unsupported cast: #{ sym.inspect } (#{ List.join ',' })" unless
93
+ m
94
+ raise ArgumentError, "ambiguous cast: #{ sym.inspect } (#{ List.join ',' })" unless
95
+ candidates.empty? or m.to_s == sym.to_s
96
+ this = self
97
+ lambda{|obj| method(m).call obj}
98
+ end
99
+ end
100
+ end
@@ -1,20 +1,20 @@
1
- module Main
2
- def Main.create *a, &b
3
- ::Main::Base.create(::Main::Base, *a, &b)
4
- end
5
-
6
- def Main.new *a, &b
7
- create(::Main::Base, &b).new *a
8
- end
9
-
10
- def Main.run argv = ARGV, env = ENV, opts = {}, &block
11
- Base.create(&block).new(argv, env, opts).run
12
- end
13
-
14
- module ::Kernel
15
- def Main argv = ARGV, env = ENV, opts = {}, &block
16
- ::Main.run argv, env, opts, &block
17
- end
18
- alias_method 'main', 'Main'
19
- end
20
- end
1
+ module Main
2
+ def Main.create *a, &b
3
+ ::Main::Base.create(::Main::Base, *a, &b)
4
+ end
5
+
6
+ def Main.new *a, &b
7
+ create(::Main::Base, &b).new *a
8
+ end
9
+
10
+ def Main.run argv = ARGV, env = ENV, opts = {}, &block
11
+ Base.create(&block).new(argv, env, opts).run
12
+ end
13
+
14
+ module ::Kernel
15
+ def Main argv = ARGV, env = ENV, opts = {}, &block
16
+ ::Main.run argv, env, opts, &block
17
+ end
18
+ alias_method 'main', 'Main'
19
+ end
20
+ end
@@ -1,470 +1,470 @@
1
- # -*- Ruby -*-
2
- # Copyright (C) 1998, 1999, 2000 Motoyuki Kasahara
3
- #
4
- # You may redistribute it and/or modify it under the same license
5
- # terms as Ruby.
6
- #
7
-
8
- #
9
- # Documents and latest version of `getoptlong.rb' are found at:
10
- # http://www.sra.co.jp/people/m-kasahr/ruby/getoptlong/
11
- #
12
-
13
- #
14
- # Parse command line options just like GNU getopt_long().
15
- #
16
- module Main
17
- class GetoptLong
18
- #
19
- # Orderings.
20
- #
21
- ORDERINGS = [REQUIRE_ORDER = 0, PERMUTE = 1, RETURN_IN_ORDER = 2]
22
-
23
- #
24
- # Argument flags.
25
- #
26
- ARGUMENT_FLAGS = [NO_ARGUMENT = 0, REQUIRED_ARGUMENT = 1,
27
- OPTIONAL_ARGUMENT = 2]
28
-
29
- #
30
- # Status codes.
31
- #
32
- STATUS_YET, STATUS_STARTED, STATUS_TERMINATED = 0, 1, 2
33
-
34
- #
35
- # Error types.
36
- #
37
- class AmbigousOption < StandardError; end
38
- class NeedlessArgument < StandardError; end
39
- class MissingArgument < StandardError; end
40
- class InvalidOption < StandardError; end
41
-
42
- #
43
- # Initializer.
44
- #
45
- def initialize(argv, *arguments)
46
- @argv = argv
47
- #
48
- # Current ordering.
49
- #
50
- if ENV.include?('POSIXLY_CORRECT')
51
- @ordering = REQUIRE_ORDER
52
- else
53
- @ordering = PERMUTE
54
- end
55
-
56
- #
57
- # Hash table of option names.
58
- # Keyes of the table are option names, and their values are canonical
59
- # names of the options.
60
- #
61
- @canonical_names = Hash.new
62
-
63
- #
64
- # Hash table of argument flags.
65
- # Keyes of the table are option names, and their values are argument
66
- # flags of the options.
67
- #
68
- @argument_flags = Hash.new
69
-
70
- #
71
- # Whether error messages are output to stderr.
72
- #
73
- @quiet = FALSE
74
-
75
- #
76
- # Status code.
77
- #
78
- @status = STATUS_YET
79
-
80
- #
81
- # Error code.
82
- #
83
- @error = nil
84
-
85
- #
86
- # Error message.
87
- #
88
- @error_message = nil
89
-
90
- #
91
- # Rest of catinated short options.
92
- #
93
- @rest_singles = ''
94
-
95
- #
96
- # List of non-option-arguments.
97
- # Append them to @argv when option processing is terminated.
98
- #
99
- @non_option_arguments = Array.new
100
-
101
- if 0 < arguments.length
102
- set_options(*arguments)
103
- end
104
- end
105
-
106
- #
107
- # Set ordering.
108
- #
109
- def ordering=(ordering)
110
- #
111
- # The method is failed if option processing has already started.
112
- #
113
- if @status != STATUS_YET
114
- set_error(ArgumentError, "argument error")
115
- raise RuntimeError,
116
- "invoke ordering=, but option processing has already started"
117
- end
118
-
119
- #
120
- # Check ordering.
121
- #
122
- if !ORDERINGS.include?(ordering)
123
- raise ArgumentError, "invalid ordering `#{ordering}'"
124
- end
125
- if ordering == PERMUTE && ENV.include?('POSIXLY_CORRECT')
126
- @ordering = REQUIRE_ORDER
127
- else
128
- @ordering = ordering
129
- end
130
- end
131
-
132
- #
133
- # Return ordering.
134
- #
135
- attr_reader :ordering
136
-
137
- #
138
- # Set options
139
- #
140
- def set_options(*arguments)
141
- #
142
- # The method is failed if option processing has already started.
143
- #
144
- if @status != STATUS_YET
145
- raise RuntimeError,
146
- "invoke set_options, but option processing has already started"
147
- end
148
-
149
- #
150
- # Clear tables of option names and argument flags.
151
- #
152
- @canonical_names.clear
153
- @argument_flags.clear
154
-
155
- arguments.each do |arg|
156
- #
157
- # Each argument must be an Array.
158
- #
159
- if !arg.is_a?(Array)
160
- raise ArgumentError, "the option list contains non-Array argument"
161
- end
162
-
163
- #
164
- # Find an argument flag and it set to `argument_flag'.
165
- #
166
- argument_flag = nil
167
- arg.each do |i|
168
- if ARGUMENT_FLAGS.include?(i)
169
- if argument_flag != nil
170
- raise ArgumentError, "too many argument-flags"
171
- end
172
- argument_flag = i
173
- end
174
- end
175
- raise ArgumentError, "no argument-flag" if argument_flag == nil
176
-
177
- canonical_name = nil
178
- arg.each do |i|
179
- #
180
- # Check an option name.
181
- #
182
- next if i == argument_flag
183
- begin
184
- if !i.is_a?(String) || i !~ /^-([^-]|-.+)$/
185
- raise ArgumentError, "an invalid option `#{i}'"
186
- end
187
- if (@canonical_names.include?(i))
188
- raise ArgumentError, "option redefined `#{i}'"
189
- end
190
- rescue
191
- @canonical_names.clear
192
- @argument_flags.clear
193
- raise
194
- end
195
-
196
- #
197
- # Register the option (`i') to the `@canonical_names' and
198
- # `@canonical_names' Hashes.
199
- #
200
- if canonical_name == nil
201
- canonical_name = i
202
- end
203
- @canonical_names[i] = canonical_name
204
- @argument_flags[i] = argument_flag
205
- end
206
- raise ArgumentError, "no option name" if canonical_name == nil
207
- end
208
- return self
209
- end
210
-
211
- #
212
- # Set/Unset `quit' mode.
213
- #
214
- attr_writer :quiet
215
-
216
- #
217
- # Return the flag of `quiet' mode.
218
- #
219
- attr_reader :quiet
220
-
221
- #
222
- # `quiet?' is an alias of `quiet'.
223
- #
224
- alias quiet? quiet
225
-
226
- #
227
- # Termintate option processing.
228
- #
229
- def terminate
230
- return nil if @status == STATUS_TERMINATED
231
- raise RuntimeError, "an error has occured" if @error != nil
232
-
233
- @status = STATUS_TERMINATED
234
- @non_option_arguments.reverse_each do |argument|
235
- @argv.unshift(argument)
236
- end
237
-
238
- @canonical_names = nil
239
- @argument_flags = nil
240
- @rest_singles = nil
241
- @non_option_arguments = nil
242
-
243
- return self
244
- end
245
-
246
- #
247
- # Examine whether option processing is termintated or not.
248
- #
249
- def terminated?
250
- return @status == STATUS_TERMINATED
251
- end
252
-
253
- #
254
- # Set an error (protected).
255
- #
256
- def set_error(type, message)
257
- #$stderr.print("#{$0}: #{message}\n") if !@quiet
258
-
259
- @error = type
260
- @error_message = message
261
- @canonical_names = nil
262
- @argument_flags = nil
263
- @rest_singles = nil
264
- @non_option_arguments = nil
265
-
266
- raise type, message
267
- end
268
- protected :set_error
269
-
270
- #
271
- # Examine whether an option processing is failed.
272
- #
273
- attr_reader :error
274
-
275
- #
276
- # `error?' is an alias of `error'.
277
- #
278
- alias error? error
279
-
280
- #
281
- # Return an error message.
282
- #
283
- def error_message
284
- return @error_message
285
- end
286
-
287
- #
288
- # Get next option name and its argument as an array.
289
- #
290
- def get
291
- option_name, option_argument = nil, ''
292
-
293
- #
294
- # Check status.
295
- #
296
- return nil if @error != nil
297
- case @status
298
- when STATUS_YET
299
- @status = STATUS_STARTED
300
- when STATUS_TERMINATED
301
- return nil
302
- end
303
-
304
- #
305
- # Get next option argument.
306
- #
307
- if 0 < @rest_singles.length
308
- argument = '-' + @rest_singles
309
- elsif (@argv.length == 0)
310
- terminate
311
- return nil
312
- elsif @ordering == PERMUTE
313
- while 0 < @argv.length && @argv[0] !~ /^-./
314
- @non_option_arguments.push(@argv.shift)
315
- end
316
- if @argv.length == 0
317
- terminate
318
- return nil
319
- end
320
- argument = @argv.shift
321
- elsif @ordering == REQUIRE_ORDER
322
- if (@argv[0] !~ /^-./)
323
- terminate
324
- return nil
325
- end
326
- argument = @argv.shift
327
- else
328
- argument = @argv.shift
329
- end
330
-
331
- #
332
- # Check the special argument `--'.
333
- # `--' indicates the end of the option list.
334
- #
335
- if argument == '--' && @rest_singles.length == 0
336
- terminate
337
- return nil
338
- end
339
-
340
- #
341
- # Check for long and short options.
342
- #
343
- if argument =~ /^(--[^=]+)/ && @rest_singles.length == 0
344
- #
345
- # This is a long style option, which start with `--'.
346
- #
347
- pattern = $1
348
- if @canonical_names.include?(pattern)
349
- option_name = pattern
350
- else
351
- #
352
- # The option `option_name' is not registered in `@canonical_names'.
353
- # It may be an abbreviated.
354
- #
355
- match_count = 0
356
- @canonical_names.each_key do |key|
357
- if key.index(pattern) == 0
358
- option_name = key
359
- match_count += 1
360
- end
361
- end
362
- if 2 <= match_count
363
- set_error(AmbigousOption, "option `#{argument}' is ambiguous")
364
- elsif match_count == 0
365
- set_error(InvalidOption, "unrecognized option `#{argument}'")
366
- end
367
- end
368
-
369
- #
370
- # Check an argument to the option.
371
- #
372
- if @argument_flags[option_name] == REQUIRED_ARGUMENT
373
- if argument =~ /=(.*)$/
374
- option_argument = $1
375
- elsif 0 < @argv.length
376
- option_argument = @argv.shift
377
- else
378
- set_error(MissingArgument,
379
- "option `#{argument}' requires an argument")
380
- end
381
- elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
382
- if argument =~ /=(.*)$/
383
- option_argument = $1
384
- elsif 0 < @argv.length && @argv[0] !~ /^-./
385
- option_argument = @argv.shift
386
- else
387
- option_argument = ''
388
- end
389
- elsif argument =~ /=(.*)$/
390
- set_error(NeedlessArgument,
391
- "option `#{option_name}' doesn't allow an argument")
392
- end
393
-
394
- elsif argument =~ /^(-(.))(.*)/
395
- #
396
- # This is a short style option, which start with `-' (not `--').
397
- # Short options may be catinated (e.g. `-l -g' is equivalent to
398
- # `-lg').
399
- #
400
- option_name, ch, @rest_singles = $1, $2, $3
401
-
402
- if @canonical_names.include?(option_name)
403
- #
404
- # The option `option_name' is found in `@canonical_names'.
405
- # Check its argument.
406
- #
407
- if @argument_flags[option_name] == REQUIRED_ARGUMENT
408
- if 0 < @rest_singles.length
409
- option_argument = @rest_singles
410
- @rest_singles = ''
411
- elsif 0 < @argv.length
412
- option_argument = @argv.shift
413
- else
414
- # 1003.2 specifies the format of this message.
415
- set_error(MissingArgument, "option requires an argument -- #{ch}")
416
- end
417
- elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
418
- if 0 < @rest_singles.length
419
- option_argument = @rest_singles
420
- @rest_singles = ''
421
- elsif 0 < @argv.length && @argv[0] !~ /^-./
422
- option_argument = @argv.shift
423
- else
424
- option_argument = ''
425
- end
426
- end
427
- else
428
- #
429
- # This is an invalid option.
430
- # 1003.2 specifies the format of this message.
431
- #
432
- if ENV.include?('POSIXLY_CORRECT')
433
- set_error(InvalidOption, "illegal option -- #{ch}")
434
- else
435
- set_error(InvalidOption, "invalid option -- #{ch}")
436
- end
437
- end
438
- else
439
- #
440
- # This is a non-option argument.
441
- # Only RETURN_IN_ORDER falled into here.
442
- #
443
- return '', argument
444
- end
445
-
446
- return @canonical_names[option_name], option_argument
447
- end
448
-
449
- #
450
- # `get_option' is an alias of `get'.
451
- #
452
- alias get_option get
453
-
454
- #
455
- # Iterator version of `get'.
456
- #
457
- def each
458
- loop do
459
- option_name, option_argument = get_option
460
- break if option_name == nil
461
- yield option_name, option_argument
462
- end
463
- end
464
-
465
- #
466
- # `each_option' is an alias of `each'.
467
- #
468
- alias each_option each
469
- end
470
- end
1
+ # -*- Ruby -*-
2
+ # Copyright (C) 1998, 1999, 2000 Motoyuki Kasahara
3
+ #
4
+ # You may redistribute it and/or modify it under the same license
5
+ # terms as Ruby.
6
+ #
7
+
8
+ #
9
+ # Documents and latest version of `getoptlong.rb' are found at:
10
+ # http://www.sra.co.jp/people/m-kasahr/ruby/getoptlong/
11
+ #
12
+
13
+ #
14
+ # Parse command line options just like GNU getopt_long().
15
+ #
16
+ module Main
17
+ class GetoptLong
18
+ #
19
+ # Orderings.
20
+ #
21
+ ORDERINGS = [REQUIRE_ORDER = 0, PERMUTE = 1, RETURN_IN_ORDER = 2]
22
+
23
+ #
24
+ # Argument flags.
25
+ #
26
+ ARGUMENT_FLAGS = [NO_ARGUMENT = 0, REQUIRED_ARGUMENT = 1,
27
+ OPTIONAL_ARGUMENT = 2]
28
+
29
+ #
30
+ # Status codes.
31
+ #
32
+ STATUS_YET, STATUS_STARTED, STATUS_TERMINATED = 0, 1, 2
33
+
34
+ #
35
+ # Error types.
36
+ #
37
+ class AmbigousOption < StandardError; end
38
+ class NeedlessArgument < StandardError; end
39
+ class MissingArgument < StandardError; end
40
+ class InvalidOption < StandardError; end
41
+
42
+ #
43
+ # Initializer.
44
+ #
45
+ def initialize(argv, *arguments)
46
+ @argv = argv
47
+ #
48
+ # Current ordering.
49
+ #
50
+ if ENV.include?('POSIXLY_CORRECT')
51
+ @ordering = REQUIRE_ORDER
52
+ else
53
+ @ordering = PERMUTE
54
+ end
55
+
56
+ #
57
+ # Hash table of option names.
58
+ # Keyes of the table are option names, and their values are canonical
59
+ # names of the options.
60
+ #
61
+ @canonical_names = Hash.new
62
+
63
+ #
64
+ # Hash table of argument flags.
65
+ # Keyes of the table are option names, and their values are argument
66
+ # flags of the options.
67
+ #
68
+ @argument_flags = Hash.new
69
+
70
+ #
71
+ # Whether error messages are output to stderr.
72
+ #
73
+ @quiet = FALSE
74
+
75
+ #
76
+ # Status code.
77
+ #
78
+ @status = STATUS_YET
79
+
80
+ #
81
+ # Error code.
82
+ #
83
+ @error = nil
84
+
85
+ #
86
+ # Error message.
87
+ #
88
+ @error_message = nil
89
+
90
+ #
91
+ # Rest of catinated short options.
92
+ #
93
+ @rest_singles = ''
94
+
95
+ #
96
+ # List of non-option-arguments.
97
+ # Append them to @argv when option processing is terminated.
98
+ #
99
+ @non_option_arguments = Array.new
100
+
101
+ if 0 < arguments.length
102
+ set_options(*arguments)
103
+ end
104
+ end
105
+
106
+ #
107
+ # Set ordering.
108
+ #
109
+ def ordering=(ordering)
110
+ #
111
+ # The method is failed if option processing has already started.
112
+ #
113
+ if @status != STATUS_YET
114
+ set_error(ArgumentError, "argument error")
115
+ raise RuntimeError,
116
+ "invoke ordering=, but option processing has already started"
117
+ end
118
+
119
+ #
120
+ # Check ordering.
121
+ #
122
+ if !ORDERINGS.include?(ordering)
123
+ raise ArgumentError, "invalid ordering `#{ordering}'"
124
+ end
125
+ if ordering == PERMUTE && ENV.include?('POSIXLY_CORRECT')
126
+ @ordering = REQUIRE_ORDER
127
+ else
128
+ @ordering = ordering
129
+ end
130
+ end
131
+
132
+ #
133
+ # Return ordering.
134
+ #
135
+ attr_reader :ordering
136
+
137
+ #
138
+ # Set options
139
+ #
140
+ def set_options(*arguments)
141
+ #
142
+ # The method is failed if option processing has already started.
143
+ #
144
+ if @status != STATUS_YET
145
+ raise RuntimeError,
146
+ "invoke set_options, but option processing has already started"
147
+ end
148
+
149
+ #
150
+ # Clear tables of option names and argument flags.
151
+ #
152
+ @canonical_names.clear
153
+ @argument_flags.clear
154
+
155
+ arguments.each do |arg|
156
+ #
157
+ # Each argument must be an Array.
158
+ #
159
+ if !arg.is_a?(Array)
160
+ raise ArgumentError, "the option list contains non-Array argument"
161
+ end
162
+
163
+ #
164
+ # Find an argument flag and it set to `argument_flag'.
165
+ #
166
+ argument_flag = nil
167
+ arg.each do |i|
168
+ if ARGUMENT_FLAGS.include?(i)
169
+ if argument_flag != nil
170
+ raise ArgumentError, "too many argument-flags"
171
+ end
172
+ argument_flag = i
173
+ end
174
+ end
175
+ raise ArgumentError, "no argument-flag" if argument_flag == nil
176
+
177
+ canonical_name = nil
178
+ arg.each do |i|
179
+ #
180
+ # Check an option name.
181
+ #
182
+ next if i == argument_flag
183
+ begin
184
+ if !i.is_a?(String) || i !~ /^-([^-]|-.+)$/
185
+ raise ArgumentError, "an invalid option `#{i}'"
186
+ end
187
+ if (@canonical_names.include?(i))
188
+ raise ArgumentError, "option redefined `#{i}'"
189
+ end
190
+ rescue
191
+ @canonical_names.clear
192
+ @argument_flags.clear
193
+ raise
194
+ end
195
+
196
+ #
197
+ # Register the option (`i') to the `@canonical_names' and
198
+ # `@canonical_names' Hashes.
199
+ #
200
+ if canonical_name == nil
201
+ canonical_name = i
202
+ end
203
+ @canonical_names[i] = canonical_name
204
+ @argument_flags[i] = argument_flag
205
+ end
206
+ raise ArgumentError, "no option name" if canonical_name == nil
207
+ end
208
+ return self
209
+ end
210
+
211
+ #
212
+ # Set/Unset `quit' mode.
213
+ #
214
+ attr_writer :quiet
215
+
216
+ #
217
+ # Return the flag of `quiet' mode.
218
+ #
219
+ attr_reader :quiet
220
+
221
+ #
222
+ # `quiet?' is an alias of `quiet'.
223
+ #
224
+ alias quiet? quiet
225
+
226
+ #
227
+ # Termintate option processing.
228
+ #
229
+ def terminate
230
+ return nil if @status == STATUS_TERMINATED
231
+ raise RuntimeError, "an error has occured" if @error != nil
232
+
233
+ @status = STATUS_TERMINATED
234
+ @non_option_arguments.reverse_each do |argument|
235
+ @argv.unshift(argument)
236
+ end
237
+
238
+ @canonical_names = nil
239
+ @argument_flags = nil
240
+ @rest_singles = nil
241
+ @non_option_arguments = nil
242
+
243
+ return self
244
+ end
245
+
246
+ #
247
+ # Examine whether option processing is termintated or not.
248
+ #
249
+ def terminated?
250
+ return @status == STATUS_TERMINATED
251
+ end
252
+
253
+ #
254
+ # Set an error (protected).
255
+ #
256
+ def set_error(type, message)
257
+ #$stderr.print("#{$0}: #{message}\n") if !@quiet
258
+
259
+ @error = type
260
+ @error_message = message
261
+ @canonical_names = nil
262
+ @argument_flags = nil
263
+ @rest_singles = nil
264
+ @non_option_arguments = nil
265
+
266
+ raise type, message
267
+ end
268
+ protected :set_error
269
+
270
+ #
271
+ # Examine whether an option processing is failed.
272
+ #
273
+ attr_reader :error
274
+
275
+ #
276
+ # `error?' is an alias of `error'.
277
+ #
278
+ alias error? error
279
+
280
+ #
281
+ # Return an error message.
282
+ #
283
+ def error_message
284
+ return @error_message
285
+ end
286
+
287
+ #
288
+ # Get next option name and its argument as an array.
289
+ #
290
+ def get
291
+ option_name, option_argument = nil, ''
292
+
293
+ #
294
+ # Check status.
295
+ #
296
+ return nil if @error != nil
297
+ case @status
298
+ when STATUS_YET
299
+ @status = STATUS_STARTED
300
+ when STATUS_TERMINATED
301
+ return nil
302
+ end
303
+
304
+ #
305
+ # Get next option argument.
306
+ #
307
+ if 0 < @rest_singles.length
308
+ argument = '-' + @rest_singles
309
+ elsif (@argv.length == 0)
310
+ terminate
311
+ return nil
312
+ elsif @ordering == PERMUTE
313
+ while 0 < @argv.length && @argv[0] !~ /^-./
314
+ @non_option_arguments.push(@argv.shift)
315
+ end
316
+ if @argv.length == 0
317
+ terminate
318
+ return nil
319
+ end
320
+ argument = @argv.shift
321
+ elsif @ordering == REQUIRE_ORDER
322
+ if (@argv[0] !~ /^-./)
323
+ terminate
324
+ return nil
325
+ end
326
+ argument = @argv.shift
327
+ else
328
+ argument = @argv.shift
329
+ end
330
+
331
+ #
332
+ # Check the special argument `--'.
333
+ # `--' indicates the end of the option list.
334
+ #
335
+ if argument == '--' && @rest_singles.length == 0
336
+ terminate
337
+ return nil
338
+ end
339
+
340
+ #
341
+ # Check for long and short options.
342
+ #
343
+ if argument =~ /^(--[^=]+)/ && @rest_singles.length == 0
344
+ #
345
+ # This is a long style option, which start with `--'.
346
+ #
347
+ pattern = $1
348
+ if @canonical_names.include?(pattern)
349
+ option_name = pattern
350
+ else
351
+ #
352
+ # The option `option_name' is not registered in `@canonical_names'.
353
+ # It may be an abbreviated.
354
+ #
355
+ match_count = 0
356
+ @canonical_names.each_key do |key|
357
+ if key.index(pattern) == 0
358
+ option_name = key
359
+ match_count += 1
360
+ end
361
+ end
362
+ if 2 <= match_count
363
+ set_error(AmbigousOption, "option `#{argument}' is ambiguous")
364
+ elsif match_count == 0
365
+ set_error(InvalidOption, "unrecognized option `#{argument}'")
366
+ end
367
+ end
368
+
369
+ #
370
+ # Check an argument to the option.
371
+ #
372
+ if @argument_flags[option_name] == REQUIRED_ARGUMENT
373
+ if argument =~ /=(.*)$/
374
+ option_argument = $1
375
+ elsif 0 < @argv.length
376
+ option_argument = @argv.shift
377
+ else
378
+ set_error(MissingArgument,
379
+ "option `#{argument}' requires an argument")
380
+ end
381
+ elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
382
+ if argument =~ /=(.*)$/
383
+ option_argument = $1
384
+ elsif 0 < @argv.length && @argv[0] !~ /^-./
385
+ option_argument = @argv.shift
386
+ else
387
+ option_argument = ''
388
+ end
389
+ elsif argument =~ /=(.*)$/
390
+ set_error(NeedlessArgument,
391
+ "option `#{option_name}' doesn't allow an argument")
392
+ end
393
+
394
+ elsif argument =~ /^(-(.))(.*)/
395
+ #
396
+ # This is a short style option, which start with `-' (not `--').
397
+ # Short options may be catinated (e.g. `-l -g' is equivalent to
398
+ # `-lg').
399
+ #
400
+ option_name, ch, @rest_singles = $1, $2, $3
401
+
402
+ if @canonical_names.include?(option_name)
403
+ #
404
+ # The option `option_name' is found in `@canonical_names'.
405
+ # Check its argument.
406
+ #
407
+ if @argument_flags[option_name] == REQUIRED_ARGUMENT
408
+ if 0 < @rest_singles.length
409
+ option_argument = @rest_singles
410
+ @rest_singles = ''
411
+ elsif 0 < @argv.length
412
+ option_argument = @argv.shift
413
+ else
414
+ # 1003.2 specifies the format of this message.
415
+ set_error(MissingArgument, "option requires an argument -- #{ch}")
416
+ end
417
+ elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
418
+ if 0 < @rest_singles.length
419
+ option_argument = @rest_singles
420
+ @rest_singles = ''
421
+ elsif 0 < @argv.length && @argv[0] !~ /^-./
422
+ option_argument = @argv.shift
423
+ else
424
+ option_argument = ''
425
+ end
426
+ end
427
+ else
428
+ #
429
+ # This is an invalid option.
430
+ # 1003.2 specifies the format of this message.
431
+ #
432
+ if ENV.include?('POSIXLY_CORRECT')
433
+ set_error(InvalidOption, "illegal option -- #{ch}")
434
+ else
435
+ set_error(InvalidOption, "invalid option -- #{ch}")
436
+ end
437
+ end
438
+ else
439
+ #
440
+ # This is a non-option argument.
441
+ # Only RETURN_IN_ORDER falled into here.
442
+ #
443
+ return '', argument
444
+ end
445
+
446
+ return @canonical_names[option_name], option_argument
447
+ end
448
+
449
+ #
450
+ # `get_option' is an alias of `get'.
451
+ #
452
+ alias get_option get
453
+
454
+ #
455
+ # Iterator version of `get'.
456
+ #
457
+ def each
458
+ loop do
459
+ option_name, option_argument = get_option
460
+ break if option_name == nil
461
+ yield option_name, option_argument
462
+ end
463
+ end
464
+
465
+ #
466
+ # `each_option' is an alias of `each'.
467
+ #
468
+ alias each_option each
469
+ end
470
+ end