home *** CD-ROM | disk | FTP | other *** search
- /*********
- * Function: TOMONEY
- * By: Tom Rettig
- *
- * Placed in the public domain by Tom Rettig Associates, 10/22/1990.
- *
- * Syntax: TOMONEY( <expN> )
- * Return: <expC> "... dollars, and ... cents"
- * Null string if passed invalid parameter.
- * Asterisks if passed too large a number.
- * Note..: Rounds to two decimal places.
- * Return string length varies in size.
- ********/
-
- #include "trlib.h"
-
- TRTYPE tomoney()
- {
- static char *units[] =
- { "NO",
- "ONE", "TWO", "THREE", "FOUR", "FIVE",
- "SIX", "SEVEN", "EIGHT", "NINE", "TEN",
- "ELEVEN", "TWELVE", "THIRTEEN", "FOURTEEN", "FIFTEEN",
- "SIXTEEN", "SEVENTEEN", "EIGHTEEN", "NINETEEN"
- };
- static char *teens[] =
- { " ", /*space*/
- "TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY",
- "SIXTY", "SEVENTY", "EIGHTY", "NINETY", " HUNDRED"
- };
- static char *magnitude[] =
- { "", /*unused null*/
- " THOUSAND", " MILLION", " BILLION",
- " TRILLION", " QUADRILLION", " QUINTILLION"
- };
- static char *misc[] =
- { " and ",
- HYPHEN, ", ", " DOLLAR", " DOLLARS", " CENT", " CENTS"
- };
- static char funcname[] = { "tomoney" };
- char *aptr[PTRMAX]; /* array of pointers to word strings */
- int i, magi; /* indexes into aptr[i] and magnitude[magi] arrays */
- char *instr, *pos, *hold; /* input pointers */
- char *ret, *iret, *p; /* output pointers */
- int allzero, zeroflag, iszero; /* flags for zero values */
- double temp;
-
- if ( PCOUNT == 1 && ISNUM(1) )
- {
- /* allocate memory for input and output buffers */
- instr = _tr_allocmem( (unsigned) (INPUTMAX+1));
- if ( !instr )
- {
- _retc( _tr_errmsgs(funcname,E_ALLOC) );
- return;
- }
- ret = _tr_allocmem( (unsigned) (OUTPUTMAX+1));
- if ( !ret )
- {
- _tr_freemem( instr,(unsigned)INPUTMAX+1);
- _retc( _tr_errmsgs(funcname,E_ALLOC) );
- return;
- }
- hold = instr;
- /* internal "numeric to ascii": */
- /* _tr_ntoa( (double)param, (int)len, (int)decimals, (char *)output ) */
- temp = _parnd(1);
- temp = _tr_fabs(temp);
- _tr_ntoa( temp, INPUTMAX, DECIMAX, instr );
-
- if ( *instr == '*' )
- {
- _retc( NUM_OVRFLW ); /* return asterisks if overflow */
- _tr_freemem( hold,(unsigned)INPUTMAX+1); /* free instr */
- _tr_freemem( ret,(unsigned)OUTPUTMAX+1);
- return;
- }
-
- /* point to first digit, and find decimal point */
- while ( *instr == SPACEC)
- instr++;
- pos = instr;
- while ( *pos!=DECPOINT && *pos )
- pos++;
-
- /* set pointers to each word, going from least significant digit to most */
- i = 0;
- if ( pos[2] == '1' && pos[1] == ZEROC ) /* one cent */
- aptr[i++] = misc[5]; /* " CENT" */
- else
- aptr[i++] = misc[6]; /* " CENTS" */
-
- /* cents digits */
- if ( pos[2] == ZEROC && pos[1] == ZEROC ) /* zero cents */
- aptr[i++] = units[0]; /* "NO" */
- else
- aptr[i++] = pos+1; /* cents string of digits */
-
- /* separate dollars from cents */
- aptr[i++] = misc[0]; /* " and " */
-
- if ( pos[-1] == '1' && pos == instr+1 ) /* one dollar */
- aptr[i++] = misc[3]; /* " DOLLAR" */
- else
- aptr[i++] = misc[4]; /* " DOLLARS" */
-
- if ( pos[-1] == ZEROC && pos == instr+1 ) /* zero dollars */
- aptr[i++] = units[0]; /* "NO" */
- else
- {
- allzero = TRUE; /* scope of all magnitudes */
- zeroflag = TRUE; /* scope of previous and current magnitudes */
- iszero = TRUE; /* scope of current magnitude only */
-
- /* loop through each magnitude of three digits until done */
- for ( magi=0; pos>instr; pos+=(-3), magi++ )
- {
- /* zero flag settings */
- if ( zeroflag && !iszero )
- zeroflag = allzero = FALSE;
- iszero = ( pos[-1]==ZEROC && pos[-2]==ZEROC && pos[-3]==ZEROC );
- if ( !zeroflag && iszero )
- zeroflag = TRUE;
-
- /* magnitude */
- if ( magi && !iszero )
- {
- if ( !zeroflag || !allzero )
- aptr[i++] = misc[2]; /* magnitude delimiter */
- aptr[i++] = magnitude[magi];
- }
-
- /* units and teens values */
- if ( pos[-1] > ZEROC )
- {
- if ( (pos[-2] == ZEROC || pos < instr+2) )
- aptr[i++] = units[ ONES(pos) ];
- else if ( pos[-2] == '1' )
- aptr[i++] = units[ (TENS(pos)*10) + ONES(pos) ];
- else if ( pos[-2] > '1' && pos >= instr+2 )
- {
- aptr[i++] = units[ ONES(pos) ];
- aptr[i++] = misc[1]; /* HYPHEN */
- aptr[i++] = teens[ TENS(pos) ];
- }
- }
- else if ( pos[-2] > ZEROC && pos >= instr+2 )
- aptr[i++] = teens[ TENS(pos) ];
-
- /* hundreds value */
- if ( pos[-3] > ZEROC && pos >= instr+2 )
- {
- if ( pos[-2] > ZEROC || pos[-1] > ZEROC )
- aptr[i++] = teens[0]; /* " " */
- aptr[i++] = teens[10]; /* " HUNDRED" */
- aptr[i++] = units[ HUNS(pos) ];
- }
- } /* endwhile */
- } /* endif */
-
- /* concatenate word pointers into one string and store in output buffer */
- iret = ret;
- i--;
- while ( i >= 0 )
- {
- p = aptr[i--];
- while ( *p )
- *iret++ = *p++;
- }
- *iret = NULLC;
-
- _retc( ret );
- _tr_freemem( hold,(unsigned)INPUTMAX+1 ); /*free instr*/
- _tr_freemem( ret,(unsigned)OUTPUTMAX+1 );
- }
- else
- _retc( _tr_errmsgs(funcname,E_SYNTAX) );
- }
- /* eof */
-
-