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, Juergen.Pfeifer@T-Online.de *
12 ***************************************************************************/
14 #include "form.priv.h"
16 MODULE_ID("$Id: fty_enum.c,v 1.5 1997/02/15 17:33:59 tom Exp $")
25 /*---------------------------------------------------------------------------
27 | Function : static void *Make_Enum_Type( va_list * ap )
29 | Description : Allocate structure for enumeration type argument.
31 | Return Values : Pointer to argument structure or NULL on error
32 +--------------------------------------------------------------------------*/
33 static void *Make_Enum_Type(va_list * ap)
35 enumARG *argp = (enumARG *)malloc(sizeof(enumARG));
42 argp->kwds = va_arg(*ap,char **);
43 ccase = va_arg(*ap,int);
44 cunique = va_arg(*ap,int);
45 argp->checkcase = ccase ? TRUE : FALSE;
46 argp->checkunique = cunique ? TRUE : FALSE;
49 while( (*kp++) ) cnt++;
55 /*---------------------------------------------------------------------------
57 | Function : static void *Copy_Enum_Type( const void * argp )
59 | Description : Copy structure for enumeration type argument.
61 | Return Values : Pointer to argument structure or NULL on error.
62 +--------------------------------------------------------------------------*/
63 static void *Copy_Enum_Type(const void * argp)
65 const enumARG *ap = (const enumARG *)argp;
66 enumARG *new = (enumARG *)0;
70 new = (enumARG *)malloc(sizeof(enumARG));
77 /*---------------------------------------------------------------------------
79 | Function : static void Free_Enum_Type( void * argp )
81 | Description : Free structure for enumeration type argument.
84 +--------------------------------------------------------------------------*/
85 static void Free_Enum_Type(void * argp)
91 #define SKIP_SPACE(x) while(((*(x))!='\0') && (is_blank(*(x)))) (x)++
96 /*---------------------------------------------------------------------------
98 | Function : static int Compare(const unsigned char * s,
99 | const unsigned char * buf,
102 | Description : Check wether or not the text in 'buf' matches the
103 | text in 's', at least partial.
105 | Return Values : NOMATCH - buffer doesn't match
106 | PARTIAL - buffer matches partially
107 | EXACT - buffer matches exactly
108 +--------------------------------------------------------------------------*/
109 static int Compare(const unsigned char *s, const unsigned char *buf,
112 SKIP_SPACE(buf); /* Skip leading spaces in both texts */
117 return (((*s)!='\0') ? NOMATCH : EXACT);
125 if (*buf++=='\0') return EXACT;
130 while(toupper(*s)==toupper(*buf))
133 if (*buf++=='\0') return EXACT;
137 /* At this location buf points to the first character where it no longer
138 matches with s. So if only blanks are following, we have a partial
139 match otherwise there is no match */
144 /* If it happens that the reference buffer is at its end, the partial
145 match is actually an exact match. */
146 return ((s[-1]!='\0') ? PARTIAL : EXACT);
149 /*---------------------------------------------------------------------------
150 | Facility : libnform
151 | Function : static bool Check_Enum_Field(
155 | Description : Validate buffer content to be a valid enumeration value
157 | Return Values : TRUE - field is valid
158 | FALSE - field is invalid
159 +--------------------------------------------------------------------------*/
160 static bool Check_Enum_Field(FIELD * field, const void * argp)
162 char **kwds = ((const enumARG *)argp)->kwds;
163 bool ccase = ((const enumARG *)argp)->checkcase;
164 bool unique = ((const enumARG *)argp)->checkunique;
165 unsigned char *bp = (unsigned char *)field_buffer(field,0);
169 while( (s=(*kwds++)) )
171 if ((res=Compare((unsigned char *)s,bp,ccase))!=NOMATCH)
174 if ((unique && res!=EXACT))
176 while( (p = *kwds++) )
178 if ((res=Compare((unsigned char *)p,bp,ccase))!=NOMATCH)
191 set_field_buffer(field,0,t);
199 static const char *dummy[] = { (char *)0 };
201 /*---------------------------------------------------------------------------
202 | Facility : libnform
203 | Function : static bool Next_Enum(FIELD * field,
206 | Description : Check for the next enumeration value
208 | Return Values : TRUE - next value found and loaded
209 | FALSE - no next value loaded
210 +--------------------------------------------------------------------------*/
211 static bool Next_Enum(FIELD * field, const void * argp)
213 const enumARG *args = (const enumARG *)argp;
214 char **kwds = args->kwds;
215 bool ccase = args->checkcase;
216 int cnt = args->count;
217 unsigned char *bp = (unsigned char *)field_buffer(field,0);
221 if (Compare((unsigned char *)(*kwds++),bp,ccase)==EXACT)
226 if ((cnt>=0) || (Compare((unsigned char *)dummy,bp,ccase)==EXACT))
228 set_field_buffer(field,0,*kwds);
234 /*---------------------------------------------------------------------------
235 | Facility : libnform
236 | Function : static bool Previous_Enum(
240 | Description : Check for the previous enumeration value
242 | Return Values : TRUE - previous value found and loaded
243 | FALSE - no previous value loaded
244 +--------------------------------------------------------------------------*/
245 static bool Previous_Enum(FIELD * field, const void * argp)
247 const enumARG *args = (const enumARG *)argp;
248 int cnt = args->count;
249 char **kwds = &args->kwds[cnt-1];
250 bool ccase = args->checkcase;
251 unsigned char *bp = (unsigned char *)field_buffer(field,0);
255 if (Compare((unsigned char *)(*kwds--),bp,ccase)==EXACT)
260 kwds = &args->kwds[args->count-1];
262 if ((cnt>=0) || (Compare((unsigned char *)dummy,bp,ccase)==EXACT))
264 set_field_buffer(field,0,*kwds);
271 static FIELDTYPE typeENUM = {
272 _HAS_ARGS | _HAS_CHOICE | _RESIDENT,
273 1, /* this is mutable, so we can't be const */
285 FIELDTYPE* TYPE_ENUM = &typeENUM;
287 /* fty_enum.c ends here */