1 /* $NetBSD: field_types.c,v 1.6 2003/03/09 00:57:17 lukem Exp $ */
4 * Copyright (c) 1998-1999 Brett Lymn
5 * (blymn@baea.com.au, brett_lymn@yahoo.com.au)
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
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 $");
38 #include "internals.h"
40 extern FIELD _formi_default_field
;
42 /* function prototypes.... */
44 _formi_create_field_args(FIELDTYPE
*type
, char **type_args
,
45 formi_type_link
**link
, va_list *args
, int *error
);
47 _formi_create_fieldtype(void);
50 * Process the arguments, if any, for the field type.
53 _formi_create_field_args(FIELDTYPE
*type
, char **type_args
,
54 formi_type_link
**link
, va_list *args
, int *error
)
60 && ((type
->flags
& _TYPE_HAS_ARGS
) == _TYPE_HAS_ARGS
)) {
61 if ((type
->flags
& _TYPE_IS_LINKED
) == _TYPE_IS_LINKED
) {
62 l
= malloc(sizeof(*l
));
64 _formi_create_field_args(type
->link
->next
,
66 &type
->link
->next
->link
,
69 _formi_create_field_args(type
->link
->prev
,
71 &type
->link
->prev
->link
,
79 if ((*type_args
= (char *) type
->make_args(args
))
87 * Allocate a new fieldtype structure, initialise it and return the
88 * struct to the caller.
91 _formi_create_fieldtype(void)
95 if ((new = malloc(sizeof(*new))) == NULL
)
98 new->flags
= _TYPE_NO_FLAGS
;
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
;
113 * Set the field type of the field to be the one given.
116 set_field_type(FIELD
*fptr
, FIELDTYPE
*type
, ...)
122 va_start(args
, type
);
124 field
= (fptr
== NULL
)? &_formi_default_field
: fptr
;
127 _formi_create_field_args(type
, &field
->args
, &type
->link
, &args
,
132 return E_BAD_ARGUMENT
;
138 * Return the field type associated with the given field
141 field_type(FIELD
*fptr
)
145 field
= (fptr
== NULL
)? &_formi_default_field
: fptr
;
152 * Return the field arguments for the given field.
155 field_arg(FIELD
*fptr
)
159 field
= (fptr
== NULL
)? &_formi_default_field
: fptr
;
165 * Create a new field type. Caller must specify a field_check routine
166 * and char_check routine.
169 new_fieldtype(int (*field_check
)(FIELD
*, char *),
170 int (*char_check
)(int, char *))
174 if ((field_check
== NULL
) && (char_check
== NULL
))
177 if ((new = _formi_create_fieldtype()) != NULL
) {
178 new->field_check
= field_check
;
179 new->char_check
= char_check
;
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)
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
--;
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
;
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
;
247 * Link the two given types to produce a new type, return this new type.
250 link_fieldtype(FIELDTYPE
*type1
, FIELDTYPE
*type2
)
254 if ((type1
== NULL
) || (type2
== NULL
))
257 if ((new = _formi_create_fieldtype()) == 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
) {
268 new->link
->prev
= type1
;
269 new->link
->next
= type2
;