Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
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)

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>

home | help