Annotation of coherent/a/usr/src/misc/picture.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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