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 intermedi- ate 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 function 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 specific field currently in use. To define a structure equivalent to a struct structs_union that declares 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 struc- ture (or empty if no name is desired) and union_name is the name of the represented union. Then the un field will be declared 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 pre- vious field contents to be lost. As a special case, the field named "field_name" is also read-only accessi- ble 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 struc- tures 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 assumed. structs_union_set() should be used to change the union field currently in use, to guarantee that the old field's contents are properly deallocated 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 speci- fied 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.quarterly 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=DEFINE_STRUCTS_UNION&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>
