main 602baa7

layout.go RawHistoryFolder

1package main
2
3import "strconv"
4
5// packetFixed computes the minimum complete packet size. The first XML byte
6// occupies byte 1; the implicit sequence/length header follows that byte.
7func packetFixed(m *Module, n *Node, reply bool) (int, error) {
8	off := 1
9	if n.Attr["no-sequence-number"] == "true" {
10		off = 1
11	}
12	for _, f := range n.Children {
13		if f.Kind == "doc" {
14			continue
15		}
16		size := 0
17		switch f.Kind {
18		case "pad":
19			if a := f.Attr["align"]; a != "" {
20				align, _ := strconv.Atoi(a)
21				size = (-off) & (align - 1)
22			} else {
23				size, _ = strconv.Atoi(f.Attr["bytes"])
24			}
25		case "field", "exprfield":
26			typ, err := lookup(m, f.Attr["type"])
27			if err != nil {
28				return 0, err
29			}
30			size = typ.Size
31		case "list":
32			if len(f.Children) == 1 && f.Children[0].Kind == "value" {
33				count, _ := strconv.Atoi(f.Children[0].Text)
34				typ, err := lookup(m, f.Attr["type"])
35				if err != nil {
36					return 0, err
37				}
38				size = count * typ.Size
39			} else {
40				goto done
41			}
42		default:
43			return 0, f.fail("unsupported packet member %s", f.Kind)
44		}
45		off += size
46		if off == 2 && n.Attr["no-sequence-number"] != "true" {
47			if reply {
48				off = 8
49			} else {
50				off = 4
51			}
52		}
53	}
54done:
55	if off < 32 {
56		off = 32
57	}
58	return off, nil
59}
60func packetSizeChecks(m *Module) error {
61	for _, n := range m.Root.Children {
62		if n.Kind == "event" || n.Kind == "eventcopy" {
63			size := 32
64			if n.Kind == "event" {
65				var err error
66				size, err = packetFixed(m, n, false)
67				if err != nil {
68					return err
69				}
70			}
71			if size != 32 {
72				return n.fail("event fixed size %d, expected 32", size)
73			}
74			m.SizeChecks = append(m.SizeChecks, sizeCheck("event "+n.Attr["name"], size, 32))
75		}
76		if n.Kind == "request" {
77			for _, r := range n.Children {
78				if r.Kind != "reply" {
79					continue
80				}
81				size, err := packetFixed(m, r, true)
82				if err != nil {
83					return err
84				}
85				expected := 32
86				if m.Header == "xproto" {
87					switch n.Attr["name"] {
88					case "QueryKeymap":
89						expected = 40
90					case "GetKeyboardControl":
91						expected = 52
92					case "GetWindowAttributes":
93						expected = 44
94					case "QueryFont", "ListFontsWithInfo":
95						expected = 60
96					}
97				}
98				m.SizeChecks = append(m.SizeChecks, sizeCheck("reply "+n.Attr["name"], size, expected))
99			}
100		}
101	}
102	return nil
103}

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 1

↑↓ moveenter openesc close