![]() |
![]()
| ![]() |
![]()
NAME
LIBRARYPDEL Library (libpdel, -lpdel) SYNOPSIS
int
DESCRIPTIONThe
struct structs_union { const char *const field_name; /* name of field currently in use */ void *un; /* pointer to the union itself */ }; The field_name always
indicates which of the union fields is currently in use. It should never be
modified directly; instead, use the function
To define a structure equivalent to a
The union's fields are accessible by name. Of course, only one field may be accessed at a time, and changing the current union field causes the previous field contents to be lost. As a special case, the field named “field_name” is also read-only accessible and always returns the name of the union field currently in use. The union itself must not contain a field named “field_name,” or else it will not be accessible. The “field_name” field does not appear in the output of structs_xml_output(3) or structs_traverse(3).
/* This structure describes one field in a union */ struct structs_ufield { const char *name; /* field name */ const struct structs_type *type; /* field type */ }; The
The fields need not be listed in the array in the same order as
they are declared in the C union. However, the array must be terminated with
#define STRUCTS_UNION_FIELD_END {
NULL, NULL } The first field in the list is the “default field” and it is chosen as the current field when a union data type is initialized. When a union data type is read in as XML by structs_xml_input(3), if the innermost XML tag is omitted (i.e., the one that specifies the field name) and the default field has primitive type, then the default field is assumed.
RETURN VALUES
SEE ALSOlibpdel(3), structs(3), structs_type(3), structs_type_struct(3), structs_xml_input EXAMPLESThe program below sets a union field using the field name and value specified on the command line: #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <err.h> #include <pdel/structs/structs.h> #include <pdel/structs/type/union.h> #include <pdel/structs/type/string.h> #include <pdel/structs/type/ip4.h> #include <pdel/structs/type/int.h> #include <pdel/util/typed_mem.h> /* My union */ union foobar { char *name; u_int16_t index; struct in_addr ipaddr; }; /* My structs_union structure */ DEFINE_STRUCTS_UNION(foobar_union, foobar); /* Structs type for a 'struct foobar_union' */ static const struct structs_ufield foobar_fields[] = { STRUCTS_UNION_FIELD(name, &structs_type_string), STRUCTS_UNION_FIELD(index, &structs_type_uint16), STRUCTS_UNION_FIELD(ipaddr, &structs_type_ip4), STRUCTS_UNION_FIELD_END }; static const struct structs_type foobar_type = STRUCTS_UNION_TYPE(foobar, &foobar_fields); static void show_union(struct foobar_union *un) { /* Show the result */ if (strcmp(un->field_name, "name") == 0) printf("name=\"%s\"\n", un->un->name); else if (strcmp(un->field_name, "index") == 0) printf("index=%u\n", un->un->index); else if (strcmp(un->field_name, "ipaddr") == 0) printf("ipaddr=%s\n", inet_ntoa(un->un->ipaddr)); else printf("unknown field \"%s\"\n", un->field_name); } int main(int argc, char **argv) { struct foobar_union un; const char *name; char *value; char ebuf[64]; /* Initialize union */ if (structs_init(&foobar_type, NULL, &un) == -1) err(1, "structs_init"); printf("Default value: "); show_union(&un); /* Get the requested field's name and value from command line */ if (argc != 3) errx(1, "usage: setfield <name> <value>"); name = argv[1]; value = argv[2]; /* Set the requested field's value */ if (structs_set_string(&foobar_type, name, value, &un, ebuf, sizeof(ebuf)) == -1) errx(1, "%s: %s", name, ebuf); /* Show the result */ printf("New value: "); show_union(&un); /* Done, clean up */ structs_free(&foobar_type, NULL, &un); return (0); } HISTORYThe PDEL library was developed at Packet Design, LLC.
AUTHORSArchie Cobbs ⟨archie@freebsd.org⟩
|