main 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,74 @@
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 'true'
19
+ true
20
+ when 'false'
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 :uri do |obj|
44
+ require 'uri'
45
+ ::URI.parse obj.to_s
46
+ end
47
+
48
+ cast :list do |*objs|
49
+ [*objs].flatten.join(',').split(/,/)
50
+ end
51
+
52
+ List.dup.each do |type|
53
+ next if type.to_s == 'list'
54
+ m = "list_of_#{ type }"
55
+ define_method m do |*objs|
56
+ list(*objs).map{|obj| send type, obj}
57
+ end
58
+ export m
59
+ List << m
60
+ end
61
+
62
+ def self.[] sym
63
+ prefix = sym.to_s.downcase.to_sym
64
+ candidates = List.select{|m| m =~ %r/^#{ prefix }/i}
65
+ m = candidates.shift
66
+ raise ArgumentError, "unsupported cast: #{ sym.inspect } (#{ List.join ',' })" unless
67
+ m
68
+ raise ArgumentError, "ambiguous cast: #{ sym.inspect } (#{ List.join ',' })" unless
69
+ candidates.empty? or m.to_s == sym.to_s
70
+ this = self
71
+ lambda{|obj| method(m).call obj}
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,15 @@
1
+ module Main
2
+ def self.new *a, &b
3
+ m = Class.new Base
4
+ m.default_options!
5
+ m.class_eval &b if b
6
+ m.new
7
+ end
8
+
9
+ module ::Kernel
10
+ def Main *a, &b
11
+ ::Main.new(*a, &b).__run__
12
+ end
13
+ alias_method 'main', 'Main'
14
+ end
15
+ end
@@ -0,0 +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