home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 125.img / PRO-C4.ZIP / BENCH1.ZIP / BENCH / FMTF.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-28  |  4.3 KB  |  190 lines

  1. /* ==( bench/fmtf.c )== */
  2.  
  3. /* ----------------------------------------------- */
  4. /* Pro-C  Copyright (C) 1988 - 1990 Vestronix Inc. */
  5. /* Modification to this source is not supported    */
  6. /* by Vestronix Inc.                               */
  7. /*            All Rights Reserved                  */
  8. /* ----------------------------------------------- */
  9. /* Written   Nig   1-Jan-87                        */
  10. /* Modified  Geo  11-Dec-89  See comments below    */
  11. /* ----------------------------------------------- */
  12. /* %W%  (%H% %T%) */
  13.  
  14. /*
  15.  *  Modifications
  16.  *
  17.  *  11-Dec-89  Geo - V2 version
  18.  *  25-Oct-89  Geo - 1.32 Merge
  19. */
  20.  
  21. # include <stdio.h>
  22. # include <bench.h>
  23.  
  24. /* Function prototypes */
  25. # ifdef ANSI
  26. static char fmtwd(char * ,char *);
  27. static void reverse(char *);
  28. # else
  29. static char fmtwd();
  30. static void reverse();
  31. # endif
  32.  
  33. int negative = FALSE;
  34. static int sign_done;
  35.  
  36. char *fmt_flt(n, mask)
  37. double n;
  38. char *mask;
  39. {
  40.     return(fmt_dbl((double)n, mask));
  41. }
  42.  
  43. char *fmt_dbl(num, msk)
  44. double num;
  45. char *msk;
  46. {
  47.     char c, *p, dc, *dp;
  48.     char numl[81], *numr;
  49.     static char maskl[41];
  50.     char *maskr;
  51.     int overflow = FALSE;
  52.  
  53.     /* break the mask into two parts, one for each side of the decimal */
  54.     strcpy(maskl, msk);
  55.     for(dp = maskl; (dc = *dp) != '\0' && dc != '.'; ++dp)
  56.         ;
  57.     if(dc != '\0')
  58.         *dp++ = '\0';
  59.     maskr = dp;
  60.  
  61.     /* find out how many decimal places were requested */
  62.     for(p = maskr; (c = *p) == '9' || c == 'z' || c == 'Z'; ++p)
  63.         ;
  64.  
  65.     /* under TC, the following are true: -0 != 0, -(-0) == -0 */
  66.     /* so, check for -0 here and set it to 0 to prevent trouble */
  67.     if(num == -0.0)
  68.         num = 0.0;
  69.  
  70.     /* convert number to non-negative and remember sign */
  71.     if(negative = (num < 0.0))
  72.         num = -num;
  73.  
  74.     /* let sprintf() do the work of actually converting it */
  75.     sprintf(numl, "%.*lf", (int)(p-maskr), num);
  76.  
  77.     /* break the number into two parts, one for each side of the decimal */
  78.     for(p = numl; (c = *p) != '\0' && c != '.'; ++p)
  79.         ;
  80.     if(c != '\0')
  81.         *p++ = '\0';
  82.     numr = p;
  83.  
  84.     /* remove any trailing 0s for now, format '9' will restore them */
  85.     /*
  86.     * This bit is obsolete and doesn't work.
  87.     *
  88.     for(p += strlen(p) - 1; *p == '0'; --p)
  89.         ;
  90.     *++p = '\0';
  91.     */
  92.  
  93.     /* format each half separately, leaving the result in the mask argument */
  94.     /* note that both parts are formatted from the decimal point outwards */
  95.     sign_done = FALSE;
  96.  
  97.     /* the part to the right of the decimal CANNOT overflow */
  98.     (void)fmtwd(numr, maskr);
  99.  
  100.     reverse(numl);
  101.     reverse(maskl);
  102.     overflow = (fmtwd(numl, maskl) != '\0');
  103.     reverse(maskl);
  104.  
  105.     /* put the decimal point back in and return the result */
  106.     if(dc != '\0')
  107.         dp[-1] = '.';
  108.  
  109.     /* put in a sign if negative, there is none yet, and there is room */
  110.     if(negative && !sign_done) {
  111.         for(p = maskl; *p == ' '; ++p)
  112.             ;
  113.         if(p == maskl)
  114.             overflow = TRUE;
  115.         else
  116.             *--p = '-';
  117.     }
  118.  
  119.     /* set overflow indicator if overflow occurred */
  120.     if(overflow)
  121.         *maskl = '?';
  122.  
  123.     return(maskl);
  124. }
  125.  
  126. static char fmtwd(num, mask)
  127. char *num, *mask;
  128. {
  129.     char mc, nc, *root;
  130.  
  131.     root = mask;
  132.     while((mc = *mask) != '\0') {
  133.         switch (mc) {
  134.         case '9':
  135.         case 'Z':
  136.         case 'z':
  137.             /* copy in digit if any left, otherwise copy '0' or ' ' */
  138.             if((nc = *num) != '\0') {
  139.                 ++num;
  140.                 *mask = nc;
  141.             }
  142.             else
  143.                 *mask = (mc == '9') ? '0' : ' ';
  144.             break;
  145.         case '+':
  146.         case '-':
  147.             /* treat as a sign only if this is the first one encountered */
  148.             if (!sign_done
  149.             /* next line allows non-sign + or - inside a num eg. ZZZ-ZZZZ */
  150.             && ( *(mask-1) == '\0' || *(mask+1) == '\0' )
  151.             ) {
  152.                 char *p;
  153.  
  154.                 sign_done = TRUE;
  155.                 /* search back for a non-blank */
  156.                 for(p = mask; --p >= root && *p == ' '; )
  157.                     ;
  158.                 *mask = ' ';
  159.                 *++p = negative ? '-' : ((mc == '+') ? '+' : ' ');
  160.             }
  161.             break;
  162.         case ',':
  163.             /* don't want to delete comma if there is going to be a zero */
  164.             if(*num == '\0' && (mask[1] == 'z' || mask[1] == 'Z'))
  165.                 *mask = ' ';
  166.             break;
  167.         default:
  168.             /* simply leave the character as is */
  169.             break;
  170.         }
  171.         ++mask;
  172.     }
  173.  
  174.     /* return next character in number; this is used to detect overflow */
  175.     return(*num);
  176. }
  177.  
  178. /* not a very general function, but it's only used in this file */
  179. static void reverse(str)
  180. char *str;
  181. {
  182.     char tmp, *estr;
  183.     for (estr = str + strlen(str) - 1; estr > str; estr--, str++) {
  184.         tmp = *estr;
  185.         *estr = *str;
  186.         *str = tmp;
  187.     }
  188. }
  189.  
  190.