home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / recio213.zip / rfix.c < prev    next >
C/C++ Source or Header  |  1995-09-05  |  8KB  |  213 lines

  1. /****************************************************************************
  2.    MODULE: rfix.c
  3.   PURPOSE: recio functions used to fix bad data
  4. COPYRIGHT: (C) 1994-1995, William Pierpoint
  5.  COMPILER: Borland C Version 3.1
  6.        OS: MSDOS Version 6.2
  7.   VERSION: 2.13
  8.   RELEASE: September 4, 1995
  9. *****************************************************************************
  10.  
  11. These functions make an educated guess at fixing bad data.  They are used in 
  12. the test programs.  They are not necessarily appropriate for your application.
  13.  
  14. Mnemonics are as follows:
  15.  
  16. Single letter (fix functions)
  17. -----------------------------
  18. b - base (prefix)
  19. c - character (suffix)
  20. d - double (suffix)
  21. f - float (suffix)
  22. i - integer (suffix)
  23. l - long (suffix)
  24. r - record pointer (first letter)
  25. t - time_t (suffix)
  26. u - unsigned (suffix)
  27.  
  28. Example: rbfixui() takes two arguments, record pointer and base (radix) of 
  29.          number, and fixes an unsigned integer.
  30. *****************************************************************************/
  31.  
  32. #include <ctype.h>
  33. #include <float.h>
  34. #include <limits.h>
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38.  
  39. #include "recio.h"
  40.  
  41. extern int str2c(const char *nptr, char **endptr);
  42. extern unsigned long str2ul(const char *nptr, char **endptr, int base);
  43.  
  44. /* these values initialized here, computed in rfixt function */
  45. time_t mintime_t=0;  /* minimum value for time_t */
  46. time_t maxtime_t=0;  /* maximum value for time_t */
  47.  
  48. /* clip value v between lower l and upper u bounds */
  49. #define range(l, v, u)  (min(max((l),(v)),(u)))
  50. #define rtmfmt(rp)      ((rp)->r_tmfmt)
  51.  
  52. /****************************************************************************/
  53. static char *                 /* return pointer to string                   */
  54.     ctoa(                     /* convert char to string                     */
  55.         int   ch,             /* character to convert                       */
  56.         char *str)            /* string buffer to use                       */
  57. /****************************************************************************/
  58. {
  59.     if (ch > 0) str[0] = ch;
  60.     else str[0] = '\0';
  61.     str[1] = '\0';
  62.     return str;
  63. }
  64.  
  65. /****************************************************************************/
  66. static char *                /* return pointer to string                    */
  67.     tdtoa(                   /* convert floating point number to string     */
  68.         double d,            /* number to convert                           */
  69.         char  *str,          /* string buffer to use                        */
  70.         int    dig)          /* number of significant digits                */
  71. /****************************************************************************/
  72. {
  73.     char *sp=str;
  74.  
  75.     /* get one digit more than number of significant digits */
  76.     sprintf(str, "%.*E", dig, d);
  77.     
  78.     /* truncate last digit of significand */
  79.     while (*sp != 'E')  sp++;
  80.     memmove(sp-1, sp, strlen(sp)+1);
  81.     return str;
  82. }
  83.  
  84. /****************************************************************************/
  85. static int                   /* return 1 if neg zero, 0 otherwise           */
  86.     isnegzero(               /* does field buffer contain negative zero     */
  87.         REC *rp)             /* record pointer                              */
  88. /****************************************************************************/
  89. {
  90.      int negzero=0;          /* 0=not neg zero; 1=neg zero */
  91.      char *sp;               /* pointer to field buffer */
  92.      
  93.      sp = rflds(rp);
  94.      while (isspace(*sp)) sp++;
  95.      if (*sp++ != '-') goto done;
  96.      while (*sp == '0') sp++;
  97.      if (*sp < '0' || *sp > '9') negzero++;
  98. done:
  99.      return negzero;
  100. }
  101.  
  102. /****************************************************************************/
  103. void rbfixi(REC *rp, int base) 
  104. /****************************************************************************/
  105. {
  106.     long l = range(INT_MIN, strtol(rflds(rp), NULL, base), INT_MAX);
  107.     if (isnegzero(rp)) rsetfldstr(rp, "0");
  108.     else rsetfldstr(rp, ltoa(l, _r_nsbuf, base)); 
  109. }
  110.  
  111. /****************************************************************************/
  112. void rbfixui(REC *rp, int base)
  113. /****************************************************************************/
  114. {
  115.     unsigned long ul = min(str2ul(rflds(rp), NULL, base), UINT_MAX);
  116.     rsetfldstr(rp, ultoa(ul, _r_nsbuf, base));
  117. }
  118.  
  119. /****************************************************************************/
  120. void rbfixl(REC *rp, int base)
  121. /****************************************************************************/
  122. {
  123.     long l = range(LONG_MIN, strtol(rflds(rp), NULL, base), LONG_MAX);
  124.     if (isnegzero(rp)) rsetfldstr(rp, "0");
  125.     else rsetfldstr(rp, ltoa(l, _r_nsbuf, base));
  126. }
  127.  
  128. /****************************************************************************/
  129. void rbfixul(REC *rp, int base) 
  130. /****************************************************************************/
  131. {
  132.     unsigned long ul= min(str2ul(rflds(rp), NULL, base), ULONG_MAX);
  133.     rsetfldstr(rp, ultoa(ul, _r_nsbuf, base));
  134. }
  135.  
  136. /****************************************************************************/
  137. void rfixi(REC *rp) 
  138. /****************************************************************************/
  139.      rbfixi(rp, 10); 
  140. }
  141.  
  142. /****************************************************************************/
  143. void rfixui(REC *rp)
  144. /****************************************************************************/
  145. {  
  146.     rbfixui(rp, 10);
  147. }
  148.  
  149. /****************************************************************************/
  150. void rfixl(REC *rp)
  151. /****************************************************************************/
  152. {
  153.     rbfixl(rp, 10);
  154. }
  155.  
  156. /****************************************************************************/
  157. void rfixul(REC *rp)
  158. /****************************************************************************/
  159. {
  160.     rbfixul(rp, 10);
  161. }
  162.  
  163. /****************************************************************************/
  164. void rfixf(REC *rp) 
  165. /****************************************************************************/
  166. {
  167.     double d = range(-FLT_MAX, strtod(rflds(rp), NULL), FLT_MAX);
  168.     if (d > -FLT_MIN && d < FLT_MIN) d=0.0; /* zero if underflow */
  169.     rsetfldstr(rp, tdtoa((float) d, _r_nsbuf, FLT_DIG));
  170. }
  171.  
  172. /****************************************************************************/
  173. void rfixd(REC *rp)
  174. /****************************************************************************/
  175. {
  176.     double d = strtod(rflds(rp), NULL);
  177.     if (d > -DBL_MIN && d < DBL_MIN) d=0.0; /* zero if underflow */
  178.     rsetfldstr(rp, tdtoa(d, _r_nsbuf, DBL_DIG));
  179. }
  180.  
  181. /****************************************************************************/
  182. void rfixc(REC *rp) 
  183. /****************************************************************************/
  184. {
  185.     int ch = str2c(rflds(rp), NULL);
  186.     rsetfldstr(rp, ctoa(ch, _r_nsbuf));
  187. }
  188.  
  189. /****************************************************************************/
  190. void rfixt(REC *rp)
  191. /****************************************************************************/
  192. {
  193.     struct tm mintm;    /* tm for TIME_T_MIN */
  194.     struct tm maxtm;    /* tm for TIME_T_MAX */
  195.     struct tm curtm;    /* tm representation of current time field */
  196.     char s[NSBUFSIZ];   /* string representation of time */
  197.  
  198.     curtm = sftotm(rflds(rp), rtmfmt(rp));
  199.     mintm = timetotm(TIME_T_MIN);
  200.     maxtm = timetotm(TIME_T_MAX);
  201.     if (curtm.tm_year >= maxtm.tm_year) {
  202.         if (!strftime(s, NSBUFSIZ-1, rtmfmt(rp), &maxtm)) {
  203.             rseterr(rp, R_EINVAL); /* insufficient size for s[] */
  204.         }
  205.     } else {
  206.         if (!strftime(s, NSBUFSIZ-1, rtmfmt(rp), &mintm)) {
  207.             rseterr(rp, R_EINVAL); /* insufficient size for s[] */
  208.         }
  209.     }
  210.     rsetfldstr(rp, s);
  211. }
  212.