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