1 /****************************************************************************
2 * Copyright (c) 1998-2006,2007 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.22 2007/10/13 19:32:26 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 = typeMalloc(enumARG, 1);
64 char **kp = (char **)0;
67 T((T_CREATE("enumARG %p"), argp));
68 argp->kwds = va_arg(*ap, char **);
69 ccase = va_arg(*ap, int);
70 cunique = va_arg(*ap, int);
72 argp->checkcase = ccase ? TRUE : FALSE;
73 argp->checkunique = cunique ? TRUE : FALSE;
83 /*---------------------------------------------------------------------------
85 | Function : static void *Copy_Enum_Type( const void * argp )
87 | Description : Copy structure for enumeration type argument.
89 | Return Values : Pointer to argument structure or NULL on error.
90 +--------------------------------------------------------------------------*/
92 Copy_Enum_Type(const void *argp)
94 enumARG *result = (enumARG *)0;
98 const enumARG *ap = (const enumARG *)argp;
100 result = typeMalloc(enumARG, 1);
104 T((T_CREATE("enumARG %p"), result));
108 return (void *)result;
111 /*---------------------------------------------------------------------------
112 | Facility : libnform
113 | Function : static void Free_Enum_Type( void * argp )
115 | Description : Free structure for enumeration type argument.
118 +--------------------------------------------------------------------------*/
120 Free_Enum_Type(void *argp)
126 #define SKIP_SPACE(x) while(((*(x))!='\0') && (is_blank(*(x)))) (x)++
131 /*---------------------------------------------------------------------------
132 | Facility : libnform
133 | Function : static int Compare(const unsigned char * s,
134 | const unsigned char * buf,
137 | Description : Check whether or not the text in 'buf' matches the
138 | text in 's', at least partial.
140 | Return Values : NOMATCH - buffer doesn't match
141 | PARTIAL - buffer matches partially
142 | EXACT - buffer matches exactly
143 +--------------------------------------------------------------------------*/
145 Compare(const unsigned char *s, const unsigned char *buf,
148 SKIP_SPACE(buf); /* Skip leading spaces in both texts */
153 return (((*s) != '\0') ? NOMATCH : EXACT);
167 while (toupper(*s++) == toupper(*buf))
174 /* At this location buf points to the first character where it no longer
175 matches with s. So if only blanks are following, we have a partial
176 match otherwise there is no match */
181 /* If it happens that the reference buffer is at its end, the partial
182 match is actually an exact match. */
183 return ((s[-1] != '\0') ? PARTIAL : EXACT);
186 /*---------------------------------------------------------------------------
187 | Facility : libnform
188 | Function : static bool Check_Enum_Field(
192 | Description : Validate buffer content to be a valid enumeration value
194 | Return Values : TRUE - field is valid
195 | FALSE - field is invalid
196 +--------------------------------------------------------------------------*/
198 Check_Enum_Field(FIELD *field, const void *argp)
200 char **kwds = ((const enumARG *)argp)->kwds;
201 bool ccase = ((const enumARG *)argp)->checkcase;
202 bool unique = ((const enumARG *)argp)->checkunique;
203 unsigned char *bp = (unsigned char *)field_buffer(field, 0);
207 while (kwds && (s = (*kwds++)))
209 if ((res = Compare((unsigned char *)s, bp, ccase)) != NOMATCH)
211 p = t = s; /* t is at least a partial match */
212 if ((unique && res != EXACT))
214 while (kwds && (p = *kwds++))
216 if ((res = Compare((unsigned char *)p, bp, ccase)) != NOMATCH)
230 set_field_buffer(field, 0, t);
240 static const char *dummy[] =
243 /*---------------------------------------------------------------------------
244 | Facility : libnform
245 | Function : static bool Next_Enum(FIELD * field,
248 | Description : Check for the next enumeration value
250 | Return Values : TRUE - next value found and loaded
251 | FALSE - no next value loaded
252 +--------------------------------------------------------------------------*/
254 Next_Enum(FIELD *field, const void *argp)
256 const enumARG *args = (const enumARG *)argp;
257 char **kwds = args->kwds;
258 bool ccase = args->checkcase;
259 int cnt = args->count;
260 unsigned char *bp = (unsigned char *)field_buffer(field, 0);
266 if (Compare((unsigned char *)(*kwds++), bp, ccase) == EXACT)
271 if ((cnt >= 0) || (Compare((const unsigned char *)dummy, bp, ccase) == EXACT))
273 set_field_buffer(field, 0, *kwds);
280 /*---------------------------------------------------------------------------
281 | Facility : libnform
282 | Function : static bool Previous_Enum(
286 | Description : Check for the previous enumeration value
288 | Return Values : TRUE - previous value found and loaded
289 | FALSE - no previous value loaded
290 +--------------------------------------------------------------------------*/
292 Previous_Enum(FIELD *field, const void *argp)
294 const enumARG *args = (const enumARG *)argp;
295 int cnt = args->count;
296 char **kwds = &args->kwds[cnt - 1];
297 bool ccase = args->checkcase;
298 unsigned char *bp = (unsigned char *)field_buffer(field, 0);
304 if (Compare((unsigned char *)(*kwds--), bp, ccase) == EXACT)
309 kwds = &args->kwds[args->count - 1];
311 if ((cnt >= 0) || (Compare((const unsigned char *)dummy, bp, ccase) == EXACT))
313 set_field_buffer(field, 0, *kwds);
320 static FIELDTYPE typeENUM =
322 _HAS_ARGS | _HAS_CHOICE | _RESIDENT,
323 1, /* this is mutable, so we can't be const */
335 NCURSES_EXPORT_VAR(FIELDTYPE *)
336 TYPE_ENUM = &typeENUM;
338 /* fty_enum.c ends here */