ddao-kwalify 0.7.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.
Files changed (208) hide show
  1. data/CHANGES.txt +243 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.txt +61 -0
  4. data/bin/kwalify +13 -0
  5. data/contrib/inline-require +153 -0
  6. data/contrib/kwalify +4159 -0
  7. data/doc-api/classes/CommandOptionError.html +184 -0
  8. data/doc-api/classes/CommandOptionParser.html +325 -0
  9. data/doc-api/classes/Kwalify.html +292 -0
  10. data/doc-api/classes/Kwalify/AssertionError.html +148 -0
  11. data/doc-api/classes/Kwalify/BaseError.html +297 -0
  12. data/doc-api/classes/Kwalify/BaseParser.html +461 -0
  13. data/doc-api/classes/Kwalify/CommandOptionError.html +168 -0
  14. data/doc-api/classes/Kwalify/ErrorHelper.html +223 -0
  15. data/doc-api/classes/Kwalify/HashInterface.html +118 -0
  16. data/doc-api/classes/Kwalify/Json.html +105 -0
  17. data/doc-api/classes/Kwalify/KwalifyError.html +111 -0
  18. data/doc-api/classes/Kwalify/Main.html +339 -0
  19. data/doc-api/classes/Kwalify/MetaValidator.html +448 -0
  20. data/doc-api/classes/Kwalify/Parser.html +155 -0
  21. data/doc-api/classes/Kwalify/PlainYamlParser.html +523 -0
  22. data/doc-api/classes/Kwalify/PlainYamlParser/Alias.html +165 -0
  23. data/doc-api/classes/Kwalify/Rule.html +433 -0
  24. data/doc-api/classes/Kwalify/SchemaError.html +148 -0
  25. data/doc-api/classes/Kwalify/SyntaxError.html +185 -0
  26. data/doc-api/classes/Kwalify/Types.html +302 -0
  27. data/doc-api/classes/Kwalify/Util.html +389 -0
  28. data/doc-api/classes/Kwalify/Util/HashLike.html +246 -0
  29. data/doc-api/classes/Kwalify/Util/OrderedHash.html +330 -0
  30. data/doc-api/classes/Kwalify/ValidationError.html +148 -0
  31. data/doc-api/classes/Kwalify/Validator.html +381 -0
  32. data/doc-api/classes/Kwalify/Yaml.html +194 -0
  33. data/doc-api/classes/Kwalify/Yaml/Parser.html +1538 -0
  34. data/doc-api/classes/Kwalify/YamlParser.html +542 -0
  35. data/doc-api/classes/Kwalify/YamlSyntaxError.html +119 -0
  36. data/doc-api/classes/Test.html +107 -0
  37. data/doc-api/classes/Test/Unit.html +101 -0
  38. data/doc-api/created.rid +1 -0
  39. data/doc-api/files/__/README_txt.html +172 -0
  40. data/doc-api/files/kwalify/errors_rb.html +114 -0
  41. data/doc-api/files/kwalify/main_rb.html +118 -0
  42. data/doc-api/files/kwalify/messages_rb.html +107 -0
  43. data/doc-api/files/kwalify/meta-validator_rb.html +117 -0
  44. data/doc-api/files/kwalify/parser/base_rb.html +116 -0
  45. data/doc-api/files/kwalify/parser/yaml_rb.html +117 -0
  46. data/doc-api/files/kwalify/rule_rb.html +116 -0
  47. data/doc-api/files/kwalify/types_rb.html +114 -0
  48. data/doc-api/files/kwalify/util/assert-text-equal_rb.html +115 -0
  49. data/doc-api/files/kwalify/util/hash-interface_rb.html +114 -0
  50. data/doc-api/files/kwalify/util/hashlike_rb.html +107 -0
  51. data/doc-api/files/kwalify/util/option-parser_rb.html +107 -0
  52. data/doc-api/files/kwalify/util/ordered-hash_rb.html +107 -0
  53. data/doc-api/files/kwalify/util/testcase-helper_rb.html +115 -0
  54. data/doc-api/files/kwalify/util_rb.html +107 -0
  55. data/doc-api/files/kwalify/validator_rb.html +117 -0
  56. data/doc-api/files/kwalify/yaml-parser_rb.html +117 -0
  57. data/doc-api/files/kwalify_rb.html +121 -0
  58. data/doc-api/fr_class_index.html +57 -0
  59. data/doc-api/fr_file_index.html +45 -0
  60. data/doc-api/fr_method_index.html +168 -0
  61. data/doc-api/index.html +24 -0
  62. data/doc-api/rdoc-style.css +208 -0
  63. data/doc/docstyle.css +188 -0
  64. data/doc/img/fig01.png +0 -0
  65. data/doc/users-guide.html +2050 -0
  66. data/examples/address-book/Makefile +10 -0
  67. data/examples/address-book/address-book.schema.yaml +45 -0
  68. data/examples/address-book/address-book.yaml +36 -0
  69. data/examples/data-binding/BABEL.data.yaml +63 -0
  70. data/examples/data-binding/BABEL.schema.yaml +31 -0
  71. data/examples/data-binding/Makefile +8 -0
  72. data/examples/data-binding/Rakefile +13 -0
  73. data/examples/data-binding/main.rb +27 -0
  74. data/examples/invoice/Makefile +9 -0
  75. data/examples/invoice/invoice.schema.yaml +43 -0
  76. data/examples/invoice/invoice.yaml +32 -0
  77. data/examples/tapkit/Makefile +10 -0
  78. data/examples/tapkit/main.rb +7 -0
  79. data/examples/tapkit/tapkit.schema.yaml +146 -0
  80. data/examples/tapkit/tapkit.yaml +85 -0
  81. data/lib/kwalify.rb +67 -0
  82. data/lib/kwalify/errors.rb +128 -0
  83. data/lib/kwalify/kwalify.schema.yaml +58 -0
  84. data/lib/kwalify/main.rb +442 -0
  85. data/lib/kwalify/messages.rb +173 -0
  86. data/lib/kwalify/meta-validator.rb +276 -0
  87. data/lib/kwalify/parser/base.rb +127 -0
  88. data/lib/kwalify/parser/yaml.rb +841 -0
  89. data/lib/kwalify/rule.rb +560 -0
  90. data/lib/kwalify/templates/genclass-java.eruby +222 -0
  91. data/lib/kwalify/templates/genclass-php.eruby +104 -0
  92. data/lib/kwalify/templates/genclass-ruby.eruby +113 -0
  93. data/lib/kwalify/types.rb +156 -0
  94. data/lib/kwalify/util.rb +157 -0
  95. data/lib/kwalify/util/assert-text-equal.rb +46 -0
  96. data/lib/kwalify/util/hash-interface.rb +18 -0
  97. data/lib/kwalify/util/hashlike.rb +51 -0
  98. data/lib/kwalify/util/option-parser.rb +220 -0
  99. data/lib/kwalify/util/ordered-hash.rb +57 -0
  100. data/lib/kwalify/util/testcase-helper.rb +112 -0
  101. data/lib/kwalify/validator.rb +282 -0
  102. data/lib/kwalify/yaml-parser.rb +870 -0
  103. data/setup.rb +1585 -0
  104. data/test/Rookbook.yaml +10 -0
  105. data/test/data/users-guide/AddressBook.java.expected +40 -0
  106. data/test/data/users-guide/BABEL.data.yaml +24 -0
  107. data/test/data/users-guide/BABEL.schema.yaml +30 -0
  108. data/test/data/users-guide/ExampleAddressBook.java +47 -0
  109. data/test/data/users-guide/Group.java.expected +24 -0
  110. data/test/data/users-guide/Person.java.expected +44 -0
  111. data/test/data/users-guide/address_book.rb +52 -0
  112. data/test/data/users-guide/address_book.schema.yaml +28 -0
  113. data/test/data/users-guide/address_book.yaml +27 -0
  114. data/test/data/users-guide/answers-schema.yaml +12 -0
  115. data/test/data/users-guide/answers-validator.rb +52 -0
  116. data/test/data/users-guide/babel_genclass.result +26 -0
  117. data/test/data/users-guide/config.schema.yaml +7 -0
  118. data/test/data/users-guide/config.yaml +4 -0
  119. data/test/data/users-guide/document01a.yaml +3 -0
  120. data/test/data/users-guide/document01b.yaml +3 -0
  121. data/test/data/users-guide/document02a.yaml +4 -0
  122. data/test/data/users-guide/document02b.yaml +4 -0
  123. data/test/data/users-guide/document03a.yaml +6 -0
  124. data/test/data/users-guide/document03b.yaml +6 -0
  125. data/test/data/users-guide/document04a.yaml +9 -0
  126. data/test/data/users-guide/document04b.yaml +9 -0
  127. data/test/data/users-guide/document05a.yaml +11 -0
  128. data/test/data/users-guide/document05b.yaml +12 -0
  129. data/test/data/users-guide/document06a.yaml +15 -0
  130. data/test/data/users-guide/document06b.yaml +16 -0
  131. data/test/data/users-guide/document07a.yaml +9 -0
  132. data/test/data/users-guide/document07b.yaml +7 -0
  133. data/test/data/users-guide/document12a.json +10 -0
  134. data/test/data/users-guide/document12b.json +6 -0
  135. data/test/data/users-guide/document13a.yaml +17 -0
  136. data/test/data/users-guide/document14a.yaml +3 -0
  137. data/test/data/users-guide/document14b.yaml +3 -0
  138. data/test/data/users-guide/document15a.yaml +6 -0
  139. data/test/data/users-guide/document15b.yaml +5 -0
  140. data/test/data/users-guide/example_address_book.rb +10 -0
  141. data/test/data/users-guide/example_address_book_java.result +32 -0
  142. data/test/data/users-guide/example_address_book_ruby.result +31 -0
  143. data/test/data/users-guide/genclass_java.result +4 -0
  144. data/test/data/users-guide/howto-validation-with-parsing.rb +28 -0
  145. data/test/data/users-guide/howto-validation.rb +25 -0
  146. data/test/data/users-guide/howto3.rb +6 -0
  147. data/test/data/users-guide/howto3.result +5 -0
  148. data/test/data/users-guide/howto3.yaml +8 -0
  149. data/test/data/users-guide/howto5_databinding.result +111 -0
  150. data/test/data/users-guide/invalid01.result +3 -0
  151. data/test/data/users-guide/invalid02.result +5 -0
  152. data/test/data/users-guide/invalid03.result +5 -0
  153. data/test/data/users-guide/invalid04.result +4 -0
  154. data/test/data/users-guide/invalid05.result +11 -0
  155. data/test/data/users-guide/invalid06.result +4 -0
  156. data/test/data/users-guide/invalid07.result +3 -0
  157. data/test/data/users-guide/invalid08.result +3 -0
  158. data/test/data/users-guide/invalid12.json +8 -0
  159. data/test/data/users-guide/invalid14.result +4 -0
  160. data/test/data/users-guide/invalid15.result +4 -0
  161. data/test/data/users-guide/loadbabel.rb +27 -0
  162. data/test/data/users-guide/loadconfig.rb +16 -0
  163. data/test/data/users-guide/loadconfig.result +6 -0
  164. data/test/data/users-guide/models.rb +22 -0
  165. data/test/data/users-guide/option_ha.result +6 -0
  166. data/test/data/users-guide/option_ha_genclass_java.result +7 -0
  167. data/test/data/users-guide/schema01.yaml +3 -0
  168. data/test/data/users-guide/schema02.yaml +12 -0
  169. data/test/data/users-guide/schema03.yaml +9 -0
  170. data/test/data/users-guide/schema04.yaml +20 -0
  171. data/test/data/users-guide/schema05.yaml +29 -0
  172. data/test/data/users-guide/schema06.yaml +11 -0
  173. data/test/data/users-guide/schema12.json +12 -0
  174. data/test/data/users-guide/schema13.yaml +13 -0
  175. data/test/data/users-guide/schema14.yaml +5 -0
  176. data/test/data/users-guide/schema15.yaml +21 -0
  177. data/test/data/users-guide/valid01.result +2 -0
  178. data/test/data/users-guide/valid02.result +2 -0
  179. data/test/data/users-guide/valid03.result +2 -0
  180. data/test/data/users-guide/valid04.result +2 -0
  181. data/test/data/users-guide/valid05.result +2 -0
  182. data/test/data/users-guide/valid06.result +2 -0
  183. data/test/data/users-guide/valid07.result +2 -0
  184. data/test/data/users-guide/valid08.result +2 -0
  185. data/test/data/users-guide/valid12.result +2 -0
  186. data/test/data/users-guide/valid13.result +2 -0
  187. data/test/data/users-guide/valid14.result +2 -0
  188. data/test/data/users-guide/valid15.result +2 -0
  189. data/test/data/users-guide/validate08.rb +37 -0
  190. data/test/test-action.rb +78 -0
  191. data/test/test-action.yaml +738 -0
  192. data/test/test-databinding.rb +83 -0
  193. data/test/test-databinding.yaml +339 -0
  194. data/test/test-main.rb +157 -0
  195. data/test/test-main.yaml +384 -0
  196. data/test/test-metavalidator.rb +80 -0
  197. data/test/test-metavalidator.yaml +1179 -0
  198. data/test/test-parser-yaml.rb +57 -0
  199. data/test/test-parser-yaml.yaml +1749 -0
  200. data/test/test-rule.rb +26 -0
  201. data/test/test-rule.yaml +317 -0
  202. data/test/test-users-guide.rb +75 -0
  203. data/test/test-validator.rb +95 -0
  204. data/test/test-validator.yaml +986 -0
  205. data/test/test-yaml-parser.rb +47 -0
  206. data/test/test-yaml-parser.yaml +1226 -0
  207. data/test/test.rb +60 -0
  208. metadata +261 -0
@@ -0,0 +1,173 @@
1
+ ###
2
+ ### $Rev: 95 $
3
+ ### $Release: 0.7.1 $
4
+ ### copyright(c) 2005-2008 kuwata-lab all rights reserved.
5
+ ###
6
+
7
+ module Kwalify
8
+
9
+ @@messages = {}
10
+
11
+ def self.msg(key)
12
+ return @@messages[key]
13
+ end
14
+
15
+
16
+
17
+ @@messages[:command_help] = <<END
18
+ kwalify - schema validator and data binding tool for YAML and JSON
19
+ ## Usage1: validate yaml document
20
+ kwalify [..options..] -f schema.yaml doc.yaml [doc2.yaml ...]
21
+ ## Usage2: validate schema definition
22
+ kwalify [..options..] -m schema.yaml [schema2.yaml ...]
23
+ ## Usage3: do action
24
+ kwalify [..options..] -a action -f schema.yaml [schema2.yaml ...]
25
+ -h, --help : help
26
+ -v : version
27
+ -q : quiet
28
+ -s : silent (obsolete, use '-q' instead)
29
+ -f schema.yaml : schema definition file
30
+ -m : meta-validation mode
31
+ -t : expand tab characters
32
+ -l : show linenumber when errored (experimental)
33
+ -E : show errors in emacs-style (experimental, implies '-l')
34
+ -a action : action ('genclass-ruby', 'genclass-php', 'genclass-java')
35
+ (try '-ha genclass-ruby' for details)
36
+ -I path : template path (for '-a')
37
+ -P : allow preceding alias
38
+ END
39
+ # -z : syntax checking of schema file
40
+ # -I path : path for template of action
41
+
42
+
43
+
44
+ ##----- begin
45
+ # filename: lib/kwalify/main.rb
46
+ @@messages[:command_option_actionnoschema] = "schema filename is not specified."
47
+ @@messages[:command_option_noaction] = "command-line option '-f' or '-m' required."
48
+ @@messages[:command_option_notemplate] = "%s: invalid action (template not found).\n"
49
+ @@messages[:schema_empty] = "%s: empty schema.\n"
50
+ @@messages[:validation_empty] = "%s#%d: empty."
51
+ @@messages[:validation_empty] = "%s#%d: empty.\n"
52
+ @@messages[:validation_valid] = "%s#%d: valid."
53
+ @@messages[:command_option_schema_required] = "-%s: schema filename required."
54
+ @@messages[:command_option_action_required] = "-%s: action required."
55
+ @@messages[:command_option_tpath_required] = "-%s: template path required."
56
+ @@messages[:command_property_invalid] = "%s: invalid property."
57
+ @@messages[:command_option_invalid] = "-%s: invalid command option."
58
+ # --
59
+ # filename: lib/kwalify/rule.rb
60
+ @@messages[:schema_notmap] = "schema definition is not a mapping."
61
+ @@messages[:key_unknown] = "unknown key."
62
+ @@messages[:type_notstr] = "not a string."
63
+ @@messages[:type_unknown] = "unknown type."
64
+ @@messages[:class_notmap] = "available only with map type."
65
+ @@messages[:required_notbool] = "not a boolean."
66
+ @@messages[:pattern_notstr] = "not a string (or regexp)"
67
+ @@messages[:pattern_notmatch] = "should be '/..../'."
68
+ @@messages[:pattern_syntaxerr] = "has regexp error."
69
+ @@messages[:enum_notseq] = "not a sequence."
70
+ @@messages[:enum_notscalar] = "not available with seq or map."
71
+ @@messages[:enum_type_unmatch] = "%s type expected."
72
+ @@messages[:enum_duplicate] = "duplicated enum value."
73
+ @@messages[:assert_notstr] = "not a string."
74
+ @@messages[:assert_noval] = "'val' is not used."
75
+ @@messages[:assert_syntaxerr] = "expression syntax error."
76
+ @@messages[:range_notmap] = "not a mapping."
77
+ @@messages[:range_notscalar] = "is available only with scalar type."
78
+ @@messages[:range_type_unmatch] = "not a %s."
79
+ @@messages[:range_undefined] = "undefined key."
80
+ @@messages[:range_twomax] = "both 'max' and 'max-ex' are not available at once."
81
+ @@messages[:range_twomin] = "both 'min' and 'min-ex' are not available at once."
82
+ @@messages[:range_maxltmin] = "max '%s' is less than min '%s'."
83
+ @@messages[:range_maxleminex] = "max '%s' is less than or equal to min-ex '%s'."
84
+ @@messages[:range_maxexlemin] = "max-ex '%s' is less than or equal to min '%s'."
85
+ @@messages[:range_maxexleminex] = "max-ex '%s' is less than or equal to min-ex '%s'."
86
+ @@messages[:length_notmap] = "not a mapping."
87
+ @@messages[:length_nottext] = "is available only with string or text."
88
+ @@messages[:length_notint] = "not an integer."
89
+ @@messages[:length_undefined] = "undefined key."
90
+ @@messages[:length_twomax] = "both 'max' and 'max-ex' are not available at once."
91
+ @@messages[:length_twomin] = "both 'min' and 'min-ex' are not available at once."
92
+ @@messages[:length_maxltmin] = "max '%s' is less than min '%s'."
93
+ @@messages[:length_maxleminex] = "max '%s' is less than or equal to min-ex '%s'."
94
+ @@messages[:length_maxexlemin] = "max-ex '%s' is less than or equal to min '%s'."
95
+ @@messages[:length_maxexleminex] = "max-ex '%s' is less than or equal to min-ex '%s'."
96
+ @@messages[:ident_notbool] = "not a boolean."
97
+ @@messages[:ident_notscalar] = "is available only with a scalar type."
98
+ @@messages[:ident_onroot] = "is not available on root element."
99
+ @@messages[:ident_notmap] = "is available only with an element of mapping."
100
+ @@messages[:unique_notbool] = "not a boolean."
101
+ @@messages[:unique_notscalar] = "is available only with a scalar type."
102
+ @@messages[:unique_onroot] = "is not available on root element."
103
+ @@messages[:default_nonscalarval] = "not a scalar."
104
+ @@messages[:default_notscalar] = "is available only with a scalar type."
105
+ @@messages[:default_unmatch] = "not a %s."
106
+ @@messages[:sequence_notseq] = "not a sequence."
107
+ @@messages[:sequence_noelem] = "required one element."
108
+ @@messages[:sequence_toomany] = "required just one element."
109
+ @@messages[:mapping_notmap] = "not a mapping."
110
+ @@messages[:mapping_noelem] = "required at least one element."
111
+ @@messages[:seq_nosequence] = "type 'seq' requires 'sequence:'."
112
+ @@messages[:seq_conflict] = "not available with sequence."
113
+ @@messages[:map_nomapping] = "type 'map' requires 'mapping:'."
114
+ @@messages[:map_conflict] = "not available with mapping."
115
+ @@messages[:scalar_conflict] = "not available with scalar type."
116
+ @@messages[:enum_conflict] = "not available with 'enum:'."
117
+ @@messages[:default_conflict] = "not available when 'required:' is true."
118
+ # --
119
+ # filename: lib/kwalify/validator.rb
120
+ @@messages[:required_novalue] = "value required but none."
121
+ @@messages[:type_unmatch] = "not a %s."
122
+ @@messages[:key_undefined] = "key '%s' is undefined."
123
+ @@messages[:required_nokey] = "key '%s:' is required."
124
+ @@messages[:value_notunique] = "is already used at '%s'."
125
+ @@messages[:assert_failed] = "assertion expression failed (%s)."
126
+ @@messages[:enum_notexist] = "invalid %s value."
127
+ @@messages[:pattern_unmatch] = "not matched to pattern %s."
128
+ @@messages[:range_toolarge] = "too large (> max %s)."
129
+ @@messages[:range_toosmall] = "too small (< min %s)."
130
+ @@messages[:range_toolargeex] = "too large (>= max %s)."
131
+ @@messages[:range_toosmallex] = "too small (<= min %s)."
132
+ @@messages[:length_toolong] = "too long (length %d > max %d)."
133
+ @@messages[:length_tooshort] = "too short (length %d < min %d)."
134
+ @@messages[:length_toolongex] = "too long (length %d >= max %d)."
135
+ @@messages[:length_tooshortex] = "too short (length %d <= min %d)."
136
+ # --
137
+ # filename: lib/kwalify/yaml-parser.rb
138
+ @@messages[:flow_hastail] = "flow style sequence is closed but got '%s'."
139
+ @@messages[:flow_eof] = "found EOF when parsing flow style."
140
+ @@messages[:flow_alias_label] = "alias name expected."
141
+ @@messages[:flow_anchor_label] = "anchor name expected."
142
+ @@messages[:flow_noseqitem] = "sequence item required (or last comma is extra)."
143
+ @@messages[:flow_seqnotclosed] = "flow style sequence requires ']'."
144
+ @@messages[:flow_mapnoitem] = "mapping item required (or last comma is extra)."
145
+ @@messages[:flow_mapnotclosed] = "flow style mapping requires '}'."
146
+ @@messages[:flow_nocolon] = "':' expected but got %s."
147
+ @@messages[:flow_str_notclosed] = "%s: string not closed."
148
+ @@messages[:anchor_duplicated] = "anchor '%s' is already used."
149
+ @@messages[:alias_extradata] = "alias cannot take any data."
150
+ @@messages[:anchor_notfound] = "anchor '%s' not found"
151
+ @@messages[:sequence_noitem] = "sequence item is expected."
152
+ @@messages[:sequence_badindent] = "illegal indent of sequence."
153
+ @@messages[:mapping_noitem] = "mapping item is expected."
154
+ @@messages[:mapping_badindent] = "illegal indent of mapping."
155
+ # --
156
+ ##----- end
157
+
158
+
159
+
160
+
161
+ @@words = {}
162
+
163
+ def self.word(key)
164
+ return @@words[key] || key
165
+ end
166
+
167
+ @@words['str'] = 'string'
168
+ @@words['int'] = 'integer'
169
+ @@words['bool'] = 'boolean'
170
+ @@words['seq'] = 'sequence'
171
+ @@words['map'] = 'mapping'
172
+
173
+ end
@@ -0,0 +1,276 @@
1
+ ###
2
+ ### $Rev: 95 $
3
+ ### $Release: 0.7.1 $
4
+ ### copyright(c) 2005-2008 kuwata-lab all rights reserved.
5
+ ###
6
+
7
+ require 'kwalify/errors'
8
+ require 'kwalify/rule'
9
+ require 'kwalify/validator'
10
+ require 'kwalify/parser/yaml'
11
+ #require 'yaml'
12
+
13
+ module Kwalify
14
+
15
+
16
+ ##
17
+ ## ex.
18
+ ## meta_validator = Kwalify::MetaValidator.instance()
19
+ ## schema = File.load_file('schema.yaml')
20
+ ## errors = meta_validator.validate(schema)
21
+ ## if !errors.empty?
22
+ ## errors.each do |error|
23
+ ## puts "[#{error.path}] #{error.message}"
24
+ ## end
25
+ ## end
26
+ ##
27
+ class MetaValidator < Validator
28
+
29
+ filename = File.join(File.dirname(__FILE__), 'kwalify.schema.yaml')
30
+ META_SCHEMA = File.read(filename)
31
+ @instance = nil
32
+
33
+ def self.instance()
34
+ unless @instance
35
+ schema = Kwalify::Yaml::Parser.new().parse(META_SCHEMA)
36
+ @instance = MetaValidator.new(schema)
37
+ end
38
+ return @instance
39
+ end
40
+
41
+ def initialize(schema, &block)
42
+ super
43
+ end
44
+
45
+ def validate_hook(value, rule, path, errors)
46
+ return if value.nil? ## realy?
47
+ return unless rule.name == "MAIN"
48
+ #
49
+ hash = value
50
+ type = hash['type']
51
+ type = Types::DEFAULT_TYPE if type.nil?
52
+ klass = Types.type_class(type)
53
+ #unless klass
54
+ # errors << validate_error(:type_unknown, rule, "#{path}/type", type)
55
+ #end
56
+ #
57
+ if hash.key?('class')
58
+ val = hash['class']
59
+ unless val.nil? || type == 'map'
60
+ errors << validate_error(:class_notmap, rule, "#{path}/class", 'class:')
61
+ end
62
+ end
63
+ #
64
+ if hash.key?('pattern')
65
+ val = hash['pattern']
66
+ pat = (val =~ /\A\/(.*)\/([mi]?[mi]?)\z/ ? $1 : val)
67
+ begin
68
+ Regexp.compile(pat)
69
+ rescue RegexpError => ex
70
+ errors << validate_error(:pattern_syntaxerr, rule, "#{path}/pattern", val)
71
+ end
72
+ end
73
+ #
74
+ if hash.key?('enum')
75
+ if Types.collection_type?(type)
76
+ errors << validate_error(:enum_notscalar, rule, path, 'enum:')
77
+ else
78
+ #elem_table = {}
79
+ hash['enum'].each do |elem|
80
+ #if elem_table[elem]
81
+ # errors << validate_error(:enum_duplicate, rule, "#{path}/enum", elem.to_s)
82
+ #end
83
+ #elem_table[elem] = true
84
+ unless elem.is_a?(klass)
85
+ errors << validate_error(:enum_type_unmatch, rule, "#{path}/enum", elem, [Kwalify.word(type)])
86
+ end
87
+ end
88
+ end
89
+ end
90
+ #
91
+ if hash.key?('assert')
92
+ val = hash['assert']
93
+ #val =~ /\bval\b/ or errors << validate_error(:assert_noval, rule, "#{path}/assert", val)
94
+ begin
95
+ eval "proc { |val| #{val} }"
96
+ rescue ::SyntaxError => ex
97
+ errors << validate_error(:assert_syntaxerr, rule, "#{path}/assert", val)
98
+ end
99
+ end
100
+ #
101
+ if hash.key?('range')
102
+ val = hash['range']
103
+ curr_path = path + "/range"
104
+ #if ! val.is_a?(Hash)
105
+ # errors << validate_error(:range_notmap, rule, curr_path, val)
106
+ #elsif ...
107
+ if Types.collection_type?(type) || type == 'bool' || type == 'any'
108
+ errors << validate_error(:range_notscalar, rule, path, 'range:')
109
+ else
110
+ val.each do |rkey, rval|
111
+ #case rkey
112
+ #when 'max', 'min', 'max-ex', 'min-ex'
113
+ unless rval.is_a?(klass)
114
+ typename = Kwalify.word(type) || type
115
+ errors << validate_error(:range_type_unmatch, rule, "#{curr_path}/#{rkey}", rval, [typename])
116
+ end
117
+ #else
118
+ # errors << validate_error(:range_undefined, rule, curr_path, "#{rkey}:")
119
+ #end
120
+ end
121
+ end
122
+ if val.key?('max') && val.key?('max-ex')
123
+ errors << validate_error(:range_twomax, rule, curr_path, nil)
124
+ end
125
+ if val.key?('min') && val.key?('min-ex')
126
+ errors << validate_error(:range_twomin, rule, curr_path, nil)
127
+ end
128
+ max, min, max_ex, min_ex = val['max'], val['min'], val['max-ex'], val['min-ex']
129
+ if max
130
+ if min && max < min
131
+ errors << validate_error(:range_maxltmin, rule, curr_path, nil, [max, min])
132
+ elsif min_ex && max <= min_ex
133
+ errors << validate_error(:range_maxleminex, rule, curr_path, nil, [max, min_ex])
134
+ end
135
+ elsif max_ex
136
+ if min && max_ex <= min
137
+ errors << validate_error(:range_maxexlemin, rule, curr_path, nil, [max_ex, min])
138
+ elsif min_ex && max_ex <= min_ex
139
+ errors << validate_error(:range_maxexleminex, rule, curr_path, nil, [max_ex, min_ex])
140
+ end
141
+ end
142
+ end
143
+ #
144
+ if hash.key?('length')
145
+ val = hash['length']
146
+ curr_path = path + "/length"
147
+ #val.is_a?(Hash) or errors << validate_error(:length_notmap, rule, curr_path, val)
148
+ unless type == 'str' || type == 'text'
149
+ errors << validate_error(:length_nottext, rule, path, 'length:')
150
+ end
151
+ #val.each do |lkey, lval|
152
+ # #case lkey
153
+ # #when 'max', 'min', 'max-ex', 'min-ex'
154
+ # unless lval.is_a?(Integer)
155
+ # errors << validate_error(:length_notint, rule, "#{curr_path}/#{lkey}", lval)
156
+ # end
157
+ # #else
158
+ # # errors << validate_error(:length_undefined, rule, curr_path, "#{lkey}:")
159
+ # #end
160
+ #end
161
+ if val.key?('max') && val.key?('max-ex')
162
+ errors << validate_error(:length_twomax, rule, curr_path, nil)
163
+ end
164
+ if val.key?('min') && val.key?('min-ex')
165
+ errors << validate_error(:length_twomin, rule, curr_path, nil)
166
+ end
167
+ max, min, max_ex, min_ex = val['max'], val['min'], val['max-ex'], val['min-ex']
168
+ if max
169
+ if min && max < min
170
+ errors << validate_error(:length_maxltmin, rule, curr_path, nil, [max, min])
171
+ elsif min_ex && max <= min_ex
172
+ errors << validate_error(:length_maxleminex, rule, curr_path, nil, [max, min_ex])
173
+ end
174
+ elsif max_ex
175
+ if min && max_ex <= min
176
+ errors << validate_error(:length_maxexlemin, rule, curr_path, nil, [max_ex, min])
177
+ elsif min_ex && max_ex <= min_ex
178
+ errors << validate_error(:length_maxexleminex, rule, curr_path, nil, [max_ex, min_ex])
179
+ end
180
+ end
181
+ end
182
+ #
183
+ if hash.key?('unique')
184
+ if hash['unique'] && Types.collection_type?(type)
185
+ errors << validate_error(:unique_notscalar, rule, path, "unique:")
186
+ end
187
+ if path.empty?
188
+ errors << validate_error(:unique_onroot, rule, "/", "unique:")
189
+ end
190
+ end
191
+ #
192
+ if hash.key?('ident')
193
+ if hash['ident'] && Types.collection_type?(type)
194
+ errors << validate_error(:ident_notscalar, rule, path, "ident:")
195
+ end
196
+ if path.empty?
197
+ errors << validate_error(:ident_onroot, rule, "/", "ident:")
198
+ end
199
+ end
200
+ #
201
+ if hash.key?('default')
202
+ val = hash['default']
203
+ if Types.collection_type?(type)
204
+ errors << validate_error(:default_notscalar, rule, path, "default:")
205
+ elsif !val.nil? && !val.is_a?(klass)
206
+ errors << validate_error(:default_unmatch, rule, "#{path}/default", val, [Kwalify.word(type)])
207
+ end
208
+ end
209
+ #
210
+ if hash.key?('sequence')
211
+ val = hash['sequence']
212
+ #if !val.nil? && !val.is_a?(Array)
213
+ # errors << validate_error(:sequence_notseq, rule, "#{path}/sequence", val)
214
+ #elsif ...
215
+ if val.nil? || val.empty?
216
+ errors << validate_error(:sequence_noelem, rule, "#{path}/sequence", val)
217
+ elsif val.length > 1
218
+ errors << validate_error(:sequence_toomany, rule, "#{path}/sequence", val)
219
+ else
220
+ elem = val[0]
221
+ assert_error("elem.class=#{elem.class}") unless elem.is_a?(Hash)
222
+ if elem['ident'] && elem['type'] != 'map'
223
+ errors << validate_error(:ident_notmap, nil, "#{path}/sequence/0", 'ident:')
224
+ end
225
+ end
226
+ end
227
+ #
228
+ if hash.key?('mapping')
229
+ val = hash['mapping']
230
+ if !val.nil? && !val.is_a?(Hash)
231
+ errors << validate_error(:mapping_notmap, rule, "#{path}/mapping", val)
232
+ elsif val.nil? || (val.empty? && !val.default)
233
+ errors << validate_error(:mapping_noelem, rule, "#{path}/mapping", val)
234
+ end
235
+ end
236
+ #
237
+ if type == 'seq'
238
+ errors << validate_error(:seq_nosequence, rule, path, nil) unless hash.key?('sequence')
239
+ #errors << validate_error(:seq_conflict, rule, path, 'enum:') if hash.key?('enum')
240
+ errors << validate_error(:seq_conflict, rule, path, 'pattern:') if hash.key?('pattern')
241
+ errors << validate_error(:seq_conflict, rule, path, 'mapping:') if hash.key?('mapping')
242
+ #errors << validate_error(:seq_conflict, rule, path, 'range:') if hash.key?('range')
243
+ #errors << validate_error(:seq_conflict, rule, path, 'length:') if hash.key?('length')
244
+ elsif type == 'map'
245
+ errors << validate_error(:map_nomapping, rule, path, nil) unless hash.key?('mapping')
246
+ #errors << validate_error(:map_conflict, rule, path, 'enum:') if hash.key?('enum')
247
+ errors << validate_error(:map_conflict, rule, path, 'pattern:') if hash.key?('pattern')
248
+ errors << validate_error(:map_conflict, rule, path, 'sequence:') if hash.key?('sequence')
249
+ #errors << validate_error(:map_conflict, rule, path, 'range:') if hash.key?('range')
250
+ #errors << validate_error(:map_conflict, rule, path, 'length:') if hash.key?('length')
251
+ else
252
+ errors << validate_error(:scalar_conflict, rule, path, 'sequence:') if hash.key?('sequence')
253
+ errors << validate_error(:scalar_conflict, rule, path, 'mapping:') if hash.key?('mapping')
254
+ if hash.key?('enum')
255
+ errors << validate_error(:enum_conflict, rule, path, 'range:') if hash.key?('range')
256
+ errors << validate_error(:enum_conflict, rule, path, 'length:') if hash.key?('length')
257
+ errors << validate_error(:enum_conflict, rule, path, 'pattern:') if hash.key?('pattern')
258
+ end
259
+ if hash.key?('default')
260
+ errors << validate_error(:default_conflict, rule, path, 'default:') if hash['required']
261
+ end
262
+ end
263
+
264
+ end # end of def validate_hook()
265
+
266
+
267
+ end # end of class MetaValidator
268
+
269
+
270
+ META_VALIDATOR = MetaValidator.instance()
271
+
272
+ def self.meta_validator # obsolete
273
+ return META_VALIDATOR
274
+ end
275
+
276
+ end
@@ -0,0 +1,127 @@
1
+ ###
2
+ ### $Rev: 92 $
3
+ ### $Release: 0.7.1 $
4
+ ### copyright(c) 2005-2008 kuwata-lab all rights reserved.
5
+ ###
6
+
7
+ require 'strscan'
8
+ require 'kwalify/errors'
9
+ require 'kwalify/util'
10
+
11
+
12
+ ##
13
+ ## base class for Yaml::Parser
14
+ ##
15
+ class Kwalify::BaseParser
16
+
17
+
18
+ def reset(input, filename=nil, untabify=false)
19
+ input = Kwalify::Util.untabify(input) if untabify
20
+ @scanner = StringScanner.new(input)
21
+ @filename = filename
22
+ @linenum = 1
23
+ @column = 1
24
+ end
25
+ attr_reader :filename, :linenum, :column
26
+
27
+
28
+ def scan(regexp)
29
+ ret = @scanner.scan(regexp)
30
+ return nil if ret.nil?
31
+ _set_column_and_linenum(ret)
32
+ return ret
33
+ end
34
+
35
+
36
+ def _set_column_and_linenum(s)
37
+ pos = s.rindex(?\n)
38
+ if pos
39
+ @column = s.length - pos
40
+ @linenum += s.count("\n")
41
+ else
42
+ @column += s.length
43
+ end
44
+ end
45
+
46
+
47
+ def match?(regexp)
48
+ return @scanner.match?(regexp)
49
+ end
50
+
51
+
52
+ def group(n)
53
+ return @scanner[n]
54
+ end
55
+
56
+
57
+ def eos?
58
+ return @scanner.eos?
59
+ end
60
+
61
+
62
+ def peep(n=1)
63
+ return @scanner.peek(n)
64
+ end
65
+
66
+
67
+ def _getch
68
+ ch = @scanner.getch()
69
+ if ch == "\n"
70
+ @linenum += 1
71
+ @column = 0
72
+ else
73
+ @column += 1
74
+ end
75
+ return ch
76
+ end
77
+
78
+
79
+ CHAR_TABLE = { "\""=>"\"", "\\"=>"\\", "n"=>"\n", "r"=>"\r", "t"=>"\t", "b"=>"\b" }
80
+
81
+ def scan_string
82
+ ch = _getch()
83
+ ch == '"' || ch == "'" or raise "assertion error"
84
+ endch = ch
85
+ s = ''
86
+ while !(ch = _getch()).nil? && ch != endch
87
+ if ch != '\\'
88
+ s << ch
89
+ elsif (ch = _getch()).nil?
90
+ raise _syntax_error("%s: string is not closed." % (endch == '"' ? "'\"'" : '"\'"'))
91
+ elsif endch == '"'
92
+ if CHAR_TABLE.key?(ch)
93
+ s << CHAR_TABLE[ch]
94
+ elsif ch == 'u'
95
+ ch2 = scan(/(?:[0-9a-f][0-9a-f]){1,4}/)
96
+ unless ch2
97
+ raise _syntax_error("\\x: invalid unicode format.")
98
+ end
99
+ s << [ch2.hex].pack('U*')
100
+ elsif ch == 'x'
101
+ ch2 = scan(/[0-9a-zA-Z][0-9a-zA-Z]/)
102
+ unless ch2
103
+ raise _syntax_error("\\x: invalid binary format.")
104
+ end
105
+ s << [ch2].pack('H2')
106
+ else
107
+ s << "\\" << ch
108
+ end
109
+ elsif endch == "'"
110
+ ch == '\'' || ch == '\\' ? s << ch : s << '\\' << ch
111
+ else
112
+ raise "unreachable"
113
+ end
114
+ end
115
+ #_getch()
116
+ return s
117
+ end
118
+
119
+
120
+ def _syntax_error(message, path=nil, linenum=@linenum, column=@column)
121
+ #message = _build_message(message_key)
122
+ return _error(Kwalify::SyntaxError, message.to_s, path, linenum, column)
123
+ end
124
+ protected :_syntax_error
125
+
126
+
127
+ end