ncurses 5.5
[ncurses.git] / form / fty_int.c
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
15 MODULE_ID("$Id: fty_int.c,v 1.19 2005/08/20 18:26:16 tom Exp $")
16
17 #if USE_WIDEC_SUPPORT
18 #define isDigit(c) (iswdigit((wint_t)(c)) || isdigit(UChar(c)))
19 #else
20 #define isDigit(c) isdigit(UChar(c))
21 #endif
22
23 #define thisARG integerARG
24
25 typedef struct
26   {
27     int precision;
28     long low;
29     long high;
30   }
31 thisARG;
32
33 /*---------------------------------------------------------------------------
34 |   Facility      :  libnform  
35 |   Function      :  static void *Make_This_Type( va_list * ap )
36 |   
37 |   Description   :  Allocate structure for integer type argument.
38 |
39 |   Return Values :  Pointer to argument structure or NULL on error
40 +--------------------------------------------------------------------------*/
41 static void *
42 Make_This_Type(va_list *ap)
43 {
44   thisARG *argp = (thisARG *) malloc(sizeof(thisARG));
45
46   if (argp)
47     {
48       argp->precision = va_arg(*ap, int);
49       argp->low = va_arg(*ap, long);
50       argp->high = va_arg(*ap, long);
51     }
52   return (void *)argp;
53 }
54
55 /*---------------------------------------------------------------------------
56 |   Facility      :  libnform  
57 |   Function      :  static void *Copy_This_Type(const void * argp)
58 |   
59 |   Description   :  Copy structure for integer type argument.  
60 |
61 |   Return Values :  Pointer to argument structure or NULL on error.
62 +--------------------------------------------------------------------------*/
63 static void *
64 Copy_This_Type(const void *argp)
65 {
66   const thisARG *ap = (const thisARG *)argp;
67   thisARG *result = (thisARG *) 0;
68
69   if (argp)
70     {
71       result = (thisARG *) malloc(sizeof(thisARG));
72       if (result)
73         *result = *ap;
74     }
75   return (void *)result;
76 }
77
78 /*---------------------------------------------------------------------------
79 |   Facility      :  libnform  
80 |   Function      :  static void Free_This_Type(void * argp)
81 |   
82 |   Description   :  Free structure for integer type argument.
83 |
84 |   Return Values :  -
85 +--------------------------------------------------------------------------*/
86 static void
87 Free_This_Type(void *argp)
88 {
89   if (argp)
90     free(argp);
91 }
92
93 /*---------------------------------------------------------------------------
94 |   Facility      :  libnform  
95 |   Function      :  static bool Check_This_Field(
96 |                                                 FIELD * field,
97 |                                                 const void * argp)
98 |   
99 |   Description   :  Validate buffer content to be a valid integer value
100 |
101 |   Return Values :  TRUE  - field is valid
102 |                    FALSE - field is invalid
103 +--------------------------------------------------------------------------*/
104 static bool
105 Check_This_Field(FIELD *field, const void *argp)
106 {
107   const thisARG *argi = (const thisARG *)argp;
108   long low = argi->low;
109   long high = argi->high;
110   int prec = argi->precision;
111   unsigned char *bp = (unsigned char *)field_buffer(field, 0);
112   char *s = (char *)bp;
113   long val;
114   char buf[100];
115   bool result = FALSE;
116
117   while (*bp && *bp == ' ')
118     bp++;
119   if (*bp)
120     {
121       if (*bp == '-')
122         bp++;
123 #if USE_WIDEC_SUPPORT
124       if (*bp)
125         {
126           bool blank = FALSE;
127           int len;
128           int n;
129           wchar_t *list = _nc_Widen_String((char *)bp, &len);
130
131           if (list != 0)
132             {
133               result = TRUE;
134               for (n = 0; n < len; ++n)
135                 {
136                   if (blank)
137                     {
138                       if (list[n] != ' ')
139                         {
140                           result = FALSE;
141                           break;
142                         }
143                     }
144                   else if (list[n] == ' ')
145                     {
146                       blank = TRUE;
147                     }
148                   else if (!isDigit(list[n]))
149                     {
150                       result = FALSE;
151                       break;
152                     }
153                 }
154               free(list);
155             }
156         }
157 #else
158       while (*bp)
159         {
160           if (!isdigit(UChar(*bp)))
161             break;
162           bp++;
163         }
164       while (*bp && *bp == ' ')
165         bp++;
166       result = (*bp == '\0');
167 #endif
168       if (result)
169         {
170           val = atol(s);
171           if (low < high)
172             {
173               if (val < low || val > high)
174                 result = FALSE;
175             }
176           if (result)
177             {
178               sprintf(buf, "%.*ld", (prec > 0 ? prec : 0), val);
179               set_field_buffer(field, 0, buf);
180             }
181         }
182     }
183   return (result);
184 }
185
186 /*---------------------------------------------------------------------------
187 |   Facility      :  libnform  
188 |   Function      :  static bool Check_This_Character(
189 |                                      int c,
190 |                                      const void * argp)
191 |   
192 |   Description   :  Check a character for the integer type.
193 |
194 |   Return Values :  TRUE  - character is valid
195 |                    FALSE - character is invalid
196 +--------------------------------------------------------------------------*/
197 static bool
198 Check_This_Character(int c, const void *argp GCC_UNUSED)
199 {
200   return ((isDigit(UChar(c)) || (c == '-')) ? TRUE : FALSE);
201 }
202
203 static FIELDTYPE typeTHIS =
204 {
205   _HAS_ARGS | _RESIDENT,
206   1,                            /* this is mutable, so we can't be const */
207   (FIELDTYPE *)0,
208   (FIELDTYPE *)0,
209   Make_This_Type,
210   Copy_This_Type,
211   Free_This_Type,
212   Check_This_Field,
213   Check_This_Character,
214   NULL,
215   NULL
216 };
217
218 NCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_INTEGER = &typeTHIS;
219
220 /* fty_int.c ends here */