fty_num.c revision 50276
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 16MODULE_ID("$Id: fty_num.c,v 1.13 1999/05/16 17:23:30 juergen Exp $") 17 18#if HAVE_LOCALE_H 19#include <locale.h> 20#endif 21 22typedef 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+--------------------------------------------------------------------------*/ 37static 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+--------------------------------------------------------------------------*/ 63static 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+--------------------------------------------------------------------------*/ 85static 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+--------------------------------------------------------------------------*/ 101static 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+--------------------------------------------------------------------------*/ 163static 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 179static 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 193FIELDTYPE* TYPE_NUMERIC = &typeNUMERIC; 194 195/* fty_num.c ends here */ 196