File: magicgen.py

package info (click to toggle)
golang-github-checkpoint-restore-go-criu 7.2.0%2Bds1-4
  • links: PTS, VCS
  • area: main
  • in suites: experimental, forky, sid, trixie
  • size: 1,796 kB
  • sloc: makefile: 231; ansic: 195; python: 137; sh: 110
file content (86 lines) | stat: -rw-r--r-- 2,332 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import sys
import re
import argparse


def main():
    parser = argparse.ArgumentParser(
        description="A script to generate Go bindings for the CRIU magic values provided by magic.h"
    )
    parser.add_argument("src", help="Input path (magic.h)", type=str)
    parser.add_argument("dest", help="Output path (magic.go)", type=str)

    args = parser.parse_args()

    try:
        with open(args.src, "r") as src:
            magics = read_magics(src)
    except IOError:
        sys.exit("Failed to open magic.h")

    try:
        with open(args.dest, "w") as dest:
            write_magics(dest, magics)
    except IOError:
        sys.exit("Failed to open magic.py")


def read_magics(src):
    magics = {}
    # The magic.h header file contains lines like below:
    # #define MAGIC_NAME MAGIC_VALUE
    # where the magic value can be a hexadecimal or regular
    # integer value. The regex below matches lines in the
    # header and extracts the name and value as regex groups.
    pattern = re.compile(r"#define\s+(\S+)\s+(0x[0-9A-Fa-f]+|\d+)")

    for line in src:
        match = pattern.match(line)
        if match:
            name = match.group(1)
            value_str = match.group(2)
            # If the magic is defined as another magic, skip it
            if value_str in magics:
                continue
            try:
                value = int(value_str, 16)
                magics[name] = value
            except ValueError:
                print(f"Failed to parse magic {name}")
                continue

    return magics


def write_magics(dest, magics):
    dest.write(
        """// Code generated by magicgen. DO NOT EDIT.

package magic

type MagicMap struct {
\tByName  map[string]uint64
\tByValue map[uint64]string
}

func LoadMagic() MagicMap {
\tmagicMap := MagicMap{
\t\tByName:  make(map[string]uint64),
\t\tByValue: make(map[uint64]string),
\t}"""
    )

    for name in sorted(magics.keys()):
        value = magics[name]
        # Ignore RAW_IMAGE_MAGIC and V1 magic
        if value == 0 or value == 1:
            continue
        name = name.replace("_MAGIC", "")
        dest.write(f'\n\tmagicMap.ByName["{name}"] = {value}')
        dest.write(f'\n\tmagicMap.ByValue[{value}] = "{name}"')

    dest.write("\n\treturn magicMap\n}\n")


if __name__ == "__main__":
    main()