source: trunk/essentials/sys-libs/ncurses/form/fty_num.c@ 3295

Last change on this file since 3295 was 2621, checked in by bird, 20 years ago

GNU ncurses 5.5

File size: 6.2 KB
Line 
1/*
2 * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT.
3 * You may freely copy it for use as a template for your own field types.
4 * If you develop a field type that might be of general use, please send
5 * it back to the ncurses maintainers for inclusion in the next version.
6 */
7/***************************************************************************
8* *
9* Author : Juergen Pfeifer *
10* *
11***************************************************************************/
12
13#include "form.priv.h"
14
15MODULE_ID("$Id: fty_num.c,v 1.22 2005/08/20 18:26:16 tom Exp $")
16
17#if HAVE_LOCALE_H
18#include <locale.h>
19#endif
20
21#if HAVE_LOCALE_H
22#define isDecimalPoint(c) ((c) == ((L && L->decimal_point) ? *(L->decimal_point) : '.'))
23#else
24#define isDecimalPoint(c) ((c) == '.')
25#endif
26
27#if USE_WIDEC_SUPPORT
28#define isDigit(c) (iswdigit((wint_t)(c)) || isdigit(UChar(c)))
29#else
30#define isDigit(c) isdigit(UChar(c))
31#endif
32
33#define thisARG numericARG
34
35typedef struct
36 {
37 int precision;
38 double low;
39 double high;
40 struct lconv *L;
41 }
42thisARG;
43
44/*---------------------------------------------------------------------------
45| Facility : libnform
46| Function : static void *Make_This_Type(va_list * ap)
47|
48| Description : Allocate structure for numeric type argument.
49|
50| Return Values : Pointer to argument structure or NULL on error
51+--------------------------------------------------------------------------*/
52static void *
53Make_This_Type(va_list *ap)
54{
55 thisARG *argn = (thisARG *) malloc(sizeof(thisARG));
56
57 if (argn)
58 {
59 argn->precision = va_arg(*ap, int);
60 argn->low = va_arg(*ap, double);
61 argn->high = va_arg(*ap, double);
62
63#if HAVE_LOCALE_H
64 argn->L = localeconv();
65#else
66 argn->L = NULL;
67#endif
68 }
69 return (void *)argn;
70}
71
72/*---------------------------------------------------------------------------
73| Facility : libnform
74| Function : static void *Copy_This_Type(const void * argp)
75|
76| Description : Copy structure for numeric type argument.
77|
78| Return Values : Pointer to argument structure or NULL on error.
79+--------------------------------------------------------------------------*/
80static void *
81Copy_This_Type(const void *argp)
82{
83 const thisARG *ap = (const thisARG *)argp;
84 thisARG *result = (thisARG *) 0;
85
86 if (argp)
87 {
88 result = (thisARG *) malloc(sizeof(thisARG));
89 if (result)
90 *result = *ap;
91 }
92 return (void *)result;
93}
94
95/*---------------------------------------------------------------------------
96| Facility : libnform
97| Function : static void Free_This_Type(void * argp)
98|
99| Description : Free structure for numeric type argument.
100|
101| Return Values : -
102+--------------------------------------------------------------------------*/
103static void
104Free_This_Type(void *argp)
105{
106 if (argp)
107 free(argp);
108}
109
110/*---------------------------------------------------------------------------
111| Facility : libnform
112| Function : static bool Check_This_Field(FIELD * field,
113| const void * argp)
114|
115| Description : Validate buffer content to be a valid numeric value
116|
117| Return Values : TRUE - field is valid
118| FALSE - field is invalid
119+--------------------------------------------------------------------------*/
120static bool
121Check_This_Field(FIELD *field, const void *argp)
122{
123 const thisARG *argn = (const thisARG *)argp;
124 double low = argn->low;
125 double high = argn->high;
126 int prec = argn->precision;
127 unsigned char *bp = (unsigned char *)field_buffer(field, 0);
128 char *s = (char *)bp;
129 double val = 0.0;
130 struct lconv *L = argn->L;
131 char buf[64];
132 bool result = FALSE;
133
134 while (*bp && *bp == ' ')
135 bp++;
136 if (*bp)
137 {
138 if (*bp == '-' || *bp == '+')
139 bp++;
140#if USE_WIDEC_SUPPORT
141 if (*bp)
142 {
143 bool blank = FALSE;
144 int state = 0;
145 int len;
146 int n;
147 wchar_t *list = _nc_Widen_String((char *)bp, &len);
148
149 if (list != 0)
150 {
151 result = TRUE;
152 for (n = 0; n < len; ++n)
153 {
154 if (blank)
155 {
156 if (list[n] != ' ')
157 {
158 result = FALSE;
159 break;
160 }
161 }
162 else if (list[n] == ' ')
163 {
164 blank = TRUE;
165 }
166 else if (isDecimalPoint(list[n]))
167 {
168 if (++state > 1)
169 {
170 result = FALSE;
171 break;
172 }
173 }
174 else if (!isDigit(list[n]))
175 {
176 result = FALSE;
177 break;
178 }
179 }
180 free(list);
181 }
182 }
183#else
184 while (*bp)
185 {
186 if (!isdigit(UChar(*bp)))
187 break;
188 bp++;
189 }
190 if (isDecimalPoint(*bp))
191 {
192 bp++;
193 while (*bp)
194 {
195 if (!isdigit(UChar(*bp)))
196 break;
197 bp++;
198 }
199 }
200 while (*bp && *bp == ' ')
201 bp++;
202 result = (*bp == '\0');
203#endif
204 if (result)
205 {
206 val = atof(s);
207 if (low < high)
208 {
209 if (val < low || val > high)
210 result = FALSE;
211 }
212 if (result)
213 {
214 sprintf(buf, "%.*f", (prec > 0 ? prec : 0), val);
215 set_field_buffer(field, 0, buf);
216 }
217 }
218 }
219 return (result);
220}
221
222/*---------------------------------------------------------------------------
223| Facility : libnform
224| Function : static bool Check_This_Character(
225| int c,
226| const void * argp)
227|
228| Description : Check a character for the numeric type.
229|
230| Return Values : TRUE - character is valid
231| FALSE - character is invalid
232+--------------------------------------------------------------------------*/
233static bool
234Check_This_Character(int c, const void *argp)
235{
236 const thisARG *argn = (const thisARG *)argp;
237 struct lconv *L = argn->L;
238
239 return ((isDigit(c) ||
240 c == '+' ||
241 c == '-' ||
242 isDecimalPoint(c))
243 ? TRUE
244 : FALSE);
245}
246
247static FIELDTYPE typeTHIS =
248{
249 _HAS_ARGS | _RESIDENT,
250 1, /* this is mutable, so we can't be const */
251 (FIELDTYPE *)0,
252 (FIELDTYPE *)0,
253 Make_This_Type,
254 Copy_This_Type,
255 Free_This_Type,
256 Check_This_Field,
257 Check_This_Character,
258 NULL,
259 NULL
260};
261
262NCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_NUMERIC = &typeTHIS;
263
264/* fty_num.c ends here */
Note: See TracBrowser for help on using the repository browser.