home *** CD-ROM | disk | FTP | other *** search
- /* ==( bench/fmti.c )== */
-
- /* ----------------------------------------------- */
- /* Pro-C Copyright (C) 1988 - 1990 Vestronix Inc. */
- /* Modification to this source is not supported */
- /* by Vestronix Inc. */
- /* All Rights Reserved */
- /* ----------------------------------------------- */
- /* Written Nig 1-Jan-87 */
- /* Modified Geo 11-Dec-89 See comments below */
- /* ----------------------------------------------- */
- /* %W% (%H% %T%) */
-
- /*
- * Modifications
- *
- * 11-Dec-89 Geo - V2 version
- * 25-Oct-89 Geo - 1.32 Merge
- */
-
- # include <stdio.h>
- # include <bench.h>
-
- /* Function prototypes */
- # ifdef ANSI
- static char fmtwd(char *, char *);
- static void reverse(char *);
- # else
- static void reverse();
- static char fmtwd();
- # endif
-
- /* Mode variables */
- static char currency;
- static int currency_done;
- static int lbracket_done;
- static int rbracket_done;
- static int money = FALSE;
- static int negative = FALSE;
- static int sign_done;
-
-
- char *fmt_int(num, mask)
- int num;
- char *mask;
- {
- return(fmt_lng((long)num, mask));
- } /* fnt_int */
-
- char *fmt_mny(num, mask)
- long num;
- char *mask;
- {
- char *p;
-
- /* if first digit not at beginning, determine currency character */
- if((p= strpbrk(mask, "Zz9")) != NULL && p != mask && !strchr("-+(,", *--p))
- currency = *p;
- else
- currency = '\0';
-
- /* format as a long value, taking into account the special money modes */
- money = TRUE;
- p = fmt_lng(num, mask);
- money = FALSE;
-
- return(p);
- } /* fmt_mny */
-
-
- char *fmt_lng(num, mask)
- long num;
- char *mask;
- {
- char c, *p, dc, *dp;
- char numl[81], *numr;
- static char maskl[41];
- char *maskr;
- int overflow = FALSE;
- int ndps;
-
- /* break the mask into two parts, one for each side of the decimal */
- strcpy(maskl, mask);
- for(dp = maskl; (dc = *dp) != '\0' && dc != '.'; ++dp)
- ;
- if(dc != '\0')
- *dp++ = '\0';
-
- maskr = dp;
-
- /* find out how many decimal places were requested */
- for(p = maskr; (c = *p) == '9' || c == 'z' || c == 'Z'; ++p)
- ;
- ndps = (int)(p - maskr);
-
- /* convert the number to non-negative, and remember the sign */
- if(negative = (num < 0L))
- num = -num;
-
- /* let sprintf do the work of actually converting it */
- sprintf(numl, "%*ld", ndps, num);
-
- /*
- * As zortech doesn't like a sprintf of the form
- * sprintf(numl, "%0*ld", ndps, num);
- * we must do it as above, then pad with any required spaces.
- */
- p = numl;
- while(*p == ' ')
- *p++ = '0';
-
- /* break the number into two parts, one for each side of the decimal */
- for(p = numl + strlen(numl), p[1] = '\0'; ndps; --p, --ndps)
- p[0] = p[-1];
- *p = '\0';
- numr = ++p;
-
- /* remove any trailing 0s from the right of the decimal for now */
- for(p += strlen(p) - 1; *p == '0'; --p)
- ;
- *++p = '\0';
-
- /* format each half separately, leaving the result in the mask argument */
- /* note that both parts are formatted from the decimal point outward */
- sign_done = currency_done = lbracket_done = rbracket_done = FALSE;
-
- /* the part to the right of the decimal cannot overflow */
- (void)fmtwd(numr, maskr);
-
- reverse(numl);
- reverse(maskl);
- overflow = (fmtwd(numl, maskl) != '\0');
- reverse(maskl);
-
- /* put the decimal point back in */
- if(dc != '\0')
- dp[-1] = '.';
-
- /* put in a sign if negative, there is none yet, and there is room */
- if(negative && !sign_done) {
- for(p = maskl; *p == ' '; ++p)
- ;
- if(p == maskl)
- overflow = TRUE;
- else
- *--p = '-';
- }
-
- /* set the overflow indicator if overflow occurred */
- if(overflow)
- *maskl = '?';
-
- return(maskl);
- } /* fmt_lng */
-
- static char fmtwd(num, mask)
- char *num, *mask;
- {
- char mc, nc, *root;
-
- root = mask;
- while((mc = *mask) != '\0') {
- if(money && mc == currency) {
- if(!currency_done) {
- char *p;
-
- currency_done = TRUE;
- /* search back for a non-blank */
- for(p = mask; --p >= root && *p == ' '; )
- ;
- *mask = ' ';
- *++p = mc;
- }
- }
- else switch (mc) {
- case '9':
- case 'Z':
- case 'z':
- /* copy in digit if any left, otherwise copy '0' or ' ' */
- if((nc = *num) != '\0') {
- ++num;
- *mask = nc;
- }
- else
- *mask = (mc == '9') ? '0' : ' ';
- break;
- case '(':
- /* treat as a bracket only if in money mode and first one */
- if(money && !lbracket_done) {
- char *p;
-
- sign_done = lbracket_done = TRUE;
- /* search back for a non-blank */
- for(p = mask; --p >= root && *p == ' '; )
- ;
- *mask = ' ';
- *++p = negative ? mc : ' ';
- }
- break;
- case ')':
- /* treat as a bracket only if in money mode and first one */
- if(money && !rbracket_done) {
- char *p;
-
- sign_done = rbracket_done = TRUE;
- /* search back for a non-blank */
- for(p = mask; --p >= root && *p == ' '; )
- ;
- *mask = ' ';
- *++p = negative ? mc : ' ';
- }
- break;
- case '+':
- case '-':
- /* treat as a sign only if this is the first one encountered */
- if (!sign_done
- /* next line allows non-sign + or - inside a num eg. ZZZ-ZZZZ */
- && ( *(mask-1) == '\0' || *(mask+1) == '\0' )
- ) {
- char *p;
-
- sign_done = TRUE;
- /* search back for a non-blank */
- for(p = mask; --p >= root && *p == ' '; )
- ;
- *mask = ' ';
- *++p = negative ? '-' : ((mc == '+') ? '+' : ' ');
- }
- break;
- case ',':
- /* don't want to delete comma if there is going to be a zero */
- if(*num == '\0' && (mask[1] == 'z' || mask[1] == 'Z'))
- *mask = ' ';
- break;
- default:
- /* simply leave the character as is */
- break;
- }
- ++mask;
- }
-
- /* return next character in number; this is used to detect overflow */
- return(*num);
- } /* fmtwd */
-
- /* not a very general function, but it's only used in this file */
- static void reverse(str)
- char *str;
- {
- char tmp, *estr;
- for (estr = str + strlen(str) - 1; estr > str; estr--, str++) {
- tmp = *estr;
- *estr = *str;
- *str = tmp;
- }
- } /* reverse */
-
-