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