FreeBSD Manual Pages
STRUCTS_TYPE_UNION(3) Library Functions Manual STRUCTS_TYPE_UNION(3) NAME structs_type_union -- structs types for C unions LIBRARY PDEL Library (libpdel, -lpdel) SYNOPSIS #include <sys/types.h> #include <stddef.h> #include <pdel/structs/structs.h> #include <pdel/structs/type/union.h> DEFINE_STRUCTS_UNION(struct_name, union_name); STRUCTS_UNION_TYPE(union_name, field_list); STRUCTS_UNION_FIELD(field_name, field_type); int structs_union_set(const struct structs_type *type, const char *name, void *data, const char *field_name); DESCRIPTION The STRUCTS_UNION_TYPE() macro defines a structs(3) type (i.e., a struct structs_type) for describing a struct structs_union, which is an intermediate structure describing a union union_name. 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 func- tion structs_union_set() (see below). un points to the actual union, which is stored in a separately allocated buffer typed_mem(3) type union union_name. This buffer is only large enough to hold the spe- cific field currently in use. To define a structure equivalent to a struct structs_union that de- clares un to have the correct C type for the union used (instead of void *), use the DEFINE_STRUCTS_UNION() macro, where struct_name is the name of the structure (or empty if no name is desired) and union_name is the name of the represented union. Then the un field will be de- clared to have type union union_name *. 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 ac- cessible 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). STRUCTS_UNION_TYPE() defines a structs(3) type for a C union. The field_list parameter must point to an array of struct structs_ufield structures describing each union field: /* This structure describes one field in a union */ struct structs_ufield { const char *name; /* field name */ const struct structs_type *type; /* field type */ }; The STRUCTS_UNION_FIELD() macro should be used to define an entry in the field array: field_name is the name of the field and field_type is a pointer to the structs(3) type describing the field. 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 STRUCTS_UNION_FIELD_END, which is defined as follows: #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 as- sumed. structs_union_set() should be used to change the union field currently in use, to guarantee that the old field's contents are properly deallo- cated and the new field's contents are properly initialized. The new field will be initialized to its default value. The sub-field name of the object pointed to by data must correspond to a struct structs_union (or equivalent structure), and field_name must match one of the union's field names. The structs_find(3) function may also be used to change the current union field. RETURN VALUES structs_union_set() returns zero if successful, otherwise -1 with errno set appropriately. SEE ALSO libpdel(3), structs(3), structs_type(3), structs_type_struct(3), structs_xml_input EXAMPLES The 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); } HISTORY The PDEL library was developed at Packet Design, LLC. http://www.packetdesign.com/ AUTHORS Archie Cobbs <archie@freebsd.org> FreeBSD ports 15.0 April 22, 2002 STRUCTS_TYPE_UNION(3)
NAME | LIBRARY | SYNOPSIS | DESCRIPTION | RETURN VALUES | SEE ALSO | EXAMPLES | HISTORY | AUTHORS
Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=structs_union_set&sektion=3&manpath=FreeBSD+Ports+15.0>
