fty_num.c revision 174994
1114987Speter/**************************************************************************** 2114987Speter * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * 3114987Speter * * 4114987Speter * Permission is hereby granted, free of charge, to any person obtaining a * 5114987Speter * copy of this software and associated documentation files (the * 6114987Speter * "Software"), to deal in the Software without restriction, including * 7114987Speter * without limitation the rights to use, copy, modify, merge, publish, * 8114987Speter * distribute, distribute with modifications, sublicense, and/or sell * 9114987Speter * copies of the Software, and to permit persons to whom the Software is * 10114987Speter * furnished to do so, subject to the following conditions: * 11114987Speter * * 12114987Speter * The above copyright notice and this permission notice shall be included * 13114987Speter * in all copies or substantial portions of the Software. * 14114987Speter * * 15114987Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 16114987Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 17114987Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 18114987Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 19114987Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 20114987Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 21114987Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 22114987Speter * * 23114987Speter * Except as contained in this notice, the name(s) of the above copyright * 24114987Speter * holders shall not be used in advertising or otherwise to promote the * 25114987Speter * sale, use or other dealings in this Software without prior written * 26114987Speter * authorization. * 27114987Speter ****************************************************************************/ 28114987Speter 29114987Speter/*************************************************************************** 30114987Speter* * 31114987Speter* Author : Juergen Pfeifer * 32114987Speter* * 33114987Speter***************************************************************************/ 34114987Speter 35114987Speter#include "form.priv.h" 36114987Speter 37114987SpeterMODULE_ID("$Id: fty_num.c,v 1.25 2007/10/13 19:32:54 tom Exp $") 38118031Sobrien 39118031Sobrien#if HAVE_LOCALE_H 40118031Sobrien#include <locale.h> 41114987Speter#endif 42114987Speter 43114987Speter#if HAVE_LOCALE_H 44114987Speter#define isDecimalPoint(c) ((c) == ((L && L->decimal_point) ? *(L->decimal_point) : '.')) 45114987Speter#else 46114987Speter#define isDecimalPoint(c) ((c) == '.') 47114987Speter#endif 48114987Speter 49114987Speter#if USE_WIDEC_SUPPORT 50114987Speter#define isDigit(c) (iswdigit((wint_t)(c)) || isdigit(UChar(c))) 51114987Speter#else 52114987Speter#define isDigit(c) isdigit(UChar(c)) 53114987Speter#endif 54114987Speter 55114987Speter#define thisARG numericARG 56114987Speter 57114987Spetertypedef struct 58114987Speter { 59114987Speter int precision; 60114987Speter double low; 61114987Speter double high; 62114987Speter struct lconv *L; 63114987Speter } 64114987SpeterthisARG; 65114987Speter 66114987Speter/*--------------------------------------------------------------------------- 67114987Speter| Facility : libnform 68114987Speter| Function : static void *Make_This_Type(va_list * ap) 69114987Speter| 70114987Speter| Description : Allocate structure for numeric type argument. 71114987Speter| 72114987Speter| Return Values : Pointer to argument structure or NULL on error 73114987Speter+--------------------------------------------------------------------------*/ 74119336Speterstatic void * 75119336SpeterMake_This_Type(va_list *ap) 76119336Speter{ 77114987Speter thisARG *argn = typeMalloc(thisARG, 1); 78114987Speter 79114987Speter if (argn) 80114987Speter { 81114987Speter T((T_CREATE("thisARG %p"), argn)); 82114987Speter argn->precision = va_arg(*ap, int); 83114987Speter argn->low = va_arg(*ap, double); 84114987Speter argn->high = va_arg(*ap, double); 85114987Speter 86114987Speter#if HAVE_LOCALE_H 87114987Speter argn->L = localeconv(); 88114987Speter#else 89114987Speter argn->L = NULL; 90114987Speter#endif 91114987Speter } 92114987Speter return (void *)argn; 93114987Speter} 94114987Speter 95114987Speter/*--------------------------------------------------------------------------- 96114987Speter| Facility : libnform 97114987Speter| Function : static void *Copy_This_Type(const void * argp) 98114987Speter| 99114987Speter| Description : Copy structure for numeric type argument. 100114987Speter| 101114987Speter| Return Values : Pointer to argument structure or NULL on error. 102114987Speter+--------------------------------------------------------------------------*/ 103114987Speterstatic void * 104114987SpeterCopy_This_Type(const void *argp) 105114987Speter{ 106114987Speter const thisARG *ap = (const thisARG *)argp; 107114987Speter thisARG *result = (thisARG *) 0; 108114987Speter 109114987Speter if (argp) 110114987Speter { 111114987Speter result = typeMalloc(thisARG, 1); 112114987Speter if (result) 113114987Speter { 114114987Speter T((T_CREATE("thisARG %p"), result)); 115114987Speter *result = *ap; 116114987Speter } 117114987Speter } 118114987Speter return (void *)result; 119114987Speter} 120114987Speter 121114987Speter/*--------------------------------------------------------------------------- 122114987Speter| Facility : libnform 123114987Speter| Function : static void Free_This_Type(void * argp) 124114987Speter| 125114987Speter| Description : Free structure for numeric type argument. 126114987Speter| 127114987Speter| Return Values : - 128114987Speter+--------------------------------------------------------------------------*/ 129114987Speterstatic void 130114987SpeterFree_This_Type(void *argp) 131114987Speter{ 132114987Speter if (argp) 133114987Speter free(argp); 134114987Speter} 135114987Speter 136114987Speter/*--------------------------------------------------------------------------- 137114987Speter| Facility : libnform 138114987Speter| Function : static bool Check_This_Field(FIELD * field, 139114987Speter| const void * argp) 140114987Speter| 141114987Speter| Description : Validate buffer content to be a valid numeric value 142114987Speter| 143114987Speter| Return Values : TRUE - field is valid 144114987Speter| FALSE - field is invalid 145114987Speter+--------------------------------------------------------------------------*/ 146114987Speterstatic bool 147114987SpeterCheck_This_Field(FIELD *field, const void *argp) 148114987Speter{ 149114987Speter const thisARG *argn = (const thisARG *)argp; 150114987Speter double low = argn->low; 151114987Speter double high = argn->high; 152114987Speter int prec = argn->precision; 153114987Speter unsigned char *bp = (unsigned char *)field_buffer(field, 0); 154114987Speter char *s = (char *)bp; 155114987Speter double val = 0.0; 156114987Speter struct lconv *L = argn->L; 157114987Speter char buf[64]; 158114987Speter bool result = FALSE; 159114987Speter 160114987Speter while (*bp && *bp == ' ') 161114987Speter bp++; 162114987Speter if (*bp) 163114987Speter { 164114987Speter if (*bp == '-' || *bp == '+') 165114987Speter bp++; 166114987Speter#if USE_WIDEC_SUPPORT 167114987Speter if (*bp) 168114987Speter { 169114987Speter bool blank = FALSE; 170114987Speter int state = 0; 171114987Speter int len; 172114987Speter int n; 173114987Speter wchar_t *list = _nc_Widen_String((char *)bp, &len); 174114987Speter 175114987Speter if (list != 0) 176114987Speter { 177114987Speter result = TRUE; 178114987Speter for (n = 0; n < len; ++n) 179114987Speter { 180114987Speter if (blank) 181114987Speter { 182114987Speter if (list[n] != ' ') 183114987Speter { 184114987Speter result = FALSE; 185114987Speter break; 186114987Speter } 187114987Speter } 188114987Speter else if (list[n] == ' ') 189114987Speter { 190114987Speter blank = TRUE; 191114987Speter } 192114987Speter else if (isDecimalPoint(list[n])) 193114987Speter { 194114987Speter if (++state > 1) 195114987Speter { 196114987Speter result = FALSE; 197114987Speter break; 198114987Speter } 199114987Speter } 200114987Speter else if (!isDigit(list[n])) 201114987Speter { 202114987Speter result = FALSE; 203114987Speter break; 204114987Speter } 205114987Speter } 206114987Speter free(list); 207114987Speter } 208114987Speter } 209114987Speter#else 210114987Speter while (*bp) 211114987Speter { 212114987Speter if (!isdigit(UChar(*bp))) 213114987Speter break; 214114987Speter bp++; 215114987Speter } 216114987Speter if (isDecimalPoint(*bp)) 217114987Speter { 218114987Speter bp++; 219114987Speter while (*bp) 220114987Speter { 221114987Speter if (!isdigit(UChar(*bp))) 222114987Speter break; 223114987Speter bp++; 224114987Speter } 225114987Speter } 226114987Speter while (*bp && *bp == ' ') 227114987Speter bp++; 228114987Speter result = (*bp == '\0'); 229114987Speter#endif 230114987Speter if (result) 231114987Speter { 232114987Speter val = atof(s); 233114987Speter if (low < high) 234114987Speter { 235114987Speter if (val < low || val > high) 236114987Speter result = FALSE; 237114987Speter } 238114987Speter if (result) 239114987Speter { 240114987Speter sprintf(buf, "%.*f", (prec > 0 ? prec : 0), val); 241114987Speter set_field_buffer(field, 0, buf); 242114987Speter } 243114987Speter } 244114987Speter } 245114987Speter return (result); 246114987Speter} 247114987Speter 248114987Speter/*--------------------------------------------------------------------------- 249114987Speter| Facility : libnform 250114987Speter| Function : static bool Check_This_Character( 251114987Speter| int c, 252114987Speter| const void * argp) 253114987Speter| 254114987Speter| Description : Check a character for the numeric type. 255114987Speter| 256114987Speter| Return Values : TRUE - character is valid 257114987Speter| FALSE - character is invalid 258114987Speter+--------------------------------------------------------------------------*/ 259114987Speterstatic bool 260114987SpeterCheck_This_Character(int c, const void *argp) 261114987Speter{ 262114987Speter const thisARG *argn = (const thisARG *)argp; 263114987Speter struct lconv *L = argn->L; 264114987Speter 265114987Speter return ((isDigit(c) || 266114987Speter c == '+' || 267119336Speter c == '-' || 268114987Speter isDecimalPoint(c)) 269114987Speter ? TRUE 270114987Speter : FALSE); 271114987Speter} 272114987Speter 273114987Speterstatic FIELDTYPE typeTHIS = 274114987Speter{ 275114987Speter _HAS_ARGS | _RESIDENT, 276114987Speter 1, /* this is mutable, so we can't be const */ 277114987Speter (FIELDTYPE *)0, 278114987Speter (FIELDTYPE *)0, 279114987Speter Make_This_Type, 280114987Speter Copy_This_Type, 281114987Speter Free_This_Type, 282114987Speter Check_This_Field, 283114987Speter Check_This_Character, 284114987Speter NULL, 285114987Speter NULL 286114987Speter}; 287114987Speter 288114987SpeterNCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_NUMERIC = &typeTHIS; 289114987Speter 290114987Speter/* fty_num.c ends here */ 291114987Speter