duxml 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/bin/validate_xml +19 -0
  3. data/lib/duxml/doc/element.rb +157 -0
  4. data/lib/duxml/doc/lazy_ox.rb +153 -0
  5. data/lib/duxml/doc/node_set.rb +39 -0
  6. data/lib/duxml/doc.rb +26 -0
  7. data/lib/duxml/meta/grammar/pattern/attr_name_pattern.rb +36 -0
  8. data/lib/duxml/meta/grammar/pattern/attr_val_pattern.rb +36 -0
  9. data/lib/duxml/meta/grammar/pattern/child_pattern.rb +72 -0
  10. data/lib/duxml/meta/grammar/pattern/text_pattern.rb +30 -0
  11. data/lib/duxml/meta/grammar/pattern.rb +98 -0
  12. data/lib/duxml/meta/grammar/pattern_maker.rb +69 -0
  13. data/lib/duxml/meta/grammar/relax_ng/attrs_rule.rb +58 -0
  14. data/lib/duxml/meta/grammar/relax_ng/children_rule.rb +83 -0
  15. data/lib/duxml/meta/grammar/relax_ng/value_rule.rb +44 -0
  16. data/lib/duxml/meta/grammar/relax_ng.rb +40 -0
  17. data/lib/duxml/meta/grammar/rule/attrs_rule.rb +78 -0
  18. data/lib/duxml/meta/grammar/rule/children_rule.rb +137 -0
  19. data/lib/duxml/meta/grammar/rule/text_rule.rb +40 -0
  20. data/lib/duxml/meta/grammar/rule/value_rule.rb +111 -0
  21. data/lib/duxml/meta/grammar/rule.rb +59 -0
  22. data/lib/duxml/meta/grammar/spreadsheet.rb +35 -0
  23. data/lib/duxml/meta/grammar.rb +134 -0
  24. data/lib/duxml/meta/history/add.rb +36 -0
  25. data/lib/duxml/meta/history/change.rb +71 -0
  26. data/lib/duxml/meta/history/change_attr.rb +34 -0
  27. data/lib/duxml/meta/history/change_text.rb +33 -0
  28. data/lib/duxml/meta/history/error.rb +25 -0
  29. data/lib/duxml/meta/history/new_attr.rb +33 -0
  30. data/lib/duxml/meta/history/new_text.rb +37 -0
  31. data/lib/duxml/meta/history/qualify_error.rb +22 -0
  32. data/lib/duxml/meta/history/remove.rb +28 -0
  33. data/lib/duxml/meta/history/undo.rb +24 -0
  34. data/lib/duxml/meta/history/validate_error.rb +21 -0
  35. data/lib/duxml/meta/history.rb +88 -0
  36. data/lib/duxml/meta.rb +51 -0
  37. data/lib/duxml/reportable.rb +27 -0
  38. data/lib/duxml/ruby_ext/fixnum.rb +56 -0
  39. data/lib/duxml/ruby_ext/module.rb +12 -0
  40. data/lib/duxml/ruby_ext/object.rb +14 -0
  41. data/lib/duxml/ruby_ext/regexp.rb +20 -0
  42. data/lib/duxml/ruby_ext/string.rb +29 -0
  43. data/lib/duxml/saxer.rb +71 -0
  44. data/lib/duxml.rb +97 -0
  45. data/xml/dita_grammar.xml +2133 -0
  46. metadata +117 -0
@@ -0,0 +1,59 @@
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/pattern')
4
+ require File.expand_path(File.dirname(__FILE__) + '/../../reportable')
5
+
6
+ module Duxml
7
+ # scans DTD statements for XML rule operators
8
+ Struct.new 'Scanner', :match, :operator
9
+
10
+ # contains methods to apply Duxml::RuleClass to XML edit or validate events
11
+ module Rule
12
+ include Reportable
13
+ end
14
+
15
+ # as an object, Rules consist of a subject, representing the XML Element, and a statement representing the Rule's logic
16
+ # this class cannot be used alone and is rather subclassed, one for each type of possible XML changes
17
+ class RuleClass < PatternClass
18
+ include Rule
19
+
20
+ # @param subj [String] NMTOKEN name of element this rule applies to
21
+ # @param _statement [String, Regexp] string statement of rule in DTD declaration form or Regexp
22
+ def initialize(subj, _statement)
23
+ @statement = _statement
24
+ @object = nil
25
+ super subj
26
+ end
27
+
28
+ attr_reader :statement, :object
29
+ end
30
+
31
+ module Rule
32
+ # Duxml::Rule's #qualify is only used to report errors found by its subclasses' #qualify methods
33
+ # @param change_or_pattern [Duxml::Pattern, Duxml::Change] Change or Pattern to be reported for Rule violation
34
+ # @return [Boolean] always false; this method should always be subclassed to apply that specific rule type's #qualify
35
+ def qualify(change_or_pattern)
36
+ type = (change_or_pattern.respond_to?(:time_stamp)) ? :QualifyError : :ValidateError
37
+ report(type, change_or_pattern)
38
+ false
39
+ end
40
+
41
+ # @return [HistoryClass] history to which this rule will report errors
42
+ def history
43
+ @observer_peers.first.first if @observer_peers.any? and @observer_peers.first.any?
44
+ end
45
+
46
+ # @param change_or_pattern [Duxml::Change, Duxml::Pattern] change or pattern that rule may apply to
47
+ # @return [Boolean] whether this rule does in fact apply
48
+ def applies_to?(change_or_pattern)
49
+ pattern_type = change_or_pattern.subject.name
50
+ subject == pattern_type
51
+ end
52
+
53
+ # @return [String] default description for a Rule
54
+ def description
55
+ statement_str = (statement.is_a?(String) ? statement : statement.inspect).gsub('\b','')
56
+ %(#{relationship.capitalize} Rule that <#{subject}>'s #{relationship} must match '#{statement_str}')
57
+ end
58
+ end # module Rule
59
+ end # module Duxml
@@ -0,0 +1,35 @@
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require 'rubyXL'
4
+
5
+ module Duxml
6
+ # contains helper methods to convert spreadsheet of DTD rules into Duxml::Rules
7
+ module Spreadsheet
8
+ private
9
+ # @param path [String] spreadsheet file
10
+ def self.sheet_to_xml(path)
11
+ worksheet = RubyXL::Parser.parse(path)[0]
12
+ attr_val_rule_hash = {}
13
+ g = GrammarClass.new
14
+ worksheet.each_with_index do |row, index|
15
+ next if index == 0
16
+ break if row[3].nil? || row[4].nil?
17
+ element_name = row[3].value
18
+ statement_str = row[4].value
19
+ g << ChildrenRuleClass.new(element_name, statement_str)
20
+ attribute_rules = row[5].value.split(/\n/)
21
+ attribute_rules.each_with_index do |rule, i|
22
+ next if i == 0 or rule.empty?
23
+ attr_name, value_expr, attr_req = *rule.split
24
+ next if [attr_name, value_expr, attr_req].any? do |s| s.empty? or s.match(/\w/).nil? end
25
+ g << AttrsRuleClass.new(element_name, attr_name, attr_req)
26
+ unless attr_val_rule_hash[attr_name]
27
+ g << ValueRuleClass.new(attr_name, value_expr)
28
+ attr_val_rule_hash[attr_name] = true
29
+ end
30
+ end # attribute_rules.each_with_index
31
+ end # worksheet.each_with_index
32
+ g
33
+ end # def sheet_to_xml(path)
34
+ end # module Spreadsheet
35
+ end # module Duxml
@@ -0,0 +1,134 @@
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../reportable')
4
+ require File.expand_path(File.dirname(__FILE__) + '/grammar/spreadsheet')
5
+ require File.expand_path(File.dirname(__FILE__) + '/grammar/pattern_maker')
6
+ require File.expand_path(File.dirname(__FILE__) + '/grammar/rule/children_rule')
7
+ require File.expand_path(File.dirname(__FILE__) + '/grammar/rule/attrs_rule')
8
+ require File.expand_path(File.dirname(__FILE__) + '/grammar/rule/value_rule')
9
+ require File.expand_path(File.dirname(__FILE__) + '/../doc/lazy_ox')
10
+ require File.expand_path(File.dirname(__FILE__) + '/grammar/rule/text_rule')
11
+ require File.expand_path(File.dirname(__FILE__) + '/grammar/relax_ng')
12
+ require 'forwardable'
13
+
14
+ module Duxml
15
+ # module shares name with <grammar> to activate its methods when that XML Element is encountered in a Meta file
16
+ module Grammar
17
+ include Reportable
18
+ include Duxml
19
+ include Spreadsheet
20
+ include PatternMaker
21
+ include LazyOx
22
+ include RelaxNG
23
+ end
24
+ # contains Duxml::Rules and can apply them by validating XML or qualifying user input
25
+ # reporting Duxml::Errors to History as needed
26
+ class GrammarClass
27
+ extend Forwardable
28
+ include Grammar
29
+
30
+ # @param rules [[RuleClass]] optional, can initialize grammar with rules
31
+ def initialize(rules=[])
32
+ @rules = rules
33
+ end
34
+
35
+ def_delegators :@rules, :<<, :[], :each
36
+ attr_reader :rules
37
+ alias_method :nodes, :rules
38
+ end
39
+
40
+ module Grammar
41
+ # @param path [String] path of grammar file; can be in .xlsx, .csv or Duxml GrammarClass file
42
+ # @return [GrammarClass, Element] XML Element named <grammar> and GrammarClass object are functionally equivalent
43
+ def self.import(path)
44
+ if %w(.xlsx .csv).include?(File.extname path)
45
+ doc = Spreadsheet.sheet_to_xml path
46
+ File.write(File.basename(path)+'.xml', Ox.dump(doc)) #TODO make optional!
47
+ doc
48
+ else
49
+ Ox.parse_obj(File.read path)
50
+ end
51
+ end
52
+
53
+ # @return [Element] returns self as XML element e.g. '<duxml:grammar/>'
54
+ def self.xml
55
+ Element.new(name.nmtokenize).extend self
56
+ end
57
+
58
+ # @return [History] history that this grammar is currently reporting to
59
+ def history
60
+ @observer_peers.first.first if @observer_peers and @observer_peers.any? and @observer_peers.first.any?
61
+ end
62
+
63
+ # @return [Boolean] whether or not any rules have been defined yet in this grammar
64
+ def defined?
65
+ !rules.empty?
66
+ end
67
+
68
+ # @param obj [Object] object that will observe this grammar's rules, usually the History
69
+ def add_observer(obj, sym=nil)
70
+ super(obj, sym || :update)
71
+ @rules.each do |r| r.add_observer(obj, :update)end
72
+ end
73
+
74
+ # @return [String] lists XML schema and content rules in order of precedence
75
+ def description
76
+ "grammar follows: \n" +
77
+ rules.collect do |change_or_error|
78
+ change_or_error.description
79
+ end.join("\n")
80
+ end
81
+
82
+ # @return [String] formatted to appear in tight spaces e.g. debugger
83
+ def inspect
84
+ "#<#{self.class.to_s} #{object_id}: @rules=#{rules.size}>"
85
+ end
86
+
87
+ # @return [String] 'grammar'
88
+ def name
89
+ 'grammar'
90
+ end
91
+
92
+ # @param node [Duxml::Object] applies grammar rules to all relationships of the given object
93
+ # @result [Boolean] whether all rules qualified
94
+ def validate(node)
95
+ rels = get_relationships(node)
96
+ results = rels.collect do |rel|
97
+ qualify rel
98
+ end
99
+ any_disqualified = results.any? do |qualified| !qualified end
100
+ !any_disqualified
101
+ end # def validate
102
+
103
+ # @param change_or_pattern [Duxml::Change, Duxml::Pattern] applies applicable rule type and subject
104
+ # to given change_or_pattern and generates errors when disqualified
105
+ # @return [Boolean] false if any rule disqualifies; true if they all pass
106
+ def qualify(change_or_pattern)
107
+ return true unless self.defined?
108
+ rules = get_rule(change_or_pattern)
109
+
110
+ # define behaviors for when there are no rules applying to a given pattern
111
+ if rules.empty?
112
+
113
+ if change_or_pattern.respond_to?(:text) or
114
+ change_or_pattern.respond_to?(:value) or
115
+ change_or_pattern.subject.is_a?(Doc)
116
+ return true
117
+ end
118
+ report(:ValidateError, change_or_pattern)
119
+ return false
120
+ end
121
+ results = rules.collect do |rule|
122
+ rule.qualify change_or_pattern
123
+ end
124
+ !results.any? do |qualified| !qualified end
125
+ end # def qualify
126
+
127
+ # @param change_or_pattern [Duxml::Change, Duxml::Pattern] change or pattern to be qualified
128
+ # @return [Array[Duxml::Rule]] rules that match the pattern type (e.g. :change_content => :content_rule)
129
+ # and subject (e.g. change_or_pattern.subject.type => 'blobs' && rule.subject => 'blobs')
130
+ def get_rule(change_or_pattern)
131
+ rules.select do |rule| rule.applies_to?(change_or_pattern) end
132
+ end # def get_rules
133
+ end # module Grammar
134
+ end # module Duxml
@@ -0,0 +1,36 @@
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/change')
4
+
5
+ module Duxml
6
+ module Add; end
7
+
8
+ # created when an doc gains a child
9
+ class AddClass < ChangeClass
10
+ include Add
11
+
12
+ def initialize(_subject, _index)
13
+ super _subject
14
+ @index = _index
15
+ end
16
+
17
+ alias_method :parent, :subject
18
+ attr_reader :subject, :index
19
+ end
20
+
21
+ module Add
22
+ def description
23
+ %(#{super} #{child.description} added to #{parent.description}.)
24
+ end
25
+
26
+ def parent
27
+ subject
28
+ end
29
+
30
+ def child
31
+ subject.nodes[index]
32
+ end
33
+
34
+ alias_method :object, :child
35
+ end # class Add
36
+ end # module Duxml
@@ -0,0 +1,71 @@
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../grammar/pattern')
4
+
5
+ module Duxml
6
+ module Change; end
7
+ # do not use - only for subclassing
8
+ # changes represent events i.e. patterns with a fixed position in time,
9
+ # and can include qualification and validation errors
10
+ class ChangeClass < PatternClass
11
+ include Change
12
+
13
+ @time_stamp
14
+
15
+ # all subclasses of Change must call this super method or implement the same function within their #initialize
16
+ #
17
+ # @param _subject [Duxml::Element] parent doc affected by change
18
+ def initialize(_subject, *args)
19
+ super _subject
20
+ @time_stamp = Time.now
21
+ args.each do |arg|
22
+ if arg.is_a?(Duxml::Element)
23
+ @object = arg
24
+ break
25
+ end
26
+ end
27
+ end
28
+
29
+ attr_reader :time_stamp
30
+ end # class ChangeClass < PatternClass
31
+
32
+ module Change
33
+ def abstract?
34
+ false
35
+ end
36
+
37
+ # @return [String] gives its time stamp
38
+ def description
39
+ "at #{time_stamp}#{line_expr}:"
40
+ end
41
+
42
+ # @return [-1,0,1,nil] compares dates of changes
43
+ def <=>(obj)
44
+ return nil unless obj.is_a?(Duxml::Change)
45
+ date <=> obj.date
46
+ end
47
+
48
+ # @return [Fixnum] line number of changed object; -l if not applicable
49
+ def line
50
+ case
51
+ when object.respond_to?(:line) && object.line.is_a?(Numeric) && object.line >= 0
52
+ object.line
53
+ when object.respond_to?(:object) && object.object.respond_to?(:line) && object.object.line.is_a?(Numeric) && object.object.line >= 0
54
+ object.object.line
55
+ when object.respond_to?(:subject) && object.subject.respond_to?(:line) && object.subject.line.is_a?(Numeric) && object.subject.line >= 0
56
+ object.subject.line
57
+ when subject.respond_to?(:line) && subject.line.is_a?(Numeric) && subject.line >= 0
58
+ subject.line
59
+ else
60
+ -1
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ # @return [String] string equivalent of object's line number
67
+ def line_expr
68
+ line >= 0 ? " on line #{line.to_s}" : ''
69
+ end
70
+ end # class Change
71
+ end # module Duxml
@@ -0,0 +1,34 @@
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/change')
4
+
5
+ module Duxml
6
+ module ChangeAttr; end
7
+
8
+ # created when Element has an attribute already and its value has been changed
9
+ class ChangeAttrClass < ChangeClass
10
+ include ChangeAttr
11
+
12
+ # @param _subject [Duxml::Element] parent doc whose attribute changed
13
+ # @param _attr_name [String] name of the changed attribute
14
+ # @param _old_value [String] old attribute value
15
+ def initialize(_subject, _attr_name, _old_value)
16
+ super _subject
17
+ @attr_name, @old_value = _attr_name, _old_value
18
+ end
19
+
20
+ attr_reader :attr_name, :old_value
21
+ end # class ChangeAttributeClass
22
+
23
+ module ChangeAttr
24
+ # @return [String] new value of attribute
25
+ def value
26
+ subject[attr_name]
27
+ end
28
+
29
+ # @return [String] self description
30
+ def description
31
+ "#{super} #{subject.description}'s @#{attr_name} changed value from '#{old_value}' to '#{value}'."
32
+ end
33
+ end # module ChangeAttribute
34
+ end # module Duxml
@@ -0,0 +1,33 @@
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/change')
4
+
5
+ module Duxml
6
+ module ChangeText; end
7
+ # created when doc has text and text has been changed
8
+ class ChangeTextClass < ChangeClass
9
+ include ChangeText
10
+
11
+ # @param _subject [Duxml::Element] parent doc whose text has changed
12
+ # @param _index [Fixnum] index of parent's nodes that text is found at
13
+ # @param _old_text [String] string that was replaced
14
+ def initialize(_subject, _index, _old_text)
15
+ super _subject
16
+ @index, @old_text = _index, _old_text
17
+ end
18
+
19
+ attr_reader :index, :old_text
20
+ end
21
+
22
+ module ChangeText
23
+ # @return [String] self description
24
+ def description
25
+ "#{super} #{subject.description}'s text at index #{index} changed from '#{old_text}' to '#{text}'."
26
+ end
27
+
28
+ # @return [String] new content (subsequent changes may mean this new content no longer exists in its original form!)
29
+ def text
30
+ subject.nodes[index]
31
+ end
32
+ end # module ChangeText
33
+ end # module Duxml
@@ -0,0 +1,25 @@
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/change')
4
+
5
+ module Duxml
6
+ module Error
7
+ def error?
8
+ true
9
+ end
10
+ end # class Error
11
+
12
+ # do not use except to subclass
13
+ class ErrorClass < ChangeClass
14
+ include Error
15
+
16
+ # @param _rule [Rule] rule that was violated
17
+ # @param _change_or_pattern [ChangeClass, PatternClass] can be triggered by a change or a pattern found in a static document
18
+ def initialize(_rule, _change_or_pattern)
19
+ super(_rule)
20
+ @object = _change_or_pattern
21
+ end
22
+ alias_method :rule, :subject
23
+ end
24
+
25
+ end # module Duxml
@@ -0,0 +1,33 @@
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/change')
4
+
5
+ module Duxml
6
+ module NewAttr; end
7
+
8
+ # created when doc gains a new attribute
9
+ class NewAttrClass < ChangeClass
10
+ include NewAttr
11
+
12
+ # @param _subject [Duxml::Element] parent doc
13
+ # @param _attr_name
14
+ def initialize(_subject, _attr_name)
15
+ super(_subject)
16
+ @attr_name = _attr_name
17
+ end
18
+
19
+ attr_reader :attr_name
20
+ end
21
+
22
+ module NewAttr
23
+ # @return [String] value of the new attribute
24
+ def value
25
+ subject[attr_name]
26
+ end
27
+
28
+ # @return [String] self description
29
+ def description
30
+ "#{super} #{subject.description} given new attribute '#{attr_name}' with value '#{value}'."
31
+ end
32
+ end # module NewAttribute
33
+ end # module Duxml
@@ -0,0 +1,37 @@
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/change')
4
+
5
+ module Duxml
6
+ module NewText; end
7
+
8
+ # created when object had no children or text and text has been added
9
+ class NewTextClass < ChangeClass
10
+ include NewText
11
+
12
+ # @param _subject [Duxml::Element] doc that has gained new text
13
+ # @param _index [Fixnum] index of new text node
14
+ def initialize(_subject, _index)
15
+ super _subject
16
+ @index = _index
17
+ end
18
+
19
+ attr_reader :index
20
+ end
21
+
22
+ module NewText
23
+ def text
24
+ subject.nodes[index]
25
+ end
26
+ alias_method :object, :text
27
+
28
+ # @return [String] self description
29
+ def description
30
+ "#{super} #{subject.description} given new text '#{text}'."
31
+ end
32
+
33
+ def line_expr
34
+ subject.line < 0 ? '' : " on line #{subject.line}"
35
+ end
36
+ end # class NewContent
37
+ end # module Duxml
@@ -0,0 +1,22 @@
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/error')
4
+
5
+ module Duxml
6
+ module QualifyError; end
7
+
8
+ # created when grammar detects error from user input
9
+ class QualifyErrorClass < ErrorClass
10
+ include QualifyError
11
+
12
+ alias_method :bad_change, :object
13
+ end
14
+
15
+ module QualifyError
16
+
17
+ def description
18
+ rule_str = rule.respond_to?(:validate) ? 'not allowed by this Grammar' : "violates #{rule.description}"
19
+ "Qualify Error #{super} #{bad_change.description} #{rule_str}."
20
+ end
21
+ end # module QualifyError
22
+ end # module Duxml
@@ -0,0 +1,28 @@
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/change')
4
+
5
+ module Duxml
6
+ module Remove; end
7
+
8
+ # created when doc loses a child
9
+ class RemoveClass < ChangeClass
10
+ include Remove
11
+ # @param _subject [Dux::Element] parent doc that lost child
12
+ # @param _child [Dux::Element] removed child; it gets added as child of this Remove object so it never actually goes away
13
+ def initialize(_subject, _child)
14
+ super(_subject)
15
+ @removed = _child
16
+ end
17
+
18
+ attr_reader :removed
19
+ alias_method :object, :removed
20
+ end
21
+
22
+ module Remove
23
+ # @return [String] describes removal event
24
+ def description
25
+ %(#{super} #{removed.description} removed from #{subject.description}.)
26
+ end
27
+ end # module Remove
28
+ end # module Duxml
@@ -0,0 +1,24 @@
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../grammar/pattern')
4
+
5
+ module Duxml
6
+ # TODO NOT IMPLEMENTED YET!!!
7
+ module Undo; end
8
+
9
+ # created when a previous change is undone
10
+ class UndoClass < ChangeClass
11
+ include Undo
12
+ end
13
+
14
+ module Undo
15
+ def description
16
+ "#{super} change '#{subject.id}' undone."
17
+ end
18
+
19
+ # returns previous change instance that was undone
20
+ def undone_change
21
+ self[:change]
22
+ end
23
+ end
24
+ end # module Duxml
@@ -0,0 +1,21 @@
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/error')
4
+
5
+ module Duxml
6
+ module ValidateError; end
7
+
8
+ # created when grammar detects error from file
9
+ class ValidateErrorClass < ErrorClass
10
+ include ValidateError
11
+
12
+ alias_method :bad_pattern, :object
13
+ end
14
+
15
+ module ValidateError
16
+ def description
17
+ rule_str = rule.respond_to?(:validate) ? 'not allowed by this Grammar' : "violates #{rule.description}"
18
+ "Validate Error #{super} #{bad_pattern.description} #{rule_str}."
19
+ end
20
+ end # module ValidateError
21
+ end # module Duxml