ruby_rnv 0.2.3 → 0.4.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.
data/ext/rnv/src/xsd.c CHANGED
@@ -1,5 +1,3 @@
1
- #include "type.h"
2
-
3
1
  /* $Id: xsd.c,v 1.47 2005/01/06 21:04:06 dvd Exp $ */
4
2
 
5
3
  #include <limits.h> /*INT_MAX*/
@@ -7,6 +5,9 @@
7
5
  #include <string.h> /*strlen*/
8
6
  #include <math.h> /*HUGE_VAL*/
9
7
  #include <assert.h>
8
+
9
+ #include "type.h"
10
+
10
11
  #include "u.h"
11
12
  #include "xmlc.h"
12
13
  #include "s.h"
@@ -16,11 +17,10 @@
16
17
  #include "er.h"
17
18
  #include "xsd.h"
18
19
 
19
- #define err(msg) (*rnv->verror_handler)(rnv,erno|ERBIT_XSD,msg"\n",ap)
20
- void xsd_default_verror_handler(rnv_t *rnv, int erno,va_list ap) {
21
- (*er_printf)("XML Schema datatypes: ");
20
+ #define err(msg) (*handler)(data,erno|ERBIT_XSD,"XML Schema datatypes: "msg"\n",ap)
21
+ void xsd_default_verror_handler(void *data, int erno, int (*handler)(void *data, int erno,char *format, va_list ap), va_list ap) {
22
22
  if(erno&ERBIT_RX) {
23
- rx_default_verror_handler(rnv, erno&~ERBIT_RX,ap);
23
+ rx_default_verror_handler(data, erno&~ERBIT_RX,handler,ap);
24
24
  } else {
25
25
  switch(erno) {
26
26
  case XSD_ER_TYP: err("unknown type %s"); break;
@@ -36,24 +36,11 @@ void xsd_default_verror_handler(rnv_t *rnv, int erno,va_list ap) {
36
36
  }
37
37
 
38
38
  static void error_handler(rx_st_t *rx_st, int erno,...) {
39
- va_list ap; va_start(ap,erno); (*rx_st->rnv->xsd_verror_handler)(rx_st->rnv,erno,ap); va_end(ap);
39
+ va_list ap; va_start(ap,erno); xsd_default_verror_handler(rx_st->user_data,erno,rx_st->verror_handler,ap); va_end(ap);
40
40
  }
41
41
 
42
- static void verror_handler_rx(rnv_t *rnv, int erno,va_list ap) {xsd_default_verror_handler(rnv,erno|ERBIT_RX,ap);}
43
-
44
- static void windup(void);
45
42
  void xsd_init(rx_st_t *rx_st) {
46
- rx_st->rnv->xsd_verror_handler = &xsd_default_verror_handler;
47
43
  rx_init(rx_st);
48
- rx_st->rnv->rx_verror_handler=&verror_handler_rx;
49
- windup();
50
- }
51
-
52
- void xsd_clear(void) {
53
- windup();
54
- }
55
-
56
- static void windup(void) {
57
44
  }
58
45
 
59
46
  #define FCT_ENUMERATION 0
@@ -81,7 +68,7 @@ static char *fcttab[NFCT]={
81
68
  #define WS_REPLACE 1
82
69
  #define WS_COLLAPSE 2
83
70
 
84
- static int (*match[])(rnv_t *rnv, rx_st_t *rx_st, char *r,char *s,int n)={&rx_match, &rx_rmatch,&rx_cmatch};
71
+ static int (*match[])(rx_st_t *rx_st, char *r,char *s,int n)={&rx_match, &rx_rmatch,&rx_cmatch};
85
72
 
86
73
  #define TYP_ENTITIES 0
87
74
  #define TYP_ENTITY 1
@@ -327,7 +314,7 @@ struct facets {
327
314
  #define PAT_MONTH0 "(0[1-9]|1[0-2])"
328
315
  #define PAT_DAY0 "([0-2][0-9]|3[01])"
329
316
  #define PAT_YEAR "-?"PAT_YEAR0 PAT_ZONE"?"
330
- #define PAT_MONTH "--"PAT_MONTH0"--"PAT_ZONE"?"
317
+ #define PAT_MONTH "--"PAT_MONTH0 PAT_ZONE"?"
331
318
  #define PAT_DAY "---"PAT_DAY0 PAT_ZONE"?"
332
319
  #define PAT_YEAR_MONTH "-?"PAT_YEAR0"-"PAT_MONTH0 PAT_ZONE"?"
333
320
  #define PAT_MONTH_DAY "--"PAT_MONTH0"-"PAT_DAY0 PAT_ZONE"?"
@@ -661,7 +648,7 @@ int xsd_allows(rx_st_t *rx_st, char *typ,char *ps,char *s,int n) {
661
648
  default: assert(0);
662
649
  }
663
650
 
664
- while(fct.npat--) ok=ok&&match[fct.whiteSpace](rx_st->rnv, rx_st, fct.pattern[fct.npat],s,n);
651
+ while(fct.npat--) ok=ok&&match[fct.whiteSpace](rx_st, fct.pattern[fct.npat],s,n);
665
652
 
666
653
  if(fct.set&(1<<FCT_LENGTH)) ok=ok&&length==fct.length;
667
654
  if(fct.set&(1<<FCT_MAX_LENGTH)) ok=ok&&length<=fct.maxLength;
data/ext/rnv/src/xsd.h CHANGED
@@ -14,10 +14,9 @@
14
14
  #define XSD_ER_WS 5
15
15
  #define XSD_ER_ENUM 6
16
16
 
17
- extern void xsd_default_verror_handler(rnv_t *rnv, int erno,va_list ap);
17
+ extern void xsd_default_verror_handler(void *data, int erno, int (*handler)(void *data, int erno,char *format, va_list ap), va_list ap);
18
18
 
19
19
  extern void xsd_init(rx_st_t *rx_st);
20
- extern void xsd_clear(void);
21
20
 
22
21
  extern int xsd_allows(rx_st_t *rx_st, char *typ,char *ps,char *s,int n);
23
22
  extern int xsd_equal(rx_st_t *rx_st, char *typ,char *val,char *s,int n);
data/lib/rnv.rb CHANGED
@@ -1,2 +1,5 @@
1
1
  require 'rnv/rnv'
2
+ require 'rnv/error'
2
3
  require 'rnv/validator'
4
+ require 'rnv/data_type_library'
5
+ require 'rnv/pre_processor'
@@ -0,0 +1,21 @@
1
+ module RNV
2
+ # Datatype library callback object
3
+ # @see https://www.oasis-open.org/committees/relax-ng/spec-20010811.html#IDA1I1R
4
+ class DataTypeLibrary
5
+ # @param [String] typ the data type
6
+ # @param [String] val
7
+ # @param [String] s
8
+ # @return [Boolean]
9
+ def equal(typ, val, s)
10
+ true
11
+ end
12
+
13
+ # @param [String] typ the data type
14
+ # @param [String] ps
15
+ # @param [String] s the value
16
+ # @return [Boolean]
17
+ def allows(typ, ps, s)
18
+ true
19
+ end
20
+ end
21
+ end
data/lib/rnv/error.rb ADDED
@@ -0,0 +1,102 @@
1
+ module RNV
2
+ class Error
3
+ attr_reader :original_message, :original_expected
4
+ attr_reader :ns_uri, :element, :attr, :value, :required, :allowed
5
+
6
+ # @return [String]
7
+ def message
8
+ @original_message
9
+ end
10
+
11
+ # @return [String]
12
+ def expected
13
+ @original_expected
14
+ end
15
+
16
+ # @return [String]
17
+ def compact_message
18
+ case @code
19
+ when :rnv_er_elem
20
+ "element <#{@element}> is not allowed"
21
+ when :rnv_er_ufin
22
+ "element <#{@element}> is incomplete"
23
+ when :rnv_er_akey
24
+ "attribute #{@attr} is not allowed"
25
+ when :rnv_er_aval
26
+ "attribute #{@attr} has invalid value '#{@value}'"
27
+ when :rnv_er_amis
28
+ "element <#{@element}> attribute missing"
29
+ else
30
+ @original_message
31
+ end
32
+ end
33
+
34
+ # @return [String]
35
+ def compact_expected
36
+ [(compact_required_set.length > 0 ? compact_expected_phrase(compact_required_set) +" required" : nil),
37
+ (compact_allowed_set.length > 0 ? compact_expected_phrase(compact_allowed_set) + " allowed" : nil)].join("; ")
38
+ end
39
+
40
+ # @param [String] data original content
41
+ # @return [String] context
42
+ def contextualize(data, max_len = 60)
43
+ out = ""
44
+ if data and @line
45
+ err_data = data.split("\n")[@line - 1]
46
+ if err_data
47
+ err_data.insert(@col - 1, "🢑")
48
+
49
+ start = 0
50
+ if @col > max_len
51
+ start = @col - max_len
52
+ end
53
+ out += (start > 0 ? "…" : "") + err_data[start..(@col + max_len)].strip + (@col + max_len < err_data.length ? "…" : "")
54
+ end
55
+ end
56
+ out
57
+ end
58
+
59
+ # @return [String]
60
+ def to_s
61
+ "#{@line}:#{@col}:error: #{self.message}\n#{self.expected}"
62
+ end
63
+
64
+ # @return [String]
65
+ def inspect
66
+ "#<RNV::Error code: :#{@code}, message: '#{self.message}', expected: '#{self.expected}, line: #{@line}, column: #{@col}>"
67
+ end
68
+
69
+ private
70
+
71
+ def compact_expected_to_s(e, with_ns = false)
72
+ case e.first
73
+ when :rn_p_attribute
74
+ compact_expected_to_s(e.last, with_ns)
75
+ when :rn_p_element
76
+ "<"+compact_expected_to_s(e.last, with_ns)+">"
77
+ when :rn_p_data
78
+ compact_expected_to_s(e.last, with_ns)
79
+ when :rn_nc_datatype
80
+ "datatype #{e[-2]}:#{e.last}"
81
+ when :rn_nc_qname
82
+ with_ns ? "#{e.first}:#{e.last}" : e.last
83
+ end
84
+ end
85
+
86
+ def compact_required_set
87
+ @compact_required_set ||= @required.map{|r| compact_expected_to_s(r)}.compact.uniq
88
+ end
89
+
90
+ def compact_allowed_set
91
+ @compact_allowed_set ||= @allowed.map{|r| compact_expected_to_s(r)}.compact.uniq
92
+ end
93
+
94
+ def compact_expected_phrase(set)
95
+ if set.length > 1
96
+ set[0..-2].join(", ") + " or "+set.last
97
+ else
98
+ set.last
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,25 @@
1
+ module RNV
2
+ # Object to modify data before validation (eg: HTML5 data-* attributes)
3
+ class PreProcessor
4
+ # replace attributes before validate
5
+ # @param [Array<Array<String>>] attrs
6
+ # @return [Array<Array<String>>]
7
+ def attributes(attrs)
8
+ attrs
9
+ end
10
+
11
+ # replace tag name before validate
12
+ # @param [String] tag
13
+ # @return [String]
14
+ def tag(tag)
15
+ tag
16
+ end
17
+
18
+ # replace content text before validate
19
+ # @param [String] txt
20
+ # @return [String]
21
+ def text(txt)
22
+ txt
23
+ end
24
+ end
25
+ end
data/lib/rnv/validator.rb CHANGED
@@ -1,37 +1,40 @@
1
1
  require 'nokogiri'
2
2
  require 'rnv/rnv'
3
+ require 'rnv/pre_processor'
3
4
 
4
5
  module RNV
6
+ class DocumentEmpty < StandardError; end
7
+
5
8
  # @!visibility private
6
9
  class NokogiriSaxDocument < Nokogiri::XML::SAX::Document
7
10
  # @return [Nokogiri::XML::SAX::ParserContext]
8
- attr_accessor :ctx
11
+ attr_accessor :ctx, :pre_processor
9
12
  # @param [RNV::Document] document
10
13
  def initialize(document)
11
14
  @document = document
12
15
  end
13
16
 
14
17
  def start_element_namespace(name, attrs = [], prefix = nil, uri = nil, ns = nil)
15
- update_line_col
16
18
  tag_attrs = attrs.map { |attr| [attr.uri ? "#{attr.uri}:#{attr.localname}" : attr.localname, attr.value] }
17
19
  tag_name = uri ? "#{uri}:#{name}" : name
18
- @document.start_tag(tag_name, tag_attrs.flatten)
20
+ @document.start_tag(@pre_processor.tag(tag_name), @pre_processor.attributes(tag_attrs))
21
+ update_line_col
19
22
  end
20
23
 
21
24
  def end_element_namespace(name, prefix = nil, uri = nil)
22
- update_line_col
23
25
  tag_name = uri ? "#{uri}:#{name}" : name
24
- @document.end_tag(tag_name)
26
+ @document.end_tag(@pre_processor.tag(tag_name))
27
+ update_line_col
25
28
  end
26
29
 
27
30
  def characters str
31
+ @document.characters(@pre_processor.text(str))
28
32
  update_line_col
29
- @document.characters(str)
30
33
  end
31
34
 
32
35
  def cdata_block str
36
+ @document.characters(@pre_processor.text(str))
33
37
  update_line_col
34
- @document.characters(str)
35
38
  end
36
39
 
37
40
  private
@@ -57,25 +60,31 @@ module RNV
57
60
  end
58
61
 
59
62
  # @param [String] str RNC schema buffer
63
+ # @return [Boolean] true if schema loaded successfuly
60
64
  def load_schema_from_string(str)
61
65
  @document.load_string(str)
62
66
  end
63
67
 
64
68
  # @param [String] file RNC schema filename
69
+ # @return [Boolean] true if schema loaded successfuly
65
70
  def load_schema_from_file(file)
66
71
  @document.load_file(file)
67
72
  end
68
73
 
69
74
  # parse and validate buffer
70
75
  # @param [String] str XML buffer to parse
76
+ # @param [RNV::PreProcessor] pre_processor an optional pre-processor for tag and attributes data
71
77
  # @return [Boolean] true if valid
72
- def parse_string(str)
73
- @document.errors = [] # reset errors
78
+ def parse_string(str, pre_processor = PreProcessor.new)
74
79
  @document.start_document
75
80
  rnv_doc = NokogiriSaxDocument.new(@document)
81
+ rnv_doc.pre_processor = pre_processor
82
+
83
+ raise RNV::DocumentEmpty if str.nil? or str.empty?
76
84
 
77
85
  parser = Nokogiri::XML::SAX::Parser.new(rnv_doc)
78
86
  parser.parse_memory(str) do |ctx|
87
+ ctx.replace_entities = true
79
88
  rnv_doc.ctx = ctx
80
89
  end
81
90
 
@@ -84,16 +93,20 @@ module RNV
84
93
 
85
94
  # parse and validate file
86
95
  # @param [String, File] xml XML file to parse
96
+ # @param [RNV::PreProcessor] pre_processor an optional pre-processor for tag and attributes data
87
97
  # @return [Boolean] true if valid
88
- def parse_file(xml)
89
- @document.errors = [] # reset errors
98
+ def parse_file(xml, pre_processor = PreProcessor.new)
90
99
  @document.start_document
91
100
  rnv_doc = NokogiriSaxDocument.new(@document)
101
+ rnv_doc.pre_processor = pre_processor
92
102
 
93
103
  file = xml.is_a?(File) ? xml : File.open(xml)
94
104
 
105
+ raise RNV::DocumentEmpty if file.size == 0
106
+
95
107
  parser = Nokogiri::XML::SAX::Parser.new(rnv_doc)
96
108
  parser.parse(file) do |ctx|
109
+ ctx.replace_entities = true
97
110
  rnv_doc.ctx = ctx
98
111
  end
99
112
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_rnv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julien Boulnois
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-08 00:00:00.000000000 Z
11
+ date: 2021-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -104,6 +104,8 @@ files:
104
104
  - Gemfile
105
105
  - ext/rnv/extconf.rb
106
106
  - ext/rnv/ruby_rnv.c
107
+ - ext/rnv/ruby_rnv.h
108
+ - ext/rnv/ruby_rnv_err.c
107
109
  - ext/rnv/src/ary.c
108
110
  - ext/rnv/src/ary.h
109
111
  - ext/rnv/src/drv.c
@@ -147,6 +149,9 @@ files:
147
149
  - ext/rnv/src/xsd_tm.c
148
150
  - ext/rnv/src/xsd_tm.h
149
151
  - lib/rnv.rb
152
+ - lib/rnv/data_type_library.rb
153
+ - lib/rnv/error.rb
154
+ - lib/rnv/pre_processor.rb
150
155
  - lib/rnv/validator.rb
151
156
  homepage: https://github.com/immateriel/ruby_rnv
152
157
  licenses: