1 /**************************************************************************** 2 * Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. * 3 * * 4 * Permission is hereby granted, free of charge, to any person obtaining a * 5 * copy of this software and associated documentation files (the * 6 * "Software"), to deal in the Software without restriction, including * 7 * without limitation the rights to use, copy, modify, merge, publish, * 8 * distribute, distribute with modifications, sublicense, and/or sell * 9 * copies of the Software, and to permit persons to whom the Software is * 10 * furnished to do so, subject to the following conditions: * 11 * * 12 * The above copyright notice and this permission notice shall be included * 13 * in all copies or substantial portions of the Software. * 14 * * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 22 * * 23 * Except as contained in this notice, the name(s) of the above copyright * 24 * holders shall not be used in advertising or otherwise to promote the * 25 * sale, use or other dealings in this Software without prior written * 26 * authorization. * 27 ****************************************************************************/ 28 29 /*************************************************************************** 30 * * 31 * Author : Juergen Pfeifer * 32 * * 33 ***************************************************************************/ 34 35 #include "form.priv.h" 36 37 MODULE_ID("$Id: fty_int.c,v 1.20 2006/04/22 21:33:05 tom Exp $") 38 39 #if USE_WIDEC_SUPPORT 40 #define isDigit(c) (iswdigit((wint_t)(c)) || isdigit(UChar(c))) 41 #else 42 #define isDigit(c) isdigit(UChar(c)) 43 #endif 44 45 #define thisARG integerARG 46 47 typedef struct 48 { 49 int precision; 50 long low; 51 long high; 52 } 53 thisARG; 54 55 /*--------------------------------------------------------------------------- 56 | Facility : libnform 57 | Function : static void *Make_This_Type( va_list * ap ) 58 | 59 | Description : Allocate structure for integer type argument. 60 | 61 | Return Values : Pointer to argument structure or NULL on error 62 +--------------------------------------------------------------------------*/ 63 static void * 64 Make_This_Type(va_list *ap) 65 { 66 thisARG *argp = (thisARG *) malloc(sizeof(thisARG)); 67 68 if (argp) 69 { 70 argp->precision = va_arg(*ap, int); 71 argp->low = va_arg(*ap, long); 72 argp->high = va_arg(*ap, long); 73 } 74 return (void *)argp; 75 } 76 77 /*--------------------------------------------------------------------------- 78 | Facility : libnform 79 | Function : static void *Copy_This_Type(const void * argp) 80 | 81 | Description : Copy structure for integer type argument. 82 | 83 | Return Values : Pointer to argument structure or NULL on error. 84 +--------------------------------------------------------------------------*/ 85 static void * 86 Copy_This_Type(const void *argp) 87 { 88 const thisARG *ap = (const thisARG *)argp; 89 thisARG *result = (thisARG *) 0; 90 91 if (argp) 92 { 93 result = (thisARG *) malloc(sizeof(thisARG)); 94 if (result) 95 *result = *ap; 96 } 97 return (void *)result; 98 } 99 100 /*--------------------------------------------------------------------------- 101 | Facility : libnform 102 | Function : static void Free_This_Type(void * argp) 103 | 104 | Description : Free structure for integer type argument. 105 | 106 | Return Values : - 107 +--------------------------------------------------------------------------*/ 108 static void 109 Free_This_Type(void *argp) 110 { 111 if (argp) 112 free(argp); 113 } 114 115 /*--------------------------------------------------------------------------- 116 | Facility : libnform 117 | Function : static bool Check_This_Field( 118 | FIELD * field, 119 | const void * argp) 120 | 121 | Description : Validate buffer content to be a valid integer value 122 | 123 | Return Values : TRUE - field is valid 124 | FALSE - field is invalid 125 +--------------------------------------------------------------------------*/ 126 static bool 127 Check_This_Field(FIELD *field, const void *argp) 128 { 129 const thisARG *argi = (const thisARG *)argp; 130 long low = argi->low; 131 long high = argi->high; 132 int prec = argi->precision; 133 unsigned char *bp = (unsigned char *)field_buffer(field, 0); 134 char *s = (char *)bp; 135 long val; 136 char buf[100]; 137 bool result = FALSE; 138 139 while (*bp && *bp == ' ') 140 bp++; 141 if (*bp) 142 { 143 if (*bp == '-') 144 bp++; 145 #if USE_WIDEC_SUPPORT 146 if (*bp) 147 { 148 bool blank = FALSE; 149 int len; 150 int n; 151 wchar_t *list = _nc_Widen_String((char *)bp, &len); 152 153 if (list != 0) 154 { 155 result = TRUE; 156 for (n = 0; n < len; ++n) 157 { 158 if (blank) 159 { 160 if (list[n] != ' ') 161 { 162 result = FALSE; 163 break; 164 } 165 } 166 else if (list[n] == ' ') 167 { 168 blank = TRUE; 169 } 170 else if (!isDigit(list[n])) 171 { 172 result = FALSE; 173 break; 174 } 175 } 176 free(list); 177 } 178 } 179 #else 180 while (*bp) 181 { 182 if (!isdigit(UChar(*bp))) 183 break; 184 bp++; 185 } 186 while (*bp && *bp == ' ') 187 bp++; 188 result = (*bp == '\0'); 189 #endif 190 if (result) 191 { 192 val = atol(s); 193 if (low < high) 194 { 195 if (val < low || val > high) 196 result = FALSE; 197 } 198 if (result) 199 { 200 sprintf(buf, "%.*ld", (prec > 0 ? prec : 0), val); 201 set_field_buffer(field, 0, buf); 202 } 203 } 204 } 205 return (result); 206 } 207 208 /*--------------------------------------------------------------------------- 209 | Facility : libnform 210 | Function : static bool Check_This_Character( 211 | int c, 212 | const void * argp) 213 | 214 | Description : Check a character for the integer type. 215 | 216 | Return Values : TRUE - character is valid 217 | FALSE - character is invalid 218 +--------------------------------------------------------------------------*/ 219 static bool 220 Check_This_Character(int c, const void *argp GCC_UNUSED) 221 { 222 return ((isDigit(UChar(c)) || (c == '-')) ? TRUE : FALSE); 223 } 224 225 static FIELDTYPE typeTHIS = 226 { 227 _HAS_ARGS | _RESIDENT, 228 1, /* this is mutable, so we can't be const */ 229 (FIELDTYPE *)0, 230 (FIELDTYPE *)0, 231 Make_This_Type, 232 Copy_This_Type, 233 Free_This_Type, 234 Check_This_Field, 235 Check_This_Character, 236 NULL, 237 NULL 238 }; 239 240 NCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_INTEGER = &typeTHIS; 241 242 /* fty_int.c ends here */ 243