summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--upbc.c86
2 files changed, 88 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 08c56cf..3e60c72 100644
--- a/Makefile
+++ b/Makefile
@@ -5,13 +5,14 @@ CXX=g++
CFLAGS=-std=c99
CPPFLAGS=-O0 -Wall -Wextra -pedantic -g -DUPB_UNALIGNED_READS_OK -fomit-frame-pointer
OBJ=upb_parse.o upb_table.o upb_msg.o upb_enum.o upb_context.o descriptor.o
-all: $(OBJ) test_table tests
+all: $(OBJ) test_table tests upbc
clean:
rm -f *.o test_table tests
libupb.a: $(OBJ)
ar rcs libupb.a $(OBJ)
test_table: libupb.a
+upbc: libupb.a
-include deps
deps: *.c *.h
diff --git a/upbc.c b/upbc.c
new file mode 100644
index 0000000..b49d24b
--- /dev/null
+++ b/upbc.c
@@ -0,0 +1,86 @@
+/*
+ * upb - a minimalist implementation of protocol buffers.
+ *
+ * upbc is the upb compiler.
+ *
+ * Copyright (c) 2009 Joshua Haberman. See LICENSE for details.
+ */
+
+#include <ctype.h>
+#include <inttypes.h>
+#include "descriptor.h"
+#include "upb_context.h"
+
+/* These are in-place string transformations that do not change the length of
+ * the string (and thus never need to re-allocate). */
+static void to_cident(struct upb_string str)
+{
+ for(uint32_t i = 0; i < str.byte_len; i++)
+ if(str.ptr[i] == '.' || str.ptr[i] == '/')
+ str.ptr[i] = '_';
+}
+
+static void to_preproc(struct upb_string str)
+{
+ to_cident(str);
+ for(uint32_t i = 0; i < str.byte_len; i++)
+ str.ptr[i] = toupper(str.ptr[i]);
+}
+
+/* The .h file defines structs for the types defined in the .proto file. It
+ * also defines constants for the enum values.
+ *
+ * Assumes that d has been validated. */
+static void write_header(google_protobuf_FileDescriptorProto *d, FILE *stream)
+{
+ /* Header file prologue. */
+ fprintf(stream, "/* Auto-generated from " UPB_STRFMT ". Do not edit. */\n\n",
+ UPB_STRARG(*d->name));
+ struct upb_string include_guard_name = upb_strdup(*d->name);
+ to_preproc(include_guard_name);
+ fprintf(stream, "#ifndef " UPB_STRFMT "\n", UPB_STRARG(include_guard_name));
+ fprintf(stream, "#define " UPB_STRFMT "\n\n", UPB_STRARG(include_guard_name));
+ fputs("#include <upb_msg.h>\n\n", stream);
+ fputs("#ifdef __cplusplus\n", stream);
+ fputs("extern \"C\" {\n", stream);
+ fputs("#endif\n\n", stream);
+
+ /* Enums. */
+ if(d->set_flags.has.enum_type) {
+ fprintf(stream, "/* Enums. */\n\n");
+ for(uint32_t i = 0; i < d->enum_type->len; i++) { /* Foreach enum */
+ google_protobuf_EnumDescriptorProto *e = d->enum_type->elements[i];
+ struct upb_string enum_name = upb_strdup(*e->name);
+ to_cident(enum_name);
+ fprintf(stream, "typedef enum " UPB_STRFMT " {\n", UPB_STRARG(enum_name));
+ if(e->set_flags.has.value) {
+ for(uint32_t j = 0; j < e->value->len; j++) { /* Foreach enum value. */
+ google_protobuf_EnumValueDescriptorProto *v = e->value->elements[i];
+ struct upb_string value_name = upb_strdup(*v->name);
+ to_preproc(value_name);
+ /* " GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_UINT32 = 13," */
+ fprintf(stream, " " UPB_STRFMT " = %" PRIu32,
+ UPB_STRARG(value_name), v->number);
+ if(j != e->value->len-1) fputc(',', stream);
+ fputc('\n', stream);
+ upb_strfree(value_name);
+ }
+ }
+ fprintf(stream, "} " UPB_STRFMT ";\n\n", UPB_STRARG(enum_name));
+ upb_strfree(enum_name);
+ }
+ }
+
+ /* Epilogue. */
+ fputs("#ifdef __cplusplus\n", stream);
+ fputs("} /* extern \"C\" */\n", stream);
+ fputs("#endif\n\n", stream);
+ fprintf(stream, "#endif /* " UPB_STRFMT " */\n", UPB_STRARG(include_guard_name));
+ upb_strfree(include_guard_name);
+}
+
+int main()
+{
+ write_header(&google_protobuf_filedescriptor, stdout);
+}
+
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback