From 919fea438a5ac5366684cfa26d2bb3d17519cb60 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Mon, 18 May 2015 10:55:20 -0700 Subject: Ported upb to C89, for greater portability. A large part of this change contains surface-level porting, like moving variable declarations to the top of the block. However there are a few more substantial things too: - moved internal-only struct definitions to a separate file (structdefs.int.h), for greater encapsulation and ABI compatibility. - removed the UPB_UPCAST macro, since it requires access to the internal-only struct definitions. Replaced uses with calls to inline, type-safe casting functions. - removed the UPB_DEFINE_CLASS/UPB_DEFINE_STRUCT macros. Class and struct definitions are now more explicit -- you get to see the actual class/struct keywords in the source. The casting convenience functions have been moved into UPB_DECLARE_DERIVED_TYPE() and UPB_DECLARE_DERIVED_TYPE2(). - the new way that we duplicate base methods in derived types is also more convenient and requires less duplication. It is also less greppable, but hopefully that is not too big a problem. Compiler flags (-std=c89 -pedantic) should help to rigorously enforce that the code is free of C99-isms. A few functions are not available in C89 (strtoll). There are temporary, hacky solutions in place. --- upb/structdefs.int.h | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 upb/structdefs.int.h (limited to 'upb/structdefs.int.h') diff --git a/upb/structdefs.int.h b/upb/structdefs.int.h new file mode 100644 index 0000000..2fa2972 --- /dev/null +++ b/upb/structdefs.int.h @@ -0,0 +1,176 @@ +/* + * upb - a minimalist implementation of protocol buffers. + * + * Copyright (c) 2015 Google Inc. See LICENSE for details. + * Author: Josh Haberman + * + * This file contains definitions of structs that should be considered private + * and NOT stable across versions of upb. + * + * The only reason they are declared here and not in .c files is to allow upb + * and the application (if desired) to embed statically-initialized instances + * of structures like defs. + * + * If you include this file, all guarantees of ABI compatibility go out the + * window! Any code that includes this file needs to recompile against the + * exact same version of upb that they are linking against. + * + * You also need to recompile if you change the value of the UPB_DEBUG_REFS + * flag. + */ + +#include + +#ifndef UPB_STATICINIT_H_ +#define UPB_STATICINIT_H_ + +#ifdef __cplusplus +/* Because of how we do our typedefs, this header can't be included from C++. */ +#error This file cannot be included from C++ +#endif + +/* upb_refcounted *************************************************************/ + + +/* upb_def ********************************************************************/ + +struct upb_def { + upb_refcounted base; + + const char *fullname; + char type; /* A upb_deftype_t (char to save space) */ + + /* Used as a flag during the def's mutable stage. Must be false unless + * it is currently being used by a function on the stack. This allows + * us to easily determine which defs were passed into the function's + * current invocation. */ + bool came_from_user; +}; + +#define UPB_DEF_INIT(name, type, refs, ref2s) \ + { UPB_REFCOUNT_INIT(refs, ref2s), name, type, false } + + +/* upb_fielddef ***************************************************************/ + +struct upb_fielddef { + upb_def base; + + union { + int64_t sint; + uint64_t uint; + double dbl; + float flt; + void *bytes; + } defaultval; + union { + const upb_msgdef *def; /* If !msg_is_symbolic. */ + char *name; /* If msg_is_symbolic. */ + } msg; + union { + const upb_def *def; /* If !subdef_is_symbolic. */ + char *name; /* If subdef_is_symbolic. */ + } sub; /* The msgdef or enumdef for this field, if upb_hassubdef(f). */ + bool subdef_is_symbolic; + bool msg_is_symbolic; + const upb_oneofdef *oneof; + bool default_is_string; + bool type_is_set_; /* False until type is explicitly set. */ + bool is_extension_; + bool lazy_; + bool packed_; + upb_intfmt_t intfmt; + bool tagdelim; + upb_fieldtype_t type_; + upb_label_t label_; + uint32_t number_; + uint32_t selector_base; /* Used to index into a upb::Handlers table. */ + uint32_t index_; +}; + +#define UPB_FIELDDEF_INIT(label, type, intfmt, tagdelim, is_extension, lazy, \ + packed, name, num, msgdef, subdef, selector_base, \ + index, defaultval, refs, ref2s) \ + { \ + UPB_DEF_INIT(name, UPB_DEF_FIELD, refs, ref2s), defaultval, {msgdef}, \ + {subdef}, NULL, false, false, \ + type == UPB_TYPE_STRING || type == UPB_TYPE_BYTES, true, is_extension, \ + lazy, packed, intfmt, tagdelim, type, label, num, selector_base, index \ + } + + +/* upb_msgdef *****************************************************************/ + +struct upb_msgdef { + upb_def base; + + size_t selector_count; + uint32_t submsg_field_count; + + /* Tables for looking up fields by number and name. */ + upb_inttable itof; /* int to field */ + upb_strtable ntof; /* name to field */ + + /* Tables for looking up oneofs by name. */ + upb_strtable ntoo; /* name to oneof */ + + /* Is this a map-entry message? + * TODO: set this flag properly for static descriptors; regenerate + * descriptor.upb.c. */ + bool map_entry; + + /* TODO(haberman): proper extension ranges (there can be multiple). */ +}; + +/* TODO: also support static initialization of the oneofs table. This will be + * needed if we compile in descriptors that contain oneofs. */ +#define UPB_MSGDEF_INIT(name, selector_count, submsg_field_count, itof, ntof, \ + refs, ref2s) \ + { \ + UPB_DEF_INIT(name, UPB_DEF_MSG, refs, ref2s), selector_count, \ + submsg_field_count, itof, ntof, \ + UPB_EMPTY_STRTABLE_INIT(UPB_CTYPE_PTR), false \ + } + + +/* upb_enumdef ****************************************************************/ + +struct upb_enumdef { + upb_def base; + + upb_strtable ntoi; + upb_inttable iton; + int32_t defaultval; +}; + +#define UPB_ENUMDEF_INIT(name, ntoi, iton, defaultval, refs, ref2s) \ + { UPB_DEF_INIT(name, UPB_DEF_ENUM, refs, ref2s), ntoi, iton, defaultval } + + +/* upb_oneofdef ***************************************************************/ + +struct upb_oneofdef { + upb_def base; + + upb_strtable ntof; + upb_inttable itof; + const upb_msgdef *parent; +}; + +#define UPB_ONEOFDEF_INIT(name, ntof, itof, refs, ref2s) \ + { UPB_DEF_INIT(name, UPB_DEF_ENUM, refs, ref2s), ntof, itof } + + +/* upb_symtab *****************************************************************/ + +struct upb_symtab { + upb_refcounted base; + + upb_strtable symtab; +}; + +#define UPB_SYMTAB_INIT(symtab, refs, ref2s) \ + { UPB_REFCOUNT_INIT(refs, ref2s), symtab } + + +#endif /* UPB_STATICINIT_H_ */ -- cgit v1.2.3