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@gmx.net *
12 ***************************************************************************/
14 #include "form.priv.h"
16 MODULE_ID("$Id: fty_enum.c,v 1.1 2001/11/05 16:53:04 berk 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
));
40 char **kp
= (char **)0;
43 argp
->kwds
= va_arg(*ap
,char **);
44 ccase
= va_arg(*ap
,int);
45 cunique
= va_arg(*ap
,int);
46 argp
->checkcase
= ccase
? TRUE
: FALSE
;
47 argp
->checkunique
= cunique
? TRUE
: FALSE
;
50 while( kp
&& (*kp
++) ) cnt
++;
56 /*---------------------------------------------------------------------------
58 | Function : static void *Copy_Enum_Type( const void * argp )
60 | Description : Copy structure for enumeration type argument.
62 | Return Values : Pointer to argument structure or NULL on error.
63 +--------------------------------------------------------------------------*/
64 static void *Copy_Enum_Type(const void * argp
)
66 enumARG
*result
= (enumARG
*)0;
70 const enumARG
*ap
= (const enumARG
*)argp
;
72 result
= (enumARG
*)malloc(sizeof(enumARG
));
76 return (void *)result
;
79 /*---------------------------------------------------------------------------
81 | Function : static void Free_Enum_Type( void * argp )
83 | Description : Free structure for enumeration type argument.
86 +--------------------------------------------------------------------------*/
87 static void Free_Enum_Type(void * argp
)
93 #define SKIP_SPACE(x) while(((*(x))!='\0') && (is_blank(*(x)))) (x)++
98 /*---------------------------------------------------------------------------
100 | Function : static int Compare(const unsigned char * s,
101 | const unsigned char * buf,
104 | Description : Check wether or not the text in 'buf' matches the
105 | text in 's', at least partial.
107 | Return Values : NOMATCH - buffer doesn't match
108 | PARTIAL - buffer matches partially
109 | EXACT - buffer matches exactly
110 +--------------------------------------------------------------------------*/
111 static int Compare(const unsigned char *s
, const unsigned char *buf
,
114 SKIP_SPACE(buf
); /* Skip leading spaces in both texts */
119 return (((*s
)!='\0') ? NOMATCH
: EXACT
);
127 if (*buf
++=='\0') return EXACT
;
132 while(toupper(*s
++)==toupper(*buf
))
134 if (*buf
++=='\0') return EXACT
;
138 /* At this location buf points to the first character where it no longer
139 matches with s. So if only blanks are following, we have a partial
140 match otherwise there is no match */
145 /* If it happens that the reference buffer is at its end, the partial
146 match is actually an exact match. */
147 return ((s
[-1]!='\0') ? PARTIAL
: EXACT
);
150 /*---------------------------------------------------------------------------
151 | Facility : libnform
152 | Function : static bool Check_Enum_Field(
156 | Description : Validate buffer content to be a valid enumeration value
158 | Return Values : TRUE - field is valid
159 | FALSE - field is invalid
160 +--------------------------------------------------------------------------*/
161 static bool Check_Enum_Field(FIELD
* field
, const void * argp
)
163 char **kwds
= ((const enumARG
*)argp
)->kwds
;
164 bool ccase
= ((const enumARG
*)argp
)->checkcase
;
165 bool unique
= ((const enumARG
*)argp
)->checkunique
;
166 unsigned char *bp
= (unsigned char *)field_buffer(field
,0);
170 while( kwds
&& (s
=(*kwds
++)) )
172 if ((res
=Compare((unsigned char *)s
,bp
,ccase
))!=NOMATCH
)
174 p
=t
=s
; /* t is at least a partial match */
175 if ((unique
&& res
!=EXACT
))
177 while( kwds
&& (p
= *kwds
++) )
179 if ((res
=Compare((unsigned char *)p
,bp
,ccase
))!=NOMATCH
)
193 set_field_buffer(field
,0,t
);
203 static const char *dummy
[] = { (char *)0 };
205 /*---------------------------------------------------------------------------
206 | Facility : libnform
207 | Function : static bool Next_Enum(FIELD * field,
210 | Description : Check for the next enumeration value
212 | Return Values : TRUE - next value found and loaded
213 | FALSE - no next value loaded
214 +--------------------------------------------------------------------------*/
215 static bool Next_Enum(FIELD
* field
, const void * argp
)
217 const enumARG
*args
= (const enumARG
*)argp
;
218 char **kwds
= args
->kwds
;
219 bool ccase
= args
->checkcase
;
220 int cnt
= args
->count
;
221 unsigned char *bp
= (unsigned char *)field_buffer(field
,0);
226 if (Compare((unsigned char *)(*kwds
++),bp
,ccase
)==EXACT
)
231 if ((cnt
>=0) || (Compare((const unsigned char *)dummy
,bp
,ccase
)==EXACT
))
233 set_field_buffer(field
,0,*kwds
);
240 /*---------------------------------------------------------------------------
241 | Facility : libnform
242 | Function : static bool Previous_Enum(
246 | Description : Check for the previous enumeration value
248 | Return Values : TRUE - previous value found and loaded
249 | FALSE - no previous value loaded
250 +--------------------------------------------------------------------------*/
251 static bool Previous_Enum(FIELD
* field
, const void * argp
)
253 const enumARG
*args
= (const enumARG
*)argp
;
254 int cnt
= args
->count
;
255 char **kwds
= &args
->kwds
[cnt
-1];
256 bool ccase
= args
->checkcase
;
257 unsigned char *bp
= (unsigned char *)field_buffer(field
,0);
262 if (Compare((unsigned char *)(*kwds
--),bp
,ccase
)==EXACT
)
267 kwds
= &args
->kwds
[args
->count
-1];
269 if ((cnt
>=0) || (Compare((const unsigned char *)dummy
,bp
,ccase
)==EXACT
))
271 set_field_buffer(field
,0,*kwds
);
279 static FIELDTYPE typeENUM
= {
280 _HAS_ARGS
| _HAS_CHOICE
| _RESIDENT
,
281 1, /* this is mutable, so we can't be const */
293 FIELDTYPE
* TYPE_ENUM
= &typeENUM
;
295 /* fty_enum.c ends here */