Skip to content

Commit 23b68f9

Browse files
authored
Add validation for xref fallback text (#3210)
* Fix xref fallback syntax Signed-off-by: Petar Andric <slate@null.net> * Add xref fallback validation Signed-off-by: Petar Andric <slate@null.net> --------- Signed-off-by: Petar Andric <slate@null.net>
1 parent 5c67cb8 commit 23b68f9

4 files changed

Lines changed: 85 additions & 4 deletions

File tree

Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ REQUIRES := --require=asciidoctor-bibtex \
144144
--require=asciidoctor-sail
145145

146146
.PHONY: all build clean build-container build-no-container build-docs build-pdf build-html build-epub build-tags docker-pull-latest submodule-check
147-
.PHONY: build-norm-rules build-norm-rules-json build-norm-rules-html check-tags update-ref
147+
.PHONY: build-norm-rules build-norm-rules-json build-norm-rules-html check-tags update-ref check-xref-fallbacks
148148

149149
all: build
150150

@@ -156,10 +156,12 @@ ifeq ("$(wildcard docs-resources/global-config.adoc)","")
156156
endif
157157

158158
build-pdf: $(DOCS_PDF)
159-
build-html: $(DOCS_HTML)
159+
build-html: $(DOCS_HTML) check-xref-fallbacks
160160
build-epub: $(DOCS_EPUB)
161161
build-tags: $(DOCS_NORM_TAGS)
162162
check-xrefs: $(addprefix $(BUILD_DIR)/, $(addsuffix .check-xrefs, $(DOCS)))
163+
check-xref-fallbacks: $(DOCS_HTML)
164+
@python3 ./scripts/check_xref_fallbacks.py $(DOCS_HTML)
163165
check-tags:
164166
@bash ./scripts/check-tag-changes.sh
165167

@@ -232,6 +234,7 @@ $(NORM_RULES_HTML): $(DOCS_NORM_TAGS) $(NORM_RULE_DEF_FILES) $(CREATE_NORM_RULE_
232234
$(BUILD_DIR)/%.check-xrefs: $(SRC_DIR)/%.adoc $(ALL_SRCS)
233235
$(WORKDIR_SETUP)
234236
$(DOCKER_CMD) $(DOCKER_QUOTE) $(ASCIIDOCTOR_HTML) -v $(OPTIONS) $(REQUIRES) $< 2>&1 | grep 'possible invalid reference' && exit 1 || [ $$? -eq 0 ] $(DOCKER_QUOTE)
237+
@[ ! -f $@.workdir/$(BUILD_DIR)/$(notdir $*).html ] && exit 0 || python3 scripts/check_xref_fallbacks.py $@.workdir/$(BUILD_DIR)/$(notdir $*).html
235238

236239
# Update docker image to latest
237240
docker-pull-latest:

scripts/check_xref_fallbacks.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/usr/bin/env python3
2+
"""Check rendered HTML for cross-reference fallback text (e.g., <a href="#ref">[ref]</a>)."""
3+
4+
import sys
5+
from html.parser import HTMLParser
6+
from pathlib import Path
7+
8+
9+
class LinkTextParser(HTMLParser):
10+
"""Extract href/text pairs from anchor elements."""
11+
12+
def __init__(self):
13+
"""Initialize parser."""
14+
super().__init__()
15+
self.in_a = False
16+
self.href = None
17+
self.text_parts = []
18+
self.links = []
19+
20+
def handle_starttag(self, tag, attrs):
21+
"""Start collecting text when entering an anchor."""
22+
if tag == "a":
23+
self.in_a = True
24+
self.href = dict(attrs).get("href", "")
25+
self.text_parts = []
26+
27+
def handle_data(self, data):
28+
"""Collect visible text while inside an anchor."""
29+
if self.in_a:
30+
self.text_parts.append(data)
31+
32+
def handle_endtag(self, tag):
33+
"""Store the completed link when leaving an anchor."""
34+
if tag == "a" and self.in_a:
35+
text = "".join(self.text_parts).strip()
36+
self.links.append((self.href, text))
37+
self.in_a = False
38+
self.href = None
39+
self.text_parts = []
40+
41+
42+
def is_fallback(text):
43+
"""Return True when link text is fully wrapped in brackets."""
44+
return bool(text) and text.startswith("[") and text.endswith("]")
45+
46+
47+
def main():
48+
"""Main execution."""
49+
if len(sys.argv) < 2:
50+
print("usage: check_xref_fallbacks.py <html-files>", file=sys.stderr)
51+
sys.exit(22)
52+
53+
found_fallback = False
54+
55+
for filename in sys.argv[1:]:
56+
path = Path(filename)
57+
html = path.read_text(encoding="utf-8", errors="replace")
58+
59+
parser = LinkTextParser()
60+
parser.feed(html)
61+
62+
bad = []
63+
for href, text in parser.links:
64+
if href.startswith("#") and is_fallback(text):
65+
bad.append((href[1:], text))
66+
67+
if bad:
68+
found_fallback = True
69+
print(f"Fallback xrefs found in {path.name}:")
70+
for href, text in bad:
71+
print(f" {href} -> {text}")
72+
73+
if found_fallback:
74+
sys.exit(1)
75+
76+
77+
if __name__ == "__main__":
78+
main()

src/unpriv/mm-explanatory.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1707,7 +1707,7 @@ are redundant with other PPO rules under RVTSO assumptions
17071707

17081708
Other general notes:
17091709

1710-
[[sec:silent-stores]]
1710+
[[silent-stores]]
17111711
* Silent stores (i.e., stores that write the same value that already
17121712
exists at a memory location) behave like any other store from a memory
17131713
model point of view. Likewise, AMOs which do not actually change the

src/unpriv/zaamo.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ implementation can guarantee the AMO eventually completes. More complex
4949
implementations might also implement AMOs at memory controllers, and can
5050
optimize away fetching the original value when the destination is `x0`.
5151
Implementations that detect silent stores may reduce write traffic for
52-
AMOs when they do not change the value in memory (see <<sec:silent-stores>>).
52+
AMOs when they do not change the value in memory (see <<silent-stores, silent stores>>).
5353
5454
The set of AMOs was chosen to support the C11/C++11 atomic memory
5555
operations efficiently, and also to support parallel reductions in

0 commit comments

Comments
 (0)