|
|
1.1 ! root 1: /* ! 2: * Let's C Version 4.0.16. ! 3: * Copyright (c) 1982-1988 by Mark Williams Company, Chicago. ! 4: * All rights reserved. May not be copied or disclosed without permission. ! 5: */ ! 6: ! 7: /* ! 8: * The picture() function is designed to give C users the same ! 9: * numeric formatting ability as COBOL and BASIC users. ! 10: * ! 11: * When compiled with -DTEST picture.c builds its own test stream. ! 12: * The various options of picture() are illustrated by the test stream ! 13: * in main(). ! 14: * Who says self documenting programs are a myth? ! 15: */ ! 16: #include "stdio.h" ! 17: #include "math.h" ! 18: extern char *index(); ! 19: static int dmod10(); ! 20: ! 21: /* ! 22: * Format double precision number. Return any overflow. ! 23: */ ! 24: double ! 25: picture (dble, format, output ) ! 26: double dble; /* the number to format */ ! 27: char *format; /* the format mask */ ! 28: char *output; /* the output area. Must be at least as large as format */ ! 29: { ! 30: register int i, plus = 1; ! 31: register char *outp, tmp; ! 32: double numb = dble; ! 33: char *sig, *j; ! 34: ! 35: if (dble < 0.0) { ! 36: numb = -dble; ! 37: plus = 0; ! 38: } ! 39: ! 40: if (outp = index(format, '.')) /* if . in format adjust number */ ! 41: for (; *outp != '\000'; outp++) ! 42: switch ( *outp ) { ! 43: case '9' : ! 44: case 'Z' : ! 45: case 'J' : ! 46: case 'K' : ! 47: case 'S' : ! 48: case 'T' : ! 49: numb *= 10.0; ! 50: } ! 51: numb += 0.5; /* round number */ ! 52: ! 53: /* scan backward for slot */ ! 54: for (i = strlen(format), output[i--] = '\000'; i >= 0; i--) { ! 55: outp = &output[i]; ! 56: switch ( tmp=format[i] ) { ! 57: case '+' : ! 58: *outp = plus ? '+' : '-'; ! 59: continue; ! 60: case 'T' : ! 61: case 'S' : ! 62: case 'J' : ! 63: case 'K' : ! 64: case '9' : ! 65: case 'Z' : ! 66: break; ! 67: default: ! 68: *outp = plus ? ' ' : tmp; ! 69: continue; ! 70: } /* switch */ ! 71: break; ! 72: } /* for */ ! 73: ! 74: /* build output string */ ! 75: for (sig = output - 1; i >= 0; i--) { ! 76: outp = &output[i]; ! 77: switch ( tmp=format[i] ) { ! 78: case '9' : /* slot for number */ ! 79: *outp = dmod10(&numb); ! 80: sig = outp - 1; ! 81: break; ! 82: case 'Z' : /* lead zero suppress */ ! 83: if (numb >= 1.0) { ! 84: *outp = dmod10(&numb); ! 85: sig = outp - 1; ! 86: } ! 87: else ! 88: *outp = ' '; ! 89: break; ! 90: case 'J' : /* lead zero shirnk */ ! 91: if (numb >= 1.0) { ! 92: *outp = dmod10(&numb); ! 93: sig = outp - 1; ! 94: } ! 95: else { ! 96: sig--; ! 97: strcpy(outp, (outp + 1)); ! 98: } ! 99: break; ! 100: case 'K' : /* all zero shrink */ ! 101: *outp = dmod10(&numb); ! 102: if ( *outp == '0' ) { ! 103: sig--; ! 104: strcpy(outp, (outp + 1)); ! 105: } ! 106: else ! 107: sig = outp - 1; ! 108: break; ! 109: case 'T' : /* suppress trailing zeros */ ! 110: *outp = dmod10(&numb); ! 111: if (*outp != '0' || sig >= output ) ! 112: sig = outp - 1; ! 113: else ! 114: *outp = ' '; ! 115: break; ! 116: case 'S' : /* shrink trailing zeros */ ! 117: *outp = dmod10(&numb); ! 118: if (*outp != '0' || sig >= output ) ! 119: sig = outp - 1; ! 120: else ! 121: strcpy(outp, (outp + 1)); ! 122: break; ! 123: case '$' : /* floating $ */ ! 124: *outp = ' '; ! 125: if (sig >= output) ! 126: *sig-- = '$'; ! 127: break; ! 128: case '-' : /* floating lead - */ ! 129: case '(' : /* floating lead ( */ ! 130: *outp = ' '; ! 131: if (sig >= output && !plus ) ! 132: *sig-- = tmp; ! 133: break; ! 134: case '+' : /* floating lead + or - */ ! 135: *outp = ' '; ! 136: if (sig >= output) ! 137: *sig-- = plus ? '+' : '-'; ! 138: break; ! 139: case '*' : /* * fill */ ! 140: *outp = '*'; ! 141: for (j = outp+1; *j == ' ';) ! 142: *j++ = '*'; ! 143: break; ! 144: case '.' : /* decimal point */ ! 145: *outp = '.'; ! 146: break; ! 147: default : ! 148: *outp = (numb >= 1.0) ? tmp: ' '; ! 149: } /* switch */ ! 150: } /* for */ ! 151: ! 152: return (numb >= 1.0) ? (plus ? floor(numb) : -floor(numb)) : 0.0; ! 153: } ! 154: ! 155: /* ! 156: * return low order decimal number of argument. ! 157: * divide argument by 10. ! 158: */ ! 159: static int ! 160: dmod10(numb) ! 161: register double *numb; ! 162: { ! 163: int wrk; ! 164: double tmp; ! 165: ! 166: if (*numb >= 10.0) { ! 167: wrk = *numb - (floor(tmp = (*numb / 10.0)) * 10.0 ); ! 168: *numb = tmp; ! 169: } ! 170: else { ! 171: wrk = *numb; ! 172: *numb = 0.0; ! 173: } ! 174: return (wrk + '0'); ! 175: } ! 176: ! 177: #ifdef TEST ! 178: static int test_no; ! 179: ! 180: /* ! 181: * Run picture and check the results. ! 182: */ ! 183: verify(mask, number, expect, oflow, descr) ! 184: char *mask; /* format mask for picturre */ ! 185: double number; /* number to format */ ! 186: char *expect; /* expected result of format */ ! 187: double oflow; /* expected overflow */ ! 188: char *descr; /* description */ ! 189: { ! 190: char result[20]; ! 191: double ret; ! 192: ! 193: test_no++; ! 194: if (descr != NULL) ! 195: printf("\n%s\n", descr); ! 196: printf("%10.3f passed through a mask of '%s' gives '%s'\n", ! 197: number, mask, expect); ! 198: if ((int)oflow) ! 199: printf(" With an overflow of %-3.1f\n", oflow); ! 200: ret = picture(number, mask, result); ! 201: if ((int)(ret - oflow)) ! 202: printf("Expected oflow\t%e\ngot\t\t%e\ttest %d\n", ! 203: oflow, ret, test_no); ! 204: if (strcmp(result, expect)) ! 205: printf("Expected\t'%s'\ngot\t\t'%s'\ttest %d\n", ! 206: expect, result, test_no); ! 207: } ! 208: ! 209: main() ! 210: { ! 211: printf("The picture() function is designed to give C users the same\n"); ! 212: printf("numeric formatting ability as COBOL and BASIC users. \n\n"); ! 213: printf("double\n"); ! 214: printf("picture (dble, format, output )\n"); ! 215: printf("double dble; /* the number to format */\n"); ! 216: printf("char *format; /* the format mask */\n"); ! 217: printf("char *output; /* the output area. Must be at least as large as format */\n"); ! 218: ! 219: verify("999 CR", 5.0, "005 ", 0.0, ! 220: "9 Provides a slot for a number."); ! 221: verify("999 CR", -5.0, "005 CR", 0.0, NULL); ! 222: printf(" Note: C & R are not special to picture. Trailing non special\n"); ! 223: printf(" characters print only if the number is negitave\n"); ! 224: ! 225: verify("ZZZ,ZZZ", 1034.0, " 1,034", 0.0, ! 226: "Z Provides a slot for a number but supresses lead zeros."); ! 227: printf(" Note: comma is not special to picture. Imbeded non special\n"); ! 228: printf(" characters print only if preceeded by significant digits\n"); ! 229: verify("JJJ,JJJ", 1034.0, "1,034", 0.0, ! 230: "J Provides a slot for a number but shrinks out lead zeros."); ! 231: ! 232: verify("K9/K9/K9", 70884.0, "7/8/84", 0.0, ! 233: "K Provides a slot for a number but shrinks out any zeros."); ! 234: ! 235: verify("$ZZZ,ZZZ", 105.0, " $105", 0.0, ! 236: "$ Floats a dollar sign to the front of the displayed number."); ! 237: ! 238: verify("Z,ZZZ.999", 105.67, " 105.670", 0.0, ! 239: ". Separates the number between decimal and integer portions."); ! 240: ! 241: verify("Z,ZZ9.9TT", 105.67, " 105.67 ", 0.0, ! 242: "T Provides a slot for a number but supresses trailing zeros."); ! 243: ! 244: verify("Z,ZZ9.9SS", 105.67, " 105.67", 0.0, ! 245: "S Provides a slot for a number but shrinks out trailing zeros."); ! 246: ! 247: verify("-Z,ZZZ", 105.0, " 105", 0.0, ! 248: "- Floats a - infront of negitive numbers"); ! 249: verify("-Z,ZZZ", -105.0, " -105", 0.0, NULL); ! 250: ! 251: verify("(ZZZ)", 105.0, " 105 ", 0.0, ! 252: "( Acts like - but prints a ("); ! 253: verify("(ZZZ)", -5.0, " (5)", 0.0, NULL); ! 254: ! 255: verify("+ZZZ", 5.0, " +5", 0.0, ! 256: "+ Floats a + or - infront of the number depending on its sign"); ! 257: verify("+ZZZ", -5.0, " -5", 0.0, NULL); ! 258: ! 259: verify("*ZZZ,ZZZ.99", 104.10, "*****104.10", 0.0, ! 260: "* Fills all lead spaces to its right"); ! 261: verify("*$ZZZ,ZZZ.99", 104.10, "*****$104.10", 0.0, NULL); ! 262: ! 263: verify("(ZZZ)", -1234.0, "(234)", -1.0, ! 264: "Any overflow is returned by picture as a double precision number."); ! 265: verify("99", 123.4, "23", 1.0, NULL); ! 266: verify("ZZ", 1200.0, "00", 12.0, NULL); ! 267: } ! 268: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.