1/****************************************************************************
2 * Copyright (c) 1998-2006,2007 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.22 2007/10/13 19:32:40 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 = typeMalloc(thisARG, 1);
67
68  if (argp)
69    {
70      T((T_CREATE("thisARG %p"), argp));
71      argp->precision = va_arg(*ap, int);
72      argp->low = va_arg(*ap, long);
73      argp->high = va_arg(*ap, long);
74    }
75  return (void *)argp;
76}
77
78/*---------------------------------------------------------------------------
79|   Facility      :  libnform
80|   Function      :  static void *Copy_This_Type(const void * argp)
81|
82|   Description   :  Copy structure for integer type argument.
83|
84|   Return Values :  Pointer to argument structure or NULL on error.
85+--------------------------------------------------------------------------*/
86static void *
87Copy_This_Type(const void *argp)
88{
89  const thisARG *ap = (const thisARG *)argp;
90  thisARG *result = (thisARG *) 0;
91
92  if (argp)
93    {
94      result = typeMalloc(thisARG, 1);
95      if (result)
96	{
97	  T((T_CREATE("thisARG %p"), result));
98	  *result = *ap;
99	}
100    }
101  return (void *)result;
102}
103
104/*---------------------------------------------------------------------------
105|   Facility      :  libnform
106|   Function      :  static void Free_This_Type(void * argp)
107|
108|   Description   :  Free structure for integer type argument.
109|
110|   Return Values :  -
111+--------------------------------------------------------------------------*/
112static void
113Free_This_Type(void *argp)
114{
115  if (argp)
116    free(argp);
117}
118
119/*---------------------------------------------------------------------------
120|   Facility      :  libnform
121|   Function      :  static bool Check_This_Field(
122|                                                 FIELD * field,
123|                                                 const void * argp)
124|
125|   Description   :  Validate buffer content to be a valid integer value
126|
127|   Return Values :  TRUE  - field is valid
128|                    FALSE - field is invalid
129+--------------------------------------------------------------------------*/
130static bool
131Check_This_Field(FIELD *field, const void *argp)
132{
133  const thisARG *argi = (const thisARG *)argp;
134  long low = argi->low;
135  long high = argi->high;
136  int prec = argi->precision;
137  unsigned char *bp = (unsigned char *)field_buffer(field, 0);
138  char *s = (char *)bp;
139  long val;
140  char buf[100];
141  bool result = FALSE;
142
143  while (*bp && *bp == ' ')
144    bp++;
145  if (*bp)
146    {
147      if (*bp == '-')
148	bp++;
149#if USE_WIDEC_SUPPORT
150      if (*bp)
151	{
152	  bool blank = FALSE;
153	  int len;
154	  int n;
155	  wchar_t *list = _nc_Widen_String((char *)bp, &len);
156
157	  if (list != 0)
158	    {
159	      result = TRUE;
160	      for (n = 0; n < len; ++n)
161		{
162		  if (blank)
163		    {
164		      if (list[n] != ' ')
165			{
166			  result = FALSE;
167			  break;
168			}
169		    }
170		  else if (list[n] == ' ')
171		    {
172		      blank = TRUE;
173		    }
174		  else if (!isDigit(list[n]))
175		    {
176		      result = FALSE;
177		      break;
178		    }
179		}
180	      free(list);
181	    }
182	}
183#else
184      while (*bp)
185	{
186	  if (!isdigit(UChar(*bp)))
187	    break;
188	  bp++;
189	}
190      while (*bp && *bp == ' ')
191	bp++;
192      result = (*bp == '\0');
193#endif
194      if (result)
195	{
196	  val = atol(s);
197	  if (low < high)
198	    {
199	      if (val < low || val > high)
200		result = FALSE;
201	    }
202	  if (result)
203	    {
204	      sprintf(buf, "%.*ld", (prec > 0 ? prec : 0), val);
205	      set_field_buffer(field, 0, buf);
206	    }
207	}
208    }
209  return (result);
210}
211
212/*---------------------------------------------------------------------------
213|   Facility      :  libnform
214|   Function      :  static bool Check_This_Character(
215|                                      int c,
216|                                      const void * argp)
217|
218|   Description   :  Check a character for the integer type.
219|
220|   Return Values :  TRUE  - character is valid
221|                    FALSE - character is invalid
222+--------------------------------------------------------------------------*/
223static bool
224Check_This_Character(int c, const void *argp GCC_UNUSED)
225{
226  return ((isDigit(UChar(c)) || (c == '-')) ? TRUE : FALSE);
227}
228
229static FIELDTYPE typeTHIS =
230{
231  _HAS_ARGS | _RESIDENT,
232  1,				/* this is mutable, so we can't be const */
233  (FIELDTYPE *)0,
234  (FIELDTYPE *)0,
235  Make_This_Type,
236  Copy_This_Type,
237  Free_This_Type,
238  Check_This_Field,
239  Check_This_Character,
240  NULL,
241  NULL
242};
243
244NCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_INTEGER = &typeTHIS;
245
246/* fty_int.c ends here */
247