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