fty_num.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT.
  3. * You may freely copy it for use as a template for your own field types.
  4. * If you develop a field type that might be of general use, please send
  5. * it back to the ncurses maintainers for inclusion in the next version.
  6. */
  7. /***************************************************************************
  8. * *
  9. * Author : Juergen Pfeifer, [email protected] *
  10. * *
  11. ***************************************************************************/
  12. #include "form.priv.h"
  13. MODULE_ID("$Id$")
  14. #if HAVE_LOCALE_H
  15. #include <locale.h>
  16. #endif
  17. typedef struct {
  18. int precision;
  19. double low;
  20. double high;
  21. struct lconv* L;
  22. } numericARG;
  23. /*---------------------------------------------------------------------------
  24. | Facility : libnform
  25. | Function : static void *Make_Numeric_Type(va_list * ap)
  26. |
  27. | Description : Allocate structure for numeric type argument.
  28. |
  29. | Return Values : Pointer to argument structure or NULL on error
  30. +--------------------------------------------------------------------------*/
  31. static void *Make_Numeric_Type(va_list * ap)
  32. {
  33. numericARG *argn = (numericARG *)malloc(sizeof(numericARG));
  34. if (argn)
  35. {
  36. argn->precision = va_arg(*ap,int);
  37. argn->low = va_arg(*ap,double);
  38. argn->high = va_arg(*ap,double);
  39. #if HAVE_LOCALE_H
  40. argn->L = localeconv();
  41. #else
  42. argn->L = NULL;
  43. #endif
  44. }
  45. return (void *)argn;
  46. }
  47. /*---------------------------------------------------------------------------
  48. | Facility : libnform
  49. | Function : static void *Copy_Numeric_Type(const void * argp)
  50. |
  51. | Description : Copy structure for numeric type argument.
  52. |
  53. | Return Values : Pointer to argument structure or NULL on error.
  54. +--------------------------------------------------------------------------*/
  55. static void *Copy_Numeric_Type(const void * argp)
  56. {
  57. const numericARG *ap = (const numericARG *)argp;
  58. numericARG *result = (numericARG *)0;
  59. if (argp)
  60. {
  61. result = (numericARG *)malloc(sizeof(numericARG));
  62. if (result)
  63. *result = *ap;
  64. }
  65. return (void *)result;
  66. }
  67. /*---------------------------------------------------------------------------
  68. | Facility : libnform
  69. | Function : static void Free_Numeric_Type(void * argp)
  70. |
  71. | Description : Free structure for numeric type argument.
  72. |
  73. | Return Values : -
  74. +--------------------------------------------------------------------------*/
  75. static void Free_Numeric_Type(void * argp)
  76. {
  77. if (argp)
  78. free(argp);
  79. }
  80. /*---------------------------------------------------------------------------
  81. | Facility : libnform
  82. | Function : static bool Check_Numeric_Field(FIELD * field,
  83. | const void * argp)
  84. |
  85. | Description : Validate buffer content to be a valid numeric value
  86. |
  87. | Return Values : TRUE - field is valid
  88. | FALSE - field is invalid
  89. +--------------------------------------------------------------------------*/
  90. static bool Check_Numeric_Field(FIELD * field, const void * argp)
  91. {
  92. const numericARG *argn = (const numericARG *)argp;
  93. double low = argn->low;
  94. double high = argn->high;
  95. int prec = argn->precision;
  96. unsigned char *bp = (unsigned char *)field_buffer(field,0);
  97. char *s = (char *)bp;
  98. double val = 0.0;
  99. struct lconv* L = argn->L;
  100. char buf[64];
  101. while(*bp && *bp==' ') bp++;
  102. if (*bp)
  103. {
  104. if (*bp=='-' || *bp=='+')
  105. bp++;
  106. while(*bp)
  107. {
  108. if (!isdigit(*bp)) break;
  109. bp++;
  110. }
  111. if (*bp==(
  112. #if HAVE_LOCALE_H
  113. (L && L->decimal_point) ? *(L->decimal_point) :
  114. #endif
  115. '.'))
  116. {
  117. bp++;
  118. while(*bp)
  119. {
  120. if (!isdigit(*bp)) break;
  121. bp++;
  122. }
  123. }
  124. while(*bp && *bp==' ') bp++;
  125. if (*bp=='\0')
  126. {
  127. val = atof(s);
  128. if (low<high)
  129. {
  130. if (val<low || val>high) return FALSE;
  131. }
  132. sprintf(buf,"%.*f",(prec>0?prec:0),val);
  133. set_field_buffer(field,0,buf);
  134. return TRUE;
  135. }
  136. }
  137. return FALSE;
  138. }
  139. /*---------------------------------------------------------------------------
  140. | Facility : libnform
  141. | Function : static bool Check_Numeric_Character(
  142. | int c,
  143. | const void * argp)
  144. |
  145. | Description : Check a character for the numeric type.
  146. |
  147. | Return Values : TRUE - character is valid
  148. | FALSE - character is invalid
  149. +--------------------------------------------------------------------------*/
  150. static bool Check_Numeric_Character(int c, const void * argp)
  151. {
  152. const numericARG *argn = (const numericARG *)argp;
  153. struct lconv* L = argn->L;
  154. return (isdigit(c) ||
  155. c == '+' ||
  156. c == '-' ||
  157. c == (
  158. #if HAVE_LOCALE_H
  159. (L && L->decimal_point) ? *(L->decimal_point) :
  160. #endif
  161. '.')
  162. ) ? TRUE : FALSE;
  163. }
  164. static FIELDTYPE typeNUMERIC = {
  165. _HAS_ARGS | _RESIDENT,
  166. 1, /* this is mutable, so we can't be const */
  167. (FIELDTYPE *)0,
  168. (FIELDTYPE *)0,
  169. Make_Numeric_Type,
  170. Copy_Numeric_Type,
  171. Free_Numeric_Type,
  172. Check_Numeric_Field,
  173. Check_Numeric_Character,
  174. NULL,
  175. NULL
  176. };
  177. FIELDTYPE* TYPE_NUMERIC = &typeNUMERIC;
  178. /* fty_num.c ends here */