Clean up protocol code generators
This commit is contained in:
		
							parent
							
								
									941ee2f10c
								
							
						
					
					
						commit
						86278c154c
					
				| @ -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 | ||||
|  | ||||
| @ -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) {" | ||||
|  | ||||
| @ -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)" | ||||
|  | ||||
| @ -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)" | ||||
|  | ||||
| @ -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() | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user