From 86278c154c0e8f88f3df91298b4fcd40f8c7571b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Eric=20Janouch?=
Date: Thu, 29 Sep 2022 16:39:26 +0200 Subject: [PATCH] Clean up protocol code generators --- CMakeLists.txt | 1 + xC-gen-proto-c.awk | 3 +- xC-gen-proto-go.awk | 87 +++++++++++++++++++++++++++------------------ xC-gen-proto-js.awk | 2 ++ xC-gen-proto.awk | 14 ++++---- xP/Makefile | 3 +- 6 files changed, 67 insertions(+), 43 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d316c15..2cd36e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,6 +164,7 @@ add_custom_command (OUTPUT xC-proto.c COMMAND env LC_ALL=C awk -f ${PROJECT_SOURCE_DIR}/xC-gen-proto.awk -f ${PROJECT_SOURCE_DIR}/xC-gen-proto-c.awk + -v PrefixCamel=Relay ${PROJECT_SOURCE_DIR}/xC-proto > xC-proto.c DEPENDS ${PROJECT_SOURCE_DIR}/xC-gen-proto.awk diff --git a/xC-gen-proto-c.awk b/xC-gen-proto-c.awk index 2810c96..d416b93 100644 --- a/xC-gen-proto-c.awk +++ b/xC-gen-proto-c.awk @@ -62,8 +62,8 @@ function codegen_begin() { "\t\t%s = !!v;\n" \ "\t}\n" + print "// Code generated from " FILENAME ". DO NOT EDIT." print "// This file directly depends on liberty.c, but doesn't include it." - print "" print "static bool" print "proto_string_serialize(const struct str *s, struct str *w) {" @@ -73,7 +73,6 @@ function codegen_begin() { print "\tstr_append_str(w, s);" print "\treturn true;" print "}" - print "" print "static bool" print "proto_string_deserialize(struct str *s, struct msg_unpacker *r) {" diff --git a/xC-gen-proto-go.awk b/xC-gen-proto-go.awk index 477a471..c0d6d48 100644 --- a/xC-gen-proto-go.awk +++ b/xC-gen-proto-go.awk @@ -70,7 +70,12 @@ function define_uint(size, shortname, gotype) { "\t}\n" } -function codegen_begin() { +# Currently two outputs cannot coexist within the same package. +function codegen_private(name) { + return "proto" name +} + +function codegen_begin( funcname) { define_sint("8") define_sint("16") define_sint("32") @@ -79,32 +84,17 @@ function codegen_begin() { define_uint("16") define_uint("32") define_uint("64") - define_internal("bool", "bool") - CodegenAppendJSON["bool"] = \ - "\tb = strconv.AppendBool(b, %s)\n" - CodegenSerialize["bool"] = \ - "\tif %s {\n" \ - "\t\tdata = append(data, 1)\n" \ - "\t} else {\n" \ - "\t\tdata = append(data, 0)\n" \ - "\t}\n" - CodegenDeserialize["bool"] = \ - "\tif data, ok = protoConsumeBoolFrom(data, &%s); !ok {\n" \ - "\t\treturn nil, ok\n" \ - "\t}\n" - define_internal("string", "string") - CodegenSerialize["string"] = \ - "\tif data, ok = protoAppendStringTo(data, %s); !ok {\n" \ - "\t\treturn nil, ok\n" \ - "\t}\n" - CodegenDeserialize["string"] = \ - "\tif data, ok = protoConsumeStringFrom(data, &%s); !ok {\n" \ - "\t\treturn nil, ok\n" \ - "\t}\n" - print "package main" + # Cater to "go generate", for what it's worth. + CodegenPackage = ENV["GOPACKAGE"] + if (!CodegenPackage) + CodegenPackage = "main" + + print "// Code generated from " FILENAME ". DO NOT EDIT." + print "" + print "package " CodegenPackage print "" print "import (" print "\t`encoding/base64`" @@ -117,10 +107,20 @@ function codegen_begin() { print ")" print "" - print "// protoConsumeBoolFrom tries to deserialize a boolean value" + CodegenAppendJSON["bool"] = \ + "\tb = strconv.AppendBool(b, %s)\n" + CodegenSerialize["bool"] = \ + "\tif %s {\n" \ + "\t\tdata = append(data, 1)\n" \ + "\t} else {\n" \ + "\t\tdata = append(data, 0)\n" \ + "\t}\n" + + funcname = codegen_private("ConsumeBoolFrom") + print "// " funcname " tries to deserialize a boolean value" print "// from the beginning of a byte stream. When successful," print "// it returns a subslice with any data that might follow." - print "func protoConsumeBoolFrom(data []byte, b *bool) ([]byte, bool) {" + print "func " funcname "(data []byte, b *bool) ([]byte, bool) {" print "\tif len(data) < 1 {" print "\t\treturn nil, false" print "\t}" @@ -133,9 +133,15 @@ function codegen_begin() { print "}" print "" - print "// protoAppendStringTo tries to serialize a string value," + CodegenDeserialize["bool"] = \ + "\tif data, ok = " funcname "(data, &%s); !ok {\n" \ + "\t\treturn nil, ok\n" \ + "\t}\n" + + funcname = codegen_private("AppendStringTo") + print "// " funcname " tries to serialize a string value," print "// appending it to the end of a byte stream." - print "func protoAppendStringTo(data []byte, s string) ([]byte, bool) {" + print "func " funcname "(data []byte, s string) ([]byte, bool) {" print "\tif len(s) > math.MaxUint32 {" print "\t\treturn nil, false" print "\t}" @@ -144,10 +150,16 @@ function codegen_begin() { print "}" print "" - print "// protoConsumeStringFrom tries to deserialize a string value" + CodegenSerialize["string"] = \ + "\tif data, ok = " funcname "(data, %s); !ok {\n" \ + "\t\treturn nil, ok\n" \ + "\t}\n" + + funcname = codegen_private("ConsumeStringFrom") + print "// " funcname " tries to deserialize a string value" print "// from the beginning of a byte stream. When successful," print "// it returns a subslice with any data that might follow." - print "func protoConsumeStringFrom(data []byte, s *string) ([]byte, bool) {" + print "func " funcname "(data []byte, s *string) ([]byte, bool) {" print "\tif len(data) < 4 {" print "\t\treturn nil, false" print "\t}" @@ -163,9 +175,15 @@ function codegen_begin() { print "}" print "" - print "// protoUnmarshalEnumJSON converts a JSON fragment to an integer," + CodegenDeserialize["string"] = \ + "\tif data, ok = " funcname "(data, &%s); !ok {\n" \ + "\t\treturn nil, ok\n" \ + "\t}\n" + + funcname = codegen_private("UnmarshalEnumJSON") + print "// " funcname " converts a JSON fragment to an integer," print "// ensuring that it's within the expected range of enum values." - print "func protoUnmarshalEnumJSON(data []byte) (int64, error) {" + print "func " funcname "(data []byte) (int64, error) {" print "\tvar n int64" print "\tif err := json.Unmarshal(data, &n); err != nil {" print "\t\treturn 0, err" @@ -197,7 +215,7 @@ function codegen_enum_value(name, subname, value, cg, goname) { "\t\t*v = " goname "\n") } -function codegen_enum(name, cg, gotype, fields) { +function codegen_enum(name, cg, gotype, fields, funcname) { gotype = PrefixCamel name print "type " gotype " int8" print "" @@ -227,11 +245,12 @@ function codegen_enum(name, cg, gotype, fields) { print "}" print "" + funcname = codegen_private("UnmarshalEnumJSON") print "func (v *" gotype ") UnmarshalJSON(data []byte) error {" print "\tvar s string" print "\tif json.Unmarshal(data, &s) == nil {" print "\t\t// Handled below." - print "\t} else if n, err := protoUnmarshalEnumJSON(data); err != nil {" + print "\t} else if n, err := " funcname "(data); err != nil {" print "\t\treturn err" print "\t} else {" print "\t\t*v = " gotype "(n)" diff --git a/xC-gen-proto-js.awk b/xC-gen-proto-js.awk index 752fd18..40b99ee 100644 --- a/xC-gen-proto-js.awk +++ b/xC-gen-proto-js.awk @@ -51,6 +51,8 @@ function define_uint(size, shortname) { } function codegen_begin() { + print "// Code generated from " FILENAME ". DO NOT EDIT." + print "" print "export class Reader extends DataView {" print "\tconstructor() {" print "\t\tsuper(...arguments)" diff --git a/xC-gen-proto.awk b/xC-gen-proto.awk index 9b65a74..1a9ab1f 100644 --- a/xC-gen-proto.awk +++ b/xC-gen-proto.awk @@ -22,7 +22,7 @@ # unless this role is already filled by, e.g., WebSocket. # # Usage: env LC_ALL=C awk -f xC-gen-proto.awk -f xC-gen-proto-{c,go,js}.awk \ -# xC-proto > xC-proto.{c,go,js} | {clang-format,gofmt,...} +# -v PrefixCamel=Relay xC-proto > xC-proto.{c,go,js} | {clang-format,gofmt,...} # --- Utilities ---------------------------------------------------------------- @@ -289,12 +289,14 @@ function deftype() { return 0 } -BEGIN { - PrefixLower = "relay_" - PrefixUpper = "RELAY_" - PrefixCamel = "Relay" +{ + if (PrefixCamel) { + PrefixLower = tolower(cameltosnake(PrefixCamel)) "_" + PrefixUpper = toupper(cameltosnake(PrefixCamel)) "_" + } - print "// Generated by xC-gen-proto.awk. DO NOT MODIFY." + # This is not in a BEGIN clause (even though it consumes all input), + # so that the code generator can insert the first FILENAME. codegen_begin() nexttoken() diff --git a/xP/Makefile b/xP/Makefile index c0198aa..6f3cdab 100644 --- a/xP/Makefile +++ b/xP/Makefile @@ -8,7 +8,8 @@ all: $(outputs) public/ircfmt.woff2 xP: xP.go proto.go go build -o $@ proto.go: ../xC-gen-proto.awk ../xC-gen-proto-go.awk ../xC-proto - $(AWK) -f ../xC-gen-proto.awk -f ../xC-gen-proto-go.awk ../xC-proto > $@ + $(AWK) -f ../xC-gen-proto.awk -f ../xC-gen-proto-go.awk \ + -v PrefixCamel=Relay ../xC-proto > $@ public/proto.js: ../xC-gen-proto.awk ../xC-gen-proto-js.awk ../xC-proto $(AWK) -f ../xC-gen-proto.awk -f ../xC-gen-proto-js.awk ../xC-proto > $@ public/ircfmt.woff2: gen-ircfmt.awk