Compare commits

...
20 Commits
Author SHA1 Message Date
skruecken 59584f3928 Dont remove build dir anymore
Build / Build (push) Successful in 1m20s
2025-05-19 21:51:32 +02:00
skruecken 77bcf116fb Removed creation of build dir 2025-05-19 21:51:07 +02:00
skruecken 41437f0f2f Embedded the Templates in the go binary
Build / Build (push) Successful in 1m26s
2025-05-19 21:46:38 +02:00
skruecken 1f05960ffc Reworked Gitea Actions
Build / Build (push) Successful in 1m52s
2025-05-19 21:24:23 +02:00
skruecken ae2879de41 Fixed Branchname
ProtoGen Action Runner / build (push) Failing after 56s
2025-05-19 21:21:36 +02:00
skruecken efd3916fb4 Reworked Actions Build 2025-05-19 21:20:37 +02:00
skruecken 52238f9aaf Added Workflow
ProtoGen Action Runner / build (push) Failing after 0s
2025-05-19 21:17:05 +02:00
skruecken a887d76dd9 Added build cli 2025-05-19 21:13:11 +02:00
skruecken 014186b65a Removed Default write to build dir 2025-05-19 21:11:36 +02:00
skruecken e6763a6d4b Modified Makefile with PHONY targets 2025-05-19 21:05:11 +02:00
skruecken e80cba9110 Added -i for Input File 2025-05-19 21:04:54 +02:00
skruecken ac5c660583 Added Build Script for Windows and linux 2025-05-19 21:01:26 +02:00
skruecken 853fda9814 Build Output File Select 2025-05-19 20:59:15 +02:00
skruecken aff454c277 Maintaince Utilty files 2025-05-19 20:59:01 +02:00
skruecken df2338b6f1 Fixed Spacing in Template 2025-04-27 15:31:09 +02:00
skruecken ca22cc501e Reorderd hook stubs in header file and fixed up some spacing 2025-04-27 15:07:54 +02:00
skruecken 49bfccfbd8 Added length to base messages 2025-04-27 12:58:50 +02:00
skruecken 73a7c8469a Added BaseMessages with messageid 2025-04-27 12:57:42 +02:00
skruecken 09e2afe329 Refactored CStyle in Header and Source File 2025-04-26 17:33:06 +02:00
skruecken d1f91e547b Fixed some Typos in Template 2025-04-26 17:25:39 +02:00
11 changed files with 256 additions and 58 deletions
+28
View File
@@ -0,0 +1,28 @@
name: Build
on: [push]
jobs:
Build:
runs-on: ubuntu-latest
container:
image: golang:latest
options: --network host
steps:
- run: |
apt-get update
apt-get install -y nodejs npm
- name: Check out repository code
uses: actions/checkout@v4
- run: echo "The ${{ gitea.repository }} repository has been cloned to the runner."
- name: List files in the repository
run: |
ls ${{ gitea.workspace }}
- run: go mod tidy
- run: make build
- run: ls -lah ${{ gitea.workspace }}
- name: Upload Build Artifacts
uses: actions/upload-artifact@v3
with:
name: alox.protogen
path: ./alox.protogen
- run: echo "This job's status is ${{ job.status }}."
+2
View File
@@ -1 +1,3 @@
alox.protogen alox.protogen
alox.protogen.exe
build/
+10
View File
@@ -0,0 +1,10 @@
.PHONY: build build_win clean
build:
GOOS=linux go build .
build_win:
GOOS=windows go build .
clean:
rm -rf build/*
+54 -4
View File
@@ -1,7 +1,10 @@
package main package main
import ( import (
"embed"
"encoding/json" "encoding/json"
"flag"
"fmt"
"log" "log"
"os" "os"
@@ -11,22 +14,69 @@ import (
"github.com/knadh/koanf/providers/file" "github.com/knadh/koanf/providers/file"
) )
//go:embed templates/*
var embeddedTemplates embed.FS
var appConfig = koanf.New(".") var appConfig = koanf.New(".")
func main() { func main() {
if err := appConfig.Load(file.Provider("testdata/conf.yaml"), yaml.Parser()); err != nil { confPath := flag.String("c", "testdata/conf.yaml", "Config File")
outFileName := flag.String("o", "", "Name of the Output File")
inputFile := flag.String("i", "testdata/prot1.json", "Name of the Input File")
flag.Parse()
if err := appConfig.Load(file.Provider(*confPath), yaml.Parser()); err != nil {
log.Printf("error loading config: %v", err) log.Printf("error loading config: %v", err)
} else { } else {
log.Printf("CONF: %v", appConfig) log.Printf("CONF: %v", appConfig)
} }
file, _ := os.ReadFile("testdata/prot1.json") file, err := os.ReadFile(*inputFile)
if err != nil {
log.Printf("ERROR: %v", err)
return
}
var cfg proto.Proto var cfg proto.Proto
json.Unmarshal(file, &cfg) json.Unmarshal(file, &cfg)
a, err := proto.CreateCStyle(&cfg) // if outFileName is set use it, if is not set set it to default value
if *outFileName != "" {
cfg.FileName = *outFileName
} else {
*outFileName = "build/proto"
}
// If filename not set in json take it from cli or default
if cfg.FileName != "" {
cfg.FileName = *outFileName
}
proto.InitTemplates(embeddedTemplates, "templates/*.tmpl")
header, err := proto.CreateCStyleHeader(&cfg)
if err != nil { if err != nil {
log.Printf("ERROR: %v", err) log.Printf("ERROR: %v", err)
} }
log.Printf("TEMPLATE: \n%v", a)
if err != nil {
log.Printf("ERROR: %v", err)
return
}
err = os.WriteFile(fmt.Sprintf("%s.h", *outFileName), []byte(header), 0666)
if err != nil {
log.Printf("ERROR: %v", err)
return
}
source, err := proto.CreateCStyleSource(&cfg)
if err != nil {
log.Printf("ERROR: %v", err)
}
err = os.WriteFile(fmt.Sprintf("%s.c", *outFileName), []byte(source), 0666)
if err != nil {
log.Printf("ERROR: %v", err)
return
}
} }
+58 -4
View File
@@ -3,6 +3,7 @@ package proto
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"io/fs"
"log" "log"
"strconv" "strconv"
"text/template" "text/template"
@@ -27,13 +28,14 @@ type ProtoMessage struct {
type ProtoMessagePayload struct { type ProtoMessagePayload struct {
Name string `json:"name"` Name string `json:"name"`
DataType string `json:"type"` DataType string `json:"type"`
ArrayLength int `json:"array,omitempty"` ArrayLength int `json:"array,omitempty"` // optional falls kein array
} }
type Proto struct { type Proto struct {
ProtocolHeader ProtocolHeader `json:"protocol"` ProtocolHeader ProtocolHeader `json:"protocol"`
ESP_TO_PC []ProtoMessage `json:"messages_esp_to_pc"` ESP_TO_PC []ProtoMessage `json:"messages_esp_to_pc"`
PC_TO_ESP []ProtoMessage `json:"messages_pc_to_esp"` PC_TO_ESP []ProtoMessage `json:"messages_pc_to_esp"`
FileName string `json:"filename,omitempty"`
} }
func (h *HexByte) UnmarshalJSON(data []byte) error { func (h *HexByte) UnmarshalJSON(data []byte) error {
@@ -62,6 +64,7 @@ type PayloadStruct struct {
} }
type CStyleData struct { type CStyleData struct {
FileName string
CenumPCTOESP Cenum CenumPCTOESP Cenum
CenumESPTOPC Cenum CenumESPTOPC Cenum
PayloadStructs []PayloadStruct PayloadStructs []PayloadStruct
@@ -69,16 +72,22 @@ type CStyleData struct {
MessagesESPtoPC []ProtoMessage MessagesESPtoPC []ProtoMessage
} }
func CreateCStyle(proto *Proto) (string, error) { var tmpl *template.Template
func InitTemplates(fsys fs.FS, pattern string) {
funcs := template.FuncMap{ funcs := template.FuncMap{
"snake": toSnakeCase, "snake": toSnakeCase,
"isLast": isLast, "isLast": isLast,
} }
tmpl, err := template.New("all").Funcs(funcs).ParseGlob("templates/*.tmpl") Ntmpl, err := template.New("all").Funcs(funcs).ParseFS(fsys, pattern)
if err != nil { if err != nil {
log.Fatalf("failed to parse templates: %v", err) log.Fatalf("failed to parse templates: %v", err)
} }
tmpl = Ntmpl
}
func CreateCStyleHeader(proto *Proto) (string, error) {
payloads := []PayloadStruct{} payloads := []PayloadStruct{}
@@ -99,6 +108,7 @@ func CreateCStyle(proto *Proto) (string, error) {
} }
var data = CStyleData{ var data = CStyleData{
FileName: proto.FileName,
CenumPCTOESP: Cenum{ CenumPCTOESP: Cenum{
EnumName: "PC_TO_ESP_MESSAGE_IDS", EnumName: "PC_TO_ESP_MESSAGE_IDS",
Entries: proto.PC_TO_ESP, Entries: proto.PC_TO_ESP,
@@ -113,7 +123,51 @@ func CreateCStyle(proto *Proto) (string, error) {
} }
var buf bytes.Buffer var buf bytes.Buffer
err = tmpl.ExecuteTemplate(&buf, "cpart", data) err := tmpl.ExecuteTemplate(&buf, "cpartHeader", data)
if err != nil {
log.Printf("Error Rendering template: %v", err)
}
return buf.String(), nil
}
func CreateCStyleSource(proto *Proto) (string, error) {
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)
}
var data = CStyleData{
FileName: proto.FileName,
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
err := tmpl.ExecuteTemplate(&buf, "cpartSource", data)
if err != nil { if err != nil {
log.Printf("Error Rendering template: %v", err) log.Printf("Error Rendering template: %v", err)
} }
+2 -2
View File
@@ -86,7 +86,7 @@ Each message is described as:
- [x] Hook-Funktionen - [x] Hook-Funktionen
- [x] Message-Dispatcher (Switch-Case) - [x] Message-Dispatcher (Switch-Case)
- [x] Send-Funktionen - [x] Send-Funktionen
- [ ] Generate Header and Source File - [x] Generate Header and Source File
--- ---
## To-Do ## To-Do
@@ -119,7 +119,7 @@ Each message is described as:
### Tooling ### Tooling
- [ ] CLI interface (`--input`, `--output`, `--language`, ...) - [ ] CLI interface (`--input`, `--output`, `--language`, ...)
- [ ] Logging / verbose mode - [ ] Logging / verbose mode
- [ ] Build script / Makefile - [x] Build script / Makefile
### Testing ### Testing
- [ ] Unit tests for generator - [ ] Unit tests for generator
+44 -9
View File
@@ -21,19 +21,35 @@ typedef struct {
{{- end }} {{- end }}
} {{ .Name }}Payload; } {{ .Name }}Payload;
{{end}} {{end}}
{{end}} {{- end}}
{{define "union"}} {{define "union"}}
typedef union { typedef union {
{{- range .}} {{- range .}}
{{.Name}} {{ .Name | snake}} {{.Name}}Payload {{ .Name | snake}};
{{- end }} {{- end }}
}PayloadUnion: } PayloadUnion;
{{end}}
{{define "basemessage"}}
typedef struct {
uint8_t Version;
{{.CenumPCTOESP.EnumName}} MessageID;
uint8_t Length;
PayloadUnion Payload;
} PCTOESPBaseMessage;
typedef struct {
uint8_t Version;
{{.CenumESPTOPC.EnumName}} MessageID;
uint8_t Length;
PayloadUnion Payload;
} ESPTOPCBaseMessage;
{{end}} {{end}}
{{define "handler"}} {{define "handler"}}
{{- range . }} {{- range . }}
void (*on_{{ .Name | snake }})({{ .Name }}Payload*) = NULL; void (*on_{{ .Name | snake }})({{ .Name }}Payload*);
{{- end}} {{- end}}
{{end}} {{end}}
@@ -52,19 +68,38 @@ void dispatch_message(uint8_t msg_id, void* payload) {
} }
{{end}} {{end}}
{{define "send_functions"}} {{define "send_function_prototype"}}
void send_message(ESP_TO_PC_MESSAGE_IDS msgid, PayloadUnion *payload);
{{end}}
{{define "send_function_source"}}
void send_message(ESP_TO_PC_MESSAGE_IDS msgid, PayloadUnion *payload) {}
{{end}}
{{define "send_functions_prototype"}}
{{- range .}} {{- range .}}
{{ $argLen := len .Payload }} {{- $argLen := len .Payload }}
void send_{{.Name | snake}}({{- range $i, $p := .Payload}}{{$p.DataType}} {{$p.Name}} {{- if not (isLast $argLen $i) }}, {{ end}} {{- end}}) { void send_{{.Name | snake}}({{- range $i, $p := .Payload}}{{$p.DataType}} {{ if .ArrayLength}}*{{end}}{{$p.Name}} {{- if not (isLast $argLen $i) }}, {{ end}} {{- end}});
{{- end }}
{{end}}
{{define "send_functions_source"}}
{{- range .}}
{{- $argLen := len .Payload }}
void send_{{.Name | snake}}({{- range $i, $p := .Payload}}{{$p.DataType}} {{ if .ArrayLength}}*{{end}}{{$p.Name}} {{ if not (isLast $argLen $i) }}, {{ end}} {{- end}}) {
{{.Name}}Payload payload; {{.Name}}Payload payload;
// Payload-Daten zuweisen // Payload-Daten zuweisen
{{- range .Payload}} {{- range .Payload}}
{{- if .ArrayLength }}
memcpy(payload.{{.Name}}, {{.Name}}, {{.ArrayLength}});
{{- else }}
payload.{{.Name}} = {{.Name}}; payload.{{.Name}} = {{.Name}};
{{- end}} {{- end}}
{{- end}}
// Nachricht senden // Nachricht senden
send_message({{.Name}}, &payload); send_message({{.Name}}, (PayloadUnion *)&payload);
} }
{{- end }} {{end}}
{{end}} {{end}}
-20
View File
@@ -1,20 +0,0 @@
{{- define "cpart" -}}
// AUTO GENERATED DO NOT EDIT!!!
#ifndef _PROTO_HEADER
#define _PROTO_HEADER
{{ block "cenum" .CenumPCTOESP }} {{ end }}
{{ block "cenum" .CenumESPTOPC }} {{ end }}
{{ block "payloads" .PayloadStructs }} {{ end }}
{{ block "union" .PayloadStructs }} {{ end }}
{{ block "handler" .MessagesPCtoESP}} {{ end }}
{{ block "dispatcher" .MessagesPCtoESP}} {{ end }}
{{ block "send_functions" .MessagesESPtoPC}} {{ end }}
#endif
{{- end -}}
+32
View File
@@ -0,0 +1,32 @@
{{- define "cpartHeader" -}}
// AUTO GENERATED DO NOT EDIT!!!
#ifndef _PROTO_HEADER
#define _PROTO_HEADER
#include <stdint.h>
// MessageIDs
{{- block "cenum" .CenumPCTOESP }} {{- end}}
{{- block "cenum" .CenumESPTOPC }} {{- end}}
// Payloads for single Messages
{{- block "payloads" .PayloadStructs }} {{- end}}
// Union for all the Payloads
{{- block "union" .PayloadStructs }} {{- end}}
// Base Message that can hold all Payloads
{{- block "basemessage" . }} {{- end}}
// Generic Send Function Prototype
{{- block "send_function_prototype" .MessagesESPtoPC}} {{- end}}
// Spezific Send Functions Prototype
{{- block "send_functions_prototype" .MessagesESPtoPC}} {{- end}}
// Prototypes for Message Recieve Handler to be set in user code
{{- block "handler" .MessagesPCtoESP}} {{ end }}
#endif
{{- end -}}
+15
View File
@@ -0,0 +1,15 @@
{{- define "cpartSource" -}}
// AUTO GENERATED DO NOT EDIT!!!
#include "{{.FileName}}.h"
#include <string.h>
// Message Dispatcher
{{- block "dispatcher" .MessagesPCtoESP}} {{ end }}
//Generic Send Function
{{- block "send_function_source" .MessagesESPtoPC}} {{ end }}
// Sepzific Send Functions
{{- block "send_functions_source" .MessagesESPtoPC}} {{ end }}
{{- end -}}
-8
View File
@@ -1,8 +0,0 @@
# Current Work
Added ArrayLenght need to implement it everywhere in the template
in Payload struct it happend already
Need it in:
- Send Parameter
- [x] Also remove trailing "," in send parameter