Add /etc/bluetooth/ with common files.
[dragonfly.git] / contrib / ncurses-5.4 / form / fty_enum.c
blob95d96d4a3887d14d03d9048c28a38786ee7c3eee
2 /*
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.
7 */
8 /***************************************************************************
9 * *
10 * Author : Juergen Pfeifer *
11 * *
12 ***************************************************************************/
14 #include "form.priv.h"
16 MODULE_ID("$Id: fty_enum.c,v 1.18 2003/11/08 20:25:29 tom Exp $")
18 typedef struct {
19 char **kwds;
20 int count;
21 bool checkcase;
22 bool checkunique;
23 } enumARG;
25 /*---------------------------------------------------------------------------
26 | Facility : libnform
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));
37 if (argp)
39 int cnt = 0;
40 char **kp = (char **)0;
41 int ccase, cunique;
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;
49 kp = argp->kwds;
50 while( kp && (*kp++) ) cnt++;
51 argp->count = cnt;
53 return (void *)argp;
56 /*---------------------------------------------------------------------------
57 | Facility : libnform
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;
68 if (argp)
70 const enumARG *ap = (const enumARG *)argp;
72 result = (enumARG *)malloc(sizeof(enumARG));
73 if (result)
74 *result = *ap;
76 return (void *)result;
79 /*---------------------------------------------------------------------------
80 | Facility : libnform
81 | Function : static void Free_Enum_Type( void * argp )
83 | Description : Free structure for enumeration type argument.
85 | Return Values : -
86 +--------------------------------------------------------------------------*/
87 static void Free_Enum_Type(void * argp)
89 if (argp)
90 free(argp);
93 #define SKIP_SPACE(x) while(((*(x))!='\0') && (is_blank(*(x)))) (x)++
94 #define NOMATCH 0
95 #define PARTIAL 1
96 #define EXACT 2
98 /*---------------------------------------------------------------------------
99 | Facility : libnform
100 | Function : static int Compare(const unsigned char * s,
101 | const unsigned char * buf,
102 | bool ccase )
104 | Description : Check whether 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,
112 bool ccase)
114 SKIP_SPACE(buf); /* Skip leading spaces in both texts */
115 SKIP_SPACE(s);
117 if (*buf=='\0')
119 return (((*s)!='\0') ? NOMATCH : EXACT);
121 else
123 if (ccase)
125 while(*s++ == *buf)
127 if (*buf++=='\0') return EXACT;
130 else
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 */
141 SKIP_SPACE(buf);
142 if (*buf)
143 return NOMATCH;
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(
153 | FIELD * field,
154 | const void * argp)
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);
167 char *s, *t, *p;
168 int res;
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)
181 if (res==EXACT)
183 t = p;
184 break;
186 else
187 t = (char *)0;
191 if (t)
193 set_field_buffer(field,0,t);
194 return TRUE;
196 if (!p)
197 break;
200 return FALSE;
203 static const char *dummy[] = { (char *)0 };
205 /*---------------------------------------------------------------------------
206 | Facility : libnform
207 | Function : static bool Next_Enum(FIELD * field,
208 | const void * argp)
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);
223 if (kwds) {
224 while(cnt--)
226 if (Compare((unsigned char *)(*kwds++),bp,ccase)==EXACT)
227 break;
229 if (cnt<=0)
230 kwds = args->kwds;
231 if ((cnt>=0) || (Compare((const unsigned char *)dummy,bp,ccase)==EXACT))
233 set_field_buffer(field,0,*kwds);
234 return TRUE;
237 return FALSE;
240 /*---------------------------------------------------------------------------
241 | Facility : libnform
242 | Function : static bool Previous_Enum(
243 | FIELD * field,
244 | const void * argp)
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);
259 if (kwds) {
260 while(cnt--)
262 if (Compare((unsigned char *)(*kwds--),bp,ccase)==EXACT)
263 break;
266 if (cnt<=0)
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);
272 return TRUE;
275 return FALSE;
279 static FIELDTYPE typeENUM = {
280 _HAS_ARGS | _HAS_CHOICE | _RESIDENT,
281 1, /* this is mutable, so we can't be const */
282 (FIELDTYPE *)0,
283 (FIELDTYPE *)0,
284 Make_Enum_Type,
285 Copy_Enum_Type,
286 Free_Enum_Type,
287 Check_Enum_Field,
288 NULL,
289 Next_Enum,
290 Previous_Enum
293 NCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_ENUM = &typeENUM;
295 /* fty_enum.c ends here */