Skip to content

Commit

Permalink
Add definedBy validation
Browse files Browse the repository at this point in the history
Signed-off-by: Afonso Oliveira <[email protected]>
  • Loading branch information
AFOliveira committed Dec 9, 2024
1 parent db49639 commit 0a02874
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 2 deletions.
26 changes: 24 additions & 2 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,37 @@ namespace :test do
end
task schema: "gen:arch" do
validator = Validator.instance
puts "Checking arch files against schema.."
puts "Checking arch files against schema..."
arch_files = Dir.glob("#{$root}/arch/**/*.yaml")
progressbar = ProgressBar.create(total: arch_files.size)

incorrect_defined_by_files = []

arch_files.each do |f|
progressbar.increment
validator.validate(f)

# Only check definedBy for instructions
if f.include?("/inst/")
yaml_content = YamlLoader.load(f, permitted_classes: [Date])
if defined_by = yaml_content['definedBy']
unless validator.valid_defined_by?(defined_by)
incorrect_defined_by_files << f
end
end
end
end

if incorrect_defined_by_files.any?
puts "\nThe following instruction files have incorrectly formatted 'definedBy' fields:"
incorrect_defined_by_files.each do |file|
puts " #{Pathname.new(file).relative_path_from($root)}"
end
exit 1
end

Rake::Task["test:insts"].invoke
puts "All files validate against their schema"
puts "All files validate against their schema"
end
task idl_model: ["gen:arch", "#{$root}/.stamps/arch-gen-_32.stamp", "#{$root}/.stamps/arch-gen-_64.stamp"] do
print "Parsing IDL code for RV32..."
Expand Down
38 changes: 38 additions & 0 deletions lib/validate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -275,4 +275,42 @@ def validate_instruction(path)
validate_instruction_encoding(inst_name, obj["encoding"]["RV64"])
end
end
# Validate the format of a definedBy field in an instruction file
#
# @param defined_by [String, Hash] The definedBy field to validate
# @return [Boolean] true if the field format is valid, false otherwise
# - String must be non-empty and without commas
# - Hash must have single key (anyOf/oneOf/allOf) with array or comma-separated list values
def valid_defined_by?(defined_by)
return false if defined_by.nil?

case defined_by
when String
# Simple string case - shouldn't contain commas
!defined_by.include?(',') && !defined_by.strip.empty?
when Hash
# Only allow one key which must be anyOf, oneOf, or allOf
return false unless defined_by.size == 1
key = defined_by.keys.first
return false unless ['anyOf', 'oneOf', 'allOf'].include?(key)

value = defined_by[key]
case value
when Array
# Each array element should be a simple string without commas
value.all? { |v| v.is_a?(String) && !v.include?(',') && !v.strip.empty? }
when String
# Also accept the compact form: anyOf: [C,Zca]
# Split by comma and/or brackets, strip whitespace and validate
elements = value.gsub(/[\[\]]/, '').split(',').map(&:strip)
elements.all? { |v| !v.empty? }
else
false
end
else
false
end
end

end

0 comments on commit 0a02874

Please sign in to comment.