main 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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