summaryrefslogtreecommitdiff
path: root/tools/upbc.c
diff options
context:
space:
mode:
authorJoshua Haberman <joshua@reverberate.org>2009-07-08 20:50:48 -0700
committerJoshua Haberman <joshua@reverberate.org>2009-07-08 20:50:48 -0700
commit9bc15a1e74623753bcce0404e9cbd67f56a5e0e1 (patch)
tree56892339903db42eebc3586f51e1ced187c2acb3 /tools/upbc.c
parent6d77fa04597f453e7af38c5b3f791c2aba3a282a (diff)
More work on the compiler.
Diffstat (limited to 'tools/upbc.c')
-rw-r--r--tools/upbc.c59
1 files changed, 55 insertions, 4 deletions
diff --git a/tools/upbc.c b/tools/upbc.c
index fa264d7..b22b958 100644
--- a/tools/upbc.c
+++ b/tools/upbc.c
@@ -221,6 +221,7 @@ int compare_entries(const void *_e1, const void *_e2)
static void write_c(struct upb_symtab_entry *entries[], int num_entries,
char *hfile_name, char *outfile_name, FILE *stream)
{
+ (void)outfile_name;
fputs("/* This file was generated by upbc (the upb compiler). "
"Do not edit. */\n\n", stream),
fprintf(stream, "#include \"%s\"\n\n", hfile_name);
@@ -236,7 +237,6 @@ static void write_c(struct upb_symtab_entry *entries[], int num_entries,
upb_strtable_init(&t, 16, sizeof(struct strtable_entry));
for(int i = 0; i < num_entries; i++) {
- //addident(entries[i].key);
struct strtable_entry e = {.e = {.key = entries[i]->e.key}};
if(upb_strtable_lookup(&t, &e.e.key) == NULL) upb_strtable_insert(&t, &e.e);
switch(entries[i]->type) {
@@ -296,9 +296,60 @@ static void write_c(struct upb_symtab_entry *entries[], int num_entries,
fputs("static struct upb_string strings[] = {\n", stream);
for(int i = 0; i < size; i++) {
struct strtable_entry *e = str_entries[i];
- fprintf(stream, " {.ptr = &strdata[%d], .byte_len=%d}", e->offset, e->e.key.byte_len);
- if(i+1 != size) fputc(',', stream);
- fputc('\n', stream);
+ fprintf(stream, " {.ptr = &strdata[%d], .byte_len=%d},\n", e->offset, e->e.key.byte_len);
+ }
+ fputs("};\n\n", stream);
+
+ /* Emit fields. */
+ fputs("static google_protobuf_FieldDescriptorProto fields[] = {\n", stream);
+ int total = 0;
+ for(int i = 0; i < num_entries; i++) {
+ if(entries[i]->type != UPB_SYM_MESSAGE) continue;
+ struct upb_msg *m = entries[i]->ref.msg;
+ for(uint32_t j = 0; j < m->num_fields; j++) {
+ struct google_protobuf_FieldDescriptorProto *fd = m->field_descriptors[j];
+ struct strtable_entry *e = upb_strtable_lookup(&t, fd->name);
+ fprintf(stream, " {.set_flags = {.bytes={0x%02hhx}}, .name=&strings[%3d], .number=%d, .label=%d, .type=%2d, .type_name=NULL},\n",
+ fd->set_flags.bytes[0], e->num, fd->number, fd->label, fd->type);
+ total ++;
+ }
+ }
+ fputs("};\n\n", stream);
+
+ fputs("static google_protobuf_FieldDescriptorProto *field_pointers[] = {\n", stream);
+ for(int i = 0; i < total; i++) {
+ fprintf(stream, " &fields[%d],\n", i);
+ }
+ fputs("};\n\n", stream);
+
+ offset = 0;
+ fputs("static UPB_MSG_ARRAY(google_protobuf_FieldDescriptorProto) field_arrays[] = {\n", stream);
+ for(int i = 0; i < num_entries; i++) {
+ if(entries[i]->type != UPB_SYM_MESSAGE) continue;
+ struct upb_msg *m = entries[i]->ref.msg;
+ fprintf(stream, " {.elements=&field_pointers[%d], .len=%d},\n", offset, m->num_fields);
+ offset += m->num_fields;
+ }
+ fputs("};\n\n", stream);
+
+ /* Emit messages. */
+ fputs("static google_protobuf_DescriptorProto messages[] = {\n", stream);
+ offset = 0;
+ for(int i = 0; i < num_entries; i++) {
+ if(entries[i]->type != UPB_SYM_MESSAGE) continue;
+ struct upb_msg *m = entries[i]->ref.msg;
+ struct google_protobuf_DescriptorProto *d = m->descriptor;
+ struct strtable_entry *e = upb_strtable_lookup(&t, d->name);
+ fprintf(stream, " {.set_flags = {.bytes={0x%02hhx}}, .name=&strings[%3d], .field=&field_arrays[%d]},\n",
+ d->set_flags.bytes[0], e->num, offset);
+ }
+ fputs("};\n\n", stream);
+
+ fputs("static google_protobuf_DescriptorProto *message_pointers[] = {\n", stream);
+ offset = 0;
+ for(int i = 0; i < num_entries; i++) {
+ if(entries[i]->type != UPB_SYM_MESSAGE) continue;
+ fprintf(stream, " &messages[%d],\n", offset);
}
fputs("};\n\n", stream);
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback