3 * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT.
4 * You may freely copy it for use as a template for your own field types.
5 * If you develop a field type that might be of general use, please send
6 * it back to the ncurses maintainers for inclusion in the next version.
8 /***************************************************************************
10 * Author : Juergen Pfeifer *
12 ***************************************************************************/
14 #include "form.priv.h"
16 MODULE_ID("$Id: fty_enum.c,v 1.19 2004/05/29 19:05:20 tom Exp $")
27 /*---------------------------------------------------------------------------
29 | Function : static void *Make_Enum_Type( va_list * ap )
31 | Description : Allocate structure for enumeration type argument.
33 | Return Values : Pointer to argument structure or NULL on error
34 +--------------------------------------------------------------------------*/
36 Make_Enum_Type(va_list *ap)
38 enumARG *argp = (enumARG *)malloc(sizeof(enumARG));
43 char **kp = (char **)0;
46 argp->kwds = va_arg(*ap, char **);
47 ccase = va_arg(*ap, int);
48 cunique = va_arg(*ap, int);
50 argp->checkcase = ccase ? TRUE : FALSE;
51 argp->checkunique = cunique ? TRUE : FALSE;
61 /*---------------------------------------------------------------------------
63 | Function : static void *Copy_Enum_Type( const void * argp )
65 | Description : Copy structure for enumeration type argument.
67 | Return Values : Pointer to argument structure or NULL on error.
68 +--------------------------------------------------------------------------*/
70 Copy_Enum_Type(const void *argp)
72 enumARG *result = (enumARG *)0;
76 const enumARG *ap = (const enumARG *)argp;
78 result = (enumARG *)malloc(sizeof(enumARG));
83 return (void *)result;
86 /*---------------------------------------------------------------------------
88 | Function : static void Free_Enum_Type( void * argp )
90 | Description : Free structure for enumeration type argument.
93 +--------------------------------------------------------------------------*/
95 Free_Enum_Type(void *argp)
101 #define SKIP_SPACE(x) while(((*(x))!='\0') && (is_blank(*(x)))) (x)++
106 /*---------------------------------------------------------------------------
107 | Facility : libnform
108 | Function : static int Compare(const unsigned char * s,
109 | const unsigned char * buf,
112 | Description : Check whether or not the text in 'buf' matches the
113 | text in 's', at least partial.
115 | Return Values : NOMATCH - buffer doesn't match
116 | PARTIAL - buffer matches partially
117 | EXACT - buffer matches exactly
118 +--------------------------------------------------------------------------*/
120 Compare(const unsigned char *s, const unsigned char *buf,
123 SKIP_SPACE(buf); /* Skip leading spaces in both texts */
128 return (((*s) != '\0') ? NOMATCH : EXACT);
142 while (toupper(*s++) == toupper(*buf))
149 /* At this location buf points to the first character where it no longer
150 matches with s. So if only blanks are following, we have a partial
151 match otherwise there is no match */
156 /* If it happens that the reference buffer is at its end, the partial
157 match is actually an exact match. */
158 return ((s[-1] != '\0') ? PARTIAL : EXACT);
161 /*---------------------------------------------------------------------------
162 | Facility : libnform
163 | Function : static bool Check_Enum_Field(
167 | Description : Validate buffer content to be a valid enumeration value
169 | Return Values : TRUE - field is valid
170 | FALSE - field is invalid
171 +--------------------------------------------------------------------------*/
173 Check_Enum_Field(FIELD *field, const void *argp)
175 char **kwds = ((const enumARG *)argp)->kwds;
176 bool ccase = ((const enumARG *)argp)->checkcase;
177 bool unique = ((const enumARG *)argp)->checkunique;
178 unsigned char *bp = (unsigned char *)field_buffer(field, 0);
182 while (kwds && (s = (*kwds++)))
184 if ((res = Compare((unsigned char *)s, bp, ccase)) != NOMATCH)
186 p = t = s; /* t is at least a partial match */
187 if ((unique && res != EXACT))
189 while (kwds && (p = *kwds++))
191 if ((res = Compare((unsigned char *)p, bp, ccase)) != NOMATCH)
205 set_field_buffer(field, 0, t);
215 static const char *dummy[] =
218 /*---------------------------------------------------------------------------
219 | Facility : libnform
220 | Function : static bool Next_Enum(FIELD * field,
223 | Description : Check for the next enumeration value
225 | Return Values : TRUE - next value found and loaded
226 | FALSE - no next value loaded
227 +--------------------------------------------------------------------------*/
229 Next_Enum(FIELD *field, const void *argp)
231 const enumARG *args = (const enumARG *)argp;
232 char **kwds = args->kwds;
233 bool ccase = args->checkcase;
234 int cnt = args->count;
235 unsigned char *bp = (unsigned char *)field_buffer(field, 0);
241 if (Compare((unsigned char *)(*kwds++), bp, ccase) == EXACT)
246 if ((cnt >= 0) || (Compare((const unsigned char *)dummy, bp, ccase) == EXACT))
248 set_field_buffer(field, 0, *kwds);
255 /*---------------------------------------------------------------------------
256 | Facility : libnform
257 | Function : static bool Previous_Enum(
261 | Description : Check for the previous enumeration value
263 | Return Values : TRUE - previous value found and loaded
264 | FALSE - no previous value loaded
265 +--------------------------------------------------------------------------*/
267 Previous_Enum(FIELD *field, const void *argp)
269 const enumARG *args = (const enumARG *)argp;
270 int cnt = args->count;
271 char **kwds = &args->kwds[cnt - 1];
272 bool ccase = args->checkcase;
273 unsigned char *bp = (unsigned char *)field_buffer(field, 0);
279 if (Compare((unsigned char *)(*kwds--), bp, ccase) == EXACT)
284 kwds = &args->kwds[args->count - 1];
286 if ((cnt >= 0) || (Compare((const unsigned char *)dummy, bp, ccase) == EXACT))
288 set_field_buffer(field, 0, *kwds);
295 static FIELDTYPE typeENUM =
297 _HAS_ARGS | _HAS_CHOICE | _RESIDENT,
298 1, /* this is mutable, so we can't be const */
310 NCURSES_EXPORT_VAR(FIELDTYPE *)
311 TYPE_ENUM = &typeENUM;
313 /* fty_enum.c ends here */