main 98594d0

casing.go RawHistoryFolder

1// SPDX-License-Identifier: MIT
2
3//go:build ignore
4
5// Command casing reads the JSON produced by casing_dump.mjs on stdin and
6// writes casing_tables.go (to the file given with -o, else on stdout). Only the code points whose JavaScript
7// mapping differs from the Go simple mapping (unicode.ToUpper/ToLower) are
8// emitted: multi-character expansions (U+00DF to "SS") and Unicode version
9// differences between Go and the JavaScript engine.
10package main
11
12import (
13	"encoding/json"
14	"flag"
15	"fmt"
16	"go/format"
17	"io"
18	"os"
19	"sort"
20	"strconv"
21	"unicode"
22)
23
24type dump struct {
25	Upper map[string]string `json:"upper"`
26	Lower map[string]string `json:"lower"`
27}
28
29func main() {
30	out := flag.String("o", "", "output file (default stdout)")
31	flag.Parse()
32	var d dump
33	if err := json.NewDecoder(os.Stdin).Decode(&d); err != nil {
34		fmt.Fprintln(os.Stderr, err)
35		os.Exit(1)
36	}
37	// Everything is printed to a pipe, gofmt-ed and then written, so that the
38	// generated file is already in canonical form.
39	r, w, err := os.Pipe()
40	if err != nil {
41		fatal(err)
42	}
43	stdout := os.Stdout
44	os.Stdout = w
45	done := make(chan []byte)
46	go func() {
47		b, _ := io.ReadAll(r)
48		done <- b
49	}()
50	defer func() {
51		_ = w.Close()
52		os.Stdout = stdout
53		src, err := format.Source(<-done)
54		if err != nil {
55			fatal(err)
56		}
57		if *out == "" {
58			_, _ = stdout.Write(src)
59			return
60		}
61		if err := os.WriteFile(*out, src, 0o644); err != nil {
62			fatal(err)
63		}
64	}()
65	fmt.Println("// SPDX-License-Identifier: MIT")
66	fmt.Println()
67	fmt.Println("// Code generated by gen/casing.go from gen/casing_dump.mjs; DO NOT EDIT.")
68	fmt.Println()
69	fmt.Println("package expr")
70	fmt.Println()
71	fmt.Println("// casingGoUnicodeVersion is the Unicode version of the Go toolchain that generated")
72	fmt.Println("// the tables below: they are relative to its unicode.ToUpper and unicode.ToLower.")
73	fmt.Printf("const casingGoUnicodeVersion = %q\n", unicode.Version)
74	fmt.Println()
75	emit("jsUpperDelta", "JavaScript String.prototype.toUpperCase", d.Upper, unicode.ToUpper)
76	emit("jsLowerDelta", "JavaScript String.prototype.toLowerCase (without the Final_Sigma context)", d.Lower, unicode.ToLower)
77}
78
79func emit(name, doc string, m map[string]string, goMap func(rune) rune) {
80	// Include code points that JavaScript maps to themselves but Go does not.
81	type entry struct {
82		cp rune
83		s  string
84	}
85	var out []entry
86	seen := map[rune]bool{}
87	for k, v := range m {
88		n, _ := strconv.Atoi(k)
89		r := rune(n)
90		seen[r] = true
91		if string(goMap(r)) != v {
92			out = append(out, entry{r, v})
93		}
94	}
95	for r := rune(0); r <= unicode.MaxRune; r++ {
96		if r >= 0xd800 && r <= 0xdfff || seen[r] {
97			continue
98		}
99		if goMap(r) != r {
100			out = append(out, entry{r, string(r)})
101		}
102	}
103	sort.Slice(out, func(i, j int) bool { return out[i].cp < out[j].cp })
104	fmt.Printf("// %s maps the code points whose %s result differs from the Go simple mapping.\n", name, doc)
105	fmt.Printf("var %s = map[rune]string{\n", name)
106	for _, e := range out {
107		fmt.Printf("\t0x%04X: %s, // %s\n", e.cp, strconv.Quote(e.s), strconv.QuoteToGraphic(string(e.cp)))
108	}
109	fmt.Println("}")
110	fmt.Println()
111}
112
113func fatal(err error) {
114	fmt.Fprintln(os.Stderr, err)
115	os.Exit(1)
116}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 3

↑↓ moveenter openesc close