Fix mdoc(7)/man(7) mix up.
[netbsd-mini2440.git] / lib / libform / field_types.c
blob5ddf1e16a4a38dcc5bb6d8f4dc77ea758ea2d30f
1 /* $NetBSD: field_types.c,v 1.6 2003/03/09 00:57:17 lukem Exp $ */
3 /*-
4 * Copyright (c) 1998-1999 Brett Lymn
5 * (blymn@baea.com.au, brett_lymn@yahoo.com.au)
6 * All rights reserved.
8 * This code has been donated to The NetBSD Foundation by the Author.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: field_types.c,v 1.6 2003/03/09 00:57:17 lukem Exp $");
35 #include <stdlib.h>
36 #include <stdarg.h>
37 #include "form.h"
38 #include "internals.h"
40 extern FIELD _formi_default_field;
42 /* function prototypes.... */
43 static void
44 _formi_create_field_args(FIELDTYPE *type, char **type_args,
45 formi_type_link **link, va_list *args, int *error);
46 static FIELDTYPE *
47 _formi_create_fieldtype(void);
50 * Process the arguments, if any, for the field type.
52 static void
53 _formi_create_field_args(FIELDTYPE *type, char **type_args,
54 formi_type_link **link, va_list *args, int *error)
56 formi_type_link *l;
58 l = NULL;
59 if ((type != NULL)
60 && ((type->flags & _TYPE_HAS_ARGS) == _TYPE_HAS_ARGS)) {
61 if ((type->flags & _TYPE_IS_LINKED) == _TYPE_IS_LINKED) {
62 l = malloc(sizeof(*l));
63 if (l != NULL) {
64 _formi_create_field_args(type->link->next,
65 type_args,
66 &type->link->next->link,
67 args,
68 error);
69 _formi_create_field_args(type->link->prev,
70 type_args,
71 &type->link->prev->link,
72 args,
73 error);
74 (*link) = l;
77 (*error)++;
78 } else {
79 if ((*type_args = (char *) type->make_args(args))
80 == NULL)
81 (*error)++;
87 * Allocate a new fieldtype structure, initialise it and return the
88 * struct to the caller.
90 static FIELDTYPE *
91 _formi_create_fieldtype(void)
93 FIELDTYPE *new;
95 if ((new = malloc(sizeof(*new))) == NULL)
96 return NULL;
98 new->flags = _TYPE_NO_FLAGS;
99 new->refcount = 0;
100 new->link = NULL;
101 new->make_args = NULL;
102 new->copy_args = NULL;
103 new->free_args = NULL;
104 new->field_check = NULL;
105 new->char_check = NULL;
106 new->next_choice = NULL;
107 new->prev_choice = NULL;
109 return new;
113 * Set the field type of the field to be the one given.
116 set_field_type(FIELD *fptr, FIELDTYPE *type, ...)
118 va_list args;
119 FIELD *field;
120 int error = 0;
122 va_start(args, type);
124 field = (fptr == NULL)? &_formi_default_field : fptr;
126 field->type = type;
127 _formi_create_field_args(type, &field->args, &type->link, &args,
128 &error);
129 va_end(args);
131 if (error)
132 return E_BAD_ARGUMENT;
134 return E_OK;
138 * Return the field type associated with the given field
140 FIELDTYPE *
141 field_type(FIELD *fptr)
143 FIELD *field;
145 field = (fptr == NULL)? &_formi_default_field : fptr;
147 return field->type;
152 * Return the field arguments for the given field.
154 char *
155 field_arg(FIELD *fptr)
157 FIELD *field;
159 field = (fptr == NULL)? &_formi_default_field : fptr;
161 return field->args;
165 * Create a new field type. Caller must specify a field_check routine
166 * and char_check routine.
168 FIELDTYPE *
169 new_fieldtype(int (*field_check)(FIELD *, char *),
170 int (*char_check)(int, char *))
172 FIELDTYPE *new;
174 if ((field_check == NULL) && (char_check == NULL))
175 return NULL;
177 if ((new = _formi_create_fieldtype()) != NULL) {
178 new->field_check = field_check;
179 new->char_check = char_check;
182 return new;
186 * Free the storage used by the fieldtype.
189 free_fieldtype(FIELDTYPE *fieldtype)
191 if (fieldtype == NULL)
192 return E_BAD_ARGUMENT;
194 if (fieldtype->refcount > 0)
195 return E_CONNECTED;
197 if ((fieldtype->flags & _TYPE_IS_BUILTIN) == _TYPE_IS_BUILTIN)
198 return E_BAD_ARGUMENT; /* don't delete builtin types! */
200 if ((fieldtype->flags & _TYPE_IS_LINKED) == _TYPE_IS_LINKED)
202 fieldtype->link->next->refcount--;
203 fieldtype->link->prev->refcount--;
206 free(fieldtype);
208 return E_OK;
212 * Set the field type arguments for the given field type.
215 set_fieldtype_arg(FIELDTYPE *fieldtype, char * (*make_args)(va_list *),
216 char * (*copy_args)(char*), void (*free_args)(char *))
218 if ((fieldtype == NULL) || (make_args == NULL)
219 || (copy_args == NULL) || (free_args == NULL))
220 return E_BAD_ARGUMENT;
222 fieldtype->make_args = make_args;
223 fieldtype->copy_args = copy_args;
224 fieldtype->free_args = free_args;
226 return E_OK;
230 * Set up the choice list functions for the given fieldtype.
233 set_fieldtype_choice(FIELDTYPE *fieldtype, int (*next_choice)(FIELD *, char *),
234 int (*prev_choice)(FIELD *, char *))
236 if ((fieldtype == NULL) || (next_choice == NULL)
237 || (prev_choice == NULL))
238 return E_BAD_ARGUMENT;
240 fieldtype->next_choice = next_choice;
241 fieldtype->prev_choice = prev_choice;
243 return E_OK;
247 * Link the two given types to produce a new type, return this new type.
249 FIELDTYPE *
250 link_fieldtype(FIELDTYPE *type1, FIELDTYPE *type2)
252 FIELDTYPE *new;
254 if ((type1 == NULL) || (type2 == NULL))
255 return NULL;
257 if ((new = _formi_create_fieldtype()) == NULL)
258 return NULL;
260 new->flags = _TYPE_IS_LINKED;
261 new->flags |= ((type1->flags & _TYPE_HAS_ARGS)
262 | (type2->flags & _TYPE_HAS_ARGS));
263 if ((new->link = malloc(sizeof(*new->link))) == NULL) {
264 free(new);
265 return NULL;
268 new->link->prev = type1;
269 new->link->next = type2;
270 type1->refcount++;
271 type2->refcount++;
273 return new;