From 4b6c8b6b2317436ab77b38e17b49a7c7b03bf3f4 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Sat, 17 Jul 2010 19:00:40 -0700 Subject: Fixed bugs in textoutput. Text output from descriptor.proto is now identical to protoc! --- core/upb_def.c | 6 +++++ core/upb_def.h | 1 + stream/upb_textprinter.c | 62 +++++++++++++++++++++++++++--------------------- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/core/upb_def.c b/core/upb_def.c index c0d72db..fd00895 100644 --- a/core/upb_def.c +++ b/core/upb_def.c @@ -331,6 +331,12 @@ upb_enum_iter upb_enum_next(upb_enumdef *e, upb_enum_iter iter) { return upb_inttable_next(&e->iton, &iter->e); } +upb_string *upb_enumdef_iton(upb_enumdef *def, upb_enumval_t num) { + upb_iton_ent *e = + (upb_iton_ent*)upb_inttable_fastlookup(&def->iton, num, sizeof(*e)); + return e ? e->string : NULL; +} + /* upb_fielddef ***************************************************************/ diff --git a/core/upb_def.h b/core/upb_def.h index 82d8520..9cdc54d 100644 --- a/core/upb_def.h +++ b/core/upb_def.h @@ -202,6 +202,7 @@ typedef int32_t upb_enumval_t; // Lookups from name to integer and vice-versa. bool upb_enumdef_ntoi(upb_enumdef *e, upb_string *name, upb_enumval_t *num); +// Caller does not own a ref on the returned string. upb_string *upb_enumdef_iton(upb_enumdef *e, upb_enumval_t num); // Iteration over name/value pairs. The order is undefined. diff --git a/stream/upb_textprinter.c b/stream/upb_textprinter.c index 75668a3..2d2e237 100644 --- a/stream/upb_textprinter.c +++ b/stream/upb_textprinter.c @@ -29,38 +29,48 @@ static void upb_textprinter_endfield(upb_textprinter *p) } static bool upb_textprinter_putval(upb_textprinter *p, upb_value val) { - p->str = upb_string_tryrecycle(p->str); + upb_bytesink_put(p->bytesink, UPB_STRLIT(": ")); + upb_enumdef *enum_def; + upb_string *enum_label; + if(p->f->type == UPB_TYPE(ENUM) && + (enum_def = upb_downcast_enumdef(p->f->def)) != NULL && + (enum_label = upb_enumdef_iton(enum_def, val.int32)) != NULL) { + // This is an enum value for which we found a corresponding string. + upb_bytesink_put(p->bytesink, enum_label); + } else { + p->str = upb_string_tryrecycle(p->str); #define CASE(fmtstr, member) upb_string_printf(p->str, fmtstr, val.member); break; - switch(p->f->type) { - case UPB_TYPE(DOUBLE): - CASE("%0.f", _double); - case UPB_TYPE(FLOAT): - CASE("%0.f", _float) - case UPB_TYPE(INT64): - case UPB_TYPE(SFIXED64): - case UPB_TYPE(SINT64): - CASE("%" PRId64, int64) - case UPB_TYPE(UINT64): - case UPB_TYPE(FIXED64): - CASE("%" PRIu64, uint64) - case UPB_TYPE(INT32): - case UPB_TYPE(SFIXED32): - case UPB_TYPE(SINT32): - CASE("%" PRId32, int32) - case UPB_TYPE(UINT32): - case UPB_TYPE(FIXED32): - case UPB_TYPE(ENUM): - CASE("%" PRIu32, uint32); - case UPB_TYPE(BOOL): - CASE("%hhu", _bool); + switch(p->f->type) { + case UPB_TYPE(DOUBLE): + CASE("%0.f", _double); + case UPB_TYPE(FLOAT): + CASE("%0.f", _float) + case UPB_TYPE(INT64): + case UPB_TYPE(SFIXED64): + case UPB_TYPE(SINT64): + CASE("%" PRId64, int64) + case UPB_TYPE(UINT64): + case UPB_TYPE(FIXED64): + CASE("%" PRIu64, uint64) + case UPB_TYPE(INT32): + case UPB_TYPE(SFIXED32): + case UPB_TYPE(SINT32): + CASE("%" PRId32, int32) + case UPB_TYPE(UINT32): + case UPB_TYPE(FIXED32): + case UPB_TYPE(ENUM): + CASE("%" PRIu32, uint32); + case UPB_TYPE(BOOL): + CASE("%hhu", _bool); + } + upb_bytesink_put(p->bytesink, p->str); } - upb_bytesink_put(p->bytesink, p->str); upb_textprinter_endfield(p); return upb_ok(upb_bytesink_status(p->bytesink)); } static bool upb_textprinter_putstr(upb_textprinter *p, upb_string *str) { - upb_bytesink_put(p->bytesink, UPB_STRLIT("\"")); + upb_bytesink_put(p->bytesink, UPB_STRLIT(": \"")); // TODO: escaping. upb_bytesink_put(p->bytesink, str); upb_bytesink_put(p->bytesink, UPB_STRLIT("\"")); @@ -79,14 +89,12 @@ static bool upb_textprinter_putdef(upb_textprinter *p, upb_fielddef *f) { upb_textprinter_indent(p); upb_bytesink_put(p->bytesink, f->name); - upb_bytesink_put(p->bytesink, UPB_STRLIT(": ")); p->f = f; return upb_ok(upb_bytesink_status(p->bytesink)); } static bool upb_textprinter_startmsg(upb_textprinter *p) { - upb_bytesink_put(p->bytesink, p->f->def->fqname); upb_bytesink_put(p->bytesink, UPB_STRLIT(" {")); if(!p->single_line) upb_bytesink_put(p->bytesink, UPB_STRLIT("\n")); p->indent_depth++; -- cgit v1.2.3