ncurses 5.3
[ncurses.git] / form / fty_int.c
1
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 *  Contact: http://www.familiepfeifer.de/Contact.aspx?Lang=en              *
12 *                                                                          *
13 ***************************************************************************/
14
15 #include "form.priv.h"
16
17 MODULE_ID("$Id: fty_int.c,v 1.12 2002/07/06 15:33:27 juergen Exp $")
18
19 typedef struct {
20   int precision;
21   long low;
22   long high;
23 } integerARG;
24
25 /*---------------------------------------------------------------------------
26 |   Facility      :  libnform  
27 |   Function      :  static void *Make_Integer_Type( va_list * ap )
28 |   
29 |   Description   :  Allocate structure for integer type argument.
30 |
31 |   Return Values :  Pointer to argument structure or NULL on error
32 +--------------------------------------------------------------------------*/
33 static void *Make_Integer_Type(va_list * ap)
34 {
35   integerARG *argp = (integerARG *)malloc(sizeof(integerARG));
36
37   if (argp)
38     {
39       argp->precision = va_arg(*ap,int);
40       argp->low       = va_arg(*ap,long);
41       argp->high      = va_arg(*ap,long);
42     }
43   return (void *)argp;
44 }
45
46 /*---------------------------------------------------------------------------
47 |   Facility      :  libnform  
48 |   Function      :  static void *Copy_Integer_Type(const void * argp)
49 |   
50 |   Description   :  Copy structure for integer type argument.  
51 |
52 |   Return Values :  Pointer to argument structure or NULL on error.
53 +--------------------------------------------------------------------------*/
54 static void *Copy_Integer_Type(const void * argp)
55 {
56   const integerARG *ap = (const integerARG *)argp;
57   integerARG *result = (integerARG *)0;
58
59   if (argp)
60     {
61       result = (integerARG *)malloc(sizeof(integerARG));
62       if (result)
63         *result = *ap;
64     }
65   return (void *)result;
66 }
67
68 /*---------------------------------------------------------------------------
69 |   Facility      :  libnform  
70 |   Function      :  static void Free_Integer_Type(void * argp)
71 |   
72 |   Description   :  Free structure for integer type argument.
73 |
74 |   Return Values :  -
75 +--------------------------------------------------------------------------*/
76 static void Free_Integer_Type(void * argp)
77 {
78   if (argp) 
79     free(argp);
80 }
81
82 /*---------------------------------------------------------------------------
83 |   Facility      :  libnform  
84 |   Function      :  static bool Check_Integer_Field(
85 |                                                    FIELD * field,
86 |                                                    const void * argp)
87 |   
88 |   Description   :  Validate buffer content to be a valid integer value
89 |
90 |   Return Values :  TRUE  - field is valid
91 |                    FALSE - field is invalid
92 +--------------------------------------------------------------------------*/
93 static bool Check_Integer_Field(FIELD * field, const void * argp)
94 {
95   const integerARG *argi = (const integerARG *)argp;
96   long low          = argi->low;
97   long high         = argi->high;
98   int prec          = argi->precision;
99   unsigned char *bp = (unsigned char *)field_buffer(field,0);
100   char *s           = (char *)bp;
101   long val;
102   char buf[100];
103
104   while( *bp && *bp==' ') bp++;
105   if (*bp)
106     {
107       if (*bp=='-') bp++;
108       while (*bp)
109         {
110           if (!isdigit(*bp)) break;
111           bp++;
112         }
113       while(*bp && *bp==' ') bp++;
114       if (*bp=='\0')
115         {
116           val = atol(s);
117           if (low<high)
118             {
119               if (val<low || val>high) return FALSE;
120             }
121           sprintf(buf,"%.*ld",(prec>0?prec:0),val);
122           set_field_buffer(field,0,buf);
123           return TRUE;
124         }
125     }
126   return FALSE;
127 }
128
129 /*---------------------------------------------------------------------------
130 |   Facility      :  libnform  
131 |   Function      :  static bool Check_Integer_Character(
132 |                                      int c,
133 |                                      const void * argp)
134 |   
135 |   Description   :  Check a character for the integer type.
136 |
137 |   Return Values :  TRUE  - character is valid
138 |                    FALSE - character is invalid
139 +--------------------------------------------------------------------------*/
140 static bool Check_Integer_Character(int c, const void * argp GCC_UNUSED)
141 {
142   return ((isdigit(c) || (c=='-')) ? TRUE : FALSE);
143 }
144
145 static FIELDTYPE typeINTEGER = {
146   _HAS_ARGS | _RESIDENT,
147   1,                           /* this is mutable, so we can't be const */
148   (FIELDTYPE *)0,
149   (FIELDTYPE *)0,
150   Make_Integer_Type,
151   Copy_Integer_Type,
152   Free_Integer_Type,
153   Check_Integer_Field,
154   Check_Integer_Character,
155   NULL,
156   NULL
157 };
158
159 NCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_INTEGER = &typeINTEGER;
160
161 /* fty_int.c ends here */