fty_int.c revision 166124
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
37MODULE_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
47typedef struct
48  {
49    int precision;
50    long low;
51    long high;
52  }
53thisARG;
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+--------------------------------------------------------------------------*/
63static void *
64Make_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+--------------------------------------------------------------------------*/
85static void *
86Copy_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+--------------------------------------------------------------------------*/
108static void
109Free_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+--------------------------------------------------------------------------*/
126static bool
127Check_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+--------------------------------------------------------------------------*/
219static bool
220Check_This_Character(int c, const void *argp GCC_UNUSED)
221{
222  return ((isDigit(UChar(c)) || (c == '-')) ? TRUE : FALSE);
223}
224
225static 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
240NCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_INTEGER = &typeTHIS;
241
242/* fty_int.c ends here */
243