Return to structs_type_union.3 CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / libpdel / structs / type |
1.1 ! misho 1: .\" Copyright (c) 2001-2002 Packet Design, LLC. ! 2: .\" All rights reserved. ! 3: .\" ! 4: .\" Subject to the following obligations and disclaimer of warranty, ! 5: .\" use and redistribution of this software, in source or object code ! 6: .\" forms, with or without modifications are expressly permitted by ! 7: .\" Packet Design; provided, however, that: ! 8: .\" ! 9: .\" (i) Any and all reproductions of the source or object code ! 10: .\" must include the copyright notice above and the following ! 11: .\" disclaimer of warranties; and ! 12: .\" (ii) No rights are granted, in any manner or form, to use ! 13: .\" Packet Design trademarks, including the mark "PACKET DESIGN" ! 14: .\" on advertising, endorsements, or otherwise except as such ! 15: .\" appears in the above copyright notice or in the software. ! 16: .\" ! 17: .\" THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND ! 18: .\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO ! 19: .\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING ! 20: .\" THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED ! 21: .\" WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, ! 22: .\" OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE, ! 23: .\" OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS ! 24: .\" OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, ! 25: .\" RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE ! 26: .\" LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE ! 27: .\" OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT, ! 28: .\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL ! 29: .\" DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF ! 30: .\" USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF ! 31: .\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ! 32: .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF ! 33: .\" THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF ! 34: .\" THE POSSIBILITY OF SUCH DAMAGE. ! 35: .\" ! 36: .\" Author: Archie Cobbs <archie@freebsd.org> ! 37: .\" ! 38: .\" $Id: structs_type_union.3,v 1.16 2004/12/16 16:49:57 archie Exp $ ! 39: .\" ! 40: .Dd April 22, 2002 ! 41: .Dt STRUCTS_TYPE_UNION 3 ! 42: .Os ! 43: .Sh NAME ! 44: .Nm structs_type_union ! 45: .Nd structs types for C unions ! 46: .Sh LIBRARY ! 47: PDEL Library (libpdel, \-lpdel) ! 48: .Sh SYNOPSIS ! 49: .In sys/types.h ! 50: .In stddef.h ! 51: .In pdel/structs/structs.h ! 52: .In pdel/structs/type/union.h ! 53: .Fn DEFINE_STRUCTS_UNION struct_name union_name ! 54: .Fn STRUCTS_UNION_TYPE union_name field_list ! 55: .Fn STRUCTS_UNION_FIELD field_name field_type ! 56: .Ft int ! 57: .Fn structs_union_set "const struct structs_type *type" "const char *name" "void *data" "const char *field_name" ! 58: .Sh DESCRIPTION ! 59: The ! 60: .Fn STRUCTS_UNION_TYPE ! 61: macro defines a ! 62: .Xr structs 3 ! 63: type (i.e., a ! 64: .Dv "struct structs_type" ) ! 65: for describing a ! 66: .Li "struct structs_union" , ! 67: which is an intermediate structure describing a ! 68: .Li union ! 69: .Fa union_name . ! 70: .Pp ! 71: .Bd -literal -compact -offset 3n ! 72: struct structs_union { ! 73: const char *const field_name; /* name of field currently in use */ ! 74: void *un; /* pointer to the union itself */ ! 75: }; ! 76: .Ed ! 77: .Pp ! 78: The ! 79: .Fa field_name ! 80: always indicates which of the union fields is currently in use. ! 81: It should never be modified directly; instead, use the function ! 82: .Fn structs_union_set ! 83: (see below). ! 84: .Fa un ! 85: points to the actual union, which is stored in a separately allocated buffer ! 86: .Xr typed_mem 3 ! 87: type ! 88: .Li "union union_name" . ! 89: This buffer is only large enough to hold the specific field currently in use. ! 90: .Pp ! 91: To define a structure equivalent to a ! 92: .Li "struct structs_union" ! 93: that declares ! 94: .Fa un ! 95: to have the correct C type for the union used (instead of ! 96: .Li "void *") , ! 97: use the ! 98: .Fn DEFINE_STRUCTS_UNION ! 99: macro, where ! 100: .Fa struct_name ! 101: is the name of the structure (or empty if no name is desired) and ! 102: .Fa union_name ! 103: is the name of the represented union. ! 104: Then the ! 105: .Fa un ! 106: field will be declared to have type ! 107: .Fa "union union_name *" . ! 108: .Pp ! 109: The union's fields are accessible by name. ! 110: Of course, only one field may be accessed at a time, and changing the ! 111: current union field causes the previous field contents to be lost. ! 112: .Pp ! 113: As a special case, the field named ! 114: .Dq field_name ! 115: is also read-only accessible and always returns the name of the union ! 116: field currently in use. ! 117: The union itself must not contain a field named ! 118: .Dq field_name, ! 119: or else it will not be accessible. ! 120: The ! 121: .Dq field_name ! 122: field does not appear in the output of ! 123: .Xr structs_xml_output 3 ! 124: or ! 125: .Xr structs_traverse 3 . ! 126: .Pp ! 127: .Fn STRUCTS_UNION_TYPE ! 128: defines a ! 129: .Xr structs 3 ! 130: type for a C union. ! 131: The ! 132: .Fa field_list ! 133: parameter must point to an array of ! 134: .Li "struct structs_ufield" ! 135: structures describing each union field: ! 136: .Pp ! 137: .Bd -literal -compact -offset 3n ! 138: /* This structure describes one field in a union */ ! 139: struct structs_ufield { ! 140: const char *name; /* field name */ ! 141: const struct structs_type *type; /* field type */ ! 142: }; ! 143: .Ed ! 144: .Pp ! 145: The ! 146: .Fn STRUCTS_UNION_FIELD ! 147: macro should be used to define an entry in the field array: ! 148: .Fa field_name ! 149: is the name of the field and ! 150: .Fa field_type ! 151: is a pointer to the ! 152: .Xr structs 3 ! 153: type describing the field. ! 154: .Pp ! 155: The fields need not be listed in the array in the same order as they ! 156: are declared in the C union. ! 157: However, the array must be terminated with ! 158: .Dv STRUCTS_UNION_FIELD_END , ! 159: which is defined as follows: ! 160: .Pp ! 161: .Dl #define STRUCTS_UNION_FIELD_END { NULL, NULL } ! 162: .Pp ! 163: The first field in the list is the ! 164: .Dq "default field" ! 165: and it is chosen as the current field when a union data type is initialized. ! 166: When a union data type is read in as XML by ! 167: .Xr structs_xml_input 3 , ! 168: if the innermost XML tag is omitted (i.e., the one that specifies the ! 169: field name) and the default field has primitive type, then the default ! 170: field is assumed. ! 171: .Pp ! 172: .Fn structs_union_set ! 173: should be used to change the union field currently in use, ! 174: to guarantee that the old field's contents are properly deallocated ! 175: and the new field's contents are properly initialized. ! 176: The new field will be initialized to its default value. ! 177: The sub-field ! 178: .Fa name ! 179: of the object pointed to by ! 180: .Fa data ! 181: must correspond to a ! 182: .Li "struct structs_union" ! 183: (or equivalent structure), and ! 184: .Fa field_name ! 185: must match one of the union's field names. ! 186: The ! 187: .Xr structs_find 3 ! 188: function may also be used to change the current union field. ! 189: .Sh RETURN VALUES ! 190: .Fn structs_union_set ! 191: returns zero if successful, otherwise -1 with ! 192: .Va errno ! 193: set appropriately. ! 194: .Sh SEE ALSO ! 195: .Xr libpdel 3 , ! 196: .Xr structs 3 , ! 197: .Xr structs_type 3 , ! 198: .Xr structs_type_struct 3 , ! 199: .Xr structs_xml_input ! 200: .Sh EXAMPLES ! 201: The program below sets a union field using the field name and ! 202: value specified on the command line: ! 203: .Pp ! 204: .Bd -literal -compact -offset 3n ! 205: #include <sys/types.h> ! 206: #include <sys/socket.h> ! 207: #include <netinet/in.h> ! 208: #include <arpa/inet.h> ! 209: ! 210: #include <stdio.h> ! 211: #include <stdlib.h> ! 212: #include <stdarg.h> ! 213: #include <err.h> ! 214: ! 215: #include <pdel/structs/structs.h> ! 216: #include <pdel/structs/type/union.h> ! 217: #include <pdel/structs/type/string.h> ! 218: #include <pdel/structs/type/ip4.h> ! 219: #include <pdel/structs/type/int.h> ! 220: #include <pdel/util/typed_mem.h> ! 221: ! 222: /* My union */ ! 223: union foobar { ! 224: char *name; ! 225: u_int16_t index; ! 226: struct in_addr ipaddr; ! 227: }; ! 228: ! 229: /* My structs_union structure */ ! 230: DEFINE_STRUCTS_UNION(foobar_union, foobar); ! 231: ! 232: /* Structs type for a 'struct foobar_union' */ ! 233: static const struct structs_ufield foobar_fields[] = { ! 234: STRUCTS_UNION_FIELD(name, &structs_type_string), ! 235: STRUCTS_UNION_FIELD(index, &structs_type_uint16), ! 236: STRUCTS_UNION_FIELD(ipaddr, &structs_type_ip4), ! 237: STRUCTS_UNION_FIELD_END ! 238: }; ! 239: static const struct structs_type foobar_type = ! 240: STRUCTS_UNION_TYPE(foobar, &foobar_fields); ! 241: ! 242: static void ! 243: show_union(struct foobar_union *un) ! 244: { ! 245: /* Show the result */ ! 246: if (strcmp(un->field_name, "name") == 0) ! 247: printf("name=\\"%s\\"\\n", un->un->name); ! 248: else if (strcmp(un->field_name, "index") == 0) ! 249: printf("index=%u\\n", un->un->index); ! 250: else if (strcmp(un->field_name, "ipaddr") == 0) ! 251: printf("ipaddr=%s\\n", inet_ntoa(un->un->ipaddr)); ! 252: else ! 253: printf("unknown field \\"%s\\"\\n", un->field_name); ! 254: } ! 255: ! 256: int ! 257: main(int argc, char **argv) ! 258: { ! 259: struct foobar_union un; ! 260: const char *name; ! 261: char *value; ! 262: char ebuf[64]; ! 263: ! 264: /* Initialize union */ ! 265: if (structs_init(&foobar_type, NULL, &un) == -1) ! 266: err(1, "structs_init"); ! 267: printf("Default value: "); ! 268: show_union(&un); ! 269: ! 270: /* Get the requested field's name and value from command line */ ! 271: if (argc != 3) ! 272: errx(1, "usage: setfield <name> <value>"); ! 273: name = argv[1]; ! 274: value = argv[2]; ! 275: ! 276: /* Set the requested field's value */ ! 277: if (structs_set_string(&foobar_type, name, ! 278: value, &un, ebuf, sizeof(ebuf)) == -1) ! 279: errx(1, "%s: %s", name, ebuf); ! 280: ! 281: /* Show the result */ ! 282: printf("New value: "); ! 283: show_union(&un); ! 284: ! 285: /* Done, clean up */ ! 286: structs_free(&foobar_type, NULL, &un); ! 287: return (0); ! 288: } ! 289: .Ed ! 290: .Sh HISTORY ! 291: The PDEL library was developed at Packet Design, LLC. ! 292: .Dv "http://www.packetdesign.com/" ! 293: .Sh AUTHORS ! 294: .An Archie Cobbs Aq archie@freebsd.org