kwalify 0.6.1 → 0.7.0

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.
Files changed (219) hide show
  1. data/CHANGES.txt +232 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.txt +16 -19
  4. data/bin/kwalify +3 -3
  5. data/contrib/inline-require +6 -4
  6. data/contrib/kwalify +3719 -2427
  7. data/doc-api/classes/CommandOptionError.html +17 -17
  8. data/doc-api/classes/CommandOptionParser.html +63 -63
  9. data/doc-api/classes/Kwalify.html +29 -7
  10. data/doc-api/classes/Kwalify/AssertionError.html +9 -9
  11. data/doc-api/classes/Kwalify/BaseError.html +72 -71
  12. data/doc-api/classes/Kwalify/BaseParser.html +461 -0
  13. data/doc-api/classes/Kwalify/CommandOptionError.html +11 -11
  14. data/doc-api/classes/Kwalify/ErrorHelper.html +51 -46
  15. data/doc-api/classes/Kwalify/HashInterface.html +13 -135
  16. data/doc-api/classes/Kwalify/Json.html +105 -0
  17. data/doc-api/classes/Kwalify/Main.html +129 -126
  18. data/doc-api/classes/Kwalify/MetaValidator.html +248 -232
  19. data/doc-api/classes/Kwalify/Parser.html +12 -12
  20. data/doc-api/classes/Kwalify/PlainYamlParser.html +166 -163
  21. data/doc-api/classes/Kwalify/PlainYamlParser/Alias.html +11 -11
  22. data/doc-api/classes/Kwalify/Rule.html +152 -130
  23. data/doc-api/classes/Kwalify/SchemaError.html +10 -10
  24. data/doc-api/classes/Kwalify/SyntaxError.html +185 -0
  25. data/doc-api/classes/Kwalify/Types.html +26 -25
  26. data/doc-api/classes/Kwalify/Util.html +389 -0
  27. data/doc-api/classes/Kwalify/Util/HashLike.html +246 -0
  28. data/doc-api/classes/Kwalify/Util/OrderedHash.html +330 -0
  29. data/doc-api/classes/Kwalify/ValidationError.html +10 -10
  30. data/doc-api/classes/Kwalify/Validator.html +153 -86
  31. data/doc-api/classes/Kwalify/Yaml.html +181 -0
  32. data/doc-api/classes/Kwalify/Yaml/Parser.html +1538 -0
  33. data/doc-api/classes/Kwalify/YamlParser.html +190 -183
  34. data/doc-api/classes/Kwalify/YamlSyntaxError.html +8 -57
  35. data/doc-api/created.rid +1 -1
  36. data/doc-api/files/__/README_txt.html +17 -22
  37. data/doc-api/files/kwalify/errors_rb.html +2 -2
  38. data/doc-api/files/kwalify/main_rb.html +4 -3
  39. data/doc-api/files/kwalify/messages_rb.html +2 -2
  40. data/doc-api/files/kwalify/meta-validator_rb.html +3 -3
  41. data/doc-api/files/kwalify/{util/yaml-helper_rb.html → parser/base_rb.html} +8 -6
  42. data/doc-api/files/kwalify/parser/yaml_rb.html +117 -0
  43. data/doc-api/files/kwalify/rule_rb.html +2 -2
  44. data/doc-api/files/kwalify/types_rb.html +2 -2
  45. data/doc-api/files/kwalify/util/assert-text-equal_rb.html +2 -2
  46. data/doc-api/files/kwalify/util/hash-interface_rb.html +9 -2
  47. data/doc-api/files/kwalify/util/hashlike_rb.html +107 -0
  48. data/doc-api/files/kwalify/util/option-parser_rb.html +2 -2
  49. data/doc-api/files/kwalify/util/ordered-hash_rb.html +107 -0
  50. data/doc-api/files/kwalify/util/testcase-helper_rb.html +2 -2
  51. data/doc-api/files/kwalify/util_rb.html +107 -0
  52. data/doc-api/files/kwalify/validator_rb.html +2 -2
  53. data/doc-api/files/kwalify/yaml-parser_rb.html +2 -2
  54. data/doc-api/files/kwalify_rb.html +3 -2
  55. data/doc-api/fr_class_index.html +8 -1
  56. data/doc-api/fr_file_index.html +5 -1
  57. data/doc-api/fr_method_index.html +128 -69
  58. data/doc/img/fig01.png +0 -0
  59. data/doc/users-guide.html +882 -717
  60. data/examples/address-book/address-book.schema.yaml +2 -2
  61. data/examples/data-binding/BABEL.data.yaml +63 -0
  62. data/examples/data-binding/BABEL.schema.yaml +31 -0
  63. data/examples/data-binding/Makefile +8 -0
  64. data/examples/data-binding/Rakefile +13 -0
  65. data/examples/data-binding/main.rb +27 -0
  66. data/examples/invoice/invoice.schema.yaml +3 -3
  67. data/examples/tapkit/tapkit.schema.yaml +2 -2
  68. data/lib/kwalify.rb +41 -4
  69. data/lib/kwalify/errors.rb +118 -96
  70. data/lib/kwalify/kwalify.schema.yaml +58 -0
  71. data/lib/kwalify/main.rb +384 -377
  72. data/lib/kwalify/messages.rb +41 -27
  73. data/lib/kwalify/meta-validator.rb +251 -331
  74. data/lib/kwalify/parser/base.rb +127 -0
  75. data/lib/kwalify/parser/yaml.rb +837 -0
  76. data/lib/kwalify/rule.rb +545 -487
  77. data/lib/kwalify/templates/genclass-java.eruby +189 -162
  78. data/lib/kwalify/templates/genclass-php.eruby +104 -0
  79. data/lib/kwalify/templates/genclass-ruby.eruby +95 -66
  80. data/lib/kwalify/types.rb +107 -106
  81. data/lib/kwalify/util.rb +157 -0
  82. data/lib/kwalify/util/assert-text-equal.rb +33 -31
  83. data/lib/kwalify/util/hash-interface.rb +11 -30
  84. data/lib/kwalify/util/hashlike.rb +51 -0
  85. data/lib/kwalify/util/option-parser.rb +144 -144
  86. data/lib/kwalify/util/ordered-hash.rb +57 -0
  87. data/lib/kwalify/util/testcase-helper.rb +3 -3
  88. data/lib/kwalify/validator.rb +267 -212
  89. data/lib/kwalify/yaml-parser.rb +822 -768
  90. data/setup.rb +861 -607
  91. data/test/Rookbook.yaml +10 -0
  92. data/test/{tmp.dir/Context.java → data/users-guide/AddressBook.java.expected} +11 -11
  93. data/test/data/users-guide/BABEL.data.yaml +24 -0
  94. data/test/data/users-guide/BABEL.schema.yaml +30 -0
  95. data/test/data/users-guide/ExampleAddressBook.java +47 -0
  96. data/test/{tmp.dir/Group.java → data/users-guide/Group.java.expected} +2 -11
  97. data/test/data/users-guide/Person.java.expected +44 -0
  98. data/test/data/users-guide/address_book.rb +52 -0
  99. data/test/data/users-guide/address_book.schema.yaml +28 -0
  100. data/test/data/users-guide/address_book.yaml +27 -0
  101. data/test/data/users-guide/answers-schema.yaml +12 -0
  102. data/test/data/users-guide/answers-validator.rb +52 -0
  103. data/test/data/users-guide/babel_genclass.result +26 -0
  104. data/test/data/users-guide/config.schema.yaml +7 -0
  105. data/test/data/users-guide/config.yaml +4 -0
  106. data/test/{tmp.dir/silent1.document → data/users-guide/document01a.yaml} +0 -0
  107. data/test/data/users-guide/document01b.yaml +3 -0
  108. data/test/data/users-guide/document02a.yaml +4 -0
  109. data/test/data/users-guide/document02b.yaml +4 -0
  110. data/test/data/users-guide/document03a.yaml +6 -0
  111. data/test/data/users-guide/document03b.yaml +6 -0
  112. data/test/data/users-guide/document04a.yaml +9 -0
  113. data/test/data/users-guide/document04b.yaml +9 -0
  114. data/test/data/users-guide/document05a.yaml +11 -0
  115. data/test/data/users-guide/document05b.yaml +12 -0
  116. data/test/data/users-guide/document06a.yaml +15 -0
  117. data/test/data/users-guide/document06b.yaml +16 -0
  118. data/test/data/users-guide/document07a.yaml +9 -0
  119. data/test/data/users-guide/document07b.yaml +7 -0
  120. data/test/data/users-guide/document12a.json +10 -0
  121. data/test/data/users-guide/document12b.json +6 -0
  122. data/test/data/users-guide/document13a.yaml +17 -0
  123. data/test/data/users-guide/document14a.yaml +3 -0
  124. data/test/data/users-guide/document14b.yaml +3 -0
  125. data/test/data/users-guide/document15a.yaml +6 -0
  126. data/test/data/users-guide/document15b.yaml +5 -0
  127. data/test/data/users-guide/example_address_book.rb +10 -0
  128. data/test/data/users-guide/example_address_book_java.result +32 -0
  129. data/test/data/users-guide/example_address_book_ruby.result +31 -0
  130. data/test/data/users-guide/genclass_java.result +4 -0
  131. data/test/data/users-guide/howto-validation-with-parsing.rb +28 -0
  132. data/test/data/users-guide/howto-validation.rb +25 -0
  133. data/test/data/users-guide/howto3.rb +6 -0
  134. data/test/data/users-guide/howto3.result +5 -0
  135. data/test/data/users-guide/howto3.yaml +8 -0
  136. data/test/data/users-guide/howto5_databinding.result +111 -0
  137. data/test/data/users-guide/invalid01.result +3 -0
  138. data/test/data/users-guide/invalid02.result +5 -0
  139. data/test/data/users-guide/invalid03.result +5 -0
  140. data/test/data/users-guide/invalid04.result +4 -0
  141. data/test/data/users-guide/invalid05.result +11 -0
  142. data/test/data/users-guide/invalid06.result +4 -0
  143. data/test/data/users-guide/invalid07.result +3 -0
  144. data/test/data/users-guide/invalid08.result +3 -0
  145. data/test/data/users-guide/invalid12.json +8 -0
  146. data/test/data/users-guide/invalid14.result +4 -0
  147. data/test/data/users-guide/invalid15.result +4 -0
  148. data/test/data/users-guide/loadbabel.rb +27 -0
  149. data/test/data/users-guide/loadconfig.rb +15 -0
  150. data/test/data/users-guide/loadconfig.result +2 -0
  151. data/test/data/users-guide/models.rb +22 -0
  152. data/test/data/users-guide/option_ha.result +6 -0
  153. data/test/data/users-guide/option_ha_genclass_java.result +7 -0
  154. data/test/{tmp.dir/meta1.schema → data/users-guide/schema01.yaml} +0 -0
  155. data/test/data/users-guide/schema02.yaml +12 -0
  156. data/test/data/users-guide/schema03.yaml +9 -0
  157. data/test/data/users-guide/schema04.yaml +20 -0
  158. data/test/data/users-guide/schema05.yaml +29 -0
  159. data/test/data/users-guide/schema06.yaml +11 -0
  160. data/test/data/users-guide/schema12.json +12 -0
  161. data/test/data/users-guide/schema13.yaml +13 -0
  162. data/test/data/users-guide/schema14.yaml +5 -0
  163. data/test/data/users-guide/schema15.yaml +21 -0
  164. data/test/data/users-guide/valid01.result +2 -0
  165. data/test/data/users-guide/valid02.result +2 -0
  166. data/test/data/users-guide/valid03.result +2 -0
  167. data/test/data/users-guide/valid04.result +2 -0
  168. data/test/data/users-guide/valid05.result +2 -0
  169. data/test/data/users-guide/valid06.result +2 -0
  170. data/test/data/users-guide/valid07.result +2 -0
  171. data/test/data/users-guide/valid08.result +2 -0
  172. data/test/data/users-guide/valid12.result +2 -0
  173. data/test/data/users-guide/valid13.result +2 -0
  174. data/test/data/users-guide/valid14.result +2 -0
  175. data/test/data/users-guide/valid15.result +2 -0
  176. data/test/data/users-guide/validate08.rb +37 -0
  177. data/test/test-action.rb +78 -0
  178. data/test/test-action.yaml +738 -0
  179. data/test/test-databinding.rb +80 -0
  180. data/test/test-databinding.yaml +301 -0
  181. data/test/test-main.rb +129 -150
  182. data/test/test-main.yaml +126 -321
  183. data/test/test-metavalidator.rb +47 -47
  184. data/test/test-metavalidator.yaml +77 -21
  185. data/test/test-parser-yaml.rb +57 -0
  186. data/test/test-parser-yaml.yaml +1749 -0
  187. data/test/test-rule.rb +14 -15
  188. data/test/test-rule.yaml +6 -3
  189. data/test/test-users-guide.rb +75 -0
  190. data/test/test-validator.rb +77 -52
  191. data/test/test-validator.yaml +168 -6
  192. data/test/test-yaml-parser.rb +47 -0
  193. data/test/{test-yamlparser.yaml → test-yaml-parser.yaml} +159 -52
  194. data/test/test.rb +37 -21
  195. metadata +136 -37
  196. data/COPYING +0 -340
  197. data/ChangeLog +0 -70
  198. data/doc-api/classes/YamlHelper.html +0 -259
  199. data/lib/kwalify/util/yaml-helper.rb +0 -82
  200. data/test/test-yamlparser.rb +0 -58
  201. data/test/tmp.dir/User.java +0 -43
  202. data/test/tmp.dir/action1.document +0 -18
  203. data/test/tmp.dir/action1.schema +0 -32
  204. data/test/tmp.dir/action2.document +0 -18
  205. data/test/tmp.dir/action2.schema +0 -32
  206. data/test/tmp.dir/emacs.document +0 -6
  207. data/test/tmp.dir/emacs.schema +0 -6
  208. data/test/tmp.dir/meta1.document +0 -0
  209. data/test/tmp.dir/meta2.document +0 -0
  210. data/test/tmp.dir/meta2.schema +0 -3
  211. data/test/tmp.dir/silent1.schema +0 -3
  212. data/test/tmp.dir/silent2.document +0 -7
  213. data/test/tmp.dir/silent2.schema +0 -3
  214. data/test/tmp.dir/stream.invalid +0 -8
  215. data/test/tmp.dir/stream.schema +0 -3
  216. data/test/tmp.dir/stream.valid +0 -8
  217. data/test/tmp.dir/untabify.document +0 -5
  218. data/test/tmp.dir/untabify.schema +0 -10
  219. data/todo.txt +0 -34
@@ -1,7 +1,7 @@
1
1
  ###
2
- ### $Rev: 51 $
3
- ### $Release: 0.6.1 $
4
- ### copyright(c) 2005 kuwata-lab all rights reserved.
2
+ ### $Rev: 83 $
3
+ ### $Release: 0.7.0 $
4
+ ### copyright(c) 2005-2008 kuwata-lab all rights reserved.
5
5
  ###
6
6
 
7
7
  require 'test/unit/testcase'
@@ -10,35 +10,37 @@ require 'tempfile'
10
10
 
11
11
  class Test::Unit::TestCase # :nodoc:
12
12
 
13
- def assert_text_equal(expected, actual, message=nil, options={}) # :nodoc:
14
- diffopt = options[:diffopt] || '-u'
15
- flag_cut = options.key?(:cut) ? options[:key] : true
13
+ def assert_text_equal(expected, actual, message=nil, options={}) # :nodoc:
14
+ expected = expected.to_s
15
+ actual = actual.to_s
16
+ diffopt = options[:diffopt] || '-u'
17
+ flag_cut = options.key?(:cut) ? options[:key] : true
16
18
 
17
- if expected == actual
18
- assert(true)
19
- return
20
- end
21
- if expected[-1] != ?\n || actual[-1] != ?\n
22
- expected += "\n"
23
- actual += "\n"
24
- end
25
- begin
26
- expfile = Tempfile.new(".expected.")
27
- expfile.write(expected); expfile.flush()
28
- actfile = Tempfile.new(".actual.")
29
- actfile.write(actual); actfile.flush()
30
- diff = `diff #{diffopt} #{expfile.path} #{actfile.path}`
31
- ensure
32
- expfile.close(true) if expfile
33
- actfile.close(true) if actfile
34
- end
35
- # cut 1st & 2nd lines
36
- message = (flag_cut ? diff.gsub(/\A.*\n.*\n/, '') : diff) unless message
37
- #raise Test::Unit::AssertionFailedError.new(message)
38
- assert_block(message) { false } # or assert(false, message)
39
- end
19
+ if expected == actual
20
+ assert(true)
21
+ return
22
+ end
23
+ if expected[-1] != ?\n || actual[-1] != ?\n
24
+ expected += "\n"
25
+ actual += "\n"
26
+ end
27
+ begin
28
+ expfile = Tempfile.new(".expected.")
29
+ expfile.write(expected); expfile.flush()
30
+ actfile = Tempfile.new(".actual.")
31
+ actfile.write(actual); actfile.flush()
32
+ diff = `diff #{diffopt} #{expfile.path} #{actfile.path}`
33
+ ensure
34
+ expfile.close(true) if expfile
35
+ actfile.close(true) if actfile
36
+ end
37
+ # cut 1st & 2nd lines
38
+ message = (flag_cut ? diff.gsub(/\A.*\n.*\n/, '') : diff) unless message
39
+ #raise Test::Unit::AssertionFailedError.new(message)
40
+ assert_block(message) { false } # or assert(false, message)
41
+ end
40
42
 
41
- alias assert_equal_with_diff assert_text_equal # for compatibility
42
- alias assert_text_equals assert_text_equal # for typo
43
+ alias assert_equal_with_diff assert_text_equal # for compatibility
44
+ alias assert_text_equals assert_text_equal # for typo
43
45
 
44
46
  end
@@ -1,37 +1,18 @@
1
1
  ###
2
- ### $Rev: 51 $$
3
- ### $Release: 0.6.1 $
4
- ### copyright(c) 2005 kuwata-lab all rights reserved.
2
+ ### $Rev: 88 $$
3
+ ### $Release: 0.7.0 $
4
+ ### copyright(c) 2005-2008 kuwata-lab all rights reserved.
5
5
  ###
6
6
 
7
- module Kwalify
8
-
9
- module HashInterface
10
-
11
- def [](key)
12
- instance_variable_get("@{key}")
13
- end
14
-
15
- def []=(key, val)
16
- instance_variable_set("@{key}", val)
17
- end
7
+ require 'kwalify/util/hashlike'
18
8
 
19
- def keys()
20
- instance_variables.collect { |name| name[1, name.length-1] }
21
- end
22
-
23
- def key?(key)
24
- instance_variables.include?("@#{key}")
25
- end
26
-
27
- def each
28
- instance_variables.each do |name|
29
- key = name[1, name.length-1]
30
- val = instance_varaible_get(name)
31
- yield(key, val)
32
- end
33
- end
9
+ module Kwalify
34
10
 
35
- end
11
+ ##
12
+ ## OBSOLETE: use Hash::Util::HashLike instead.
13
+ ##
14
+ module HashInterface
15
+ include Kwalify::Util::HashLike
16
+ end
36
17
 
37
18
  end
@@ -0,0 +1,51 @@
1
+ ###
2
+ ### $Rev: 89 $
3
+ ### $Release: 0.7.0 $
4
+ ### copyright(c) 2005-2008 kuwata-lab all rights reserved.
5
+ ###
6
+
7
+ module Kwalify
8
+
9
+ module Util
10
+
11
+ ##
12
+ ## add hash-like methods
13
+ ##
14
+ module HashLike
15
+
16
+ def [](key)
17
+ instance_variable_get("@#{key}")
18
+ end
19
+
20
+ def []=(key, val)
21
+ instance_variable_set("@#{key}", val)
22
+ end
23
+
24
+ #--
25
+ #def keys()
26
+ # instance_variables().collect { |name| name[1, name.length-1] }
27
+ #end
28
+ #++
29
+
30
+ def key?(key)
31
+ instance_variables().include?("@#{key}")
32
+ end
33
+ if Object.instance_methods.include?('instance_variable_defined?')
34
+ def key?(key)
35
+ instance_variable_defined?("@#{key}")
36
+ end
37
+ end
38
+
39
+ def each # not necessary
40
+ instance_variables().each do |name|
41
+ key = name[1, name.length-1]
42
+ val = instance_variable_get(name)
43
+ yield(key, val)
44
+ end
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -1,29 +1,29 @@
1
1
  ###
2
- ### $Rev: 51 $
3
- ### $Release: 0.6.1 $
4
- ### copyright(c) 2005 kuwata-lab all rights reserved.
2
+ ### $Rev: 83 $
3
+ ### $Release: 0.7.0 $
4
+ ### copyright(c) 2005-2008 kuwata-lab all rights reserved.
5
5
  ###
6
6
 
7
7
  class CommandOptionError < StandardError
8
- def initialize(option, error_symbol, message=nil)
9
- if !message
10
- case error_symbol
11
- when :no_argument
12
- message = "-%s: argument required." % option
13
- when :unknown_option
14
- message = "-%s: unknown option." % option
15
- when :invalid_property
16
- message = "-%s: invalid property." % option
17
- else
18
- message = "*** internal error(optchar=#{option}, error_symbol=#{error_symbol}) ***"
19
- end
8
+ def initialize(option, error_symbol, message=nil)
9
+ if !message
10
+ case error_symbol
11
+ when :no_argument
12
+ message = "-%s: argument required." % option
13
+ when :unknown_option
14
+ message = "-%s: unknown option." % option
15
+ when :invalid_property
16
+ message = "-%s: invalid property." % option
17
+ else
18
+ message = "*** internal error(optchar=#{option}, error_symbol=#{error_symbol}) ***"
20
19
  end
21
- super(message)
22
- @option = option
23
- @error_symbol = error_symbol
24
- end
20
+ end
21
+ super(message)
22
+ @option = option
23
+ @error_symbol = error_symbol
24
+ end
25
25
 
26
- attr_reader :option, :error_symbol
26
+ attr_reader :option, :error_symbol
27
27
  end
28
28
 
29
29
 
@@ -86,135 +86,135 @@ end
86
86
 
87
87
  class CommandOptionParser
88
88
 
89
- ## arg_none: option string which takes no argument
90
- ## arg_required: option string which takes argument
91
- ## arg_otpional: option string which may takes argument optionally
92
- def initialize(arg_none=nil, arg_required=nil, arg_optional=nil)
93
- @arg_none = arg_none || ""
94
- @arg_required = arg_required || ""
95
- @arg_optional = arg_optional || ""
96
- end
97
-
98
-
99
- def self.to_value(str)
100
- case str
101
- when nil, "null", "nil" ; return nil
102
- when "true", "yes" ; return true
103
- when "false", "no" ; return false
104
- when /\A\d+\z/ ; return str.to_i
105
- when /\A\d+\.\d+\z/ ; return str.to_f
106
- when /\/(.*)\// ; return Regexp.new($1)
107
- when /\A'.*'\z/, /\A".*"\z/ ; return eval(str)
108
- else ; return str
89
+ ## arg_none: option string which takes no argument
90
+ ## arg_required: option string which takes argument
91
+ ## arg_otpional: option string which may takes argument optionally
92
+ def initialize(arg_none=nil, arg_required=nil, arg_optional=nil)
93
+ @arg_none = arg_none || ""
94
+ @arg_required = arg_required || ""
95
+ @arg_optional = arg_optional || ""
96
+ end
97
+
98
+
99
+ def self.to_value(str)
100
+ case str
101
+ when nil, "null", "nil" ; return nil
102
+ when "true", "yes" ; return true
103
+ when "false", "no" ; return false
104
+ when /\A\d+\z/ ; return str.to_i
105
+ when /\A\d+\.\d+\z/ ; return str.to_f
106
+ when /\/(.*)\// ; return Regexp.new($1)
107
+ when /\A'.*'\z/, /\A".*"\z/ ; return eval(str)
108
+ else ; return str
109
+ end
110
+ end
111
+
112
+
113
+ ## argv:: array of string
114
+ ## auto_convert:: if true, convert properties value to int, boolean, string, regexp, ... (default false)
115
+ def parse(argv, auto_convert=false)
116
+ options = {}
117
+ properties = {}
118
+ while argv[0] && argv[0][0] == ?-
119
+ optstr = argv.shift
120
+ optstr = optstr[1, optstr.length-1]
121
+ #
122
+ if optstr[0] == ?- ## property
123
+ unless optstr =~ /\A\-([-\w]+)(?:=(.*))?/
124
+ raise CommandOptionError.new(optstr, :invalid_property)
125
+ end
126
+ prop_name = $1; prop_value = $2
127
+ if auto_convert
128
+ key = prop_name.gsub(/-/, '_').intern
129
+ value = prop_value.nil? ? true : CommandOptionParser.to_value(prop_value)
130
+ properties[key] = value
131
+ else
132
+ properties[prop_name] = prop_value
133
+ end
134
+ #
135
+ else ## options
136
+ while optstr && !optstr.empty?
137
+ optchar = optstr[0]
138
+ optstr[0,1] = ""
139
+ #puts "*** debug: optchar=#{optchar.chr}, optstr=#{optstr.inspect}"
140
+ if @arg_none.include?(optchar)
141
+ options[optchar] = true
142
+ elsif @arg_required.include?(optchar)
143
+ arg = optstr.empty? ? argv.shift : optstr
144
+ raise CommandOptionError.new(optchar.chr, :no_argument) unless arg
145
+ options[optchar] = arg
146
+ optstr = nil
147
+ elsif @arg_optional.include?(optchar)
148
+ arg = optstr.empty? ? true : optstr
149
+ options[optchar] = arg
150
+ optstr = nil
151
+ else
152
+ raise CommandOptionError.new(optchar.chr, :unknown_option)
153
+ end
154
+ end
109
155
  end
110
- end
111
-
112
-
113
- ## argv:: array of string
114
- ## auto_convert:: if true, convert properties value to int, boolean, string, regexp, ... (default false)
115
- def parse(argv, auto_convert=false)
116
- options = {}
117
- properties = {}
118
- while argv[0] && argv[0][0] == ?-
119
- optstr = argv.shift
120
- optstr = optstr[1, optstr.length-1]
121
- #
122
- if optstr[0] == ?- ## property
123
- unless optstr =~ /\A\-([-\w]+)(?:=(.*))?/
124
- raise CommandOptionError.new(optstr, :invalid_property)
125
- end
126
- prop_name = $1; prop_value = $2
127
- if auto_convert
128
- key = prop_name.gsub(/-/, '_').intern
129
- value = prop_value == nil ? true : CommandOptionParser.to_value(prop_value)
130
- properties[key] = value
131
- else
132
- properties[prop_name] = prop_value
133
- end
134
- #
135
- else ## options
136
- while optstr && !optstr.empty?
137
- optchar = optstr[0]
138
- optstr[0,1] = ""
139
- #puts "*** debug: optchar=#{optchar.chr}, optstr=#{optstr.inspect}"
140
- if @arg_none.include?(optchar)
141
- options[optchar] = true
142
- elsif @arg_required.include?(optchar)
143
- arg = optstr.empty? ? argv.shift : optstr
144
- raise CommandOptionError.new(optchar.chr, :no_argument) unless arg
145
- options[optchar] = arg
146
- optstr = nil
147
- elsif @arg_optional.include?(optchar)
148
- arg = optstr.empty? ? true : optstr
149
- options[optchar] = arg
150
- optstr = nil
151
- else
152
- raise CommandOptionError.new(optchar.chr, :unknown_option)
153
- end
154
- end
155
- end
156
- #
157
- end # end of while
158
-
159
- return options, properties
160
- end
156
+ #
157
+ end # end of while
158
+
159
+ return options, properties
160
+ end
161
161
 
162
162
  end
163
163
 
164
164
 
165
165
  if __FILE__ == $0
166
- ## create parser
167
- arg_none = "hv" # ex. -h -v
168
- arg_required = "xf" # ex. -x suffix -f filename
169
- arg_optional = "i" # ex. -i (or -i10)
170
- parser = CommandOptionParser.new(arg_none, arg_required, arg_optional)
171
-
172
- ## parse options
173
- argv = %w[-h -v -f filename -i 10 aaa bbb]
174
- options, properties = parser.parse(argv)
175
- p options #=> { ?h=>true, ?v=>true, ?f=>"filename", ?i=>true }
176
- p argv #=> ["10", "aaa", "bbb"]
177
-
178
- ## parse options #2
179
- argv = %w[-hvx.txt -ffilename -i10 aaa bbb]
180
- options, properties = parser.parse(argv)
181
- p options #=> { ?h=>true, ?v=>true, ?x=>".txt", ?f=>"filename", ?i=>"10" }
182
- p argv #=> ["aaa", "bbb"]
183
-
184
- ## parse properties
185
- argv = %w[-hi --index=10 --user-name=foo --help]
186
- options, properties = parser.parse(argv)
187
- p options #=> {?h=>true, ?i=>true}
188
- p properties #=> {"index"=>"10", "user-name"=>"foo", "help"=>nil}
189
-
190
- ## parse properties with auto-convert
191
- argv = %w[-hi --index=10 --user-name=foo --help]
192
- options, properties = parser.parse(argv, true)
193
- p options #=> {?h=>true, ?i=>true}
194
- p properties #=> {:index=>10, :user_name=>foo, :help=>true}
195
-
196
- ## -a: unknown option.
197
- argv = %w[-abc]
198
- begin
199
- options, properties = parser.parse(argv)
200
- rescue CommandOptionError => ex
201
- $stderr.puts ex.message # -a: unknown option.
202
- end
203
-
204
- ## -f: argument required.
205
- argv = %w[-f]
206
- begin
207
- options, properties = parser.parse(argv)
208
- rescue CommandOptionError => ex
209
- $stderr.puts ex.message # -f: argument required.
210
- end
211
-
212
- ## --@prop=10: invalid property.
213
- argv = %w[--@prop=10]
214
- begin
215
- options, properties = parser.parse(argv)
216
- rescue CommandOptionError => ex
217
- $stderr.puts ex.message # --@prop=10: invalid property.
218
- end
166
+ ## create parser
167
+ arg_none = "hv" # ex. -h -v
168
+ arg_required = "xf" # ex. -x suffix -f filename
169
+ arg_optional = "i" # ex. -i (or -i10)
170
+ parser = CommandOptionParser.new(arg_none, arg_required, arg_optional)
171
+
172
+ ## parse options
173
+ argv = %w[-h -v -f filename -i 10 aaa bbb]
174
+ options, properties = parser.parse(argv)
175
+ p options #=> { ?h=>true, ?v=>true, ?f=>"filename", ?i=>true }
176
+ p argv #=> ["10", "aaa", "bbb"]
177
+
178
+ ## parse options #2
179
+ argv = %w[-hvx.txt -ffilename -i10 aaa bbb]
180
+ options, properties = parser.parse(argv)
181
+ p options #=> { ?h=>true, ?v=>true, ?x=>".txt", ?f=>"filename", ?i=>"10" }
182
+ p argv #=> ["aaa", "bbb"]
183
+
184
+ ## parse properties
185
+ argv = %w[-hi --index=10 --user-name=foo --help]
186
+ options, properties = parser.parse(argv)
187
+ p options #=> {?h=>true, ?i=>true}
188
+ p properties #=> {"index"=>"10", "user-name"=>"foo", "help"=>nil}
189
+
190
+ ## parse properties with auto-convert
191
+ argv = %w[-hi --index=10 --user-name=foo --help]
192
+ options, properties = parser.parse(argv, true)
193
+ p options #=> {?h=>true, ?i=>true}
194
+ p properties #=> {:index=>10, :user_name=>foo, :help=>true}
195
+
196
+ ## -a: unknown option.
197
+ argv = %w[-abc]
198
+ begin
199
+ options, properties = parser.parse(argv)
200
+ rescue CommandOptionError => ex
201
+ $stderr.puts ex.message # -a: unknown option.
202
+ end
203
+
204
+ ## -f: argument required.
205
+ argv = %w[-f]
206
+ begin
207
+ options, properties = parser.parse(argv)
208
+ rescue CommandOptionError => ex
209
+ $stderr.puts ex.message # -f: argument required.
210
+ end
211
+
212
+ ## --@prop=10: invalid property.
213
+ argv = %w[--@prop=10]
214
+ begin
215
+ options, properties = parser.parse(argv)
216
+ rescue CommandOptionError => ex
217
+ $stderr.puts ex.message # --@prop=10: invalid property.
218
+ end
219
219
 
220
220
  end