Inital Commit with working code gen for c
This commit is contained in:
+144
@@ -0,0 +1,144 @@
|
||||
package proto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type HexByte byte
|
||||
|
||||
type ProtocolHeader struct {
|
||||
StartByte HexByte `json:"start_byte"`
|
||||
MessageLength int `json:"message_length"`
|
||||
MaxPayload int `json:"max_payload"`
|
||||
Checksum string `json:"checksum"`
|
||||
}
|
||||
|
||||
type ProtoMessage struct {
|
||||
Name string `json:"name"`
|
||||
ID HexByte `json:"id"`
|
||||
Payload []ProtoMessagePayload `json:"payload,omitempty"` // optional falls kein payload
|
||||
}
|
||||
|
||||
type ProtoMessagePayload struct {
|
||||
Name string `json:"name"`
|
||||
DataType string `json:"type"`
|
||||
}
|
||||
|
||||
type Proto struct {
|
||||
ProtocolHeader ProtocolHeader `json:"protocol"`
|
||||
ESP_TO_PC []ProtoMessage `json:"messages_esp_to_pc"`
|
||||
PC_TO_ESP []ProtoMessage `json:"messages_pc_to_esp"`
|
||||
}
|
||||
|
||||
func (h *HexByte) UnmarshalJSON(data []byte) error {
|
||||
var s string
|
||||
if err := json.Unmarshal(data, &s); err != nil { // turn into go string
|
||||
return err
|
||||
}
|
||||
|
||||
i, err := strconv.ParseUint(s, 0, 8)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*h = HexByte(i)
|
||||
return nil
|
||||
}
|
||||
|
||||
type Cenum struct {
|
||||
EnumName string
|
||||
Entries []ProtoMessage
|
||||
}
|
||||
|
||||
type PayloadStruct struct {
|
||||
Name string
|
||||
Entries []ProtoMessagePayload
|
||||
}
|
||||
|
||||
type CStyleData struct {
|
||||
CenumPCTOESP Cenum
|
||||
CenumESPTOPC Cenum
|
||||
PayloadStructs []PayloadStruct
|
||||
MessagesPCtoESP []ProtoMessage
|
||||
MessagesESPtoPC []ProtoMessage
|
||||
}
|
||||
|
||||
func CreateCStyle(proto *Proto) (string, error) {
|
||||
funcs := template.FuncMap{
|
||||
"snake": toSnakeCase,
|
||||
}
|
||||
|
||||
tmpl, err := template.New("all").Funcs(funcs).ParseGlob("templates/*.tmpl")
|
||||
if err != nil {
|
||||
log.Fatalf("failed to parse templates: %v", err)
|
||||
}
|
||||
|
||||
payloads := []PayloadStruct{}
|
||||
|
||||
for _, payload := range proto.PC_TO_ESP {
|
||||
tmp := PayloadStruct{
|
||||
Name: payload.Name,
|
||||
Entries: payload.Payload,
|
||||
}
|
||||
payloads = append(payloads, tmp)
|
||||
}
|
||||
|
||||
for _, payload := range proto.ESP_TO_PC {
|
||||
tmp := PayloadStruct{
|
||||
Name: payload.Name,
|
||||
Entries: payload.Payload,
|
||||
}
|
||||
payloads = append(payloads, tmp)
|
||||
}
|
||||
|
||||
for _, payload := range payloads {
|
||||
for i, entry := range payload.Entries {
|
||||
in := strings.Index(entry.DataType, "[")
|
||||
if in > 0 {
|
||||
payload.Entries[i].Name = fmt.Sprintf("%s%s", payload.Entries[i].Name, payload.Entries[i].DataType[in:])
|
||||
payload.Entries[i].DataType = payload.Entries[i].DataType[:in]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var data = CStyleData{
|
||||
CenumPCTOESP: Cenum{
|
||||
EnumName: "PC_TO_ESP_MESSAGE_IDS",
|
||||
Entries: proto.PC_TO_ESP,
|
||||
},
|
||||
CenumESPTOPC: Cenum{
|
||||
EnumName: "ESP_TO_PC_MESSAGE_IDS",
|
||||
Entries: proto.ESP_TO_PC,
|
||||
},
|
||||
PayloadStructs: payloads,
|
||||
MessagesPCtoESP: proto.PC_TO_ESP,
|
||||
MessagesESPtoPC: proto.ESP_TO_PC,
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
tmpl.ExecuteTemplate(&buf, "cpart", data)
|
||||
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
func toSnakeCase(str string) string {
|
||||
var out []rune
|
||||
for i, r := range str {
|
||||
if unicode.IsUpper(r) {
|
||||
if i != 0 {
|
||||
out = append(out, '_')
|
||||
}
|
||||
out = append(out, unicode.ToLower(r))
|
||||
} else {
|
||||
out = append(out, r)
|
||||
}
|
||||
}
|
||||
return string(out)
|
||||
}
|
||||
Reference in New Issue
Block a user