home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 15 / CD_ASCQ_15_070894.iso / news / 683 / recio120 / testch.c < prev    next >
C/C++ Source or Header  |  1994-04-08  |  11KB  |  329 lines

  1. /* testch.c - tests int, double, char and string char delimited functions */
  2. /* recio version 1.20, release April 8, 1994 */
  3. /* Copyright (C) 1994 William Pierpoint */
  4.  
  5. #include <ctype.h>
  6. #include <errno.h>
  7. #include <limits.h>
  8. #include <float.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12.  
  13. #include "recio.h"
  14.  
  15. /* errors normally to stderr; but for test purposes, stdout */
  16. #define errout  stdout
  17.  
  18. /****************************************************************************
  19. Dynamic string copy function, kludged for use with recio.  This 
  20. function is not part of recio nor was rseterr() designed to work 
  21. with it, but you get the idea. 
  22. Precondition: set dst to null ptr when declaring it, e.g. char *dst=NULL;
  23. Obligation: free dst when finished with it.
  24. *****************************************************************************/
  25. char *                  /* return dst                                       */
  26.     scopys(             /* copy string dynamically                          */
  27.         char *dst,      /* destination string pointer                       */
  28.         char *src)      /* source string pointer                            */
  29. /****************************************************************************/
  30. {                       
  31.   size_t dlen;          /* strlen of dst */
  32.   size_t slen;          /* strlen of src */
  33.   int errnum;           /* error number */
  34.  
  35.   /* if null src pointer */
  36.   if (!src) {
  37.     rseterr(NULL, EINVAL);
  38.     dst = NULL;
  39.     goto done;
  40.   }
  41.   
  42.   if (dst) {
  43.     dlen = strlen(dst);
  44.     slen = strlen(src);
  45.     if (dlen < slen) {
  46.       do {
  47.         dst = (char *) realloc(dst, slen+1);
  48.         if (!dst) {
  49.           errnum = rseterr(NULL, ENOMEM);
  50.           if (errnum) goto done;
  51.         }
  52.       } while (!dst);
  53.     }
  54.     strcpy(dst, src);
  55.   } else {
  56.      do {
  57.        dst = strdup(src);
  58.        if (!dst) {
  59.          errnum = rseterr(NULL, ENOMEM);
  60.          if (errnum) goto done;
  61.        }
  62.      } while (!dst);
  63.    }
  64. done:
  65.   return dst;
  66. }
  67.  
  68. /****************************************************************************/
  69. void                         /* return nothing                              */
  70.     rfixnum(                 /* fix number                                  */
  71.         REC *rp,             /* record pointer                              */
  72.         int  errnum,         /* error number                                */
  73.         int (*rfix)(REC *))  /* rfix function pointer                       */
  74. /****************************************************************************/
  75. {
  76.   switch (errnum) {
  77.   case R_EMISDAT:
  78.     fprintf(errout, "...substituting zero\n");
  79.     rsetfldstr(rp, "0");
  80.     break;
  81.   case R_EINVDAT:
  82.   case R_ERANGE:
  83.     fprintf(errout, "...substituting best guess\n");
  84.     rfix(rp);
  85.     break;
  86.   }
  87. }
  88.  
  89. /****************************************************************************/
  90. void                         /* return nothing                              */
  91.     rfixchar(                /* fix character                               */
  92.         REC *rp,             /* record pointer                              */
  93.         int  errnum,         /* error number                                */
  94.         int (*rfix)(REC *))  /* rfix function pointer                       */
  95. /****************************************************************************/
  96. {
  97.   switch (errnum) {
  98.   case R_EMISDAT:
  99.     fprintf(errout, "...substituting the letter N\n");
  100.     rsetfldstr(rp, "N");
  101.     break;
  102.   case R_EINVDAT:
  103.     fprintf(errout, "...substituting best guess\n");
  104.     rfix(rp);
  105.     break;
  106.   }
  107. }
  108.  
  109. /****************************************************************************/
  110. void                         /* return nothing                              */
  111.     rfixstr(                 /* fix string                                  */
  112.         REC *rp,             /* record pointer                              */
  113.         int  errnum,         /* error number                                */
  114.         int (*rfix)(REC *))  /* rfix function pointer                       */
  115. /****************************************************************************/
  116. {
  117.   switch (errnum) {
  118.   case R_EMISDAT:
  119.     fprintf(errout, "...substituting empty field\n");
  120.     rfix(rp);
  121.     break;
  122.   }
  123. }
  124.  
  125. /****************************************************************************/
  126. void                         /* returns nothing                             */
  127.     rerrfn(                  /* recio callback error function               */
  128.         REC *rp)             /* record pointer                              */
  129. /****************************************************************************/
  130. {
  131.   int errnum;       /* error number */
  132.  
  133.   if (risvalid(rp)) {
  134.   
  135.     /* if reof indicator set */
  136.     if (reof(rp)) { 
  137.       fprintf(errout, "ERROR reading %s: "
  138.        "tried to read past end of file\n", rnames(rp));
  139.     
  140.     /* else rerror indicator set */
  141.     } else {
  142.  
  143.       /* determine cause of error */
  144.       errnum = rerror(rp);
  145.       switch (errnum) {
  146.  
  147.       /* data errors */
  148.       case R_ERANGE:   /* data out of range */
  149.       case R_EINVDAT:  /* invalid data */
  150.       case R_EMISDAT:  /* missing data */
  151.         fprintf(errout, "DATA ERROR reading %s at record %lu and field %d "
  152.          "-- %s\n", rnames(rp), rrecno(rp), rfldno(rp), rerrstr(rp));
  153.           
  154.         /* determine context */
  155.         switch (rcxtno(rp)) {
  156.         case RECIN:
  157.           
  158.           /* determine field */
  159.           switch (rfldno(rp)) {
  160.           case 1:  /* the integer field i */
  161.             rfixnum(rp, errnum, rfixi);
  162.             break;
  163.           
  164.           case 2:  /* the unsigned integer field ui */
  165.             rfixnum(rp, errnum, rfixui);
  166.             break;
  167.  
  168.            case 3:  /* the long field l */
  169.             rfixnum(rp, errnum, rfixl);
  170.             break;
  171.  
  172.            case 4:  /* the unsigned long field ul */
  173.             rfixnum(rp, errnum, rfixul);
  174.             break;
  175.  
  176.            case 5:  /* the float field f */
  177.             rfixnum(rp, errnum, rfixf);
  178.             break;
  179.  
  180.           case 6:  /* the double field d */
  181.             rfixnum(rp, errnum, rfixd);
  182.             break;
  183.  
  184.           case 7: /* the character field ch */
  185.             rfixchar(rp, errnum, rfixc);
  186.             break;
  187.  
  188.           case 8: /* the string field str */
  189.             rfixstr(rp, errnum, rfixs);
  190.             break;
  191.  
  192.           default: /* programming error - no case for field */
  193.             fprintf(errout, "FATAL ERROR in %s: code missing for field %u\n",
  194.              rnames(rp), rfldno(rp));
  195.             abort();
  196.             break;
  197.           }
  198.           break;
  199.         
  200.         default:  /* programming error - missing context number */
  201.           fprintf (errout, "FATAL ERROR in %s: missing context number\n", 
  202.            rnames(rp));
  203.           abort();
  204.           break;
  205.         }
  206.         break;
  207.         
  208.       /* non-fatal errors */
  209.       case R_ENOREG:
  210.         fprintf(errout, "WARNING: function atexit failed\n");
  211.         rclearerr(rp);
  212.         break;
  213.  
  214.       /* fatal errors (R_EINVAL, R_ENOMEM) */
  215.       case R_EINVAL:
  216.         fprintf(errout, "FATAL ERROR reading FILE %s: invalid argument", 
  217.          rnames(rp));
  218.         abort();
  219.         break;
  220.       case R_ENOMEM:
  221.         fprintf(errout, "FATAL ERROR reading FILE %s: out of memory", 
  222.          rnames(rp));
  223.         abort();
  224.         break;
  225.       default:
  226.         fprintf(errout, "FATAL ERROR reading FILE %s: unknown error", 
  227.          rnames(rp));
  228.         abort();
  229.         break;
  230.       }
  231.     }
  232.   
  233.   /* invalid record pointer */
  234.   } else {
  235.     switch (errno) {
  236.  
  237.     /* non-fatal errors */
  238.     case EACCES:
  239.     case EMFILE:
  240.       fprintf(errout, "WARNING: %s\n", strerror(errno));
  241.       break;
  242.  
  243.     /* fatal errors (EINVAL, ENOMEM) */
  244.     default:
  245.       fprintf(errout, "FATAL ERROR: %s\n", strerror(errno));
  246.       abort();
  247.       break;
  248.     }
  249.     errno = 0;
  250.   }
  251. }
  252.  
  253. /****************************************************************************
  254. main
  255. *****************************************************************************/
  256. #include <io.h>
  257.  
  258. int main()
  259. {
  260.   int i;                        /* integer field */
  261.   unsigned int ui;              /* unsigned integer field */
  262.   long l;                       /* long field */
  263.   unsigned long ul;             /* unsigned long field */
  264.   float f;                      /* float field */
  265.   double d;                     /* double field */
  266.   int ch;                       /* character field */
  267.   char *str = NULL;             /* string field */
  268.   
  269.   /* install error function */
  270.   rseterrfn(rerrfn);
  271.   
  272.   /* set field and text delimiters */
  273.   rsetfldch(recin, ',');
  274.   rsettxtch(recin, '"');
  275.   
  276.   /* if input not redirected */
  277.   if (isatty(fileno(stdin))) {
  278.     /* print instructions */
  279.     puts("TESTCH version 1.20 Copyright (C) 1994 William Pierpoint");
  280.     puts("Tests recio character delimited functions.");
  281.     puts("It reads eight fields, separated by commas, from the console.");
  282.     puts("The field types are: int, unsigned int, long, unsigned long,");
  283.     puts("                     float, double, character, and string.\n");
  284.     puts("Example:");
  285.     puts("-1, 1, 99999, -99999, 3.14159, 3.14159265, Y, \"Hello, World!\"\n");
  286.     puts("Press Ctrl-Z followed by the Enter key to exit program.");
  287.     puts("You may begin now.\n");
  288.   }
  289.   
  290.   /* loop through input */
  291.   while (rgetrec(recin)) {
  292.  
  293.     /* if input redirected, echo record contents */
  294.     if (!isatty(fileno(stdin))) puts(rrecs(recin));
  295.  
  296.     /* parse record */
  297.     i   = rgeti(recin);
  298.     ui  = rgetui(recin);
  299.     l   = rgetl(recin);
  300.     ul  = rgetul(recin);
  301.     f   = rgetf(recin);
  302.     d   = rgetd(recin);
  303.     ch  = rgetc(recin);
  304.     str = scopys(str, rgets(recin));
  305.     
  306.     /* print results */
  307.     printf("\n");
  308.     printf("         Integer field: %d\n", i);
  309.     printf("Unsigned Integer field: %u\n", ui);
  310.     printf("            Long field: %ld\n", l);
  311.     printf("   Unsigned Long field: %lu\n", ul);
  312.     printf("           Float field: %.*e\n", FLT_DIG-1, f);
  313.     printf("          Double field: %.*e\n", DBL_DIG-1, d);
  314.     printf("       Character field: %c\n", ch);
  315.     printf("          String field: %s\n\n", str);
  316.   }
  317.   
  318.   /* free string fields */
  319.   free (str);
  320.   
  321.   /* check stream for error */
  322.   if (rerror(recin)) { 
  323.     fprintf(errout, "ERROR reading %s: %s\n", 
  324.      rnames(recin), rerrstr(recin));
  325.     exit (EXIT_FAILURE);
  326.   }
  327.   return EXIT_SUCCESS;
  328. }
  329.