dc-kwalify 0.7.2

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 (209) hide show
  1. data/CHANGES.txt +252 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.txt +61 -0
  4. data/bin/kwalify +13 -0
  5. data/contrib/inline-require +179 -0
  6. data/contrib/kwalify +4160 -0
  7. data/doc/docstyle.css +188 -0
  8. data/doc/img/fig01.png +0 -0
  9. data/doc/users-guide.html +2050 -0
  10. data/doc-api/classes/CommandOptionError.html +184 -0
  11. data/doc-api/classes/CommandOptionParser.html +325 -0
  12. data/doc-api/classes/Kwalify/AssertionError.html +148 -0
  13. data/doc-api/classes/Kwalify/BaseError.html +297 -0
  14. data/doc-api/classes/Kwalify/BaseParser.html +461 -0
  15. data/doc-api/classes/Kwalify/CommandOptionError.html +168 -0
  16. data/doc-api/classes/Kwalify/ErrorHelper.html +223 -0
  17. data/doc-api/classes/Kwalify/HashInterface.html +118 -0
  18. data/doc-api/classes/Kwalify/Json.html +105 -0
  19. data/doc-api/classes/Kwalify/KwalifyError.html +111 -0
  20. data/doc-api/classes/Kwalify/Main.html +339 -0
  21. data/doc-api/classes/Kwalify/MetaValidator.html +448 -0
  22. data/doc-api/classes/Kwalify/Parser.html +155 -0
  23. data/doc-api/classes/Kwalify/PlainYamlParser/Alias.html +165 -0
  24. data/doc-api/classes/Kwalify/PlainYamlParser.html +523 -0
  25. data/doc-api/classes/Kwalify/Rule.html +433 -0
  26. data/doc-api/classes/Kwalify/SchemaError.html +148 -0
  27. data/doc-api/classes/Kwalify/SyntaxError.html +185 -0
  28. data/doc-api/classes/Kwalify/Types.html +302 -0
  29. data/doc-api/classes/Kwalify/Util/HashLike.html +246 -0
  30. data/doc-api/classes/Kwalify/Util/OrderedHash.html +330 -0
  31. data/doc-api/classes/Kwalify/Util.html +390 -0
  32. data/doc-api/classes/Kwalify/ValidationError.html +148 -0
  33. data/doc-api/classes/Kwalify/Validator.html +381 -0
  34. data/doc-api/classes/Kwalify/Yaml/Parser.html +1538 -0
  35. data/doc-api/classes/Kwalify/Yaml.html +194 -0
  36. data/doc-api/classes/Kwalify/YamlParser.html +542 -0
  37. data/doc-api/classes/Kwalify/YamlSyntaxError.html +119 -0
  38. data/doc-api/classes/Kwalify.html +292 -0
  39. data/doc-api/classes/Test/Unit.html +101 -0
  40. data/doc-api/classes/Test.html +107 -0
  41. data/doc-api/created.rid +1 -0
  42. data/doc-api/files/__/README_txt.html +172 -0
  43. data/doc-api/files/kwalify/errors_rb.html +114 -0
  44. data/doc-api/files/kwalify/main_rb.html +118 -0
  45. data/doc-api/files/kwalify/messages_rb.html +107 -0
  46. data/doc-api/files/kwalify/meta-validator_rb.html +117 -0
  47. data/doc-api/files/kwalify/parser/base_rb.html +116 -0
  48. data/doc-api/files/kwalify/parser/yaml_rb.html +117 -0
  49. data/doc-api/files/kwalify/rule_rb.html +116 -0
  50. data/doc-api/files/kwalify/types_rb.html +114 -0
  51. data/doc-api/files/kwalify/util/assert-text-equal_rb.html +115 -0
  52. data/doc-api/files/kwalify/util/hash-interface_rb.html +114 -0
  53. data/doc-api/files/kwalify/util/hashlike_rb.html +107 -0
  54. data/doc-api/files/kwalify/util/option-parser_rb.html +107 -0
  55. data/doc-api/files/kwalify/util/ordered-hash_rb.html +107 -0
  56. data/doc-api/files/kwalify/util/testcase-helper_rb.html +115 -0
  57. data/doc-api/files/kwalify/util_rb.html +107 -0
  58. data/doc-api/files/kwalify/validator_rb.html +117 -0
  59. data/doc-api/files/kwalify/yaml-parser_rb.html +117 -0
  60. data/doc-api/files/kwalify_rb.html +121 -0
  61. data/doc-api/fr_class_index.html +57 -0
  62. data/doc-api/fr_file_index.html +45 -0
  63. data/doc-api/fr_method_index.html +168 -0
  64. data/doc-api/index.html +24 -0
  65. data/doc-api/rdoc-style.css +208 -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/errors.rb +127 -0
  82. data/lib/kwalify/kwalify.schema.yaml +58 -0
  83. data/lib/kwalify/main.rb +442 -0
  84. data/lib/kwalify/messages.rb +173 -0
  85. data/lib/kwalify/meta-validator.rb +275 -0
  86. data/lib/kwalify/parser/base.rb +127 -0
  87. data/lib/kwalify/parser/yaml.rb +841 -0
  88. data/lib/kwalify/rule.rb +559 -0
  89. data/lib/kwalify/templates/genclass-java.eruby +222 -0
  90. data/lib/kwalify/templates/genclass-php.eruby +104 -0
  91. data/lib/kwalify/templates/genclass-ruby.eruby +113 -0
  92. data/lib/kwalify/types.rb +156 -0
  93. data/lib/kwalify/util/assert-text-equal.rb +46 -0
  94. data/lib/kwalify/util/hash-interface.rb +18 -0
  95. data/lib/kwalify/util/hashlike.rb +51 -0
  96. data/lib/kwalify/util/option-parser.rb +220 -0
  97. data/lib/kwalify/util/ordered-hash.rb +57 -0
  98. data/lib/kwalify/util/testcase-helper.rb +112 -0
  99. data/lib/kwalify/util.rb +158 -0
  100. data/lib/kwalify/validator.rb +282 -0
  101. data/lib/kwalify/yaml-parser.rb +870 -0
  102. data/lib/kwalify.rb +67 -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 +415 -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-util.rb +125 -0
  204. data/test/test-validator.rb +95 -0
  205. data/test/test-validator.yaml +986 -0
  206. data/test/test-yaml-parser.rb +47 -0
  207. data/test/test-yaml-parser.yaml +1226 -0
  208. data/test/test.rb +61 -0
  209. metadata +274 -0
@@ -0,0 +1,173 @@
1
+ ###
2
+ ### $Rev$
3
+ ### $Release: 0.7.2 $
4
+ ### copyright(c) 2005-2010 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,275 @@
1
+ ###
2
+ ### $Rev$
3
+ ### $Release: 0.7.2 $
4
+ ### copyright(c) 2005-2010 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
+
32
+ def self.instance()
33
+ unless @instance
34
+ schema = Kwalify::Yaml::Parser.new().parse(META_SCHEMA)
35
+ @instance = MetaValidator.new(schema)
36
+ end
37
+ return @instance
38
+ end
39
+
40
+ def initialize(schema, &block)
41
+ super
42
+ end
43
+
44
+ def validate_hook(value, rule, path, errors)
45
+ return if value.nil? ## realy?
46
+ return unless rule.name == "MAIN"
47
+ #
48
+ hash = value
49
+ type = hash['type']
50
+ type = Types::DEFAULT_TYPE if type.nil?
51
+ klass = Types.type_class(type)
52
+ #unless klass
53
+ # errors << validate_error(:type_unknown, rule, "#{path}/type", type)
54
+ #end
55
+ #
56
+ if hash.key?('class')
57
+ val = hash['class']
58
+ unless val.nil? || type == 'map'
59
+ errors << validate_error(:class_notmap, rule, "#{path}/class", 'class:')
60
+ end
61
+ end
62
+ #
63
+ if hash.key?('pattern')
64
+ val = hash['pattern']
65
+ pat = (val =~ /\A\/(.*)\/([mi]?[mi]?)\z/ ? $1 : val)
66
+ begin
67
+ Regexp.compile(pat)
68
+ rescue RegexpError => ex
69
+ errors << validate_error(:pattern_syntaxerr, rule, "#{path}/pattern", val)
70
+ end
71
+ end
72
+ #
73
+ if hash.key?('enum')
74
+ if Types.collection_type?(type)
75
+ errors << validate_error(:enum_notscalar, rule, path, 'enum:')
76
+ else
77
+ #elem_table = {}
78
+ hash['enum'].each do |elem|
79
+ #if elem_table[elem]
80
+ # errors << validate_error(:enum_duplicate, rule, "#{path}/enum", elem.to_s)
81
+ #end
82
+ #elem_table[elem] = true
83
+ unless elem.is_a?(klass)
84
+ errors << validate_error(:enum_type_unmatch, rule, "#{path}/enum", elem, [Kwalify.word(type)])
85
+ end
86
+ end
87
+ end
88
+ end
89
+ #
90
+ if hash.key?('assert')
91
+ val = hash['assert']
92
+ #val =~ /\bval\b/ or errors << validate_error(:assert_noval, rule, "#{path}/assert", val)
93
+ begin
94
+ eval "proc { |val| #{val} }"
95
+ rescue ::SyntaxError => ex
96
+ errors << validate_error(:assert_syntaxerr, rule, "#{path}/assert", val)
97
+ end
98
+ end
99
+ #
100
+ if hash.key?('range')
101
+ val = hash['range']
102
+ curr_path = path + "/range"
103
+ #if ! val.is_a?(Hash)
104
+ # errors << validate_error(:range_notmap, rule, curr_path, val)
105
+ #elsif ...
106
+ if Types.collection_type?(type) || type == 'bool' || type == 'any'
107
+ errors << validate_error(:range_notscalar, rule, path, 'range:')
108
+ else
109
+ val.each do |rkey, rval|
110
+ #case rkey
111
+ #when 'max', 'min', 'max-ex', 'min-ex'
112
+ unless rval.is_a?(klass)
113
+ typename = Kwalify.word(type) || type
114
+ errors << validate_error(:range_type_unmatch, rule, "#{curr_path}/#{rkey}", rval, [typename])
115
+ end
116
+ #else
117
+ # errors << validate_error(:range_undefined, rule, curr_path, "#{rkey}:")
118
+ #end
119
+ end
120
+ end
121
+ if val.key?('max') && val.key?('max-ex')
122
+ errors << validate_error(:range_twomax, rule, curr_path, nil)
123
+ end
124
+ if val.key?('min') && val.key?('min-ex')
125
+ errors << validate_error(:range_twomin, rule, curr_path, nil)
126
+ end
127
+ max, min, max_ex, min_ex = val['max'], val['min'], val['max-ex'], val['min-ex']
128
+ if max
129
+ if min && max < min
130
+ errors << validate_error(:range_maxltmin, rule, curr_path, nil, [max, min])
131
+ elsif min_ex && max <= min_ex
132
+ errors << validate_error(:range_maxleminex, rule, curr_path, nil, [max, min_ex])
133
+ end
134
+ elsif max_ex
135
+ if min && max_ex <= min
136
+ errors << validate_error(:range_maxexlemin, rule, curr_path, nil, [max_ex, min])
137
+ elsif min_ex && max_ex <= min_ex
138
+ errors << validate_error(:range_maxexleminex, rule, curr_path, nil, [max_ex, min_ex])
139
+ end
140
+ end
141
+ end
142
+ #
143
+ if hash.key?('length')
144
+ val = hash['length']
145
+ curr_path = path + "/length"
146
+ #val.is_a?(Hash) or errors << validate_error(:length_notmap, rule, curr_path, val)
147
+ unless type == 'str' || type == 'text'
148
+ errors << validate_error(:length_nottext, rule, path, 'length:')
149
+ end
150
+ #val.each do |lkey, lval|
151
+ # #case lkey
152
+ # #when 'max', 'min', 'max-ex', 'min-ex'
153
+ # unless lval.is_a?(Integer)
154
+ # errors << validate_error(:length_notint, rule, "#{curr_path}/#{lkey}", lval)
155
+ # end
156
+ # #else
157
+ # # errors << validate_error(:length_undefined, rule, curr_path, "#{lkey}:")
158
+ # #end
159
+ #end
160
+ if val.key?('max') && val.key?('max-ex')
161
+ errors << validate_error(:length_twomax, rule, curr_path, nil)
162
+ end
163
+ if val.key?('min') && val.key?('min-ex')
164
+ errors << validate_error(:length_twomin, rule, curr_path, nil)
165
+ end
166
+ max, min, max_ex, min_ex = val['max'], val['min'], val['max-ex'], val['min-ex']
167
+ if max
168
+ if min && max < min
169
+ errors << validate_error(:length_maxltmin, rule, curr_path, nil, [max, min])
170
+ elsif min_ex && max <= min_ex
171
+ errors << validate_error(:length_maxleminex, rule, curr_path, nil, [max, min_ex])
172
+ end
173
+ elsif max_ex
174
+ if min && max_ex <= min
175
+ errors << validate_error(:length_maxexlemin, rule, curr_path, nil, [max_ex, min])
176
+ elsif min_ex && max_ex <= min_ex
177
+ errors << validate_error(:length_maxexleminex, rule, curr_path, nil, [max_ex, min_ex])
178
+ end
179
+ end
180
+ end
181
+ #
182
+ if hash.key?('unique')
183
+ if hash['unique'] && Types.collection_type?(type)
184
+ errors << validate_error(:unique_notscalar, rule, path, "unique:")
185
+ end
186
+ if path.empty?
187
+ errors << validate_error(:unique_onroot, rule, "/", "unique:")
188
+ end
189
+ end
190
+ #
191
+ if hash.key?('ident')
192
+ if hash['ident'] && Types.collection_type?(type)
193
+ errors << validate_error(:ident_notscalar, rule, path, "ident:")
194
+ end
195
+ if path.empty?
196
+ errors << validate_error(:ident_onroot, rule, "/", "ident:")
197
+ end
198
+ end
199
+ #
200
+ if hash.key?('default')
201
+ val = hash['default']
202
+ if Types.collection_type?(type)
203
+ errors << validate_error(:default_notscalar, rule, path, "default:")
204
+ elsif !val.nil? && !val.is_a?(klass)
205
+ errors << validate_error(:default_unmatch, rule, "#{path}/default", val, [Kwalify.word(type)])
206
+ end
207
+ end
208
+ #
209
+ if hash.key?('sequence')
210
+ val = hash['sequence']
211
+ #if !val.nil? && !val.is_a?(Array)
212
+ # errors << validate_error(:sequence_notseq, rule, "#{path}/sequence", val)
213
+ #elsif ...
214
+ if val.nil? || val.empty?
215
+ errors << validate_error(:sequence_noelem, rule, "#{path}/sequence", val)
216
+ elsif val.length > 1
217
+ errors << validate_error(:sequence_toomany, rule, "#{path}/sequence", val)
218
+ else
219
+ elem = val[0]
220
+ assert_error("elem.class=#{elem.class}") unless elem.is_a?(Hash)
221
+ if elem['ident'] && elem['type'] != 'map'
222
+ errors << validate_error(:ident_notmap, nil, "#{path}/sequence/0", 'ident:')
223
+ end
224
+ end
225
+ end
226
+ #
227
+ if hash.key?('mapping')
228
+ val = hash['mapping']
229
+ if !val.nil? && !val.is_a?(Hash)
230
+ errors << validate_error(:mapping_notmap, rule, "#{path}/mapping", val)
231
+ elsif val.nil? || (val.empty? && !val.default)
232
+ errors << validate_error(:mapping_noelem, rule, "#{path}/mapping", val)
233
+ end
234
+ end
235
+ #
236
+ if type == 'seq'
237
+ errors << validate_error(:seq_nosequence, rule, path, nil) unless hash.key?('sequence')
238
+ #errors << validate_error(:seq_conflict, rule, path, 'enum:') if hash.key?('enum')
239
+ errors << validate_error(:seq_conflict, rule, path, 'pattern:') if hash.key?('pattern')
240
+ errors << validate_error(:seq_conflict, rule, path, 'mapping:') if hash.key?('mapping')
241
+ #errors << validate_error(:seq_conflict, rule, path, 'range:') if hash.key?('range')
242
+ #errors << validate_error(:seq_conflict, rule, path, 'length:') if hash.key?('length')
243
+ elsif type == 'map'
244
+ errors << validate_error(:map_nomapping, rule, path, nil) unless hash.key?('mapping')
245
+ #errors << validate_error(:map_conflict, rule, path, 'enum:') if hash.key?('enum')
246
+ errors << validate_error(:map_conflict, rule, path, 'pattern:') if hash.key?('pattern')
247
+ errors << validate_error(:map_conflict, rule, path, 'sequence:') if hash.key?('sequence')
248
+ #errors << validate_error(:map_conflict, rule, path, 'range:') if hash.key?('range')
249
+ #errors << validate_error(:map_conflict, rule, path, 'length:') if hash.key?('length')
250
+ else
251
+ errors << validate_error(:scalar_conflict, rule, path, 'sequence:') if hash.key?('sequence')
252
+ errors << validate_error(:scalar_conflict, rule, path, 'mapping:') if hash.key?('mapping')
253
+ if hash.key?('enum')
254
+ errors << validate_error(:enum_conflict, rule, path, 'range:') if hash.key?('range')
255
+ errors << validate_error(:enum_conflict, rule, path, 'length:') if hash.key?('length')
256
+ errors << validate_error(:enum_conflict, rule, path, 'pattern:') if hash.key?('pattern')
257
+ end
258
+ if hash.key?('default')
259
+ errors << validate_error(:default_conflict, rule, path, 'default:') if hash['required']
260
+ end
261
+ end
262
+
263
+ end # end of def validate_hook()
264
+
265
+
266
+ end # end of class MetaValidator
267
+
268
+
269
+ META_VALIDATOR = MetaValidator.instance()
270
+
271
+ def self.meta_validator # obsolete
272
+ return META_VALIDATOR
273
+ end
274
+
275
+ end
@@ -0,0 +1,127 @@
1
+ ###
2
+ ### $Rev$
3
+ ### $Release: 0.7.2 $
4
+ ### copyright(c) 2005-2010 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.peep(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