1/*2* THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT.3* You may freely copy it for use as a template for your own field types.4* If you develop a field type that might be of general use, please send5* it back to the ncurses maintainers for inclusion in the next version.6*/7/***************************************************************************8* *9* Author : Juergen Pfeifer, [email protected] *10* *11***************************************************************************/1213#include "form.priv.h"1415MODULE_ID("$Id$")1617#if HAVE_LOCALE_H18#include <locale.h>19#endif2021typedef struct {22int precision;23double low;24double high;25struct lconv* L;26} numericARG;2728/*---------------------------------------------------------------------------29| Facility : libnform30| Function : static void *Make_Numeric_Type(va_list * ap)31|32| Description : Allocate structure for numeric type argument.33|34| Return Values : Pointer to argument structure or NULL on error35+--------------------------------------------------------------------------*/36static void *Make_Numeric_Type(va_list * ap)37{38numericARG *argn = (numericARG *)malloc(sizeof(numericARG));3940if (argn)41{42argn->precision = va_arg(*ap,int);43argn->low = va_arg(*ap,double);44argn->high = va_arg(*ap,double);45#if HAVE_LOCALE_H46argn->L = localeconv();47#else48argn->L = NULL;49#endif50}51return (void *)argn;52}5354/*---------------------------------------------------------------------------55| Facility : libnform56| Function : static void *Copy_Numeric_Type(const void * argp)57|58| Description : Copy structure for numeric type argument.59|60| Return Values : Pointer to argument structure or NULL on error.61+--------------------------------------------------------------------------*/62static void *Copy_Numeric_Type(const void * argp)63{64const numericARG *ap = (const numericARG *)argp;65numericARG *result = (numericARG *)0;6667if (argp)68{69result = (numericARG *)malloc(sizeof(numericARG));70if (result)71*result = *ap;72}73return (void *)result;74}7576/*---------------------------------------------------------------------------77| Facility : libnform78| Function : static void Free_Numeric_Type(void * argp)79|80| Description : Free structure for numeric type argument.81|82| Return Values : -83+--------------------------------------------------------------------------*/84static void Free_Numeric_Type(void * argp)85{86if (argp)87free(argp);88}8990/*---------------------------------------------------------------------------91| Facility : libnform92| Function : static bool Check_Numeric_Field(FIELD * field,93| const void * argp)94|95| Description : Validate buffer content to be a valid numeric value96|97| Return Values : TRUE - field is valid98| FALSE - field is invalid99+--------------------------------------------------------------------------*/100static bool Check_Numeric_Field(FIELD * field, const void * argp)101{102const numericARG *argn = (const numericARG *)argp;103double low = argn->low;104double high = argn->high;105int prec = argn->precision;106unsigned char *bp = (unsigned char *)field_buffer(field,0);107char *s = (char *)bp;108double val = 0.0;109char buf[64];110111while(*bp && *bp==' ') bp++;112if (*bp)113{114if (*bp=='-' || *bp=='+')115bp++;116while(*bp)117{118if (!isdigit(*bp)) break;119bp++;120}121if (*bp==(122#if HAVE_LOCALE_H123(L && L->decimal_point) ? *(L->decimal_point) :124#endif125'.'))126{127bp++;128while(*bp)129{130if (!isdigit(*bp)) break;131bp++;132}133}134while(*bp && *bp==' ') bp++;135if (*bp=='\0')136{137val = atof(s);138if (low<high)139{140if (val<low || val>high) return FALSE;141}142snprintf(buf,sizeof(buf),"%.*f",(prec>0?prec:0),val);143set_field_buffer(field,0,buf);144return TRUE;145}146}147return FALSE;148}149150/*---------------------------------------------------------------------------151| Facility : libnform152| Function : static bool Check_Numeric_Character(153| int c,154| const void * argp)155|156| Description : Check a character for the numeric type.157|158| Return Values : TRUE - character is valid159| FALSE - character is invalid160+--------------------------------------------------------------------------*/161static bool Check_Numeric_Character(int c, const void * argp)162{163argp=0; /* Silence unused parameter warning. */164return (isdigit(c) ||165c == '+' ||166c == '-' ||167c == (168#if HAVE_LOCALE_H169(L && L->decimal_point) ? *(L->decimal_point) :170#endif171'.')172) ? TRUE : FALSE;173}174175static FIELDTYPE typeNUMERIC = {176_HAS_ARGS | _RESIDENT,1771, /* this is mutable, so we can't be const */178(FIELDTYPE *)0,179(FIELDTYPE *)0,180Make_Numeric_Type,181Copy_Numeric_Type,182Free_Numeric_Type,183Check_Numeric_Field,184Check_Numeric_Character,185NULL,186NULL187};188189FIELDTYPE* TYPE_NUMERIC = &typeNUMERIC;190191/* fty_num.c ends here */192193194