File:  [MW Coherent from dump] / coherent / a / usr / src / misc / picture.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:34 2019 UTC (7 years ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/*
 *	Let's C Version 4.0.16.
 *	Copyright (c) 1982-1988 by Mark Williams Company, Chicago.
 *	All rights reserved. May not be copied or disclosed without permission.
 */

/*
 * The picture() function is designed to give C users the same
 * numeric formatting ability as COBOL and BASIC users. 
 *
 * When compiled with -DTEST picture.c builds its own test stream.
 * The various options of picture() are illustrated by the test stream
 * in main().
 * Who says self documenting programs are a myth?
 */
#include "stdio.h"
#include "math.h"
extern char *index();
static int dmod10();

/*
 * Format double precision number. Return any overflow.
 */
double
picture (dble, format, output )
double dble;	/* the number to format */
char  *format;	/* the format mask */
char  *output;	/* the output area. Must be at least as large as format */
{
	register int i, plus = 1;
	register char *outp, tmp;
	double numb = dble;
	char *sig, *j;

	if (dble < 0.0) {
		numb = -dble;
		plus = 0;
	} 

	if (outp = index(format, '.'))	/* if . in format adjust number */
		for(; *outp != '\000'; outp++)
			switch ( *outp ) {
				case '9' :
				case 'Z' :
				case 'J' :
				case 'K' :
				case 'S' :
				case 'T' :
					numb *= 10.0;
			}
	numb += 0.5;		/* round number */

	 /* scan backward for slot */
	for(i = strlen(format), output[i--] = '\000'; i >= 0; i--) {
		outp = &output[i];
		switch ( tmp=format[i] ) {
			case '+' :
				*outp = plus ? '+' : '-';
				continue;
			case 'T' :
			case 'S' :
			case 'J' :
			case 'K' :
			case '9' :
			case 'Z' :
				break;
			default:
				*outp = plus ? ' ' : tmp;
				continue;
		} /* switch */
		break;
	} /* for */

	/* build output string */
	for (sig = output - 1; i >= 0; i--) {
		outp = &output[i];
		switch ( tmp=format[i] ) {
			case '9' :	/* slot for number */
				*outp = dmod10(&numb);
				sig = outp - 1;
				break;
			case 'Z' :	/* lead zero suppress */
				if (numb >= 1.0) {
					*outp = dmod10(&numb);
					sig = outp - 1;
				}
				else
					*outp = ' ';
				break;
			case 'J' :	/* lead zero shirnk */
				if (numb >= 1.0) {
					*outp = dmod10(&numb);
					sig = outp - 1;
				}
				else {
					sig--;
					strcpy(outp, (outp + 1));
				}
				break;
			case 'K' :	/* all zero shrink */
				*outp = dmod10(&numb);
				if ( *outp == '0' ) {
					sig--;
					strcpy(outp, (outp + 1));
				}
				else
					sig = outp - 1;
				break;
			case 'T' :	/* suppress trailing zeros */
				*outp = dmod10(&numb);
				if(*outp != '0' || sig >= output )
					sig = outp - 1;
				else
					*outp = ' ';
				break;
			case 'S' :	/* shrink trailing zeros */
				*outp = dmod10(&numb);
				if(*outp != '0' || sig >= output )
					sig = outp - 1;
				else
					strcpy(outp, (outp + 1));
				break;
			case '$' :	/* floating $ */
				*outp = ' ';
				if (sig >= output)
					*sig-- = '$';
				break;
			case '-' :	/* floating lead - */
			case '(' :	/* floating lead ( */
				*outp = ' ';
				if (sig >= output && !plus )
					*sig-- = tmp;
				break;
			case '+' :	/* floating lead + or - */
				*outp = ' ';
				if (sig >= output)
					*sig-- = plus ? '+' : '-';
				break;
			case '*' :	/* * fill */
				*outp = '*';
				for (j = outp+1; *j == ' ';)
					*j++ = '*';
				break;
			case '.' :	/* decimal point */
				*outp = '.';
				break;
			default :
				*outp = (numb >= 1.0) ? tmp: ' ';
		}	/* switch */
	}	/* for */

	return (numb >= 1.0) ? (plus ? floor(numb) : -floor(numb)) : 0.0;
}

/*
 * return low order decimal number of argument.
 * divide argument by 10.
 */
static int
dmod10(numb)
register double *numb;
{
	int wrk;
	double tmp;

	if (*numb >= 10.0) {
		wrk = *numb - (floor(tmp = (*numb / 10.0)) * 10.0 );
		*numb = tmp;
	}
	else {
		wrk = *numb;
		*numb = 0.0;
	}
	return(wrk + '0');
}

#ifdef TEST
static int    test_no;

/*
 * Run picture and check the results.
 */
verify(mask, number, expect, oflow, descr)
char *mask;	/* format mask for picturre */
double number;	/* number to format */
char *expect;	/* expected result of format */
double oflow;	/* expected overflow */
char *descr;	/* description */
{
	char   result[20];
	double ret;

	test_no++;
	if(descr != NULL)
		printf("\n%s\n", descr);
	printf("%10.3f passed through a mask of '%s' gives '%s'\n",
		number, mask, expect);
	if((int)oflow)
		printf("    With an overflow of %-3.1f\n", oflow);
	ret = picture(number, mask, result);
	if((int)(ret - oflow))
		printf("Expected oflow\t%e\ngot\t\t%e\ttest %d\n",
			oflow, ret, test_no);
	if(strcmp(result, expect))
		printf("Expected\t'%s'\ngot\t\t'%s'\ttest %d\n",
			expect, result, test_no);
}

main()
{
   printf("The picture() function is designed to give C users the same\n");
   printf("numeric formatting ability as COBOL and BASIC users. \n\n");
   printf("double\n");
   printf("picture (dble, format, output )\n");
   printf("double dble;    /* the number to format */\n");
   printf("char  *format;  /* the format mask */\n");
   printf("char  *output;  /* the output area. Must be at least as large as format */\n");

	verify("999 CR",	   5.0,	"005   ",	0.0,
	  "9    Provides a slot for a number.");
	verify("999 CR",	  -5.0,	"005 CR",	0.0, NULL);
   printf(" Note: C & R are not special to picture. Trailing non special\n");
   printf("       characters print only if the number is negitave\n");

	verify("ZZZ,ZZZ",	1034.0,	"  1,034",	0.0,
	  "Z    Provides a slot for a number but supresses lead zeros.");
   printf(" Note: comma is not special to picture. Imbeded non special\n");
   printf("       characters print only if preceeded by significant digits\n");
	verify("JJJ,JJJ",	1034.0,	"1,034",	0.0,
	  "J    Provides a slot for a number but shrinks out lead zeros.");

	verify("K9/K9/K9",     70884.0,	"7/8/84",	0.0,
	  "K    Provides a slot for a number but shrinks out any zeros.");

	verify("$ZZZ,ZZZ",	105.0,	"    $105",	0.0,
	   "$    Floats a dollar sign to the front of the displayed number.");

	verify("Z,ZZZ.999",	105.67,	"  105.670",	0.0,
	   ".    Separates the number between decimal and integer portions.");

	verify("Z,ZZ9.9TT",	105.67,	"  105.67 ",	0.0,
	   "T    Provides a slot for a number but supresses trailing zeros.");

	verify("Z,ZZ9.9SS",	105.67,	"  105.67",	0.0,
	   "S    Provides a slot for a number but shrinks out trailing zeros.");

	verify("-Z,ZZZ",	105.0,	"   105",	0.0,
	   "-    Floats a - infront of negitive numbers");
	verify("-Z,ZZZ",       -105.0,	"  -105",	0.0, NULL);

	verify("(ZZZ)",		105.0,	" 105 ",	0.0,
		"(    Acts like - but prints a (");
	verify("(ZZZ)",		 -5.0,	"  (5)",	0.0, NULL);

	verify("+ZZZ",		  5.0,	"  +5",		0.0,
	   "+    Floats a + or - infront of the number depending on its sign");
	verify("+ZZZ",		 -5.0,	"  -5",		0.0, NULL);

	verify("*ZZZ,ZZZ.99",	104.10,	"*****104.10",	0.0,
	   "*    Fills all lead spaces to its right");
	verify("*$ZZZ,ZZZ.99",	104.10,	"*****$104.10",	0.0, NULL);

	verify("(ZZZ)",	      -1234.0,	"(234)",       -1.0,
	   "Any overflow is returned by picture as a double precision number.");
	verify("99",		123.4,	"23",		1.0, NULL);
	verify("ZZ",	       1200.0,	"00",	       12.0, NULL);
}
#endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.