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 *
11 * Contact: http://www.familiepfeifer.de/Contact.aspx?Lang=en *
13 ***************************************************************************/
15 #include "form.priv.h"
17 MODULE_ID("$Id: fty_enum.c,v 1.16 2002/07/13 11:35:08 juergen Exp $")
26 /*---------------------------------------------------------------------------
28 | Function : static void *Make_Enum_Type( va_list * ap )
30 | Description : Allocate structure for enumeration type argument.
32 | Return Values : Pointer to argument structure or NULL on error
33 +--------------------------------------------------------------------------*/
34 static void *Make_Enum_Type(va_list * ap)
36 enumARG *argp = (enumARG *)malloc(sizeof(enumARG));
41 char **kp = (char **)0;
44 argp->kwds = va_arg(*ap,char **);
45 ccase = va_arg(*ap,int);
46 cunique = va_arg(*ap,int);
47 argp->checkcase = ccase ? TRUE : FALSE;
48 argp->checkunique = cunique ? TRUE : FALSE;
51 while( kp && (*kp++) ) cnt++;
57 /*---------------------------------------------------------------------------
59 | Function : static void *Copy_Enum_Type( const void * argp )
61 | Description : Copy structure for enumeration type argument.
63 | Return Values : Pointer to argument structure or NULL on error.
64 +--------------------------------------------------------------------------*/
65 static void *Copy_Enum_Type(const void * argp)
67 enumARG *result = (enumARG *)0;
71 const enumARG *ap = (const enumARG *)argp;
73 result = (enumARG *)malloc(sizeof(enumARG));
77 return (void *)result;
80 /*---------------------------------------------------------------------------
82 | Function : static void Free_Enum_Type( void * argp )
84 | Description : Free structure for enumeration type argument.
87 +--------------------------------------------------------------------------*/
88 static void Free_Enum_Type(void * argp)
94 #define SKIP_SPACE(x) while(((*(x))!='\0') && (is_blank(*(x)))) (x)++
99 /*---------------------------------------------------------------------------
100 | Facility : libnform
101 | Function : static int Compare(const unsigned char * s,
102 | const unsigned char * buf,
105 | Description : Check wether or not the text in 'buf' matches the
106 | text in 's', at least partial.
108 | Return Values : NOMATCH - buffer doesn't match
109 | PARTIAL - buffer matches partially
110 | EXACT - buffer matches exactly
111 +--------------------------------------------------------------------------*/
112 static int Compare(const unsigned char *s, const unsigned char *buf,
115 SKIP_SPACE(buf); /* Skip leading spaces in both texts */
120 return (((*s)!='\0') ? NOMATCH : EXACT);
128 if (*buf++=='\0') return EXACT;
133 while(toupper(*s++)==toupper(*buf))
135 if (*buf++=='\0') return EXACT;
139 /* At this location buf points to the first character where it no longer
140 matches with s. So if only blanks are following, we have a partial
141 match otherwise there is no match */
146 /* If it happens that the reference buffer is at its end, the partial
147 match is actually an exact match. */
148 return ((s[-1]!='\0') ? PARTIAL : EXACT);
151 /*---------------------------------------------------------------------------
152 | Facility : libnform
153 | Function : static bool Check_Enum_Field(
157 | Description : Validate buffer content to be a valid enumeration value
159 | Return Values : TRUE - field is valid
160 | FALSE - field is invalid
161 +--------------------------------------------------------------------------*/
162 static bool Check_Enum_Field(FIELD * field, const void * argp)
164 char **kwds = ((const enumARG *)argp)->kwds;
165 bool ccase = ((const enumARG *)argp)->checkcase;
166 bool unique = ((const enumARG *)argp)->checkunique;
167 unsigned char *bp = (unsigned char *)field_buffer(field,0);
171 while( kwds && (s=(*kwds++)) )
173 if ((res=Compare((unsigned char *)s,bp,ccase))!=NOMATCH)
175 p=t=s; /* t is at least a partial match */
176 if ((unique && res!=EXACT))
178 while( kwds && (p = *kwds++) )
180 if ((res=Compare((unsigned char *)p,bp,ccase))!=NOMATCH)
194 set_field_buffer(field,0,t);
204 static const char *dummy[] = { (char *)0 };
206 /*---------------------------------------------------------------------------
207 | Facility : libnform
208 | Function : static bool Next_Enum(FIELD * field,
211 | Description : Check for the next enumeration value
213 | Return Values : TRUE - next value found and loaded
214 | FALSE - no next value loaded
215 +--------------------------------------------------------------------------*/
216 static bool Next_Enum(FIELD * field, const void * argp)
218 const enumARG *args = (const enumARG *)argp;
219 char **kwds = args->kwds;
220 bool ccase = args->checkcase;
221 int cnt = args->count;
222 unsigned char *bp = (unsigned char *)field_buffer(field,0);
227 if (Compare((unsigned char *)(*kwds++),bp,ccase)==EXACT)
232 if ((cnt>=0) || (Compare((const unsigned char *)dummy,bp,ccase)==EXACT))
234 set_field_buffer(field,0,*kwds);
241 /*---------------------------------------------------------------------------
242 | Facility : libnform
243 | Function : static bool Previous_Enum(
247 | Description : Check for the previous enumeration value
249 | Return Values : TRUE - previous value found and loaded
250 | FALSE - no previous value loaded
251 +--------------------------------------------------------------------------*/
252 static bool Previous_Enum(FIELD * field, const void * argp)
254 const enumARG *args = (const enumARG *)argp;
255 int cnt = args->count;
256 char **kwds = &args->kwds[cnt-1];
257 bool ccase = args->checkcase;
258 unsigned char *bp = (unsigned char *)field_buffer(field,0);
263 if (Compare((unsigned char *)(*kwds--),bp,ccase)==EXACT)
268 kwds = &args->kwds[args->count-1];
270 if ((cnt>=0) || (Compare((const unsigned char *)dummy,bp,ccase)==EXACT))
272 set_field_buffer(field,0,*kwds);
280 static FIELDTYPE typeENUM = {
281 _HAS_ARGS | _HAS_CHOICE | _RESIDENT,
282 1, /* this is mutable, so we can't be const */
294 NCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_ENUM = &typeENUM;
296 /* fty_enum.c ends here */