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 #include "form.priv.h" 10 #include <locale.h> 11 12 typedef struct { 13 int precision; 14 double low; 15 double high; 16 struct lconv* L; 17 } numericARG; 18 19 /*--------------------------------------------------------------------------- 20 | Facility : libnform 21 | Function : static void *Make_Numeric_Type(va_list * ap) 22 | 23 | Description : Allocate structure for numeric type argument. 24 | 25 | Return Values : Pointer to argument structure or NULL on error 26 +--------------------------------------------------------------------------*/ 27 static void *Make_Numeric_Type(va_list * ap) 28 { 29 numericARG *argn = (numericARG *)malloc(sizeof(numericARG)); 30 31 if (argn) 32 { 33 argn->precision = va_arg(*ap,int); 34 argn->low = va_arg(*ap,double); 35 argn->high = va_arg(*ap,double); 36 argn->L = localeconv(); 37 } 38 return (void *)argn; 39 } 40 41 /*--------------------------------------------------------------------------- 42 | Facility : libnform 43 | Function : static void *Copy_Numeric_Type(const void * argp) 44 | 45 | Description : Copy structure for numeric type argument. 46 | 47 | Return Values : Pointer to argument structure or NULL on error. 48 +--------------------------------------------------------------------------*/ 49 static void *Copy_Numeric_Type(const void * argp) 50 { 51 numericARG *ap = (numericARG *)argp; 52 numericARG *new = (numericARG *)0; 53 54 if (argp) 55 { 56 new = (numericARG *)malloc(sizeof(numericARG)); 57 if (new) 58 *new = *ap; 59 } 60 return (void *)new; 61 } 62 63 /*--------------------------------------------------------------------------- 64 | Facility : libnform 65 | Function : static void Free_Numeric_Type(void * argp) 66 | 67 | Description : Free structure for numeric type argument. 68 | 69 | Return Values : - 70 +--------------------------------------------------------------------------*/ 71 static void Free_Numeric_Type(void * argp) 72 { 73 if (argp) 74 free(argp); 75 } 76 77 /*--------------------------------------------------------------------------- 78 | Facility : libnform 79 | Function : static bool Check_Numeric_Field(FIELD * field, 80 | const void * argp) 81 | 82 | Description : Validate buffer content to be a valid numeric value 83 | 84 | Return Values : TRUE - field is valid 85 | FALSE - field is invalid 86 +--------------------------------------------------------------------------*/ 87 static bool Check_Numeric_Field(FIELD * field, const void * argp) 88 { 89 numericARG *argn = (numericARG *)argp; 90 double low = argn->low; 91 double high = argn->high; 92 int prec = argn->precision; 93 unsigned char *bp = (unsigned char *)field_buffer(field,0); 94 char *s = (char *)bp; 95 double val = 0.0; 96 struct lconv* L = argn->L; 97 char buf[64]; 98 99 while(*bp && *bp==' ') bp++; 100 if (*bp) 101 { 102 if (*bp=='-' || *bp=='+') 103 bp++; 104 while(*bp) 105 { 106 if (!isdigit(*bp)) break; 107 bp++; 108 } 109 if (*bp==((L && L->decimal_point) ? *(L->decimal_point) : '.')) 110 { 111 bp++; 112 while(*bp) 113 { 114 if (!isdigit(*bp)) break; 115 bp++; 116 } 117 } 118 while(*bp && *bp==' ') bp++; 119 if (*bp=='\0') 120 { 121 val = atof(s); 122 if (low<high) 123 { 124 if (val<low || val>high) return FALSE; 125 } 126 sprintf(buf,"%.*f",prec,val); 127 set_field_buffer(field,0,buf); 128 return TRUE; 129 } 130 } 131 return FALSE; 132 } 133 134 /*--------------------------------------------------------------------------- 135 | Facility : libnform 136 | Function : static bool Check_Numeric_Character( 137 | int c, 138 | const void * argp) 139 | 140 | Description : Check a character for the numeric type. 141 | 142 | Return Values : TRUE - character is valid 143 | FALSE - character is invalid 144 +--------------------------------------------------------------------------*/ 145 static bool Check_Numeric_Character(int c, const void * argp) 146 { 147 numericARG *argn = (numericARG *)argp; 148 struct lconv* L = argn->L; 149 150 return (isdigit(c) || 151 c == '+' || 152 c == '-' || 153 c == ((L && L->decimal_point) ? *(L->decimal_point) : '.') 154 ) ? TRUE : FALSE; 155 } 156 157 static FIELDTYPE typeNUMERIC = { 158 _HAS_ARGS | _RESIDENT, 159 1, /* this is mutable, so we can't be const */ 160 (FIELDTYPE *)0, 161 (FIELDTYPE *)0, 162 Make_Numeric_Type, 163 Copy_Numeric_Type, 164 Free_Numeric_Type, 165 Check_Numeric_Field, 166 Check_Numeric_Character, 167 NULL, 168 NULL 169 }; 170 171 FIELDTYPE* TYPE_NUMERIC = &typeNUMERIC; 172 173 /* fty_num.c ends here */ 174