Skip to content

Commit 1660fd9

Browse files
Merge pull request #128 from riscv/127-create-error-if-normative-rule-names-start-with-norm
Error if norm rule name starts with "norm:". Also display num of parameters.
2 parents 8e51e9f + 0eaff1a commit 1660fd9

File tree

2 files changed

+38
-20
lines changed

2 files changed

+38
-20
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ CREATE_NORM_RULE_TOOL := $(TOOLS_DIR)/create_normative_rules.rb
2929
CREATE_NORM_RULE_RUBY := ruby $(CREATE_NORM_RULE_TOOL)
3030

3131
# Stuff for building mock standards document in HTML to have links into it.
32-
DOCS = "test"
32+
DOCS = test
3333
DOCS_HTML := $(addprefix $(BUILD_DIR)/, $(addsuffix .html, $(DOCS)))
3434
ENV := LANG=C.utf8
3535
ASCIIDOCTOR_HTML := $(ENV) asciidoctor

tools/create_normative_rules.rb

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ def parse_argv
242242
tag_fname2url={}
243243
output_fname=nil
244244
output_format="json"
245-
warn_if_tags_no_rules = 0
245+
warn_if_tags_no_rules = false
246246

247247
i = 0
248248
while i < ARGV.count
@@ -259,7 +259,7 @@ def parse_argv
259259
when "-h"
260260
output_format = "html"
261261
when "-w"
262-
warn_if_tags_no_rules = 1
262+
warn_if_tags_no_rules = true
263263
when "-d"
264264
if (ARGV.count-i) < 1
265265
info("Missing argument for -d option")
@@ -458,25 +458,33 @@ def validate_defs_and_tags(defs, tags, warn_if_tags_no_rules)
458458
fatal("Need NormativeTags for tags but was passed a #{tags.class}") unless tags.is_a?(NormativeTags)
459459

460460
missing_tag_cnt = 0
461+
bad_norm_rule_name_cnt = 0
461462
unref_cnt = 0
462463
referenced_tags = {} # Key is tag name and value is any non-nil value
463464
rule_name_lengths = []
464465
tag_name_lengths = []
465466

466-
# Detect missing tags and unreferenced tags.
467+
# Go through each normative rule definition. Look for:
468+
# - References to non-existant tags
469+
# - Normative rule names starting with "norm:" prefix (should only be for tags)
467470
defs.norm_rule_defs.each do |d|
468471
unless d.tag_refs.nil?
469472
d.tag_refs.each do |tag_ref|
470473
# Lookup tag by its name
471474
tag = tags.get_tag(tag_ref)
472475

473476
if tag.nil?
474-
missing_tag_cnt = missing_tag_cnt + 1
475-
error("Normative rule #{d.name} defined in file #{d.def_filename} references non-existent tag #{tag_ref}")
477+
missing_tag_cnt += 1
478+
error("Normative rule #{d.name} references non-existent tag #{tag_ref} in file #{d.def_filename}")
476479
else
477480
referenced_tags[tag.name] = 1 # Any non-nil value
478481
end
479482
end
483+
484+
if d.name.start_with?("norm:")
485+
bad_norm_rule_name_cnt += 1
486+
error("Normative rule #{d.name} starts with \"norm:\" prefix. This prefix is only for tag names, not rule names.")
487+
end
480488
end
481489

482490
# Increment length (ensure it isn't nil first with ||=)
@@ -488,7 +496,7 @@ def validate_defs_and_tags(defs, tags, warn_if_tags_no_rules)
488496
tags.get_tags.each do |tag|
489497
if referenced_tags[tag.name].nil?
490498
msg = "Tag #{tag.name} not referenced by any normative rule. Did you forget to define a normative rule?"
491-
if warn_if_tags_no_rules == 1
499+
if warn_if_tags_no_rules
492500
info(msg)
493501
else
494502
error(msg)
@@ -505,16 +513,22 @@ def validate_defs_and_tags(defs, tags, warn_if_tags_no_rules)
505513
error("#{missing_tag_cnt} reference#{missing_tag_cnt == 1 ? "" : "s"} to non-existing tags")
506514
end
507515

516+
if bad_norm_rule_name_cnt > 0
517+
error("#{bad_norm_rule_name_cnt} illegal normative rule name#{bad_norm_rule_name_cnt == 1 ? "" : "s"}")
518+
end
519+
508520
if unref_cnt > 0
509521
msg = "#{unref_cnt} tag#{unref_cnt == 1 ? "" : "s"} have no normative rules referencing them"
510-
if warn_if_tags_no_rules == 1
522+
if warn_if_tags_no_rules
511523
info(msg)
512524
else
513525
error(msg)
514526
end
515527
end
516528

517-
fatal("Exiting due to errors") if ((missing_tag_cnt > 0) || ((unref_cnt > 0) && (warn_if_tags_no_rules == 0)))
529+
if (missing_tag_cnt > 0) || (bad_norm_rule_name_cnt > 0) || ((unref_cnt > 0) && !warn_if_tags_no_rules)
530+
fatal("Exiting due to errors")
531+
end
518532

519533
# Display counts of name lengths.
520534
#info("")
@@ -536,11 +550,6 @@ def output_json(filename, normative_rules_hash)
536550
fatal("Need String for filename but passed a #{filename.class}") unless filename.is_a?(String)
537551
fatal("Need Hash<String, Array> for normative_rules_hash but passed a #{normative_rules_hash.class}") unless normative_rules_hash.is_a?(Hash)
538552

539-
nr_array = normative_rules_hash["normative_rules"]
540-
raise "Expecting an array for key normative_rules but got an #{nr_array.class}" unless nr_array.is_a?(Array)
541-
542-
info("Storing #{nr_array.count} normative rules into file #{filename}")
543-
544553
# Serialize normative_rules_hash to JSON format String.
545554
# Shouldn't throw exceptions since we created the data being serialized.
546555
serialized_string = JSON.pretty_generate(normative_rules_hash)
@@ -565,8 +574,6 @@ def output_xlsx(filename, defs, tags)
565574
fatal("Need NormativeRuleDefs for defs but passed a #{defs.class}") unless defs.is_a?(NormativeRuleDefs)
566575
fatal("Need NormativeTags for tags but passed a #{tags.class}") unless tags.is_a?(NormativeTags)
567576

568-
info("Storing #{defs.norm_rule_defs.count} normative rules into file #{filename}")
569-
570577
# Create a new Excel workbook
571578
info("Creating Excel workbook #{filename}")
572579
workbook = WriteXLSX.new(filename)
@@ -649,8 +656,6 @@ def output_adoc(filename, defs, tags, tag_fname2url)
649656
fatal("Need NormativeTags for tags but passed a #{tags.class}") unless tags.is_a?(NormativeTags)
650657
fatal("Need Hash for tag_fname2url but passed a #{tag_fname2url.class}") unless tag_fname2url.is_a?(Hash)
651658

652-
info("Storing #{defs.norm_rule_defs.count} normative rules into file #{filename}")
653-
654659
# Organize rules by chapter name. Each hash key is chapter name. Each hash entry is an Array<NormativeRuleDef>
655660
defs_by_chapter_name = {}
656661
defs.norm_rule_defs.each do |d|
@@ -703,8 +708,6 @@ def output_html(filename, defs, tags, tag_fname2url)
703708
fatal("Need NormativeTags for tags but passed a #{tags.class}") unless tags.is_a?(NormativeTags)
704709
fatal("Need Hash for tag_fname2url but passed a #{tag_fname2url.class}") unless tag_fname2url.is_a?(Hash)
705710

706-
info("Storing #{defs.norm_rule_defs.count} normative rules into file #{filename}")
707-
708711
# Organize rules by chapter name. Each hash key is chapter name. Each hash entry is an Array<NormativeRuleDef>
709712
defs_by_chapter_name = {}
710713
chapter_names=[]
@@ -1010,6 +1013,18 @@ def truncate_after_newlines(text, max_newlines)
10101013
truncated_text
10111014
end
10121015

1016+
def count_parameters(defs)
1017+
raise ArgumentError, "Need NormativeRuleDefs for defs but passed a #{defs.class}" unless defs.is_a?(NormativeRuleDefs)
1018+
1019+
num_parameters = 0
1020+
1021+
defs.norm_rule_defs.each do |d|
1022+
num_parameters += 1 if d.kind == "parameter"
1023+
end
1024+
1025+
return num_parameters
1026+
end
1027+
10131028
# Convert newlines to <br>.
10141029
def html_handle_newlines(text)
10151030
raise ArgumentError, "Expected String for text but was passed a #{text}.class" unless text.is_a?(String)
@@ -1035,6 +1050,9 @@ def html_handle_newlines(text)
10351050
tags = load_tags(tag_fnames)
10361051
validate_defs_and_tags(defs, tags, warn_if_tags_no_rules)
10371052

1053+
info("Storing #{defs.norm_rule_defs.count} normative rules into file #{output_fname}")
1054+
info("Includes #{count_parameters(defs)} parameters")
1055+
10381056
case output_format
10391057
when "json"
10401058
normative_rules_hash = create_normative_rules_hash(defs, tags, tag_fname2url)

0 commit comments

Comments
 (0)