|
#define | M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_XCODE |
|
#define | out(...) fprintf(thefile, __VA_ARGS__) |
|
#define | TOK(tok) (int)(tok)->ft_len, (int)(tok)->ft_len, (tok)->ft_val |
|
#define | T(term) TOK(&(term)->fn_tok) |
|
#define | SAFE(ctx, cond) ((ctx)->fc_remain > 0 && (cond)) |
|
#define | TOK(tok) (int)(tok)->ft_len, (int)(tok)->ft_len, (tok)->ft_val |
|
#define | T(term) TOK(&(term)->fn_tok) |
|
#define | _XT(x) |
|
#define | _XT(x) |
|
#define | _XT(x) |
|
#define | _TI(x) |
|
#define | _TI(x) |
|
#define | _TI(x) |
|
#define | _EN(x) |
|
#define | _EN(x) |
|
#define | _EN(x) |
|
#define | _FI(x) M0_INTERNAL void x(void); |
|
#define | _FI(x) x(); |
|
#define | _FI(x) |
|
#define | _FF(x) M0_INTERNAL void x(void); |
|
#define | _FF(x) |
|
#define | _FF(x) x(); |
|
#define | M0_XCODE_VAL(obj, fieldno, elno, __type) ((__type *)m0_xcode_addr(obj, fieldno, elno)) |
|
#define | M0_XCODE_OBJ(type, ptr) |
|
#define | M0_XC_ATTR(name, val) __attribute__((annotate("xc_" name "," val))) |
|
#define | M0_XCA_ARRAY M0_XC_ATTR("atype", "M0_XA_ARRAY") |
|
#define | M0_XCA_BLOB M0_XC_ATTR("atype", "M0_XA_BLOB") |
|
#define | M0_XCA_OPAQUE(value) M0_XC_ATTR("opaque", value) |
|
#define | M0_XCA_TAG(value) M0_XC_ATTR("tag", value) |
|
#define | M0_XCA_FENUM(value) M0_XC_ATTR("fenum", #value) |
|
#define | M0_XCA_FBITMASK(value) M0_XC_ATTR("fbitmask", #value) |
|
#define | M0_XCA_DOMAIN(value) M0_XC_ATTR("domain", #value) |
|
|
enum | ff2c_token_type {
FTT_IDENTIFIER = 1,
FTT_REQUIRE,
FTT_STRING,
FTT_VOID,
FTT_U8,
FTT_U32,
FTT_U64,
FTT_OPAQUE,
FTT_RECORD,
FTT_UNION,
FTT_SEQUENCE,
FTT_ARRAY,
FTT_OPEN,
FTT_CLOSE,
FTT_SEMICOLON,
FTT_TAG,
FTT_ESCAPE
} |
|
enum | { FF2C_CTX_STACK_MAX = 32
} |
|
enum | ff2c_term_type {
FNT_FF = 1,
FNT_REQUIRE,
FNT_DECLARATION,
FNT_ATOMIC,
FNT_COMPOUND,
FNT_TYPENAME,
FNT_TAG,
FNT_ESCAPE,
FNT_NR
} |
|
enum | xcode_op { XO_ENC,
XO_DEC,
XO_LEN,
XO_NR
} |
|
enum | m0_xcode_aggr {
M0_XA_RECORD,
M0_XA_UNION,
M0_XA_SEQUENCE,
M0_XA_ARRAY,
M0_XA_TYPEDEF,
M0_XA_OPAQUE,
M0_XA_ATOM,
M0_XA_NR
} |
|
enum | m0_xode_atom_type {
M0_XAT_VOID,
M0_XAT_U8,
M0_XAT_U32,
M0_XAT_U64,
M0_XAT_NR
} |
|
enum | { M0_XCODE_DECOR_READ,
M0_XCODE_DECOR_MAX = 10
} |
|
enum | m0_xcode_type_flags { M0_XCODE_TYPE_FLAG_DOM_BE = 1 << 0,
M0_XCODE_TYPE_FLAG_DOM_RPC = 1 << 1,
M0_XCODE_TYPE_FLAG_DOM_CONF = 1 << 2
} |
|
enum | { M0_XCODE_DEPTH_MAX = 10
} |
|
|
static const struct m0_xcode_enum_val * | valget (const struct m0_xcode_enum *en, uint64_t val) |
|
static const struct m0_xcode_enum_val * | nameget (const struct m0_xcode_enum *en, const char *name, int nr) |
|
static int | enum_getnum (const char *buf, uint64_t *out) |
|
static const char * | enum_id (const char *buf) |
|
static const char * | bitmask_id (const char *buf) |
|
bool | m0_xcode_enum_is_valid (const struct m0_xcode_enum *en, uint64_t val) |
|
const char * | m0_xcode_enum_print (const struct m0_xcode_enum *en, uint64_t val, char *buf) |
|
int | m0_xcode_enum_read (const struct m0_xcode_enum *en, const char *buf, int nr, uint64_t *val) |
|
bool | m0_xcode_bitmask_is_valid (const struct m0_xcode_enum *en, uint64_t val) |
|
int | m0_xcode_bitmask_print (const struct m0_xcode_enum *en, uint64_t val, char *buf, int nr) |
|
int | m0_xcode_bitmask_read (const struct m0_xcode_enum *en, const char *buf, int nr, uint64_t *val) |
|
M0_INTERNAL int | m0_xcode_enum_field_read (const struct m0_xcode_cursor *it, struct m0_xcode_obj *obj, const char *str) |
|
M0_INTERNAL int | m0_xcode_bitmask_field_read (const struct m0_xcode_cursor *it, struct m0_xcode_obj *obj, const char *str) |
|
static bool | enum_char (char ch) |
|
int | main (int argc, char **argv) |
|
static void | indent (int depth) |
|
static void | type_h (const struct ff2c_type *t, int depth) |
|
static void | field_h (const struct ff2c_field *f, int depth) |
|
int | ff2c_h_gen (const struct ff2c_ff *ff, const struct ff2c_gen_opt *opt) |
|
static void | field_def (const struct ff2c_type *t, const struct ff2c_field *f, int i) |
|
static void | type_fields (const struct ff2c_type *t) |
|
static void | type_decl (const struct ff2c_type *t) |
|
static void | type_def (const struct ff2c_type *t) |
|
int | ff2c_c_gen (const struct ff2c_ff *ff, const struct ff2c_gen_opt *opt) |
|
static void | ctx_move (struct ff2c_context *ctx, size_t nob) |
|
static void | ctx_step (struct ff2c_context *ctx) |
|
static bool | at (struct ff2c_context *ctx, char c) |
|
static bool | at_string (struct ff2c_context *ctx, const char *s, size_t n) |
|
static bool | is_start (char c) |
|
static bool | is_middle (char c) |
|
static void | tok_end (struct ff2c_context *ctx, struct ff2c_token *tok) |
|
static void | skip_space (struct ff2c_context *ctx) |
|
static bool | get_literal (struct ff2c_context *ctx, struct ff2c_token *tok) |
|
int | ff2c_token_get (struct ff2c_context *ctx, struct ff2c_token *tok) |
|
void | ff2c_token_put (struct ff2c_context *ctx, struct ff2c_token *tok) |
|
void | ff2c_context_init (struct ff2c_context *ctx, const char *buf, size_t size) |
|
void | ff2c_context_fini (struct ff2c_context *ctx) |
|
int | ff2c_context_loc (struct ff2c_context *ctx, int nr, char *buf) |
|
static struct ff2c_term * | alloc (void) |
|
static void | error (struct ff2c_context *ctx, const char *msg) |
|
static struct ff2c_term * | add (struct ff2c_term *term) |
|
static void | token (struct ff2c_context *ctx, struct ff2c_term *term, struct ff2c_token *tok) |
|
static int | declaration (struct ff2c_context *ctx, struct ff2c_term *term) |
|
static int | field (struct ff2c_context *ctx, struct ff2c_term *term) |
|
static int | field_list (struct ff2c_context *ctx, struct ff2c_term *term) |
|
static int | type (struct ff2c_context *ctx, struct ff2c_term *term) |
|
static int | require (struct ff2c_context *ctx, struct ff2c_term *term) |
|
static int | statement (struct ff2c_context *ctx, struct ff2c_term *term) |
|
static int | ff (struct ff2c_context *ctx, struct ff2c_term *term) |
|
int | ff2c_parse (struct ff2c_context *ctx, struct ff2c_term **out) |
|
void | ff2c_term_fini (struct ff2c_term *term) |
|
static void * | alloc (size_t nr) |
|
| __attribute__ ((format(printf, 1, 2))) |
|
static void * | add (struct ff2c_list *list, void *obj) |
|
static void * | add_new (struct ff2c_list *list, size_t size) |
|
void | require_init (struct ff2c_ff *ff, struct ff2c_require *r, const struct ff2c_term *term) |
|
void | type_init (struct ff2c_ff *ff, struct ff2c_type *t, const struct ff2c_term *term) |
|
void | field_init (struct ff2c_ff *ff, struct ff2c_type *t, struct ff2c_field *f, int i, const struct ff2c_term *term) |
|
void | tree_walk (struct ff2c_ff *ff, const struct ff2c_term *top) |
|
void | ff2c_sem_init (struct ff2c_ff *ff, struct ff2c_term *top) |
|
void | ff2c_sem_fini (struct ff2c_ff *ff) |
|
char * | fmt (const char *format,...) __attribute__((format(printf |
|
int | m0_xcode_init (void) |
|
void | m0_xcode_fini (void) |
|
M0_INTERNAL const char * | space_skip (const char *str) |
|
static int | string_literal (const struct m0_xcode_cursor *it, struct m0_xcode_obj *obj, const char *str) |
|
static int | char_check (const char **str, char ch) |
|
static char | punctchar (struct m0_xcode_cursor *it) |
|
M0_INTERNAL int | m0_xcode_read (struct m0_xcode_obj *obj, const char *str) |
|
static bool | quoted_string (const struct m0_xcode_type *xt, const struct m0_xcode_obj *obj, struct m0_fop_str *qstr) |
|
M0_INTERNAL int | m0_xcode_print (const struct m0_xcode_obj *obj, char *str, int nr) |
|
static bool | is_pointer (const struct m0_xcode_type *xt, const struct m0_xcode_field *field) |
|
static unsigned | alignment_mask (const struct m0_xcode_field *field) |
|
static bool | field_invariant (const struct m0_xcode_type *xt, const struct m0_xcode_field *field) |
|
bool | m0_xcode_type_invariant (const struct m0_xcode_type *xt) |
|
static bool | at_array (const struct m0_xcode_cursor *it, const struct m0_xcode_cursor_frame *prev, const struct m0_xcode_obj *par) |
|
static void ** | allocp (struct m0_xcode_cursor *it, size_t *out) |
|
M0_INTERNAL void | m0_xcode_free_obj (struct m0_xcode_obj *obj) |
|
static int | ctx_walk (struct m0_xcode_ctx *ctx, enum xcode_op op) |
|
static void | __xcode_free (struct m0_xcode_cursor *it) |
|
M0_INTERNAL void | m0_xcode_free (struct m0_xcode_ctx *ctx) |
|
M0_INTERNAL int | m0_xcode_dup (struct m0_xcode_ctx *dest, struct m0_xcode_ctx *src) |
|
M0_INTERNAL int | m0_xcode_cmp (const struct m0_xcode_obj *o0, const struct m0_xcode_obj *o1) |
|
M0_INTERNAL void * | m0_xcode_addr (const struct m0_xcode_obj *obj, int fileno, uint64_t elno) |
|
M0_INTERNAL int | m0_xcode_subobj (struct m0_xcode_obj *subobj, const struct m0_xcode_obj *obj, int fieldno, uint64_t elno) |
|
M0_INTERNAL uint64_t | m0_xcode_atom (const struct m0_xcode_obj *obj) |
|
M0_INTERNAL uint64_t | m0_xcode_tag (const struct m0_xcode_obj *obj) |
|
M0_INTERNAL int | m0_xcode_find (struct m0_xcode_obj *obj, const struct m0_xcode_type *xt, void **place) |
|
M0_INTERNAL void | m0_xcode_bob_type_init (struct m0_bob_type *bt, const struct m0_xcode_type *xt, size_t magix_field, uint64_t magix) |
|
M0_INTERNAL void * | m0_xcode_ctx_top (const struct m0_xcode_ctx *ctx) |
|
M0_INTERNAL void | m0_xcode_union_init (struct m0_xcode_type *un, const char *name, const char *discriminator, size_t maxbranches) |
|
M0_INTERNAL void | m0_xcode_union_fini (struct m0_xcode_type *un) |
|
M0_INTERNAL void | m0_xcode_union_add (struct m0_xcode_type *un, const char *name, const struct m0_xcode_type *xt, uint64_t tag) |
|
M0_INTERNAL void | m0_xcode_union_close (struct m0_xcode_type *un) |
|
static void | xcode_flags_check (struct m0_xcode_type *xt, struct flags_data *fd) |
|
M0_INTERNAL bool | m0_xcode_type_flags (struct m0_xcode_type *xt, uint32_t on, uint32_t off, uint64_t aggr_umask) |
|
void | m0_xc_u8_init (void) |
|
void | m0_xc_u16_init (void) |
|
void | m0_xc_u32_init (void) |
|
void | m0_xc_u64_init (void) |
|
void | m0_xc_void_init (void) |
|
void | m0_xc_opaque_init (void) |
|
| M0_BASSERT (sizeof(enum m0_xcode_type_flags)<=sizeof(uint32_t)) |
|
M0_INTERNAL int | m0_xcode_decor_register (void) |
|
|
xcode provides an iteration interface to walk through the hierarchy of types and fields.
This interface consists of two functions: m0_xcode_next(), m0_xcode_skip() and m0_xcode_cursor data-type.
m0_xcode_next() takes a starting type (m0_xcode_type) and walks the tree of its fields, their types, their fields &c., all the way down to the atomic types.
m0_xcode_next() can be used to walk the tree in any "standard" order: preorder, inorder and postorder traversals are supported. To this end, m0_xcode_next() visits each tree node multiple times, setting the flag m0_xcode_cursor::xcu_stack[]::s_flag according to the order.
|
enum | m0_xcode_cursor_flag {
M0_XCODE_CURSOR_NONE,
M0_XCODE_CURSOR_PRE,
M0_XCODE_CURSOR_IN,
M0_XCODE_CURSOR_POST,
M0_XCODE_CURSOR_NR
} |
|
const char * | m0_xcode_cursor_flag_name [M0_XCODE_CURSOR_NR] |
|
M0_INTERNAL void | m0_xcode_cursor_init (struct m0_xcode_cursor *it, const struct m0_xcode_obj *obj) |
|
M0_INTERNAL struct m0_xcode_cursor_frame * | m0_xcode_cursor_top (struct m0_xcode_cursor *it) |
|
M0_INTERNAL const struct m0_xcode_field * | m0_xcode_cursor_field (const struct m0_xcode_cursor *it) |
|
M0_INTERNAL int | m0_xcode_next (struct m0_xcode_cursor *it) |
|
M0_INTERNAL void | m0_xcode_skip (struct m0_xcode_cursor *it) |
|
|
Encoding-decoding (collectively xcoding) support is implemented on top of introspection facilities provided by the xcode module. xcoding provides 3 operations: - sizing (m0_xcode_length()): returns the size of a buffer sufficient to
hold serialized object representation;
- encoding (m0_xcode_encode()): constructs a serialized object
representation in a given buffer;
- decoding (m0_xcode_decode()): constructs an in-memory object, given its
serialized representation.
xcoding traverses the tree of sub-objects, starting from the topmost object to be xcoded. For each visited object, if a method, corresponding to the xcoding operation (encode, decode, length) is not NULL in object's type m0_xcode_type_ops vector, this method is called and no further processing of this object is done. Otherwise, "standard xcoding" takes place.
Standard xcoding is non-trivial only for leaves in the sub-object tree (i.e., for objects of ATOM aggregation type): - for encoding, place object's value into the buffer, convert it to
desired endianness and advance buffer position;
- for decoding, extract value from the buffer, convert it, store in the
in-memory object and advance buffer position;
- for sizing, increment required buffer size by the size of atomic type.
In addition, decoding allocates memory as necessary.
|
enum | m0_xcode_endianness { M0_XEND_LE,
M0_XEND_BE,
M0_XEND_NR
} |
|
enum | m0_xcode_what { M0_XCODE_ENCODE = 0,
M0_XCODE_DECODE = 1
} |
|
const char * | m0_xcode_endianness_name [M0_XEND_NR] |
|
M0_EXTERN ssize_t | m0_xcode_alloc_obj (struct m0_xcode_cursor *it, void *(*alloc)(struct m0_xcode_cursor *, size_t)) |
|
M0_INTERNAL bool | m0_xcode_is_byte_array (const struct m0_xcode_type *xt) |
|
M0_INTERNAL void | m0_xcode_ctx_init (struct m0_xcode_ctx *ctx, const struct m0_xcode_obj *obj) |
|
M0_INTERNAL int | m0_xcode_decode (struct m0_xcode_ctx *ctx) |
|
M0_INTERNAL int | m0_xcode_encode (struct m0_xcode_ctx *ctx) |
|
M0_INTERNAL int | m0_xcode_length (struct m0_xcode_ctx *ctx) |
|
M0_INTERNAL void | m0_xcode_type_iterate (struct m0_xcode_type *xt, void(*t)(struct m0_xcode_type *, void *), void(*f)(struct m0_xcode_type *, struct m0_xcode_field *, void *), void *datum) |
|
M0_INTERNAL int | m0_xcode_encdec (struct m0_xcode_obj *obj, struct m0_bufvec_cursor *cur, enum m0_xcode_what what) |
|
M0_INTERNAL int | m0_xcode_data_size (struct m0_xcode_ctx *ctx, const struct m0_xcode_obj *obj) |
|
M0_INTERNAL void * | m0_xcode_alloc (struct m0_xcode_cursor *it, size_t nob) |
|
M0_INTERNAL int | m0_xcode_obj_enc_to_buf (struct m0_xcode_obj *obj, void **buf, m0_bcount_t *len) |
|
M0_INTERNAL int | m0_xcode_obj_dec_from_buf (struct m0_xcode_obj *obj, void *buf, m0_bcount_t len) |
|
Enumeration support in xcode
xcode provides a rudimentary support for enumeration (enum) reflection.
A enumeration type is represented by an instance of m0_xcode_enum structure, which contains an array (m0_xcode_enum::xe_val[]) of m0_xcode_enum_val structures describing all valid enumeration constants for the type.
xcode provides functions to convert enums between binary and symbolic form (m0_xcode_enum_read() and m0_xcode_print()). In addition, a enum can be interpreted as a set of bit-flags, OR-ed to construct bit-masks. Resulting bit-masks can be parsed and printed by m0_xcode_bitmask_read() and m0_xcode_bitmask_print().
m0_xcode_enum representation is constructed automatically by the build process for each enum declaration tagged with the M0_XCA_ENUM. This only works for named enums.
xcode module implements a modest set of introspection facilities. A user defines a structure (m0_xcode_type) which describes the in memory layout of a C data-type. xcode provides interfaces to iterate over hierarchy of such descriptors and to associate user defined state with types and fields.
A motivating example of xcode usage is universal encoding and decoding interface (m0_xcode_decode(), m0_xcode_encode(), m0_xcode_length()) which converts between an in-memory object and its serialized representation.
Other usages of xcoding interfaces are:
- pretty-printing,
- pointer swizzling and adjustment when loading BE segments into memory,
- consistency checking: traversing data-structures in memory validating
check-sums and invariants.
Not every C data-structure can be represented by xcode. The set of representable data-structures is defined inductively according to the "aggregation type" of data-structure:
- ATOM aggregation type: scalar data-types void, uint8_t, uint32_t and
uint64_t are representable,
- RECORD aggregation type: a struct type, whose members are all
representable is representable,
- UNION aggregation type: a "discriminated union" structure of the form
struct {
scalar_t discriminator;
union {
...
};
where scalar_t is one of the scalar data-types mentioned above and all union fields are representable is representable,
- SEQUENCE aggregation type: a "counted array" structure of the form
where scalar_t is one of the scalar data-types mentioned above and el_t is representable,
- ARRAY is a fixed size array
where N is a compile-time constant and el_t is representable.
OPAQUE aggregation type: pointer type is representable when it is used as the type of a field in a representable type and a special function (m0_xcode_field::xf_opaque()) is assigned to the field, which returns the representation of the type of an object the pointer points to.
The usage of function allows representation of pointer structures where the actual type of the object pointed to depends on the contents of its parent structure.
A representable type is described by an instance of struct m0_xcode_type, which describes type attributes and also contains an array (m0_xcode_type::xct_child[]) of "fields". A field is represented by struct m0_xcode_field and describes a sub-object. The field points to a m0_xcode_type instance, describing the type of sub-object. This way a hierarchy (forest of trees) of types is organized. Its leaves are atomic types.
Sub-objects are located contiguously in memory, except for SEQUENCE elements and OPAQUE fields.
xcode description of a data-type can be provided either by
- manually creating an instance of m0_xcode_type structure, describing
properties of the data-type or
- by tagging C structure declarations with macros defined in
xcode/xcode.h and then executing xcode/m0gccxml2xcode on the header file
or
- by creating a description of the desired serialized format of a
data-type and using ff2c translator (xcode/ff2c/ff2c.c) to produce C
files (.c and .h) containing the matching data-type definitions and
xcode descriptors.
The first method is suitable for memory-only structures. The last 2 methods are for structures designed to be transmitted over network of stored on persistent storage (fops, db records, &c.). m0gccxml2xcode is the preferable method. ff2c should only be used when m0gccxml2xcode cannot accomplish the task.
ff2c
ff2c is a simple translator, taking as an input a set of descriptions of desired serialized representations and producing a set of C declarations of types having given serialized representations. In addition, definitions of xcode data (m0_xcode_type and m0_xcode_field) for generated types is produced.
Serialized representation descriptions are given in a language with the following grammar:
ff ::= statement-list
statement-list ::= statement | statement ';' statement-list
statement ::= require | declaration
require ::= 'require' '"' pathname '"'
declaration ::= type identifier
type ::= atomic | compound | opaque | identifier
atomic ::= 'void' | 'u8' | 'u32' | 'u64'
compound ::= kind '{' field-list '}'
opaque ::= '*' identifier
kind ::= 'record' | 'union' | 'sequence'
field-list ::= field | field ';' field-list
field ::= declaration tag escape
tag ::= empty | ':' expression
escape ::= empty | '[' identifier ']'
The language is case-sensitive. Tokens are separated by blank space and C-style comments.
The meaning of language constructs is explained in the following example:
/* ff2c input file. */
/*
* The following command generates ./xcode/ff2c/sample.{c,h}
*
* $ ./xcode/ff2c/ff2c ./xcode/ff2c/sample.ff
*
*/
/*
* C-style comments are used, blank-spaces between tokens are ignored.
*
* Semicolon is used as a _separator_, not a _terminator_. That is, various
* lists (fields, declarations) have a form E0 ; E1 ; ... ; EN.
*/
/*
* "require" statement introduces a dependency on other source file. For each
* "require", an #include directive is produced, which includes corresponding
* header file, "lib/vec.h" in this case
*/
require "lib/vec";
require "fop/fop";
/*
* Following in this file are type declaration statements, which all have form
* "type-declaration type-name".
*/
/* define "fid" as a RECORD type, having two U64 fields. */
record {
u64 f_container;
u64 f_offset
} fid;
/*
* Produced C declaration is:
* struct fid {
* uint64_t f_container;
* uint64_t f_offset;
* };
*/
/*
* Define "optfid" as a UNION containing a byte discriminator field (o_flag),
* followed either by a fid (provided o_flag's value is 1) or a U32 value
* o_short (provided o_flag's value is 3).
*/
union {
u8 o_flag;
fid o_fid :1;
u32 o_short :3
} optfid;
/*
* Produced C declaration is:
*
* struct optfid {
* uint8_t o_flag;
* union {
* struct fid o_fid;
* uint32_t o_short;
* } u;
* };
*/
/* define optfidarray as a counted array of optfid instances. */
sequence {
u64 ofa_nr;
optfid ofa_data
} optfidarray;
/*
* Produced C declaration is:
*
* struct optfidarray {
* uint64_t ofa_nr;
* struct optfid *ofa_data;
* };
*/
/*
* define fixarray as a fixed-size array of optfids. Array size is NR, which
* must be defined in one of "require"-d files.
*/
sequence {
void fa_none :NR;
optfid fa_data
} fixarray;
/*
* Produced C declaration is:
*
* struct fixarray {
* m0_void_t fa_none;
* struct optfid *fa_data;
* };
*/
/* demonstrate declaration of a more complex structure. */
record {
fid p_fid;
/*
* "p_cred" is opaque field. It is represented as a pointer to struct
* m0_cred. The actual type of pointed object is returned by
* m0_package_cred_get() function.
*/
*m0_cred p_cred [m0_package_cred_get];
/*
* field's type can be defined in-place. ff2c generates a name of the
* form "parent_type"_"field_name" for such anonymous type.
*/
sequence {
u32 s_nr;
record {
u8 e_flag;
fixarray e_payload;
record {
u64 d_0;
u64 d_1
} e_datum
} s_el
} p_name
} package;
/*
* Produced C declaration is:
*
* struct package {
* struct fid p_fid;
* struct m0_cred *p_cred;
* struct package_p_name {
* uint32_t s_nr;
* struct p_name_s_el {
* uint8_t e_flag;
* struct fixarray e_payload;
* struct s_el_e_datum {
* uint64_t d_0;
* uint64_t d_1;
* } e_datum;
* } s_el;
* } p_name;
* };
*
* And (in sample.c):
*
* int m0_package_cred_get(const struct m0_xcode_obj *par,
* const struct m0_xcode_type **out);
*
*/
array {
fid quad : NR
} fixfid
/*
* Produced C declaration is:
*
* struct fixfid {
* struct fid[NR];
* };
*/
The translator is structured as a sequence of 4 passes:
- lexical analysis (lex.c): takes a buffer as an input and produces a
stream of tokens;
- parser (parser.h): builds a parse tree out of stream of tokens. Every
node in the tree have the same structure: it contains a token and a list
of child nodes;
- semantical pass (sem.h): traverses parse tree and builds a tree of
semantical nodes, corresponding to types and fields. Semantical nodes
are "higher level" than syntax nodes are more closely aligned with the
requirements of the following generation pass;
- generation (gen.h): take semantic tree and produce corresponding C
declarations and definitions.
ff2c. Lexical analysis.
Very simple hand-crafted lexer.
Input is a contiguous memory buffer (buffer vector can be supported easily).
ff2c_context data-structure tracks current input position. To make meaningful error reporting possible (line, column) coordinates are also tracked.
Next input token is returned by ff2c_token_get(). Returned token points (ff2c_token::ft_val) directly into the input buffer. Specifically, token value is not NUL terminated.
ff2c. Parser.
Recursive-descent parser.
◆ _EN [1/3]
◆ _EN [2/3]
◆ _EN [3/3]
◆ _FF [1/3]
#define _FF |
( |
|
x | ) |
M0_INTERNAL void x(void); |
◆ _FF [2/3]
◆ _FF [3/3]
◆ _FI [1/3]
#define _FI |
( |
|
x | ) |
M0_INTERNAL void x(void); |
◆ _FI [2/3]
◆ _FI [3/3]
◆ _TI [1/3]
◆ _TI [2/3]
◆ _TI [3/3]
◆ _XT [1/3]
◆ _XT [2/3]
◆ _XT [3/3]
◆ M0_TRACE_SUBSYSTEM
#define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_XCODE |
◆ M0_XC_ATTR
Set xcode attribute on a struct or strucut's field. This sets a special gcc attribute which is ignored by gcc during compilation, but which is then used by gccxml and m0gccxml2xcode to generate xcode data.
Please, refer to m0gccxml2xcode documentation for more details.
Definition at line 43 of file xcode_attr.h.
◆ M0_XCA_ARRAY
◆ M0_XCA_BLOB
#define M0_XCA_BLOB M0_XC_ATTR("atype", "M0_XA_BLOB") |
◆ M0_XCA_DOMAIN
◆ M0_XCA_FBITMASK
◆ M0_XCA_FENUM
◆ M0_XCA_OPAQUE
◆ M0_XCA_TAG
◆ M0_XCODE_OBJ
Value:}
static void ptr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition at line 962 of file xcode.h.
◆ M0_XCODE_VAL
#define M0_XCODE_VAL |
( |
|
obj, |
|
|
|
fieldno, |
|
|
|
elno, |
|
|
|
__type |
|
) |
| ((__type *)m0_xcode_addr(obj, fieldno, elno)) |
Helper macro to return field value cast to a given type.
Definition at line 821 of file xcode.h.
◆ out
#define out |
( |
|
... | ) |
fprintf(thefile, __VA_ARGS__) |
Definition at line 41 of file gen.c.
◆ SAFE
#define SAFE |
( |
|
ctx, |
|
|
|
cond |
|
) |
| ((ctx)->fc_remain > 0 && (cond)) |
Definition at line 75 of file lex.c.
◆ T [1/2]
Definition at line 51 of file gen.c.
◆ T [2/2]
Definition at line 76 of file sem.c.
◆ TOK [1/2]
#define TOK |
( |
|
tok | ) |
(int)(tok)->ft_len, (int)(tok)->ft_len, (tok)->ft_val |
Definition at line 50 of file gen.c.
◆ TOK [2/2]
#define TOK |
( |
|
tok | ) |
(int)(tok)->ft_len, (int)(tok)->ft_len, (tok)->ft_val |
Definition at line 75 of file sem.c.
◆ m0_void_t
typedef char m0_void_t[0] |
Void type used by ff2c in places where C syntax requires a type name.
Definition at line 925 of file xcode.h.
◆ anonymous enum
Enumerator |
---|
FF2C_CTX_STACK_MAX | |
Definition at line 120 of file lex.h.
◆ anonymous enum
Enumerator |
---|
M0_XCODE_DECOR_READ | |
M0_XCODE_DECOR_MAX | |
Definition at line 243 of file xcode.h.
◆ anonymous enum
Enumerator |
---|
M0_XCODE_DEPTH_MAX | |
Definition at line 383 of file xcode.h.
◆ ff2c_term_type
Enumerator |
---|
FNT_FF | |
FNT_REQUIRE | |
FNT_DECLARATION | |
FNT_ATOMIC | |
FNT_COMPOUND | |
FNT_TYPENAME | |
FNT_TAG | |
FNT_ESCAPE | |
FNT_NR | |
Definition at line 42 of file parser.h.
◆ ff2c_token_type
Token types. For each value, a regular expression, matching the tokens of this type is provided. CONT means "[a-zA-Z_0-9]*"
Enumerator |
---|
FTT_IDENTIFIER | "[a-zA-Z_]CONT"
|
FTT_REQUIRE | "require"
|
FTT_STRING | "\"[^"]*""
|
FTT_VOID | "void"
|
FTT_U8 | "u8"
|
FTT_U32 | "u32"
|
FTT_U64 | "u64"
|
FTT_OPAQUE | "\*CONT"
|
FTT_RECORD | "record"
|
FTT_UNION | "union"
|
FTT_SEQUENCE | "sequence"
|
FTT_ARRAY | "array"
|
FTT_OPEN | "{"
|
FTT_CLOSE | "}"
|
FTT_SEMICOLON | ";"
|
FTT_TAG | ":CONT"
|
FTT_ESCAPE | "\[CONT\]"
|
Definition at line 53 of file lex.h.
◆ m0_xcode_aggr
Type of aggregation for a data-type.
A value of this enum, stored in m0_code_type::xct_aggr determines how fields of the type are interpreted.
Enumerator |
---|
M0_XA_RECORD | RECORD corresponds to C struct. Fields of RECORD type are located one after another in memory.
|
M0_XA_UNION | UNION corresponds to discriminated union. Its first field is referred to as a "discriminator" and has an atomic type. Other fields of union are tagged (m0_xcode_field::xf_tag) and the value of the discriminator field determines which of the following fields is actually used.
- Note
- that, similarly to M0_XA_SEQUENCE, the discriminator field can have M0_XAT_VOID type. In this case its tag is used instead of its value (use cases are not clear).
|
M0_XA_SEQUENCE | SEQUENCE corresponds to counted array. Sequence always has two fields: a scalar "counter" field and a field denoting the element of the array.
- Note
- if counter has type M0_XAT_VOID, its tag used as a counter. This is used to represent fixed size arrays without an explicit counter field.
|
M0_XA_ARRAY | Array is a fixed size array. It always has a single field. The number of elements in the array is recorded as the tag is this field.
|
M0_XA_TYPEDEF | TYPEDEF is an alias for another type. It always has a single field.
|
M0_XA_OPAQUE | OPAQUE represents a pointer.
A field of OPAQUE type must have m0_xcode_field::xf_opaque() function pointer set to a function which determines the actual type of the object pointed to.
|
M0_XA_ATOM | ATOM represents "atomic" data-types having no internal structure. m0_xcode_type-s with m0_xcode_type::xct_aggr set to M0_XA_ATOM have m0_xcode_type::xct_nr == 0 and no fields.
Atomic types are enumerated in m0_xode_atom_type.
|
M0_XA_NR | |
Definition at line 164 of file xcode.h.
◆ m0_xcode_cursor_flag
Traversal order.
Enumerator |
---|
M0_XCODE_CURSOR_NONE | This value is never returned by m0_xcode_next(). It is set by the user to indicate the beginning of iteration.
|
M0_XCODE_CURSOR_PRE | Tree element is visited for the first time.
|
M0_XCODE_CURSOR_IN | The sub-tree, rooted at an element's field has been processed fully.
|
M0_XCODE_CURSOR_POST | All fields have been processed fully, this is the last time the element is visited.
|
M0_XCODE_CURSOR_NR | |
Definition at line 408 of file xcode.h.
◆ m0_xcode_endianness
◆ m0_xcode_type_flags
Enumerator |
---|
M0_XCODE_TYPE_FLAG_DOM_BE | Type belongs to BE xcode domain, - See also
- M0_XCA_DOMAIN
|
M0_XCODE_TYPE_FLAG_DOM_RPC | Type belongs to RPC xcode domain, - See also
- M0_XCA_DOMAIN
|
M0_XCODE_TYPE_FLAG_DOM_CONF | Type belongs to CONF xcode domain, - See also
- M0_XCA_DOMAIN
|
Definition at line 300 of file xcode.h.
◆ m0_xcode_what
Enumerator |
---|
M0_XCODE_ENCODE | |
M0_XCODE_DECODE | |
Definition at line 647 of file xcode.h.
◆ m0_xode_atom_type
Atomic types.
To each value of this enumeration, except for M0_XAT_NR, a separate m0_xcode_type (M0_XT_VOID, M0_XT_U8, &c.).
Enumerator |
---|
M0_XAT_VOID | |
M0_XAT_U8 | |
M0_XAT_U32 | |
M0_XAT_U64 | |
M0_XAT_NR | |
Definition at line 231 of file xcode.h.
◆ xcode_op
Enumerator |
---|
XO_ENC | |
XO_DEC | |
XO_LEN | |
XO_NR | |
Definition at line 141 of file xcode.c.
◆ __attribute__()
__attribute__ |
( |
(format(printf, 1, 2)) |
| ) |
|
Definition at line 51 of file sem.c.
◆ __xcode_free()
◆ add() [1/2]
◆ add() [2/2]
static void* add |
( |
struct ff2c_list * |
list, |
|
|
void * |
obj |
|
) |
| |
|
static |
Definition at line 64 of file sem.c.
◆ add_new()
static void* add_new |
( |
struct ff2c_list * |
list, |
|
|
size_t |
size |
|
) |
| |
|
static |
Definition at line 70 of file sem.c.
◆ alignment_mask()
Returns "portable" alignment for a field, which would work on any architecture.
Definition at line 51 of file xcode.c.
◆ alloc() [1/2]
◆ alloc() [2/2]
static void* alloc |
( |
size_t |
nr | ) |
|
|
static |
Definition at line 40 of file sem.c.
◆ allocp()
◆ at()
Definition at line 77 of file lex.c.
◆ at_array()
◆ at_string()
static bool at_string |
( |
struct ff2c_context * |
ctx, |
|
|
const char * |
s, |
|
|
size_t |
n |
|
) |
| |
|
static |
Definition at line 82 of file lex.c.
◆ bitmask_id()
static const char * bitmask_id |
( |
const char * |
buf | ) |
|
|
static |
◆ char_check()
static int char_check |
( |
const char ** |
str, |
|
|
char |
ch |
|
) |
| |
|
static |
◆ ctx_move()
static void ctx_move |
( |
struct ff2c_context * |
ctx, |
|
|
size_t |
nob |
|
) |
| |
|
static |
Definition at line 57 of file lex.c.
◆ ctx_step()
Definition at line 70 of file lex.c.
◆ ctx_walk()
Common xcoding function, implementing encoding, decoding and sizing.
Definition at line 260 of file xcode.c.
◆ declaration()
◆ enum_char()
static bool enum_char |
( |
char |
ch | ) |
|
|
static |
◆ enum_getnum()
static int enum_getnum |
( |
const char * |
buf, |
|
|
uint64_t * |
out |
|
) |
| |
|
static |
◆ enum_id()
static const char * enum_id |
( |
const char * |
buf | ) |
|
|
static |
◆ error()
static void error |
( |
struct ff2c_context * |
ctx, |
|
|
const char * |
msg |
|
) |
| |
|
static |
◆ ff()
◆ ff2c_c_gen()
◆ ff2c_context_fini()
◆ ff2c_context_init()
void ff2c_context_init |
( |
struct ff2c_context * |
ctx, |
|
|
const char * |
buf, |
|
|
size_t |
size |
|
) |
| |
◆ ff2c_context_loc()
int ff2c_context_loc |
( |
struct ff2c_context * |
ctx, |
|
|
int |
nr, |
|
|
char * |
buf |
|
) |
| |
Print human-readable description of the current input position in "buf".
Definition at line 234 of file lex.c.
◆ ff2c_h_gen()
Definition at line 93 of file gen.c.
◆ ff2c_parse()
◆ ff2c_sem_fini()
void ff2c_sem_fini |
( |
struct ff2c_ff * |
ff | ) |
|
◆ ff2c_sem_init()
◆ ff2c_term_fini()
void ff2c_term_fini |
( |
struct ff2c_term * |
term | ) |
|
◆ ff2c_token_get()
Returns the next token.
- Return values
-
+ve | success. "tok" is filled with the new token |
0 | end of the input buffer reached |
-ve | malformed input, error code is returned. |
Definition at line 134 of file lex.c.
◆ ff2c_token_put()
Put token back.
The next call to ff2c_token_get() will return this token.
When multiple tokens are put back, they are returned in LIFO order. Up to FF2C_CTX_STACK_MAX tokens can be returned.
Definition at line 217 of file lex.c.
◆ field()
◆ field_def()
◆ field_h()
static void field_h |
( |
const struct ff2c_field * |
f, |
|
|
int |
depth |
|
) |
| |
|
static |
Definition at line 55 of file gen.c.
◆ field_init()
Definition at line 99 of file sem.c.
◆ field_invariant()
◆ field_list()
◆ fmt()
char* fmt |
( |
const char * |
format, |
|
|
|
... |
|
) |
| |
◆ get_literal()
◆ indent()
static void indent |
( |
int |
depth | ) |
|
|
static |
Definition at line 43 of file gen.c.
◆ is_middle()
static bool is_middle |
( |
char |
c | ) |
|
|
static |
Definition at line 92 of file lex.c.
◆ is_pointer()
◆ is_start()
static bool is_start |
( |
char |
c | ) |
|
|
static |
Definition at line 87 of file lex.c.
◆ M0_BASSERT()
◆ m0_xc_opaque_init()
void m0_xc_opaque_init |
( |
void |
| ) |
|
◆ m0_xc_u16_init()
void m0_xc_u16_init |
( |
void |
| ) |
|
◆ m0_xc_u32_init()
void m0_xc_u32_init |
( |
void |
| ) |
|
◆ m0_xc_u64_init()
void m0_xc_u64_init |
( |
void |
| ) |
|
◆ m0_xc_u8_init()
void m0_xc_u8_init |
( |
void |
| ) |
|
◆ m0_xc_void_init()
void m0_xc_void_init |
( |
void |
| ) |
|
◆ m0_xcode_addr()
M0_INTERNAL void * m0_xcode_addr |
( |
const struct m0_xcode_obj * |
obj, |
|
|
int |
fieldno, |
|
|
uint64_t |
elno |
|
) |
| |
Returns the address of a sub-object within an object.
- Parameters
-
obj | - typed object |
fieldno | - ordinal number of field |
elno | - for a SEQUENCE or ARRAY field, index of the element to return the address of. |
The behaviour of this function for SEQUENCE objects depends on "elno" value. SEQUENCE objects have the following structure:
struct x_seq {
scalar_t xs_nr;
struct y *xs_body;
};
where xs_nr stores a number of elements in the sequence and xs_body points to an array of the elements.
With fieldno == 1, m0_xcode_addr() returns
- &xseq->xs_body when (elno == ~0ULL) and
- &xseq->xs_body[elno] otherwise.
Definition at line 612 of file xcode.c.
◆ m0_xcode_alloc()
M0_INTERNAL void * m0_xcode_alloc |
( |
struct m0_xcode_cursor * |
it, |
|
|
size_t |
nob |
|
) |
| |
◆ m0_xcode_alloc_obj()
Handles memory allocation during decoding.
This function takes an xcode iteration cursor and, if necessary, allocates memory where the object currently being decoded will reside.
The pointer to the allocated memory is returned in m0_xcode_obj::xo_ptr. In addition, this pointer is stored at the appropriate offset in the parent object.
Definition at line 228 of file xcode.c.
◆ m0_xcode_atom()
M0_INTERNAL uint64_t m0_xcode_atom |
( |
const struct m0_xcode_obj * |
obj | ) |
|
Returns the value of the given atomic field.
Definition at line 652 of file xcode.c.
◆ m0_xcode_bitmask_field_read()
Custom field reader for bitmasks.
The pointer to this function is installed into m0_xcode_field::xf_read by m0gccxml2xcode for fields tagged with the M0_XCA_FBITMASK macro.
Definition at line 155 of file enum.c.
◆ m0_xcode_bitmask_is_valid()
bool m0_xcode_bitmask_is_valid |
( |
const struct m0_xcode_enum * |
en, |
|
|
uint64_t |
val |
|
) |
| |
◆ m0_xcode_bitmask_print()
int m0_xcode_bitmask_print |
( |
const struct m0_xcode_enum * |
en, |
|
|
uint64_t |
val, |
|
|
char * |
buf, |
|
|
int |
nr |
|
) |
| |
Outputs the symbolic name of a bitmask.
The general forms of the output, constructed in the first "nr" bytes of "buf" are:
* CONST_0|CONST_1|...|CONST_N|REST
*
* CONST_0|CONST_1|...|CONST_N
*
where CONST-s are symbolic names of set bits in the bitmask and REST is the sexadecimal representation of the remaining invalid bits that have no matching constants. The second form is used when m0_xcode_bitmask_is_valid() holds.
Definition at line 85 of file enum.c.
◆ m0_xcode_bitmask_read()
int m0_xcode_bitmask_read |
( |
const struct m0_xcode_enum * |
en, |
|
|
const char * |
buf, |
|
|
int |
nr, |
|
|
uint64_t * |
val |
|
) |
| |
Parses the symbolic representation of the bitmask.
This function can parse the output of m0_xcode_bitmask_print(). And maybe more, but do not rely on it.
Definition at line 112 of file enum.c.
◆ m0_xcode_bob_type_init()
M0_INTERNAL void m0_xcode_bob_type_init |
( |
struct m0_bob_type * |
bt, |
|
|
const struct m0_xcode_type * |
xt, |
|
|
size_t |
magix_field, |
|
|
uint64_t |
magix |
|
) |
| |
Partially initializes a branded object type from a xcode type descriptor.
- See also
- bob.h
Definition at line 731 of file xcode.c.
◆ m0_xcode_cmp()
◆ m0_xcode_ctx_init()
Sets up the context to start xcoding of a given object.
Definition at line 373 of file xcode.c.
◆ m0_xcode_ctx_top()
M0_INTERNAL void * m0_xcode_ctx_top |
( |
const struct m0_xcode_ctx * |
ctx | ) |
|
◆ m0_xcode_cursor_field()
Returns the field currently being processed.
Definition at line 48 of file cursor.c.
◆ m0_xcode_cursor_init()
◆ m0_xcode_cursor_top()
M0_INTERNAL struct m0_xcode_cursor_frame * m0_xcode_cursor_top |
( |
struct m0_xcode_cursor * |
it | ) |
|
Returns the topmost frame in the cursor's stack.
Definition at line 41 of file cursor.c.
◆ m0_xcode_data_size()
Initializes xcode context and returns the length of xcode object.
Definition at line 437 of file xcode.c.
◆ m0_xcode_decode()
M0_INTERNAL int m0_xcode_decode |
( |
struct m0_xcode_ctx * |
ctx | ) |
|
◆ m0_xcode_decor_register()
M0_INTERNAL int m0_xcode_decor_register |
( |
void |
| ) |
|
Returns a previously unused "decoration number", which can be used as an index in m0_xcode_field::xf_decor[] and m0_xcode_type::xct_decor[] arrays.
This number can be used to associate additional state with xcode introspection elements:
...
f->xf_decor[foo_decor_num] =
m0_alloc(
sizeof(
struct foo_field_decor));
◆ m0_xcode_dup()
◆ m0_xcode_encdec()
Initializes xcode context and encodes or decodes the xcode object in the cursor based on value.
Definition at line 416 of file xcode.c.
◆ m0_xcode_encode()
M0_INTERNAL int m0_xcode_encode |
( |
struct m0_xcode_ctx * |
ctx | ) |
|
◆ m0_xcode_enum_field_read()
Custom field reader for enums.
The pointer to this function is installed into m0_xcode_field::xf_read by m0gccxml2xcode for fields tagged with the M0_XCA_FENUM macro.
Definition at line 142 of file enum.c.
◆ m0_xcode_enum_is_valid()
bool m0_xcode_enum_is_valid |
( |
const struct m0_xcode_enum * |
en, |
|
|
uint64_t |
val |
|
) |
| |
◆ m0_xcode_enum_print()
const char * m0_xcode_enum_print |
( |
const struct m0_xcode_enum * |
en, |
|
|
uint64_t |
val, |
|
|
char * |
buf |
|
) |
| |
Returns symbolic name for a enum constant.
If "buf" is NULL:
- this function always returns a static string;
- for an invalid value, a fixed (per enum type) string is returned (see
m0_xcode_enum_val::xev_name). This string does not depend on the value
and hence, cannot be parsed back by m0_xcode_enum_read().
If "buf" is not NULL:
- valid values are processed as in (buf == NULL) case, that is, a static
string is returned;
- invalid value is snprintf-ed into buf in the sexadecimal form. The
buffer should be sufficiently large.
Definition at line 51 of file enum.c.
◆ m0_xcode_enum_read()
int m0_xcode_enum_read |
( |
const struct m0_xcode_enum * |
en, |
|
|
const char * |
buf, |
|
|
int |
nr, |
|
|
uint64_t * |
val |
|
) |
| |
Parses a symbolic enum constant name into the binary value.
"buf" should be a usual zero-terminated string. The function first tries to interpret first "nr" bytes as a symbolic name of a constant in the given enum. Failing that, the function tries to interpret first "nr" bytes of "buf" as a sexadecimal representation of a value (potentially looking beyond "nr" bytes in this case).
Definition at line 65 of file enum.c.
◆ m0_xcode_find()
Finds and returns (in *place) first (in m0_xcode_next() order) field of type xt in the given object.
Returns -ENOENT if no field is found.
Definition at line 713 of file xcode.c.
◆ m0_xcode_fini()
void m0_xcode_fini |
( |
void |
| ) |
|
Finalises all xcode types processed by m0gccxml2xcode during build.
- See also
- m0_xcode_init()
Definition at line 60 of file init.c.
◆ m0_xcode_free()
Frees xcode object and its sub-objects.
Descends through sub-objects tree, freeing memory allocated during tree construction. The same algorithm (allocp()) is used to determine what to allocate and what to free.
Actions are done in post-order: the parent is freed after all children are done with.
This is the only xcode function that has to deal with partially constructed objects.
Definition at line 476 of file xcode.c.
◆ m0_xcode_free_obj()
M0_INTERNAL void m0_xcode_free_obj |
( |
struct m0_xcode_obj * |
obj | ) |
|
◆ m0_xcode_init()
int m0_xcode_init |
( |
void |
| ) |
|
Initialises all xcode types processed by m0gccxml2xcode during build.
- See also
- m0_xcode_fini()
Definition at line 43 of file init.c.
◆ m0_xcode_is_byte_array()
M0_INTERNAL bool m0_xcode_is_byte_array |
( |
const struct m0_xcode_type * |
xt | ) |
|
True iff "xt" is an array of bytes.
Definition at line 221 of file xcode.c.
◆ m0_xcode_length()
M0_INTERNAL int m0_xcode_length |
( |
struct m0_xcode_ctx * |
ctx | ) |
|
Calculates the length of serialized representation.
Definition at line 390 of file xcode.c.
◆ m0_xcode_next()
Iterates over tree of xcode types.
To start the iteration, call this with the cursor where m0_xcode_cursor_frame::s_obj field of the 0th stack frame is set to the desired object and the rest of the cursor is zeroed (see m0_xcode_ctx_init()).
m0_xcode_next() returns a positive value when iteration can be continued, 0 when the iteration is complete and negative error code on error. The intended usage pattern is
On each return, m0_xcode_next() sets the cursor to point to the next element reached in iteration. The information about the element is stored in the topmost element of the cursor's stack and can be extracted with m0_xcode_cursor_top().
An element with N children is reached 1 + N + 1 times: once in preorder, once in inorder after each child is processed and once in postorder. Here N equals
- number of fields in a RECORD object;
- 1 or 2 in a UNION object: one for discriminator and one for an actually
present field, if any;
- 1 + (number of elements in array) in a SEQUENCE object. Additional 1 is
for count field;
- number of elements in array in an ARRAY object;
- 0 for an ATOMIC object.
For example, to traverse the tree in preorder, one does something like
... process the element ...
}
}
Definition at line 59 of file cursor.c.
◆ m0_xcode_obj_dec_from_buf()
Takes buffer with encoded object and builds original object.
Definition at line 850 of file xcode.c.
◆ m0_xcode_obj_enc_to_buf()
Allocates buffer and places there encoded object.
Definition at line 832 of file xcode.c.
◆ m0_xcode_print()
M0_INTERNAL int m0_xcode_print |
( |
const struct m0_xcode_obj * |
obj, |
|
|
char * |
str, |
|
|
int |
nr |
|
) |
| |
Prints an xcode object to a string.
This function is (almost) the inverse of m0_xcode_read().
- Note
- No attempt at pretty-printing is done. All atomic values are output in hexadecimal, etc. Its main intended use is logging and debugging. Byte arrays that contain only printable ASCII values are printed in the "string literal" format.
Definition at line 278 of file string.c.
◆ m0_xcode_read()
M0_INTERNAL int m0_xcode_read |
( |
struct m0_xcode_obj * |
obj, |
|
|
const char * |
str |
|
) |
| |
Reads an object from a human-readable string representation.
String has the following EBNF grammar:
S ::= RECORD | UNION | SEQUENCE | ARRAY | ATOM | CUSTOM
RECORD ::= '(' [S-LIST] ')'
S-LIST ::= S | S-LIST ',' S
UNION ::= '{' TAG '|' [S] '}'
SEQUENCE ::= STRING | COUNTED
ARRAY ::= '<' [S-LIST] '>'
STRING ::= '"' CHAR* '"'
COUNTED ::= '[' COUNT ':' [S-LIST] ']'
ATOM ::= EMPTY | NUMBER
TAG ::= ATOM
COUNT ::= ATOM
CUSTOM ::= '^' CHAR* | '@' CHAR*
Where CHAR is any non-NUL character, NUMBER is anything recognizable by sscanf(3) as a number and EMPTY is the empty string. Blank-spaces (
, , , , space and comments) between tokens are ignored. Comments start with a hash symbol and run to the end of line.
Custom type representations start with a caret (^) and are recognised by m0_xcode_type_ops::xto_read() call-backs.
Custom field representations start with with '@' and are recognised by a call-back stored in m0_xcode_field::xf_read()
Examples:
* (0, 1)
* (0, (1, 2))
* ()
* {1| (1, 2)}
* {2| 6}
* {3|} # a union with invalid discriminant or with a void value
* [0] # 0 sized array
* [3: 6, 5, 4]
* [: 1, 2, 3] # fixed size sequence
* <7, 12, 0> # fixed size array
* "incomprehensible" # a byte (U8) sequence with 16 elements
* 10 # number 10
* 0xa # number 10
* 012 # number 10
* (0, "katavothron", {42| [3: ("x"), ("y"), ("z")]}, "paradiorthosis")
*
Typedefs and opaque types require no special syntax.
- Return values
-
0 | success |
-EPROTO | syntax error |
-EINVAL | invalid data in string after end of representation |
-ve | other error (-ENOMEM, &c.) |
Error or not, the caller should free the (partially) constructed object with m0_xcode_free().
Definition at line 162 of file string.c.
◆ m0_xcode_skip()
Abandons the iteration at the current level and returns one level up.
Definition at line 148 of file cursor.c.
◆ m0_xcode_subobj()
M0_INTERNAL int m0_xcode_subobj |
( |
struct m0_xcode_obj * |
subobj, |
|
|
const struct m0_xcode_obj * |
obj, |
|
|
int |
fieldno, |
|
|
uint64_t |
elno |
|
) |
| |
◆ m0_xcode_tag()
M0_INTERNAL uint64_t m0_xcode_tag |
( |
const struct m0_xcode_obj * |
obj | ) |
|
Returns the value of first field in a given object, assuming this field is atomic.
This function is suitable to return discriminator of a UNION object or element count of a SEQUENCE object.
- Note
- when the first field has M0_XT_VOID type, the tag (m0_xcode_field::xf_tag) of this field is returned.
Definition at line 679 of file xcode.c.
◆ m0_xcode_type_flags()
Returns true iff the type has all "on" and none of "off" bits in m0_xcode_type::xct_flags and the same holds recursively for types of all its fields. Doesn't check xcode types with aggregation type specified by aggr_umask.
Definition at line 878 of file xcode.c.
◆ m0_xcode_type_invariant()
◆ m0_xcode_type_iterate()
Iterates (recurses) over fields of the given type and their types.
"t" is invoked for each type embedded in "xt" (including "xt" itself).
"f" is invoked for each field embedded in "xt".
Definition at line 395 of file xcode.c.
◆ m0_xcode_union_add()
M0_INTERNAL void m0_xcode_union_add |
( |
struct m0_xcode_type * |
un, |
|
|
const char * |
name, |
|
|
const struct m0_xcode_type * |
xt, |
|
|
uint64_t |
tag |
|
) |
| |
◆ m0_xcode_union_close()
M0_INTERNAL void m0_xcode_union_close |
( |
struct m0_xcode_type * |
un | ) |
|
◆ m0_xcode_union_fini()
M0_INTERNAL void m0_xcode_union_fini |
( |
struct m0_xcode_type * |
un | ) |
|
◆ m0_xcode_union_init()
M0_INTERNAL void m0_xcode_union_init |
( |
struct m0_xcode_type * |
un, |
|
|
const char * |
name, |
|
|
const char * |
discriminator, |
|
|
size_t |
maxbranches |
|
) |
| |
Starts construction of a "dynamic union".
With the help of m0_xcode_union_init(), m0_xcode_union_add() and m0_xcode_union_close() a discriminated union type (M0_XA_UNION) can be constructed at run-time. A use case is a situation where branches of the union are defined in separate modules. With dynamic union, new branches can be added without modifying central code.
After a call to m0_xcode_union_init(), new branches are added with m0_xcode_union_add(). When all branches are added, m0_xcode_union_close() completes the construction of union xcode type. The result can be used as a usual xcode type.
The implementation is deliberately simplistic to avoid issues with sizeof and alignment calculations. Union discriminator is always M0_XT_U64.
- Parameters
-
un | - xcode type to be initialised. The user has to allocate this together with at least m0_xcode_field instances. See conf/db.c:conx_obj for example. |
name - xcode type name, assigned to un->xct_name
- Parameters
-
discriminator | - the name of the first field |
maxbranch | - maximal number of branches that can be added |
- See also
- m0_xcode_union_add(), m0_xcode_union_close()
Definition at line 751 of file xcode.c.
◆ main()
int main |
( |
int |
argc, |
|
|
char ** |
argv |
|
) |
| |
◆ nameget()
◆ punctchar()
◆ quoted_string()
◆ require()
◆ require_init()
Definition at line 78 of file sem.c.
◆ skip_space()
◆ space_skip()
M0_INTERNAL const char* space_skip |
( |
const char * |
str | ) |
|
◆ statement()
◆ string_literal()
◆ tok_end()
Definition at line 97 of file lex.c.
◆ token()
◆ tree_walk()
◆ type()
◆ type_decl()
static void type_decl |
( |
const struct ff2c_type * |
t | ) |
|
|
static |
◆ type_def()
static void type_def |
( |
const struct ff2c_type * |
t | ) |
|
|
static |
◆ type_fields()
static void type_fields |
( |
const struct ff2c_type * |
t | ) |
|
|
static |
◆ type_h()
static void type_h |
( |
const struct ff2c_type * |
t, |
|
|
int |
depth |
|
) |
| |
|
static |
Definition at line 69 of file gen.c.
◆ type_init()
◆ valget()
◆ xcode_flags_check()
◆ ff2c_term_type_name [1/2]
const char* ff2c_term_type_name[] |
◆ ff2c_term_type_name [2/2]
const char* ff2c_term_type_name[] |
Initial value:
Definition at line 236 of file parser.c.
◆ ff2c_token_type_name [1/2]
const char* ff2c_token_type_name[] |
Human-readable names of values in ff2c_token_type
Definition at line 241 of file lex.c.
◆ ff2c_token_type_name [2/2]
const char* ff2c_token_type_name[] |
Initial value:Human-readable names of values in ff2c_token_type
Definition at line 241 of file lex.c.
◆ field_reader
◆ keywords
◆ m0_xcode_aggr_name [1/2]
const char* m0_xcode_aggr_name[M0_XA_NR] |
Human-readable names of m0_xcode_aggr values.
Definition at line 955 of file xcode.c.
◆ m0_xcode_aggr_name [2/2]
const char* m0_xcode_aggr_name[M0_XA_NR] |
Initial value:Human-readable names of m0_xcode_aggr values.
Definition at line 955 of file xcode.c.
◆ m0_xcode_atom_type_name [1/2]
const char* m0_xcode_atom_type_name[M0_XAT_NR] |
Human-readable names of elements of m0_xcode_atom_type
Definition at line 965 of file xcode.c.
◆ m0_xcode_atom_type_name [2/2]
const char* m0_xcode_atom_type_name[M0_XAT_NR] |
Initial value:Human-readable names of elements of m0_xcode_atom_type
Definition at line 965 of file xcode.c.
◆ m0_xcode_cursor_flag_name [1/2]
Human-readable names of values in m0_xcode_cursor_flag
Definition at line 977 of file xcode.c.
◆ m0_xcode_cursor_flag_name [2/2]
Initial value:Human-readable names of values in m0_xcode_cursor_flag
Definition at line 977 of file xcode.c.
◆ m0_xcode_endianness_name [1/2]
Human-readable names of values in m0_xcode_endianness
Definition at line 972 of file xcode.c.
◆ m0_xcode_endianness_name [2/2]
Initial value:Human-readable names of values in m0_xcode_endianness
Definition at line 972 of file xcode.c.
◆ M0_XT_OPAQUE [1/2]
Initial value:= {
.xct_name = "opaque",
.xct_sizeof = sizeof (void *),
.xct_nr = 0
}
Definition at line 948 of file xcode.c.
◆ M0_XT_OPAQUE [2/2]
◆ M0_XT_U32 [1/2]
Initial value:= {
.xct_name = "u32",
.xct_sizeof = sizeof(uint32_t),
.xct_nr = 0
}
Definition at line 932 of file xcode.c.
◆ M0_XT_U32 [2/2]
◆ M0_XT_U64 [1/2]
Initial value:= {
.xct_name = "u64",
.xct_sizeof = sizeof(uint64_t),
.xct_nr = 0
}
Definition at line 940 of file xcode.c.
◆ M0_XT_U64 [2/2]
◆ M0_XT_U8 [1/2]
Initial value:= {
.xct_name = "u8",
.xct_sizeof = sizeof(uint8_t),
.xct_nr = 0
}
Definition at line 924 of file xcode.c.
◆ M0_XT_U8 [2/2]
◆ M0_XT_VOID [1/2]
Initial value:= {
.xct_name = "void",
.xct_sizeof = 0,
.xct_nr = 0
}
Definition at line 916 of file xcode.c.
◆ M0_XT_VOID [2/2]
◆ name
Initial value:= {
[
FTT_VOID] = {
"void",
"&M0_XT_VOID",
"m0_void_t" },
[
FTT_U8] = {
"u8",
"&M0_XT_U8",
"uint8_t" },
[
FTT_U32] = {
"u32",
"&M0_XT_U32",
"uint32_t" },
[
FTT_U64] = {
"u64",
"&M0_XT_U64",
"uint64_t" },
}
Definition at line 91 of file sem.c.
◆ punctuation
Initial value:
Definition at line 137 of file string.c.
◆ structure
Initial value:
Definition at line 126 of file string.c.
◆ thefile
Definition at line 39 of file gen.c.