Skip to content

Commit bce9aa6

Browse files
committed
[herd-www] Support every Arm ARM release for all catalogues
1 parent c2c93d9 commit bce9aa6

File tree

7 files changed

+181
-30
lines changed

7 files changed

+181
-30
lines changed

herd-www/Makefile

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
CAT2HTML7=$(if $(shell which cat2html7), cat2html7, ../_build/default/tools/cat2html.exe)
2-
BOOKS=aarch64 aarch64-ifetch aarch64-mixed aarch64-MTE aarch64-MTE-mixed aarch64-VMSA aarch64-ETS2 aarch64-faults bpf x86 linux
2+
AARCH64_BOOKS= aarch64 aarch64-ifetch aarch64-mixed aarch64-MTE aarch64-MTE-mixed aarch64-VMSA aarch64-ETS2 aarch64-faults
3+
BOOKS= $(AARCH64_BOOKS) bpf x86 linux
34
WWW_CATALOGUE=www/catalogue
45
HERD_CATALOGUE=../catalogue
56
PROG=jerd.js
67
WWW_PROG=www/$(PROG)
78
WWW_LIB=www/weblib
89
JSON_SHELVES=$(foreach book,$(BOOKS),$(WWW_CATALOGUE)/$(book)/shelf.json)
10+
ARM_ARM_RELEASES=$(wildcard ../herd/libdir/aarch64/*)
11+
ENV_PAIRS := $(foreach d,$(ARM_ARM_RELEASES),$(notdir $(d)) $(d))
912
CATINCLUDES=../herd/libdir linux $(foreach b,$(BOOKS),$(HERD_CATALOGUE)/$(b)/cats)
10-
CATINCLUDESDEP=$(foreach d,$(CATINCLUDES),$(wildcard $(d)/*.*))
13+
CATINCLUDESDEP=$(foreach d,$(CATINCLUDES) $(ARM_ARM_RELEASES),$(wildcard $(d)/*.*))
1114
DUNETGT=../_build/default/herd-www
1215
all: web
1316

@@ -22,6 +25,12 @@ define make-book
2225
$(WWW_CATALOGUE)/$1/:
2326
mkdir -p $(WWW_CATALOGUE)
2427
rsync -a --copy-unsafe-links --delete $(HERD_CATALOGUE)/$1/ $(WWW_CATALOGUE)/$1/
28+
$(if $(filter $1,$(AARCH64_BOOKS)), \
29+
$(foreach d,$(ARM_ARM_RELEASES), \
30+
mkdir -p $(WWW_CATALOGUE)/$1/cats/$(notdir $(d)) && \
31+
cp $(d)/aarch64.cat $(WWW_CATALOGUE)/$1/cats/$(notdir $(d))/aarch64.cat; \
32+
) \
33+
,)
2534

2635
.PHONY:: $(WWW_CATALOGUE)/$1/
2736
endef
@@ -40,7 +49,7 @@ $(PROG): catIncludes.ml force
4049
cp $(DUNETGT)/jerd.bc.js $(PROG) && chmod u+w $(PROG)
4150

4251
catIncludes.ml: generate_includes.ml $(CATINCLUDESDEP)
43-
ocaml ./generate_includes.ml -norec $(CATINCLUDES) > $@
52+
ocaml ./generate_includes.ml -norec -envs $(ENV_PAIRS) -- $(CATINCLUDES) > $@
4453

4554
$(foreach book,$(BOOKS),$(eval $(call make-json-shelf,$(book))))
4655
$(foreach book,$(BOOKS),$(eval $(call make-book,$(book))))

herd-www/catalogue_to_json.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,31 @@
22

33
import importlib
44
import json
5-
import re
5+
import os
66
import sys
7+
from glob import glob
8+
9+
def discover_release_cats():
10+
"""
11+
Discover extra aarch64.cat files under:
12+
cats/*/aarch64.cat
13+
14+
Returns paths relative to the book directory, e.g.:
15+
cats/ArmARM-L.b/aarch64.cat
16+
"""
17+
matches = glob(os.path.join('cats', '*', 'aarch64.cat'))
18+
# Normalize to forward slashes for JSON / browser use
19+
return sorted(m.replace(os.sep, '/') for m in matches)
720

821
def jsonify(fname):
922
m = importlib.import_module(fname)
23+
24+
base_cats = list(m.cats)
25+
extra_cats = discover_release_cats()
26+
1027
j = json.dumps({
1128
'record' : m.record,
12-
'cats' : m.cats,
29+
'cats' : base_cats + extra_cats,
1330
'illustrative_tests' : m.illustrative_tests,
1431
'cfgs' : m.cfgs,
1532
'bells' : m.bells if 'bells' in dir(m) else None,

herd-www/generate_includes.ml

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ let output_header () =
2222
Printf.printf
2323
"(* Warning: file generated by ./generate_includes.ml DO NOT EDIT *)\n\n"
2424

25-
let output_env fs =
25+
let output_env env_names fs =
26+
let formatted_names = List.map (Printf.sprintf "%S") env_names in
27+
Printf.printf "let envs = [%s]\n" (String.concat "; " formatted_names);
2628
Printf.printf "let map_env = StringMap.empty\n" ;
2729
List.iter
2830
(fun (k,cts) ->
@@ -35,8 +37,12 @@ let output_env fs =
3537
let output_postlude () =
3638
let pp s = Printf.printf "%s\n" s in
3739
pp "let autoloader ~prefix ~path =" ;
40+
pp " let dir = Filename.basename prefix in" ;
41+
pp " let fname = if List.exists (String.equal dir) envs then" ;
42+
pp " Filename.concat dir path" ;
43+
pp " else path in" ;
3844
pp " try" ;
39-
pp " ignore (prefix) ; Some (StringMap.find path map_env)" ;
45+
pp " Some (StringMap.find fname map_env)" ;
4046
pp " with Not_found -> None" ;
4147
()
4248

@@ -84,30 +90,73 @@ let rec all_files do_rec m path d =
8490
done ;
8591
!mr
8692

93+
let do_rec = ref false
94+
let envs = ref []
95+
8796
let bind d f =
8897
let g = Filename.concat d (Filename.basename f) in
8998
f,read_file g
9099

91100
let _ =
92101
let mr = ref StringMap.empty in
93-
let k0,do_rec =
94-
if Array.length Sys.argv < 2 then 1,false
95-
else
96-
match Sys.argv.(1) with
97-
| "-rec" -> 2,true
98-
| "-norec" -> 2,false
99-
| _ -> 1,true in
100-
for k = k0 to Array.length Sys.argv-1 do
101-
mr := all_files do_rec !mr "" Sys.argv.(k)
102-
done ;
102+
let i = ref 1 in
103+
let argc = Array.length Sys.argv in
104+
let dirs = ref [] in
105+
106+
let rec parse () =
107+
if !i >= argc then ()
108+
else match Sys.argv.(!i) with
109+
| "-rec" ->
110+
do_rec := true ;
111+
incr i ;
112+
parse ()
113+
| "-norec" ->
114+
do_rec := false ;
115+
incr i ;
116+
parse ()
117+
| "-envs" -> (* Self-contained cat environments, to set as libdirs.
118+
They are passed as pairs of (name, path). The name will be used
119+
as a path distinguisher inside the map_env for files under path *)
120+
incr i ;
121+
(* collect (name, dir) pairs until -- *)
122+
while !i < argc && Sys.argv.(!i) <> "--" do
123+
if !i + 1 >= argc then begin
124+
Printf.eprintf "Error: -envs expects (name dir) pairs, got dangling name.\n" ;
125+
exit 2
126+
end ;
127+
let name = Sys.argv.(!i) in
128+
let dir = Sys.argv.(!i + 1) in
129+
envs := (name, dir) :: !envs ;
130+
i := !i + 2
131+
done ;
132+
if !i < argc && Sys.argv.(!i) = "--" then incr i ;
133+
parse ()
134+
| s ->
135+
dirs := s :: !dirs ;
136+
incr i ;
137+
parse ()
138+
in
139+
parse () ;
140+
141+
let dirs = List.rev !dirs in
142+
let envs = List.rev !envs in
143+
let env_names = List.map fst envs in
144+
145+
List.iter
146+
(fun d -> mr := all_files !do_rec !mr "" d)
147+
dirs ;
148+
List.iter
149+
(fun (name, d) -> mr := all_files !do_rec !mr name d)
150+
envs ;
151+
103152
begin match Filename.basename prog with
104153
| "generate_includes.ml" ->
105154
let files =
106155
StringMap.fold
107156
(fun f d k -> bind d f::k)
108157
!mr [] in
109158
output_header () ;
110-
output_env files ;
159+
output_env env_names files ;
111160
output_postlude ()
112161
| "generate_names.ml" ->
113162
let files =

herd-www/jerd.ml

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,30 @@ let set_defaults () =
6464
show := default.show
6565

6666
(* Configure parser/models/etc. *)
67-
let run_herd bell cat litmus cfg =
67+
let run_herd bell cat litmus cfg cat_label =
6868

6969
let bell = Js.to_string bell
7070
and cat = Js.to_string cat
7171
and litmus = Js.to_string litmus
72-
and cfg = Js.to_string cfg in
72+
and cfg = Js.to_string cfg
73+
and cat_label = Js.to_string cat_label in
74+
75+
let cat_env_opt = match String.split_on_char '/' cat_label with
76+
| [env; _] -> Some env
77+
| _ -> None in
7378

7479
if dbg then begin
75-
eprintf "** bell **\n%s" bell ;
76-
eprintf "** cat **\n%s" cat ;
77-
eprintf "** cfg **\n%s" cfg ;
78-
eprintf "** lit **\n%s" litmus ;
80+
eprintf "** bell **\n%s\n" bell ;
81+
eprintf "** cat **\n%s\n" cat ;
82+
eprintf "** cfg **\n%s\n" cfg ;
83+
eprintf "** lit **\n%s\n" litmus ;
84+
eprintf "** cat_label **\n%s\n" cat_label ;
85+
begin match cat_env_opt with
86+
| Some env ->
87+
eprintf "** cat_env **\n%s\n" env
88+
| None ->
89+
eprintf "** cat_env **\n<none>\n"
90+
end;
7991
()
8092
end ;
8193

@@ -111,11 +123,15 @@ let run_herd bell cat litmus cfg =
111123
end ;
112124
let args = ref [Filename.concat WebInput.webpath litmus_fname] in
113125

126+
let includes = Option.fold ~some:(fun env ->
127+
WebInput.get_env_webpath env :: !includes
128+
) ~none:!includes cat_env_opt in
129+
114130
(* Read generic model, if any *)
115131
let module ML =
116132
MyLib.Make
117133
(struct
118-
let includes = !includes
134+
let includes = includes
119135
let env = None
120136
let libdir = Version.libdir
121137
let debug = false

herd-www/webInput.ml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ let autoloader ~prefix ~path =
7575
try pp path (CatIncludes.autoloader ~prefix:prefix ~path:path)
7676
with Not_found -> None
7777

78+
let get_env_webpath path =
79+
Filename.concat webpath path
80+
7881
let register_autoloader () =
79-
Js_of_ocaml.Sys_js.unmount ~path:webpath ;
80-
Js_of_ocaml.Sys_js.mount ~path:webpath autoloader
82+
let paths = webpath :: List.map get_env_webpath CatIncludes.envs in
83+
List.iter (fun webpath ->
84+
Js_of_ocaml.Sys_js.unmount ~path:webpath ;
85+
Js_of_ocaml.Sys_js.mount ~path:webpath autoloader
86+
) paths

herd-www/webInput.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,8 @@ val set_cat_str : string -> string
2323
val set_cfg_str : string -> string
2424
val set_litmus_str : string -> string
2525

26+
(* Get the full pseudo file-system path for a cat environment *)
27+
val get_env_webpath : string -> string
28+
2629
(* Initialise pseudo file-system *)
2730
val register_autoloader : unit -> unit

herd-www/www/jerd_driver.js

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ function initCurrentState() {
2121
'shelf' : null,
2222
'compatNum' : null,
2323
'campaignCode' : [],
24+
'catLabelPrefix' : '',
2425
'bell' : { 'origText' : null, 'origUrl' : null, 'pos' : null },
2526
'cat' : { 'origText' : null, 'origUrl' : null, 'pos' : null },
2627
'cfg' : { 'origText' : null, 'origUrl' : null, 'pos' : null },
@@ -42,6 +43,37 @@ function basename(path) {
4243
return path.split('/').pop()
4344
}
4445

46+
// Longest common directory prefix among a list of URLs/paths.
47+
// Example:
48+
// ["catalogue/aarch64/cats/aarch64.cat",
49+
// "catalogue/aarch64/cats/ArmARM-L.b/aarch64.cat"]
50+
// -> "catalogue/aarch64/cats/"
51+
function commonDirPrefix(urls) {
52+
if (!urls || urls.length === 0) return '';
53+
var prefix = urls[0];
54+
for (var i = 1; i < urls.length; i++) {
55+
var u = urls[i];
56+
var j = 0;
57+
while (j < prefix.length && j < u.length && prefix[j] === u[j]) j++;
58+
prefix = prefix.substring(0, j);
59+
if (prefix === '') break;
60+
}
61+
// Only keep whole-directory prefix
62+
var slash = prefix.lastIndexOf('/');
63+
return slash >= 0 ? prefix.substring(0, slash + 1) : '';
64+
}
65+
66+
// Label cats by stripping the common prefix (computed per-record).
67+
// Falls back to basename if the prefix isn't known or doesn't match.
68+
function catLabel(url) {
69+
var prefix = currentState['catLabelPrefix'] || '';
70+
if (url === null) return '';
71+
if (prefix && url.indexOf(prefix) === 0) {
72+
return url.substring(prefix.length);
73+
}
74+
return basename(url);
75+
}
76+
4577
function shortname(path) {
4678
if (path === null) {
4779
return null
@@ -258,8 +290,9 @@ function populateEditorPanelHeader(id, elems) {
258290
}
259291

260292
function prepareEditorFile(editorName, key, val, callback) {
261-
var baseVal = basename(val);
262-
var itemId = 'file-' + baseVal.replace(/\+/g, '.');
293+
var baseVal = (editorName === 'cat') ? catLabel(val) : basename(val);
294+
// baseVal may contain '/', so sanitize for HTML id usage.
295+
var itemId = 'file-' + baseVal.replace(/\+/g, '.').replace(/\//g, '__');
263296

264297
return $('<li/>')
265298
.append($('<a/>', {
@@ -333,7 +366,11 @@ function doDownloadAndSetEditorValue(url, name, pos) {
333366
currentState[name]['pos'] = pos;
334367
updateLinkToExample();
335368

336-
$(selectMenuIdOfEditorName(name)).html(basename(url));
369+
if (name === 'cat') {
370+
$(selectMenuIdOfEditorName(name)).html(catLabel(url));
371+
} else {
372+
$(selectMenuIdOfEditorName(name)).html(basename(url));
373+
}
337374

338375
editors[name].setValue(data, -1);
339376
if (name === 'litmus') {
@@ -815,6 +852,10 @@ function readRecord(record, displayName, compatNum, bellKey, catKey, cfgKey, lit
815852
currentState['displayName'] = displayName;
816853
currentState['shelf'] = resolveUrlsInShelf(result, record);
817854

855+
// Precompute the common prefix used to label cats uniquely.
856+
// resolveUrlsInShelf has expanded entries to full URLs like "catalogue/<record>/<...>".
857+
currentState['catLabelPrefix'] = commonDirPrefix(currentState['shelf']['cats'] || []);
858+
818859
updateAllEditors(compatNum, bellKey, catKey, cfgKey, litmusKey, false);
819860

820861
if (currentState['shelf']['compatibilities'] === null) {
@@ -960,11 +1001,16 @@ function jerdIt() {
9601001
var catStr = editors['cat'].getValue();
9611002
var cfgStr = editors['cfg'].getValue();
9621003
var litmusStr = editors['litmus'].getValue();
1004+
var catSelectedLabel = '';
1005+
if (currentState['cat'] && currentState['cat']['origUrl'] !== null) {
1006+
catSelectedLabel = catLabel(currentState['cat']['origUrl']);
1007+
}
9631008
runHerd(
9641009
bellStr,
9651010
catStr,
9661011
litmusStr,
9671012
cfgStr,
1013+
catSelectedLabel,
9681014
);
9691015
displayDotOutputs();
9701016
}
@@ -980,12 +1026,17 @@ function jerdAll() {
9801026
var cfgStr = editors['cfg'].getValue();
9811027
var catStr = editors['cat'].getValue();
9821028
var litmusStr = data;
1029+
var catSelectedLabel = '';
1030+
if (currentState['cat'] && currentState['cat']['origUrl'] !== null) {
1031+
catSelectedLabel = catLabel(currentState['cat']['origUrl']);
1032+
}
9831033

9841034
runHerd(
9851035
bellStr,
9861036
catStr,
9871037
litmusStr,
9881038
cfgStr,
1039+
catSelectedLabel,
9891040
);
9901041

9911042
var herdOutput = editors['herdoutput'].getValue();

0 commit comments

Comments
 (0)