forked from SAP/cgo-ase
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gen_types.go
116 lines (96 loc) · 2.47 KB
/
gen_types.go
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// SPDX-FileCopyrightText: 2020 SAP SE
// SPDX-FileCopyrightText: 2021 SAP SE
// SPDX-FileCopyrightText: 2022 SAP SE
// SPDX-FileCopyrightText: 2023 SAP SE
//
// SPDX-License-Identifier: Apache-2.0
// +build ignore
package main
import (
"bufio"
"bytes"
"fmt"
"go/format"
"io/ioutil"
"log"
"os"
"sort"
"strconv"
"strings"
)
func main() {
file, err := os.Open("./includes/cstypes.h")
if err != nil {
log.Printf("Failed to open cstypes.h: %v", err)
return
}
defer file.Close()
scanner := bufio.NewScanner(file)
// Keep references from name to integer
typeMap := map[string]int{}
// Record all types in a string slice to sort after parsing all
// types. This is used to generate reproducible maps, preventing
// a different order with each run.
typeSlice := sort.StringSlice{}
for scanner.Scan() {
str := scanner.Text()
if !strings.HasPrefix(str, "#define") {
continue
}
split := strings.Fields(str)
// Verify the three parts '#define CS_x_TYPE (CS_INT)x'
if len(split) != 3 {
continue
}
// Verify second part 'CS_x_TYPE'
if !strings.HasPrefix(split[1], "CS_") || !strings.HasSuffix(split[1], "_TYPE") {
continue
}
// CS_<x>_TYPE
key := strings.Split(split[1], "_")[1]
// (CS_INT)<x> or (CS_INT)(<x>)
value := strings.Split(split[2], ")")[1]
// <x> or (<x>) -> <x>
value = strings.Trim(value, "()")
// Convert to integer
valueI, err := strconv.Atoi(value)
if err != nil {
log.Printf("Failed to parse '%s' as integer: %v", value, err)
return
}
typeMap[key] = valueI
// TODO is skipping ILLEGAL ok?
if key == "ILLEGAL" {
continue
}
typeSlice = append(typeSlice, key)
}
typeSlice.Sort()
// Write typeConsts.go
buf := bytes.Buffer{}
buf.WriteString("package ase\n\n")
// Write constants
buf.WriteString("const (\n")
for _, key := range typeSlice {
val := typeMap[key]
buf.WriteString(fmt.Sprintf(" %s ASEType = %d\n", key, val))
}
buf.WriteString(")\n\n")
// Write type maps
buf.WriteString("var type2string = map[ASEType]string{\n")
for _, key := range typeSlice {
buf.WriteString(fmt.Sprintf(" %s: \"%s\",\n", key, key))
}
buf.WriteString("}\n\n")
// Format buffer
formattedBuf, err := format.Source(buf.Bytes())
if err != nil {
log.Printf("Formatting code failed: %v", err)
os.Exit(1)
}
// Write result to typeConsts.go
if err := ioutil.WriteFile("typeConsts.go", formattedBuf, 0644); err != nil {
log.Printf("Writing generated code to typeConsts.go failed: %v", err)
os.Exit(1)
}
}