optiflag 0.6 → 0.6.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. data/ReleaseNotes.txt +35 -0
  2. data/doc/classes/OptiFlag.html +439 -0
  3. data/doc/classes/OptiFlag.src/M000001.html +49 -0
  4. data/doc/classes/OptiFlag.src/M000002.html +49 -0
  5. data/doc/classes/OptiFlag.src/M000003.html +30 -0
  6. data/doc/classes/OptiFlag/Flagset.html +459 -0
  7. data/doc/classes/OptiFlag/Flagset.src/M000003.html +45 -0
  8. data/doc/classes/OptiFlag/Flagset.src/M000004.html +45 -0
  9. data/doc/classes/OptiFlag/Flagset.src/M000005.html +18 -0
  10. data/doc/classes/OptiFlag/Flagset.src/M000006.html +20 -0
  11. data/doc/classes/OptiFlag/Flagset.src/M000007.html +35 -0
  12. data/doc/classes/OptiFlag/Flagset.src/M000008.html +23 -0
  13. data/doc/classes/OptiFlag/Flagset.src/M000009.html +24 -0
  14. data/doc/classes/OptiFlag/Flagset.src/M000010.html +28 -0
  15. data/doc/classes/OptiFlag/Flagset.src/M000011.html +20 -0
  16. data/doc/classes/OptiFlag/Flagset.src/M000012.html +24 -0
  17. data/doc/classes/OptiFlag/Flagset.src/M000013.html +24 -0
  18. data/doc/classes/OptiFlag/Flagset.src/M000014.html +32 -0
  19. data/doc/classes/OptiFlag/Flagset.src/M000015.html +25 -0
  20. data/doc/classes/OptiFlag/Flagset.src/M000016.html +53 -0
  21. data/doc/classes/OptiFlag/Flagset.src/M000017.html +53 -0
  22. data/doc/classes/OptiFlag/Flagset/EachFlag.html +930 -0
  23. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000024.html +36 -0
  24. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000025.html +18 -0
  25. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000026.html +36 -0
  26. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000027.html +36 -0
  27. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000028.html +18 -0
  28. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000029.html +18 -0
  29. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000030.html +19 -0
  30. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000031.html +19 -0
  31. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000032.html +18 -0
  32. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000033.html +18 -0
  33. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000034.html +18 -0
  34. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000035.html +22 -0
  35. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000036.html +19 -0
  36. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000037.html +18 -0
  37. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000038.html +18 -0
  38. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000039.html +18 -0
  39. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000040.html +18 -0
  40. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000041.html +18 -0
  41. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000042.html +18 -0
  42. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000043.html +19 -0
  43. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000044.html +18 -0
  44. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000045.html +19 -0
  45. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000046.html +18 -0
  46. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000047.html +18 -0
  47. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000048.html +18 -0
  48. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000049.html +18 -0
  49. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000050.html +18 -0
  50. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000051.html +18 -0
  51. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000052.html +20 -0
  52. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000053.html +18 -0
  53. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000054.html +18 -0
  54. data/doc/classes/OptiFlag/Flagset/EachFlag.src/M000055.html +22 -0
  55. data/doc/classes/OptiFlag/Flagset/Errors.html +192 -0
  56. data/doc/classes/OptiFlag/Flagset/Errors.src/M000021.html +18 -0
  57. data/doc/classes/OptiFlag/Flagset/Errors.src/M000022.html +19 -0
  58. data/doc/classes/OptiFlag/Flagset/Errors.src/M000023.html +18 -0
  59. data/doc/classes/OptiFlag/Flagset/Errors.src/M000024.html +18 -0
  60. data/doc/classes/OptiFlag/Flagset/Errors.src/M000025.html +19 -0
  61. data/doc/classes/OptiFlag/Flagset/Errors.src/M000026.html +36 -0
  62. data/doc/classes/OptiFlag/Flagset/Help.html +125 -0
  63. data/doc/classes/OptiFlag/Flagset/Help/Bundle.html +160 -0
  64. data/doc/classes/OptiFlag/Flagset/Help/Bundle.src/M000018.html +18 -0
  65. data/doc/classes/OptiFlag/Flagset/Help/Bundle.src/M000019.html +18 -0
  66. data/doc/classes/OptiFlag/Flagset/Help/StandardHelpBundle.html +118 -0
  67. data/doc/classes/OptiFlag/Flagset/NewInterface.html +296 -0
  68. data/doc/classes/OptiFlag/Flagset/NewInterface.src/M000017.html +18 -0
  69. data/doc/classes/OptiFlag/Flagset/NewInterface.src/M000018.html +18 -0
  70. data/doc/classes/OptiFlag/Flagset/NewInterface.src/M000019.html +18 -0
  71. data/doc/classes/OptiFlag/Flagset/NewInterface.src/M000020.html +18 -0
  72. data/doc/classes/OptiFlag/Flagset/NewInterface.src/M000021.html +18 -0
  73. data/doc/classes/OptiFlag/Flagset/NewInterface.src/M000022.html +18 -0
  74. data/doc/classes/OptiFlag/Flagset/NewInterface.src/M000023.html +18 -0
  75. data/doc/created.rid +1 -0
  76. data/doc/files/optiflag-help_rb.html +101 -0
  77. data/doc/files/optiflag-parse_rb.html +101 -0
  78. data/doc/files/optiflag_rb.html +167 -0
  79. data/doc/files/optiflag_rb.src/M000001.html +18 -0
  80. data/doc/fr_class_index.html +34 -0
  81. data/doc/fr_file_index.html +29 -0
  82. data/doc/fr_method_index.html +82 -0
  83. data/doc/index.html +24 -0
  84. data/doc/rdoc-style.css +208 -0
  85. data/examples/example_1.rb +21 -0
  86. data/examples/example_1_1.rb +21 -0
  87. data/{doc/example → examples}/example_1_2.rb +8 -8
  88. data/examples/example_2.rb +31 -0
  89. data/{doc/example → examples}/example_2_1.rb +4 -4
  90. data/{doc/example → examples}/example_2_2.rb +7 -5
  91. data/{doc/example → examples}/example_2_3.rb +9 -9
  92. data/{doc/example → examples}/example_2_4.rb +4 -4
  93. data/{doc/example → examples}/example_2_5.rb +4 -4
  94. data/{doc/example → examples}/example_2_6.rb +6 -6
  95. data/{doc/example → examples}/example_3.rb +7 -6
  96. data/examples/example_6.rb +20 -0
  97. data/{doc/example → examples}/example_7.rb +5 -4
  98. data/examples/example_8.rb +26 -0
  99. data/optiflag-help.rb +42 -0
  100. data/optiflag-parse.rb +281 -0
  101. data/optiflag.gemspec +4 -3
  102. data/optiflag.rb +972 -0
  103. data/quick.rb +12 -0
  104. data/{test → testcases}/tc_advanced_usage_helping.rb +4 -0
  105. data/{test → testcases}/tc_basic_alternate_forms.rb +0 -0
  106. data/{test → testcases}/tc_basic_char_flags.rb +12 -12
  107. data/{test → testcases}/tc_basic_optional_flag.rb +0 -0
  108. data/{test → testcases}/tc_basic_parsing.rb +0 -0
  109. data/{test → testcases}/tc_basic_usage_helping.rb +0 -0
  110. data/{test → testcases}/tc_basic_value_validation.rb +0 -0
  111. data/{test → testcases}/tc_bug_one.rb +0 -0
  112. data/{test → testcases}/tc_bug_two.rb +0 -0
  113. data/{test → testcases}/tc_change_symbols.rb +0 -0
  114. data/{test → testcases}/tc_enumerated_value_validation.rb +0 -0
  115. data/{test → testcases}/tc_flagall.rb +4 -0
  116. data/{test → testcases}/tc_flagless_arg.rb +0 -0
  117. data/{test → testcases}/tc_keyword.rb +0 -0
  118. data/testcases/tc_new_basic_parsing.rb +51 -0
  119. data/testcases/tc_poro_tester.rb +30 -0
  120. data/{test → testcases}/tc_values_as_hash.rb +0 -0
  121. metadata +152 -52
  122. data/doc/example/example_1.rb +0 -30
  123. data/doc/example/example_1_1.rb +0 -27
  124. data/doc/example/example_2.rb +0 -28
  125. data/doc/example/example_4.rb +0 -12
  126. data/doc/example/example_5.rb +0 -26
  127. data/doc/example/example_6.rb +0 -17
  128. data/lib/optiflag.rb +0 -860
@@ -1,27 +0,0 @@
1
- require 'optiflag'
2
-
3
- # Example 1.1:
4
- # Variation 1: add a method 'handle_errors_and_help' to autoparse, check, and augment ARGV
5
- module Example extend OptiFlag::Flagset
6
- flag "dir"
7
- flag "log"
8
- flag "username"
9
- flag "password"
10
-
11
- handle_errors_and_help
12
- end
13
-
14
- # Some code to _use_ the values
15
- puts "User has input:#{ ARGV.flag_value.dir } for dir"
16
- puts "User has input:#{ ARGV.flag_value.log } for log"
17
- puts "User has input:#{ ARGV.flag_value.username } for username"
18
- puts "User has input:#{ ARGV.flag_value.password } for password"
19
-
20
- puts " The variable ARGV has been extend to hold the return variables."
21
-
22
- # Try the following inputs
23
- ## Breaks:
24
- #h# ruby example_1_1.rb
25
- ## Works:
26
- #h# ruby example_1_1.rb -log logdirectory -dir directory -username me -password fluffy
27
- # ruby example_1_1.rb --log logdirectory --dir directory --username me --password fluffy
@@ -1,28 +0,0 @@
1
- require 'optiflag'
2
- $log = "c:/log"
3
-
4
- # Example 2: Adding an optional flag and a usage flag
5
- module Example extend OptiFlag::Flagset
6
- flag "dir"
7
- optional_flag "log"
8
- flag "username"
9
- flag "password"
10
- usage_flag "h","help","?"
11
-
12
- handle_errors_and_help
13
- end
14
-
15
- if ARGV.flag_value.log? # note the question mark '?'
16
- $log = ARGV.flag_value.log
17
- puts "User input: #{ $log } for log via the command-line"
18
- else
19
- puts "User did NOT input log via the command-line"
20
- end
21
-
22
- #h# ruby example_2.rb --dir directory --username me --password fluffy
23
- #h# ruby example_2.rb --dir directory --username me --password fluffy --log c:/tmp/log
24
- # ruby example_2.rb -dir directory -username me -password fluffy -log c:/tmp/log
25
- #h# ruby example_2.rb -h
26
- #h# ruby example_2.rb -?
27
- # ruby example_2.rb -help
28
-
@@ -1,12 +0,0 @@
1
- require 'optiflag'
2
-
3
- # Example 4: Disallowing warnings to proceed
4
- module Example extend OptiFlag::Flagset
5
- flag "dir"
6
- flag "username"
7
- handle_errors_and_help :with_no_warnings
8
- end
9
-
10
- #h# ruby example_4.rb -garbage -dir c:/temp -username daniel -this-is-garbage that.is.left.over
11
-
12
-
@@ -1,26 +0,0 @@
1
- require 'optiflag'
2
-
3
- # Example 5: Using keyword
4
- module Example extend OptiFlag::Flagset
5
- keyword "checkin" do
6
- alternate_forms "ci"
7
- end
8
- keyword "checkout" do
9
- alternate_forms "co"
10
- end
11
- flag "file"
12
- flag "m" do
13
- alternate_forms "message"
14
- end
15
-
16
- handle_errors_and_help
17
- end
18
-
19
- puts "User has chosen to checkin #{ARGV.flag_value.file } " if ARGV.flag_value.ci?
20
- puts "User has chosen to check out #{ARGV.flag_value.file }" if ARGV.flag_value.checkout?
21
-
22
- #h# ruby example_5.rb ci -file c:/StronglyTyped.java -m done
23
- #h# ruby example_5.rb co -file c:/StronglyTyped.java -m done
24
-
25
-
26
-
@@ -1,17 +0,0 @@
1
- require 'optiflag'
2
-
3
- # Example 6: Using Hash Access
4
- module HashAcess extend OptiFlag::Flagset
5
- flag "dir"
6
- flag "log_level"
7
-
8
- handle_errors_and_help
9
- end
10
-
11
- puts "Dir is: #{ ARGV.flag_value[:dir] }"
12
- puts "Log Level is: #{ ARGV.flag_value[:log_level] }"
13
-
14
- #h# ruby example_6.rb -dir "c:/Program Files/Apache Software Foundation/Tomcat 5/" -log_level 3
15
-
16
-
17
-
data/lib/optiflag.rb DELETED
@@ -1,860 +0,0 @@
1
- #
2
- # http://optiflag.rubyforge.org/
3
- #
4
- # Author:: Daniel O. Eklund
5
- # Copyright:: Copyright (c) 2006 Daniel O. Eklund. All rights reserved.
6
- # License:: Ruby license.
7
-
8
- module OptiFlag
9
- VERSION = "0.6"
10
- end
11
-
12
- #------------------------------------------------------------------------------------------
13
- #------------------------------------------------------------------------------------------
14
- #------------------------------------------------------------------------------------------
15
- #------------- Clause-Level Flag-Modifiers via the EachFlag class -----------------------
16
- #------------------------------------------------------------------------------------------
17
- #------------------------------------------------------------------------------------------
18
- #------------------------------------------------------------------------------------------
19
- module OptiFlag
20
- module Flagset
21
- @dash_symbol = "-"
22
- attr_reader :dash_symbol
23
- module_function :dash_symbol
24
- def self.flag_symbol(val)
25
- @dash_symbol = val
26
- end
27
- def self.increment_order_counter()
28
- @counter ||= 0
29
- @counter = @counter + 1
30
- return @counter -1
31
- end
32
- class EachFlag
33
- attr_reader :name, :flag, :ordered_added,
34
- :position_validator,:validation_error,
35
- :position_enumerated_values_validator,:the_pretranslate,:the_posttranslate,
36
- :the_posttranslate_all,:the_pretranslate_all,:enclosing_module,
37
- :the_description,:the_long_dash_symbol,:the_dash_symbol,
38
- :the_arity,:the_long_form,:the_alternate_forms,:the_is_required
39
- attr_writer :the_form_that_is_actually_used
40
- attr_accessor :value,:for_help,:for_extended_help,:proxied_bound_method
41
- def initialize(name,flag,enclosing_module)
42
- # these next two lines are a highly complicated hack needed to make
43
- # the use of two module definitions in one file, one with a flag_symbol
44
- # and one without.. See tc_change_symbols.rb for the two tests that used to
45
- # cause the problem... also see the changes as part of the definition of
46
- # OptiFlag.Flagset().... -- D.O.E 5/30/06
47
- # Search for 'def OptiFlag.Flagset(hash)' in this file
48
- singleton_class_of_enclosing_module = class << enclosing_module; self; end;
49
- x = singleton_class_of_enclosing_module.included_modules.select do |x|
50
- (x.to_s =~ /OptiF/) or (x.to_s =~ /#<Modu/)
51
- end[0]
52
-
53
- @the_compresses,@enclosing_module = false,enclosing_module
54
- @position_validator,@validation_error = [],[]
55
- @position_enumerated_values_validator = []
56
- @ordered_added = OptiFlag::Flagset::increment_order_counter()
57
- @name,@flag,@the_long_form = name,flag,flag
58
- @the_dash_symbol, @the_arity, @the_alternate_forms,
59
- @the_is_required, @the_long_dash_symbol = x.dash_symbol, 1, [], true, "--"
60
- end
61
- # clause-level flag-modifier
62
- def translate(position=0,&theblock)
63
- pretranslate(position,&theblock)
64
- end
65
- # clause-level flag-modifier
66
- def translate_all(&theblock)
67
- pretranslate_all(&theblock)
68
- end
69
- # clause-level flag-modifier
70
- def pretranslate(position=0,&theblock)
71
- @the_pretranslate ||= []
72
- @the_pretranslate[position] = theblock
73
- end
74
- # clause-level flag-modifier
75
- def posttranslate(position=0,&theblock)
76
- @the_posttranslate ||= []
77
- @the_posttranslate[position] = theblock
78
- end
79
- # clause-level flag-modifier
80
- def pretranslate_all(&theblock)
81
- @the_pretranslate_all = theblock
82
- end
83
- # clause-level flag-modifier
84
- def posttranslate_all(&theblock)
85
- @the_posttranslate_all = theblock
86
- end
87
- # clause-level flag-modifier
88
- def is_required(yes_or_no)
89
- @the_is_required = yes_or_no
90
- end
91
- # clause-level flag-modifier
92
- def value_matches(desc_regexp_pair,arg_position=0)
93
- if desc_regexp_pair.class == Regexp
94
- desc_regexp_pair = ["This value does not match the pattern: #{ desc_regexp_pair.source }",
95
- desc_regexp_pair]
96
- end
97
- @position_validator[arg_position] = desc_regexp_pair
98
- end
99
- # clause-level flag-modifier
100
- def value_in_set(array_of_acceptable_values,arg_position=0)
101
- @position_enumerated_values_validator[arg_position] =
102
- array_of_acceptable_values
103
- end
104
- # clause-level flag-modifier
105
- def required
106
- is_required(true)
107
- end
108
- # clause-level flag-modifier
109
- def optional
110
- is_required(false)
111
- end
112
- # clause-level flag-modifier
113
- def no_arg
114
- no_args
115
- end
116
- # clause-level flag-modifier
117
- def no_args
118
- arity 0
119
- end
120
- # clause-level flag-modifier
121
- def one_arg
122
- arity 1
123
- end
124
- # clause-level flag-modifier
125
- def two_args
126
- arity 2
127
- end
128
- # clause-level flag-modifier
129
- def alternate_forms(*args)
130
- @the_alternate_forms = *args
131
- end
132
- # clause-level flag-modifier
133
- def long_form(form)
134
- @the_long_form = form
135
- end
136
- # clause-level flag-modifier
137
- def arity(num)
138
- @the_arity = num
139
- end
140
- # clause-level flag-modifier
141
- def dash_symbol(symb)
142
- @the_dash_symbol = symb
143
- end
144
- # clause-level flag-modifier
145
- def long_dash_symbol(symb)
146
- @the_long_dash_symbol = symb
147
- end
148
- # clause-level flag-modifier
149
- def description(desc)
150
- @the_description = desc
151
- end
152
- # clause-level flag-modifier
153
- def compresses(val=true)
154
- @the_compresses = val
155
- end
156
- def as_string_basic
157
- "#{ self.the_dash_symbol }#{ self.flag }"
158
- end
159
- def as_alternate_forms
160
- ret = @the_alternate_forms.collect do |x|
161
- "#{ self.the_dash_symbol }#{ x }"
162
- end
163
- end
164
- def as_string_extended
165
- "#{ self.the_long_dash_symbol }#{self.the_long_form }"
166
- end
167
- def as_the_form_that_is_actually_used
168
- @the_form_that_is_actually_used
169
- end
170
- def value=(val)
171
- @value = val
172
- if pbMeth = self.proxied_bound_method
173
- pbMeth.call val
174
- end
175
- end
176
- end
177
- end
178
- end
179
-
180
- #----------------------------------------------------------------------------------
181
- #--------------------------------------- -------------------
182
- #--------------------------------------- A clause is the -------------------
183
- #------------- Clause Definitions ----- main statement -------------------
184
- #------------ top-level flag-declarer -- within the module -------------------
185
- #--------------------------------------- -------------------
186
- #----------------------------------------------------------------------------------
187
- module OptiFlag
188
- module Flagset
189
- # top-level flag-declarer
190
- def flag(flag_name_pair,hash={},&the_block)
191
- if flag_name_pair.class == String or flag_name_pair.class == Symbol
192
- flag_name_pair = [flag_name_pair.to_s,flag_name_pair.to_sym]
193
- end
194
- flag = flag_name_pair[0]
195
- if flag_name_pair[1]
196
- name = flag_name_pair[1]
197
- else
198
- name = flag.to_sym
199
- end
200
- @all_flags ||= {}
201
- obj = @all_flags[name]
202
- obj ||= EachFlag.new(name,flag,self)
203
- obj.instance_eval &the_block if block_given?
204
- hash.each_pair do |fxn,val|
205
- obj.send(fxn,val)
206
- end
207
- @all_flags[name] = obj
208
- end
209
- # top-level flag-declarer
210
- def optional_flag(flag_name_pair,hash={},&the_block)
211
- flag(flag_name_pair,hash,&the_block)
212
- flag_name_pair = [flag_name_pair] if flag_name_pair.class == String
213
- name = flag_name_pair[1] || flag_name_pair[0]
214
- flag_properties name.to_sym do
215
- optional
216
- end
217
- end
218
- # top-level flag-declarer
219
- def optional_switch_flag(flag_name_pair,hash={},&the_block)
220
- flag(flag_name_pair,hash,&the_block)
221
- flag_name_pair = [flag_name_pair] if flag_name_pair.class == String
222
- name = flag_name_pair[1] || flag_name_pair[0]
223
- flag_properties name.to_sym do
224
- optional
225
- arity 0
226
- end
227
- end
228
- # top-level flag-declarer
229
- def keyword(flag_name_pair,hash={},&the_block)
230
- @all_keywords ||= []
231
- @all_keywords << name
232
- flag(flag_name_pair,hash,&the_block)
233
- flag_name_pair = [flag_name_pair] if flag_name_pair.class == String
234
- name = flag_name_pair[1] || flag_name_pair[0]
235
- flag_properties name.to_sym do
236
- dash_symbol ""
237
- long_dash_symbol ""
238
- arity 0
239
- optional
240
- end
241
- end
242
- # top-level flag-declarer
243
- def using_object(a_single_object)
244
- potential_methods = (a_single_object.methods - Object.methods)
245
- require 'enumerator'
246
- valid_instance_var = []
247
- potential_opt_switch_flags, potential_methods =
248
- potential_methods.partition {|x| x =~ /\?$/ }
249
- potential_methods.each_slice(2) do |getter,setter|
250
- if setter == (getter + "=")
251
- valid_instance_var << [getter,setter];
252
- end
253
- end
254
- valid_instance_var.each do |getter,setter|
255
- bound_method = a_single_object.method(setter)
256
- flag getter do
257
- self.proxied_bound_method = bound_method
258
- end
259
- end
260
- end
261
- # top-level flag-declarer
262
- def usage_flag(*args)
263
- first,*rest = args
264
- optional_flag [first] do
265
- self.for_help = true
266
- description "Help"
267
- no_args
268
- alternate_forms *rest if rest.length > 0
269
- end
270
- end
271
- # top-level flag-declarer
272
- def extended_help_flag(*args)
273
- first,*rest = args
274
- optional_flag [first] do
275
- self.for_extended_help = true
276
- description "Extended Help"
277
- no_args
278
- alternate_forms *rest if rest.length > 0
279
- end
280
- end
281
- # top-level flag-declarer
282
- def character_flag(switch,group="default",&the_block)
283
- throw "Character switches can only be 1 character long" if switch.to_s.length > 1
284
- flag(switch.to_sym,&the_block)
285
- @group ||= {}
286
- the_flag_we_just_added = @all_flags[switch.to_sym]
287
-
288
- key = [group.to_sym,the_flag_we_just_added.the_dash_symbol]
289
- # puts "#{ key.join(',') }"
290
- @group[key] ||= []
291
- @group[key] << the_flag_we_just_added
292
- # re-assert ourselves
293
- flag [switch.to_s, switch] do
294
- optional
295
- arity 0
296
- compresses
297
- end
298
- end
299
- # top-level flag-declarer
300
- def flag_properties(symb,&the_block)
301
- raise "Block needed for flag_properties" if not block_given?
302
- @all_flags ||= {}
303
- obj = @all_flags[symb.to_sym]
304
- return if obj==nil
305
- obj.instance_eval &the_block if block_given?
306
- end
307
- alias :properties :flag_properties
308
- def argument_order(*args)
309
- puts "You want the arguments in this order: #{ args }"
310
- end
311
- end
312
- end
313
-
314
- # defining the callable client-interface
315
- module OptiFlag
316
- module Flagset
317
- module NewInterface
318
- attr_accessor :errors,:flag_value,:specification_errors,:help_requested_on,:warnings
319
- attr_writer :help_requested,:extended_help_requested
320
- def errors?
321
- self.errors != nil
322
- end
323
- def warnings?
324
- self.warnings != nil
325
- end
326
- def help_requested?
327
- @help_requested != nil
328
- end
329
- def extended_help_requested?
330
- @extended_help_requested !=nil
331
- end
332
- end
333
- class Errors
334
- attr_accessor :missing_flags,:other_errors,:validation_errors
335
- def initialize
336
- @missing_flags,@other_errors,@validation_errors = [],[],[]
337
- end
338
- def any_errors?
339
- @missing_flags.length >0 or @other_errors.length >0 or
340
- @validation_errors.length > 0
341
- end
342
- def divulge_problems(output=$stdout)
343
- output.puts "Errors found:"
344
- if @missing_flags.length >0
345
- output.puts "Missing Flags:"
346
- @missing_flags.each do |x|
347
- output.puts " #{ x }"
348
- end
349
- end
350
- if @other_errors.length >0
351
- output.puts "Other Errors:"
352
- @other_errors.each do |x|
353
- output.puts " #{ x }"
354
- end
355
- end
356
- if @validation_errors.length >0
357
- output.puts "Validation Errors:"
358
- @validation_errors.each do |x|
359
- output.puts " #{ x }"
360
- end
361
- end
362
- end
363
- end
364
- def create_new_value_class()
365
- klass = Hash.new
366
- klass.instance_eval do
367
- def init_with_these(all_objs)
368
- @all_flags = all_objs
369
- end
370
- end
371
- klass.init_with_these(@all_flags)
372
- @all_flags.each_value do |y|
373
- # only allow alphabetic symbols to create methods
374
- if (y.name.to_s =~ /^[a-zA-Z]+/)
375
- klass.instance_eval %{
376
- def #{y.name}()
377
- @all_flags[:#{ y.name }].value if @all_flags[:#{ y.name }]
378
- end
379
- def #{y.name}_details()
380
- @all_flags[:#{ y.name }] if @all_flags[:#{ y.name }]
381
- end}
382
- end
383
- all_names = [y.name]
384
- all_names << y.the_alternate_forms if y.the_alternate_forms.length > 0
385
- all_names.flatten!
386
- all_names = all_names.select{|x| x.to_s =~ /^[a-zA-Z]+/}
387
- all_names.each do |x|
388
- klass.instance_eval %{
389
- def #{x}?()
390
- ret = @all_flags[:#{ y.name }].value
391
- return false if ret == nil
392
- return @all_flags[:#{ y.name }].value if @all_flags[:#{ y.name }]
393
- end}
394
- end
395
- end
396
- return klass
397
- end
398
-
399
- end # end of Flagset module
400
- end # end of OptiFlag module
401
-
402
-
403
- #------------------------------------------------------------------------------------------
404
- #------------------------------------------------------------------------------------------
405
- #------------------------------------------------------------------------------------------
406
- #------------- The actual Parsing and Error Finding Code -----------------------
407
- #------------------------------------------------------------------------------------------
408
- #------------------------------------------------------------------------------------------
409
- #------------------------------------------------------------------------------------------
410
- module OptiFlag
411
- module Flagset
412
- def parse(args,clone=true)
413
- safe_args = args.clone if clone
414
- safe_args = args if ! clone
415
- # the following 10 lines were changed so
416
- # that a module could reparse a command-line
417
- # and not have a global-state change for
418
- # everyone... I had mulled just mandating that
419
- # a SomeArgModule::parse(ARGV) statement
420
- # could only occur once, but since everything else
421
- # is getting ugly, might as well allow this
422
- # --D.O.E 5/30/2006
423
- new_self = self.clone
424
- new_flags = {}
425
- @all_flags.each_pair do |key,val|
426
- val = val.clone
427
- new_flags[key] = val
428
- end
429
- new_self.module_eval do
430
- @all_flags = new_flags
431
- safe_args = search_for_missing_character_switches(safe_args)
432
-
433
- safe_args = create_api(safe_args)
434
-
435
- safe_args = search_for_missing_flags(safe_args)
436
- populate_values(safe_args)
437
- now_populate_hash(@all_flags,safe_args)
438
- end
439
- return safe_args
440
- end
441
-
442
- private
443
- def now_populate_hash(all_flags,safe_args)
444
- all_flags.each_pair do |k,v|
445
- safe_args.flag_value[k.to_sym] = v.value
446
- v.the_alternate_forms.each do |x|
447
- safe_args.flag_value[x.to_sym] = v.value
448
- end
449
- end
450
- end
451
- def find_help_flags(safe_args)
452
- arg_copy = safe_args.clone
453
-
454
- #first we get rid of all non-help flags...
455
- non_help_flags = @all_flags.values.select{|value| !value.for_help }
456
- non_help_flags.each do |val|
457
- flag_finder_and_stripper(val.as_the_form_that_is_actually_used,val.the_arity,arg_copy)
458
- end
459
- # ...because the help flag is overloaded... it can have an arity of 0 or 1
460
- help_flag = @all_flags.values.select{|value| value.for_help }
461
- if help_flag.length > 0
462
- flag = help_flag[0].as_the_form_that_is_actually_used
463
-
464
- found,discard = flag_finder_and_stripper(flag,1,arg_copy)
465
- if found.length > 0
466
- safe_args.help_requested = true
467
- if found.length == 2
468
- safe_args.help_requested_on = found[1]
469
- end
470
- end
471
- end
472
- arg_copy = safe_args.clone
473
-
474
- ext_help_flag = @all_flags.values.select{|value| value.for_extended_help }
475
- if ext_help_flag.length > 0
476
- flag = ext_help_flag[0].as_the_form_that_is_actually_used
477
-
478
- found,discard = flag_finder_and_stripper(flag,0,arg_copy)
479
- if found.length > 0
480
- safe_args.extended_help_requested = true
481
- end
482
- end
483
- end
484
- def flag_finder_and_stripper(flag,arity,args)
485
- idx = args.index(flag)
486
- if idx == nil
487
- return [], args
488
- end
489
- the_range = idx..(idx + arity)
490
- flag_and_values = args[the_range]
491
- fragment = args[the_range].clone
492
- args[the_range] = nil
493
- return fragment, args
494
- end
495
- def populate_values(safe_args)
496
- find_the_flag_that_is_actually_used(safe_args)
497
- arg_copy = safe_args.clone
498
- @all_flags.values.each do |flag_obj|
499
- the_string_flag = flag_obj.as_the_form_that_is_actually_used
500
- flag_and_values, arg_copy =
501
- flag_finder_and_stripper(the_string_flag,flag_obj.the_arity,arg_copy)
502
- if flag_and_values.length >2
503
- discard,*theRest = flag_and_values
504
- flag_obj.value = theRest
505
- end
506
- flag_obj.value = flag_and_values[1] if flag_and_values.length ==2
507
- flag_obj.value = true if flag_and_values.length == 1 and flag_obj.the_arity == 0
508
- if flag_and_values.length == 1 and flag_obj.the_arity >0
509
- problem = "Argument(s) missing for flag #{ flag_obj.as_the_form_that_is_actually_used }"
510
- safe_args.errors ||= Errors.new
511
- safe_args.errors.validation_errors << problem
512
- end
513
- end
514
- if arg_copy.length > 0 # is there anything left over
515
- safe_args.warnings ||= []
516
- safe_args.warnings <<
517
- "There are extra arguments left over: [#{ arg_copy.join(', ') }]. "
518
- end
519
- validate_values(safe_args)
520
- find_help_flags(safe_args)
521
-
522
- return safe_args
523
- end
524
- def validate_values(safe_args)
525
- run_pre_translate(safe_args)
526
- #TODO: the two following helper methods
527
- # are essentially the same... maybe, we can pull the
528
- # logic into the EachFlag object itself...
529
- # something to think about (D.O.E. 5/22/2006)
530
- validate_values_by_regexp(safe_args)
531
- validate_values_by_enumerated_values(safe_args)
532
- run_post_translate(safe_args)
533
- end
534
- def validate_values_by_enumerated_values(safe_args)
535
- flags_requiring_validation = @all_flags.values.select do |x|
536
- x.position_enumerated_values_validator.length > 0 && x.value
537
- end
538
- flags_requiring_validation.each do |flag_obj|
539
- value = flag_obj.value
540
- value = [value] if value.class != Array
541
- flag_obj.position_enumerated_values_validator.each_with_index do |enum_vals,idx|
542
- something_matches = enum_vals.select{|x| x.to_s == value[idx] }
543
- if something_matches.length == 0
544
- problem = "For the flag: '#{ flag_obj.as_string_basic }' the value you gave was '#{ value[idx] }'."
545
- problem << "\n But the value must be one of the following: [#{ enum_vals.join(', ') }]"
546
- flag_obj.validation_error << problem
547
- safe_args.errors ||= Errors.new
548
- safe_args.errors.validation_errors << problem
549
- end
550
- end
551
- end
552
- end
553
- def validate_values_by_regexp(safe_args)
554
- flags_requiring_validation = @all_flags.values.select do |x|
555
- x.position_validator.length > 0 && x.value
556
- end
557
- flags_requiring_validation.each do |flag_obj|
558
- value = flag_obj.value
559
- value = [value] if value.class != Array
560
- flag_obj.position_validator.each_with_index do |(desc,regex),idx|
561
- if ! value[idx].match regex
562
- problem = "For the flag: '#{ flag_obj.as_string_basic }' the value you gave was '#{ value[idx] }'."
563
- problem << "\n #{ desc }"
564
- flag_obj.validation_error << problem
565
- safe_args.errors ||= Errors.new
566
- safe_args.errors.validation_errors << problem
567
- end
568
- end
569
- end
570
- end
571
- def run_pre_translate(safe_args)
572
- flags_requiring_pre_translating = @all_flags.values.select do |x|
573
- x.the_pretranslate && x.value
574
- end
575
- standard_translating(flags_requiring_pre_translating,:the_pretranslate)
576
- end
577
- def run_post_translate(safe_args)
578
- flags_requiring_post_translating = @all_flags.values.select do |x|
579
- x.the_posttranslate && x.value
580
- end
581
- standard_translating(flags_requiring_post_translating,:the_posttranslate)
582
- end
583
- def standard_translating(arr,pre_or_post)
584
- arr.each do |flag|
585
- flag.send(pre_or_post).each_with_index do |translate,idx|
586
- the_value = flag.value
587
- the_value = [the_value] if the_value.class != Array
588
- if translate.arity > 1
589
- retVal = translate.call *the_value
590
- retVal ||= []
591
- retVal = [retVal] if retVal.class !=Array
592
- if retVal.length != translate.arity
593
- raise "Error: the translate block you used had #{ translate.arity } arguments, but your block returned #{ retVal.length } values. They must be equal."
594
- end
595
- flag.value = retVal
596
- elsif translate.arity == 1
597
- retVal = translate.call(the_value[idx])
598
- flag.value[idx] = retVal
599
- end
600
- end
601
- end
602
- end
603
- def find_the_flag_that_is_actually_used(safe_args)
604
- there_might_be_errors = safe_args.errors || Errors.new
605
- args_copy = safe_args.clone
606
- @all_flags.values.each do |x|
607
- shortform,longform = x.as_string_basic,x.as_string_extended
608
- all_forms = [shortform,longform] + x.as_alternate_forms
609
- form_found_mask = all_forms.collect do |form|
610
- is_form_found, args_copy =
611
- flag_finder_and_stripper(form,x.the_arity,args_copy)
612
- [ (is_form_found.length > 0), is_form_found ]
613
- end
614
- any_found = form_found_mask.select{|(found,parms)| found}
615
- if any_found.length > 1
616
- there_might_be_errors.other_errors <<
617
- "More than one flag form of -- is present. This is ambiguous. Choose one only."
618
- end
619
- if any_found.length == 1
620
- x.the_form_that_is_actually_used = any_found[0][1][0]
621
- end
622
- end
623
- if there_might_be_errors.any_errors?
624
- safe_args.errors = there_might_be_errors
625
- end
626
- return safe_args
627
- end
628
- def search_for_missing_character_switches(safe_args)
629
- these_args = safe_args.clone
630
- return safe_args if @group == nil
631
- chars_found_for_this_group = {}
632
- all_chars = ""
633
- @group.each_pair do |k,val|
634
- name_of_flag = val.collect{|x| x.name}
635
- all_chars_alphabetical = name_of_flag.join('').unpack('c*').sort.pack('c*')
636
- args_namespaced = these_args.select{|x| x.match("^#{ k[1] }") }
637
- seems_to_match = []
638
- args_namespaced.each do |flag|
639
- flag_value = flag.match("^#{ k[1]}").post_match
640
- potential = all_chars_alphabetical.tr(flag_value,"")
641
- if potential.length == all_chars_alphabetical.length - flag_value.length
642
- seems_to_match << flag_value
643
- all_chars_alphabetical = all_chars_alphabetical.tr(flag_value,"")
644
- these_args = these_args - [flag]
645
- end
646
- end
647
- seems_to_match = seems_to_match.flatten.join('')
648
- chars_found_for_this_group[k] = seems_to_match
649
- all_chars << seems_to_match
650
- end
651
-
652
- all_chars.split(//).each do |x|
653
- opt_flag = @all_flags[x.to_sym]
654
- opt_flag.value = true
655
- end
656
-
657
- return safe_args
658
- end
659
-
660
- def search_for_missing_flags(safe_args)
661
- there_might_be_errors = Errors.new
662
- required_flags = @all_flags.values.sort{|x,y| x.ordered_added <=> y.ordered_added }.select{|x| x.the_is_required }
663
- args_copy = safe_args.clone
664
- required_flags.each do |x|
665
- shortform,longform = x.as_string_basic,x.as_string_extended
666
- all_forms = [shortform,longform] + x.as_alternate_forms
667
-
668
- form_found_mask = all_forms.collect do |form|
669
- is_form_found, args_copy =
670
- flag_finder_and_stripper(form,x.the_arity,args_copy)
671
- [ (is_form_found.length > 0), is_form_found ]
672
- end
673
- is_first_found,is_second_found = form_found_mask
674
- any_found = form_found_mask.select{|(found,parms)| found}
675
- if any_found.length == 0
676
- there_might_be_errors.missing_flags << x.as_string_basic
677
- end
678
- if is_second_found[0] && is_first_found[0]
679
- there_might_be_errors.other_errors <<
680
- "Both forms #{ x.as_string_basic } and #{x.as_string_extended } are present. This is ambiguous. Choose one only."
681
- end
682
- if any_found.length == 1
683
- x.the_form_that_is_actually_used = any_found[0][1][0]
684
- end
685
- end
686
- if there_might_be_errors.any_errors?
687
- safe_args.errors = there_might_be_errors
688
- end
689
- return safe_args
690
- end
691
- def create_api(safe_args)
692
-
693
- safe_args.extend NewInterface
694
- safe_args.flag_value = create_new_value_class()
695
- return safe_args
696
- end
697
- end
698
- end
699
-
700
- module OptiFlag
701
- def OptiFlag.Flagset(hash)
702
- # changed this from just returning Flagset...
703
- # Reason Being: a user can specify two modules in one file
704
- # one with this method, and one just using Flagset...
705
- # if you don't clone at this point, you are left with
706
- # a global change... BUT to get the cloning working
707
- # I had to do some singleton_class trickeration as part of
708
- # the initialize method for EachFlag... I am not
709
- # 100% sure I understand what I just did. -- D.O.E 5/30/06
710
- mod = Flagset.clone
711
- hash.each_pair do |symb,val|
712
- mod.send(symb.to_sym,val)
713
- end
714
- return mod
715
- end
716
-
717
- end
718
-
719
- module OptiFlag
720
- module Flagset
721
- def handle_errors_and_help(level=:not_strict)
722
- return if !@all_flags
723
- parse(ARGV,false)
724
- if ARGV.help_requested?
725
- if !ARGV.help_requested_on
726
- show_help
727
- elsif the_on = ARGV.help_requested_on
728
- show_individual_extended_help(the_on.to_sym)
729
- end
730
- exit
731
- end
732
- if ARGV.extended_help_requested?
733
- show_extended_help
734
- exit
735
- end
736
- if ARGV.errors?
737
- ARGV.errors.divulge_problems
738
- show_help
739
- exit
740
- end
741
- if ARGV.warnings? and level == :with_no_warnings
742
- puts "In strict warning handling mode. Warnings will cause process to exit."
743
- ARGV.warnings.each do |x|
744
- puts " #{ x }"
745
- end
746
- puts "Please fix these warnings and try again."
747
- exit
748
- end
749
- ARGV
750
- end # end of method handle_errors_and_help
751
- end # end of Flagset
752
- end # end of OptiFlag
753
-
754
-
755
-
756
- # Specification error possibilities (at FlagsetDefinition)
757
- # 1) a value_matches and a value_in_set on the same argument
758
- # 2) ambiguous flag names (e.g. two flags both with name -help)
759
- # 3) short symbol flag and long symbol flags match each other
760
-
761
- # Specification error possibilities (at DefinitionSwitcher)
762
- # 1)
763
- # 2)
764
-
765
- # Warning conditions
766
- # 1) Left-over arguments
767
-
768
-
769
- #---------------------------------------------------------------------------------------------------------------
770
- #---------------------------------------------------------------------------------------------------------------
771
- #---------------------------------------------------------------------------------------------------------------
772
- #---------------------------------- help and error rendering stuff --------------------------------------------
773
- #---------------------------------------------------------------------------------------------------------------
774
- #---------------------------------------------------------------------------------------------------------------
775
- #---------------------------------------------------------------------------------------------------------------
776
- module OptiFlag
777
- module Flagset
778
- module Help
779
- class Bundle
780
- attr_accessor :help,:extended_help,:banner;
781
- end
782
- module StandardHelpBundle
783
- STANDARD_HELP_BANNER = proc do |render_on|
784
- render_on.printf(" %-10s %-15s %5s\n","Flag","Name","Is Required?")
785
- end
786
- STANDARD_HELP = proc do |render_on,short,long,dash_short,dash_long,required_or_not,description|
787
- render_on.printf(" #{ dash_short }%-10s %-15s %5s\n",
788
- short,short,required_or_not)
789
- end
790
- STANDARD_EXTENDED_HELP = proc do |render_on,short,long,dash_short,dash_long,required_or_not,description,arity,alternate_forms,name|
791
- render_on.puts "--------------------------------"
792
- desc = <<-EOF
793
- Name: #{ name }
794
- Simple Flag: #{ dash_short }#{ short }
795
- Required?: #{ required_or_not }
796
- # of Arguments: #{ (arity > 0) ? arity : 'None' }
797
- EOF
798
- desc << <<-EOF if description
799
- Description: #{ description }
800
- EOF
801
- desc << <<-EOF if long
802
- Long Form Flag: #{ dash_long }#{ long }
803
- EOF
804
- desc << <<-EOF if alternate_forms.length > 0
805
- Alternate Flags: #{ dash_short }[#{ alternate_forms.join(', ') }]
806
- EOF
807
- render_on.puts desc
808
- end
809
- end
810
- end
811
- end
812
- end
813
-
814
-
815
- module OptiFlag
816
- module Flagset
817
- attr_accessor :registered_help,:help_banner,:registered_extended_help;
818
- def register_bundle(bundle)
819
- self.registered_extended_help = bundle.extended_help
820
- self.registered_help = bundle.help
821
- self.help_banner = bundle.banner
822
- end
823
-
824
- def registered_help; Help::StandardHelpBundle::STANDARD_HELP; end
825
- def registered_extended_help; Help::StandardHelpBundle::STANDARD_EXTENDED_HELP; end
826
- def help_banner; Help::StandardHelpBundle::STANDARD_HELP_BANNER; end
827
-
828
- def render_help(stdo=$stdout)
829
- help = self.registered_help
830
- help_banner = self.help_banner
831
-
832
- help_banner.call stdo
833
- @all_flags.each_pair do |key,val|
834
- help.call stdo,val.flag,val.the_long_form,val.the_dash_symbol,val.the_long_dash_symbol,val.the_is_required,val.the_description
835
- end
836
- end
837
- def show_help(start_message="",stdo=$stdout)
838
- stdo.puts start_message
839
- render_help(stdo)
840
- @all_keywords ||= []
841
- @all_keywords.each do |x|
842
- stdo.puts "Flagless Argument: #{ x }"
843
- end
844
- end
845
- def show_extended_help(start_message="",stdo=$stdout)
846
- show_help(start_message,stdo)
847
- @all_flags.keys.each do |name|
848
- show_individual_extended_help(name,stdo)
849
- end
850
- end
851
- def show_individual_extended_help(name,stdo=$stdout)
852
- x = @all_flags[name]
853
- return if !x
854
- extended_help = self.registered_extended_help
855
- extended_help.call stdo, x.flag, x.the_long_form,x.the_dash_symbol,x.the_long_dash_symbol,
856
- x.the_is_required,x.the_description,x.the_arity,x.the_alternate_forms,x.name
857
- end
858
- end
859
- end
860
-