1 /****************************************************************************
2 * Copyright (c) 1998-2004,2006 Free Software Foundation, Inc. *
4 * Permission is hereby granted, free of charge, to any person obtaining a *
5 * copy of this software and associated documentation files (the *
6 * "Software"), to deal in the Software without restriction, including *
7 * without limitation the rights to use, copy, modify, merge, publish, *
8 * distribute, distribute with modifications, sublicense, and/or sell *
9 * copies of the Software, and to permit persons to whom the Software is *
10 * furnished to do so, subject to the following conditions: *
12 * The above copyright notice and this permission notice shall be included *
13 * in all copies or substantial portions of the Software. *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
23 * Except as contained in this notice, the name(s) of the above copyright *
24 * holders shall not be used in advertising or otherwise to promote the *
25 * sale, use or other dealings in this Software without prior written *
27 ****************************************************************************/
29 /***************************************************************************
31 * Author : Juergen Pfeifer *
33 ***************************************************************************/
35 #include "form.priv.h"
37 MODULE_ID("$Id: fty_enum.c,v 1.20 2006/04/22 21:33:05 tom Exp $")
48 /*---------------------------------------------------------------------------
50 | Function : static void *Make_Enum_Type( va_list * ap )
52 | Description : Allocate structure for enumeration type argument.
54 | Return Values : Pointer to argument structure or NULL on error
55 +--------------------------------------------------------------------------*/
57 Make_Enum_Type(va_list *ap)
59 enumARG *argp = (enumARG *)malloc(sizeof(enumARG));
64 char **kp = (char **)0;
67 argp->kwds = va_arg(*ap, char **);
68 ccase = va_arg(*ap, int);
69 cunique = va_arg(*ap, int);
71 argp->checkcase = ccase ? TRUE : FALSE;
72 argp->checkunique = cunique ? TRUE : FALSE;
82 /*---------------------------------------------------------------------------
84 | Function : static void *Copy_Enum_Type( const void * argp )
86 | Description : Copy structure for enumeration type argument.
88 | Return Values : Pointer to argument structure or NULL on error.
89 +--------------------------------------------------------------------------*/
91 Copy_Enum_Type(const void *argp)
93 enumARG *result = (enumARG *)0;
97 const enumARG *ap = (const enumARG *)argp;
99 result = (enumARG *)malloc(sizeof(enumARG));
104 return (void *)result;
107 /*---------------------------------------------------------------------------
108 | Facility : libnform
109 | Function : static void Free_Enum_Type( void * argp )
111 | Description : Free structure for enumeration type argument.
114 +--------------------------------------------------------------------------*/
116 Free_Enum_Type(void *argp)
122 #define SKIP_SPACE(x) while(((*(x))!='\0') && (is_blank(*(x)))) (x)++
127 /*---------------------------------------------------------------------------
128 | Facility : libnform
129 | Function : static int Compare(const unsigned char * s,
130 | const unsigned char * buf,
133 | Description : Check whether or not the text in 'buf' matches the
134 | text in 's', at least partial.
136 | Return Values : NOMATCH - buffer doesn't match
137 | PARTIAL - buffer matches partially
138 | EXACT - buffer matches exactly
139 +--------------------------------------------------------------------------*/
141 Compare(const unsigned char *s, const unsigned char *buf,
144 SKIP_SPACE(buf); /* Skip leading spaces in both texts */
149 return (((*s) != '\0') ? NOMATCH : EXACT);
163 while (toupper(*s++) == toupper(*buf))
170 /* At this location buf points to the first character where it no longer
171 matches with s. So if only blanks are following, we have a partial
172 match otherwise there is no match */
177 /* If it happens that the reference buffer is at its end, the partial
178 match is actually an exact match. */
179 return ((s[-1] != '\0') ? PARTIAL : EXACT);
182 /*---------------------------------------------------------------------------
183 | Facility : libnform
184 | Function : static bool Check_Enum_Field(
188 | Description : Validate buffer content to be a valid enumeration value
190 | Return Values : TRUE - field is valid
191 | FALSE - field is invalid
192 +--------------------------------------------------------------------------*/
194 Check_Enum_Field(FIELD *field, const void *argp)
196 char **kwds = ((const enumARG *)argp)->kwds;
197 bool ccase = ((const enumARG *)argp)->checkcase;
198 bool unique = ((const enumARG *)argp)->checkunique;
199 unsigned char *bp = (unsigned char *)field_buffer(field, 0);
203 while (kwds && (s = (*kwds++)))
205 if ((res = Compare((unsigned char *)s, bp, ccase)) != NOMATCH)
207 p = t = s; /* t is at least a partial match */
208 if ((unique && res != EXACT))
210 while (kwds && (p = *kwds++))
212 if ((res = Compare((unsigned char *)p, bp, ccase)) != NOMATCH)
226 set_field_buffer(field, 0, t);
236 static const char *dummy[] =
239 /*---------------------------------------------------------------------------
240 | Facility : libnform
241 | Function : static bool Next_Enum(FIELD * field,
244 | Description : Check for the next enumeration value
246 | Return Values : TRUE - next value found and loaded
247 | FALSE - no next value loaded
248 +--------------------------------------------------------------------------*/
250 Next_Enum(FIELD *field, const void *argp)
252 const enumARG *args = (const enumARG *)argp;
253 char **kwds = args->kwds;
254 bool ccase = args->checkcase;
255 int cnt = args->count;
256 unsigned char *bp = (unsigned char *)field_buffer(field, 0);
262 if (Compare((unsigned char *)(*kwds++), bp, ccase) == EXACT)
267 if ((cnt >= 0) || (Compare((const unsigned char *)dummy, bp, ccase) == EXACT))
269 set_field_buffer(field, 0, *kwds);
276 /*---------------------------------------------------------------------------
277 | Facility : libnform
278 | Function : static bool Previous_Enum(
282 | Description : Check for the previous enumeration value
284 | Return Values : TRUE - previous value found and loaded
285 | FALSE - no previous value loaded
286 +--------------------------------------------------------------------------*/
288 Previous_Enum(FIELD *field, const void *argp)
290 const enumARG *args = (const enumARG *)argp;
291 int cnt = args->count;
292 char **kwds = &args->kwds[cnt - 1];
293 bool ccase = args->checkcase;
294 unsigned char *bp = (unsigned char *)field_buffer(field, 0);
300 if (Compare((unsigned char *)(*kwds--), bp, ccase) == EXACT)
305 kwds = &args->kwds[args->count - 1];
307 if ((cnt >= 0) || (Compare((const unsigned char *)dummy, bp, ccase) == EXACT))
309 set_field_buffer(field, 0, *kwds);
316 static FIELDTYPE typeENUM =
318 _HAS_ARGS | _HAS_CHOICE | _RESIDENT,
319 1, /* this is mutable, so we can't be const */
331 NCURSES_EXPORT_VAR(FIELDTYPE *)
332 TYPE_ENUM = &typeENUM;
334 /* fty_enum.c ends here */