xref: /freebsd/contrib/ncurses/form/fty_int.c (revision 21817992b3314c908ab50f0bb88d2ee750b9c4ac)
14a1a9510SRong-En Fan /****************************************************************************
2*21817992SBaptiste Daroussin  * Copyright 2020,2021 Thomas E. Dickey                                     *
3e1865124SBaptiste Daroussin  * Copyright 1998-2010,2012 Free Software Foundation, Inc.                  *
44a1a9510SRong-En Fan  *                                                                          *
54a1a9510SRong-En Fan  * Permission is hereby granted, free of charge, to any person obtaining a  *
64a1a9510SRong-En Fan  * copy of this software and associated documentation files (the            *
74a1a9510SRong-En Fan  * "Software"), to deal in the Software without restriction, including      *
84a1a9510SRong-En Fan  * without limitation the rights to use, copy, modify, merge, publish,      *
94a1a9510SRong-En Fan  * distribute, distribute with modifications, sublicense, and/or sell       *
104a1a9510SRong-En Fan  * copies of the Software, and to permit persons to whom the Software is    *
114a1a9510SRong-En Fan  * furnished to do so, subject to the following conditions:                 *
124a1a9510SRong-En Fan  *                                                                          *
134a1a9510SRong-En Fan  * The above copyright notice and this permission notice shall be included  *
144a1a9510SRong-En Fan  * in all copies or substantial portions of the Software.                   *
154a1a9510SRong-En Fan  *                                                                          *
164a1a9510SRong-En Fan  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
174a1a9510SRong-En Fan  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
184a1a9510SRong-En Fan  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
194a1a9510SRong-En Fan  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
204a1a9510SRong-En Fan  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
214a1a9510SRong-En Fan  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
224a1a9510SRong-En Fan  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
234a1a9510SRong-En Fan  *                                                                          *
244a1a9510SRong-En Fan  * Except as contained in this notice, the name(s) of the above copyright   *
254a1a9510SRong-En Fan  * holders shall not be used in advertising or otherwise to promote the     *
264a1a9510SRong-En Fan  * sale, use or other dealings in this Software without prior written       *
274a1a9510SRong-En Fan  * authorization.                                                           *
284a1a9510SRong-En Fan  ****************************************************************************/
290e3d5408SPeter Wemm 
300e3d5408SPeter Wemm /***************************************************************************
310e3d5408SPeter Wemm *                                                                          *
324a1a9510SRong-En Fan *  Author : Juergen Pfeifer                                                *
330e3d5408SPeter Wemm *                                                                          *
340e3d5408SPeter Wemm ***************************************************************************/
350e3d5408SPeter Wemm 
360e3d5408SPeter Wemm #include "form.priv.h"
370e3d5408SPeter Wemm 
38*21817992SBaptiste Daroussin MODULE_ID("$Id: fty_int.c,v 1.33 2021/06/17 21:11:08 tom Exp $")
390e3d5408SPeter Wemm 
404a1a9510SRong-En Fan #if USE_WIDEC_SUPPORT
414a1a9510SRong-En Fan #define isDigit(c) (iswdigit((wint_t)(c)) || isdigit(UChar(c)))
424a1a9510SRong-En Fan #else
434a1a9510SRong-En Fan #define isDigit(c) isdigit(UChar(c))
444a1a9510SRong-En Fan #endif
454a1a9510SRong-En Fan 
464a1a9510SRong-En Fan #define thisARG integerARG
474a1a9510SRong-En Fan 
484a1a9510SRong-En Fan typedef struct
494a1a9510SRong-En Fan   {
500e3d5408SPeter Wemm     int precision;
510e3d5408SPeter Wemm     long low;
520e3d5408SPeter Wemm     long high;
534a1a9510SRong-En Fan   }
544a1a9510SRong-En Fan thisARG;
550e3d5408SPeter Wemm 
5606bfebdeSXin LI typedef struct
5706bfebdeSXin LI   {
5806bfebdeSXin LI     int precision;
5906bfebdeSXin LI     long low;
6006bfebdeSXin LI     long high;
6106bfebdeSXin LI   }
6206bfebdeSXin LI integerPARM;
6306bfebdeSXin LI 
6406bfebdeSXin LI /*---------------------------------------------------------------------------
6506bfebdeSXin LI |   Facility      :  libnform
6606bfebdeSXin LI |   Function      :  static void *Generic_This_Type( void * arg )
6706bfebdeSXin LI |
6806bfebdeSXin LI |   Description   :  Allocate structure for integer type argument.
6906bfebdeSXin LI |
7006bfebdeSXin LI |   Return Values :  Pointer to argument structure or NULL on error
7106bfebdeSXin LI +--------------------------------------------------------------------------*/
7206bfebdeSXin LI static void *
Generic_This_Type(void * arg)7306bfebdeSXin LI Generic_This_Type(void *arg)
7406bfebdeSXin LI {
7506bfebdeSXin LI   thisARG *argp = (thisARG *)0;
7606bfebdeSXin LI   thisARG *param = (thisARG *)arg;
7706bfebdeSXin LI 
7806bfebdeSXin LI   if (param)
7906bfebdeSXin LI     {
8006bfebdeSXin LI       argp = typeMalloc(thisARG, 1);
8106bfebdeSXin LI 
8206bfebdeSXin LI       if (argp)
8306bfebdeSXin LI 	{
8406bfebdeSXin LI 	  T((T_CREATE("thisARG %p"), (void *)argp));
8506bfebdeSXin LI 	  *argp = *param;
8606bfebdeSXin LI 	}
8706bfebdeSXin LI     }
8806bfebdeSXin LI   return (void *)argp;
8906bfebdeSXin LI }
9006bfebdeSXin LI 
910e3d5408SPeter Wemm /*---------------------------------------------------------------------------
920e3d5408SPeter Wemm |   Facility      :  libnform
934a1a9510SRong-En Fan |   Function      :  static void *Make_This_Type( va_list * ap )
940e3d5408SPeter Wemm |
950e3d5408SPeter Wemm |   Description   :  Allocate structure for integer type argument.
960e3d5408SPeter Wemm |
970e3d5408SPeter Wemm |   Return Values :  Pointer to argument structure or NULL on error
980e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
994a1a9510SRong-En Fan static void *
Make_This_Type(va_list * ap)1004a1a9510SRong-En Fan Make_This_Type(va_list *ap)
1010e3d5408SPeter Wemm {
10206bfebdeSXin LI   thisARG arg;
1030e3d5408SPeter Wemm 
10406bfebdeSXin LI   arg.precision = va_arg(*ap, int);
10506bfebdeSXin LI   arg.low = va_arg(*ap, long);
10606bfebdeSXin LI   arg.high = va_arg(*ap, long);
10706bfebdeSXin LI 
10806bfebdeSXin LI   return Generic_This_Type((void *)&arg);
1090e3d5408SPeter Wemm }
1100e3d5408SPeter Wemm 
1110e3d5408SPeter Wemm /*---------------------------------------------------------------------------
1120e3d5408SPeter Wemm |   Facility      :  libnform
1134a1a9510SRong-En Fan |   Function      :  static void *Copy_This_Type(const void * argp)
1140e3d5408SPeter Wemm |
1150e3d5408SPeter Wemm |   Description   :  Copy structure for integer type argument.
1160e3d5408SPeter Wemm |
1170e3d5408SPeter Wemm |   Return Values :  Pointer to argument structure or NULL on error.
1180e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
1194a1a9510SRong-En Fan static void *
Copy_This_Type(const void * argp)1204a1a9510SRong-En Fan Copy_This_Type(const void *argp)
1210e3d5408SPeter Wemm {
1224a1a9510SRong-En Fan   const thisARG *ap = (const thisARG *)argp;
1234a1a9510SRong-En Fan   thisARG *result = (thisARG *)0;
1240e3d5408SPeter Wemm 
1250e3d5408SPeter Wemm   if (argp)
1260e3d5408SPeter Wemm     {
1275ca44d1cSRong-En Fan       result = typeMalloc(thisARG, 1);
1287a656419SBaptiste Daroussin 
1290e3d5408SPeter Wemm       if (result)
1305ca44d1cSRong-En Fan 	{
13106bfebdeSXin LI 	  T((T_CREATE("thisARG %p"), (void *)result));
1320e3d5408SPeter Wemm 	  *result = *ap;
1330e3d5408SPeter Wemm 	}
1345ca44d1cSRong-En Fan     }
1350e3d5408SPeter Wemm   return (void *)result;
1360e3d5408SPeter Wemm }
1370e3d5408SPeter Wemm 
1380e3d5408SPeter Wemm /*---------------------------------------------------------------------------
1390e3d5408SPeter Wemm |   Facility      :  libnform
1404a1a9510SRong-En Fan |   Function      :  static void Free_This_Type(void * argp)
1410e3d5408SPeter Wemm |
1420e3d5408SPeter Wemm |   Description   :  Free structure for integer type argument.
1430e3d5408SPeter Wemm |
1440e3d5408SPeter Wemm |   Return Values :  -
1450e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
1464a1a9510SRong-En Fan static void
Free_This_Type(void * argp)1474a1a9510SRong-En Fan Free_This_Type(void *argp)
1480e3d5408SPeter Wemm {
1490e3d5408SPeter Wemm   if (argp)
1500e3d5408SPeter Wemm     free(argp);
1510e3d5408SPeter Wemm }
1520e3d5408SPeter Wemm 
1530e3d5408SPeter Wemm /*---------------------------------------------------------------------------
1540e3d5408SPeter Wemm |   Facility      :  libnform
1554a1a9510SRong-En Fan |   Function      :  static bool Check_This_Field(
1560e3d5408SPeter Wemm |                                                 FIELD * field,
1570e3d5408SPeter Wemm |                                                 const void * argp)
1580e3d5408SPeter Wemm |
1590e3d5408SPeter Wemm |   Description   :  Validate buffer content to be a valid integer value
1600e3d5408SPeter Wemm |
1610e3d5408SPeter Wemm |   Return Values :  TRUE  - field is valid
1620e3d5408SPeter Wemm |                    FALSE - field is invalid
1630e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
1644a1a9510SRong-En Fan static bool
Check_This_Field(FIELD * field,const void * argp)1654a1a9510SRong-En Fan Check_This_Field(FIELD *field, const void *argp)
1660e3d5408SPeter Wemm {
1674a1a9510SRong-En Fan   const thisARG *argi = (const thisARG *)argp;
1680e3d5408SPeter Wemm   long low = argi->low;
1690e3d5408SPeter Wemm   long high = argi->high;
1700e3d5408SPeter Wemm   int prec = argi->precision;
1710e3d5408SPeter Wemm   unsigned char *bp = (unsigned char *)field_buffer(field, 0);
1720e3d5408SPeter Wemm   char *s = (char *)bp;
1734a1a9510SRong-En Fan   bool result = FALSE;
1740e3d5408SPeter Wemm 
175*21817992SBaptiste Daroussin   while (*bp == ' ')
1764a1a9510SRong-En Fan     bp++;
1770e3d5408SPeter Wemm   if (*bp)
1780e3d5408SPeter Wemm     {
1794a1a9510SRong-En Fan       if (*bp == '-')
1804a1a9510SRong-En Fan 	bp++;
1814a1a9510SRong-En Fan #if USE_WIDEC_SUPPORT
1824a1a9510SRong-En Fan       if (*bp)
1834a1a9510SRong-En Fan 	{
1844a1a9510SRong-En Fan 	  int len;
1854a1a9510SRong-En Fan 	  wchar_t *list = _nc_Widen_String((char *)bp, &len);
1864a1a9510SRong-En Fan 
1874a1a9510SRong-En Fan 	  if (list != 0)
1884a1a9510SRong-En Fan 	    {
189*21817992SBaptiste Daroussin 	      bool blank = FALSE;
190*21817992SBaptiste Daroussin 	      int n;
191*21817992SBaptiste Daroussin 
1924a1a9510SRong-En Fan 	      result = TRUE;
1934a1a9510SRong-En Fan 	      for (n = 0; n < len; ++n)
1944a1a9510SRong-En Fan 		{
1954a1a9510SRong-En Fan 		  if (blank)
1964a1a9510SRong-En Fan 		    {
1974a1a9510SRong-En Fan 		      if (list[n] != ' ')
1984a1a9510SRong-En Fan 			{
1994a1a9510SRong-En Fan 			  result = FALSE;
2004a1a9510SRong-En Fan 			  break;
2014a1a9510SRong-En Fan 			}
2024a1a9510SRong-En Fan 		    }
2034a1a9510SRong-En Fan 		  else if (list[n] == ' ')
2044a1a9510SRong-En Fan 		    {
2054a1a9510SRong-En Fan 		      blank = TRUE;
2064a1a9510SRong-En Fan 		    }
2074a1a9510SRong-En Fan 		  else if (!isDigit(list[n]))
2084a1a9510SRong-En Fan 		    {
2094a1a9510SRong-En Fan 		      result = FALSE;
2104a1a9510SRong-En Fan 		      break;
2114a1a9510SRong-En Fan 		    }
2124a1a9510SRong-En Fan 		}
2134a1a9510SRong-En Fan 	      free(list);
2144a1a9510SRong-En Fan 	    }
2154a1a9510SRong-En Fan 	}
2164a1a9510SRong-En Fan #else
2170e3d5408SPeter Wemm       while (*bp)
2180e3d5408SPeter Wemm 	{
2194a1a9510SRong-En Fan 	  if (!isdigit(UChar(*bp)))
2204a1a9510SRong-En Fan 	    break;
2210e3d5408SPeter Wemm 	  bp++;
2220e3d5408SPeter Wemm 	}
2234a1a9510SRong-En Fan       while (*bp && *bp == ' ')
2244a1a9510SRong-En Fan 	bp++;
2254a1a9510SRong-En Fan       result = (*bp == '\0');
2264a1a9510SRong-En Fan #endif
2274a1a9510SRong-En Fan       if (result)
2280e3d5408SPeter Wemm 	{
229*21817992SBaptiste Daroussin 	  long val = atol(s);
230*21817992SBaptiste Daroussin 
2310e3d5408SPeter Wemm 	  if (low < high)
2320e3d5408SPeter Wemm 	    {
2334a1a9510SRong-En Fan 	      if (val < low || val > high)
2344a1a9510SRong-En Fan 		result = FALSE;
2350e3d5408SPeter Wemm 	    }
2364a1a9510SRong-En Fan 	  if (result)
2374a1a9510SRong-En Fan 	    {
238*21817992SBaptiste Daroussin 	      char buf[100];
239*21817992SBaptiste Daroussin 
24073f0a83dSXin LI 	      _nc_SPRINTF(buf, _nc_SLIMIT(sizeof(buf))
24173f0a83dSXin LI 			  "%.*ld", (prec > 0 ? prec : 0), val);
2420e3d5408SPeter Wemm 	      set_field_buffer(field, 0, buf);
2430e3d5408SPeter Wemm 	    }
2440e3d5408SPeter Wemm 	}
2454a1a9510SRong-En Fan     }
2464a1a9510SRong-En Fan   return (result);
2470e3d5408SPeter Wemm }
2480e3d5408SPeter Wemm 
2490e3d5408SPeter Wemm /*---------------------------------------------------------------------------
2500e3d5408SPeter Wemm |   Facility      :  libnform
2514a1a9510SRong-En Fan |   Function      :  static bool Check_This_Character(
2520e3d5408SPeter Wemm |                                      int c,
2530e3d5408SPeter Wemm |                                      const void * argp)
2540e3d5408SPeter Wemm |
2550e3d5408SPeter Wemm |   Description   :  Check a character for the integer type.
2560e3d5408SPeter Wemm |
2570e3d5408SPeter Wemm |   Return Values :  TRUE  - character is valid
2580e3d5408SPeter Wemm |                    FALSE - character is invalid
2590e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
2604a1a9510SRong-En Fan static bool
Check_This_Character(int c,const void * argp GCC_UNUSED)2614a1a9510SRong-En Fan Check_This_Character(int c, const void *argp GCC_UNUSED)
2620e3d5408SPeter Wemm {
2634a1a9510SRong-En Fan   return ((isDigit(UChar(c)) || (c == '-')) ? TRUE : FALSE);
2640e3d5408SPeter Wemm }
2650e3d5408SPeter Wemm 
2664a1a9510SRong-En Fan static FIELDTYPE typeTHIS =
2674a1a9510SRong-En Fan {
2680e3d5408SPeter Wemm   _HAS_ARGS | _RESIDENT,
2690e3d5408SPeter Wemm   1,				/* this is mutable, so we can't be const */
2700e3d5408SPeter Wemm   (FIELDTYPE *)0,
2710e3d5408SPeter Wemm   (FIELDTYPE *)0,
2724a1a9510SRong-En Fan   Make_This_Type,
2734a1a9510SRong-En Fan   Copy_This_Type,
2744a1a9510SRong-En Fan   Free_This_Type,
27506bfebdeSXin LI   INIT_FT_FUNC(Check_This_Field),
27606bfebdeSXin LI   INIT_FT_FUNC(Check_This_Character),
27706bfebdeSXin LI   INIT_FT_FUNC(NULL),
27806bfebdeSXin LI   INIT_FT_FUNC(NULL),
27906bfebdeSXin LI #if NCURSES_INTEROP_FUNCS
28006bfebdeSXin LI   Generic_This_Type
28106bfebdeSXin LI #endif
2820e3d5408SPeter Wemm };
2830e3d5408SPeter Wemm 
2847a656419SBaptiste Daroussin FORM_EXPORT_VAR(FIELDTYPE *) TYPE_INTEGER = &typeTHIS;
2850e3d5408SPeter Wemm 
28606bfebdeSXin LI #if NCURSES_INTEROP_FUNCS
28706bfebdeSXin LI /* The next routines are to simplify the use of ncurses from
2887a656419SBaptiste Daroussin    programming languages with restrictions on interop with C level
28906bfebdeSXin LI    constructs (e.g. variable access or va_list + ellipsis constructs)
29006bfebdeSXin LI */
2917a656419SBaptiste Daroussin FORM_EXPORT(FIELDTYPE *)
_nc_TYPE_INTEGER(void)29206bfebdeSXin LI _nc_TYPE_INTEGER(void)
29306bfebdeSXin LI {
29406bfebdeSXin LI   return TYPE_INTEGER;
29506bfebdeSXin LI }
29606bfebdeSXin LI #endif
29706bfebdeSXin LI 
2980e3d5408SPeter Wemm /* fty_int.c ends here */
299