Annotation of coherent/d/bin/nroff/expr.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * expr.c
                      3:  * Nroff/Troff.
                      4:  * Expression reader.
                      5:  */
                      6: 
                      7: #include <ctype.h>
                      8: #include "roff.h"
                      9: 
                     10: /* Local variables. */
                     11: static int     experr;                 /* Got an error */
                     12: static int     expmul;                 /* Default unit multiplier */
                     13: static int     expdiv;                 /* Default unit divisor */
                     14: static char    *expp;                  /* Pointer in expression */
                     15: 
                     16: /*
                     17:  * Return the int value of an expression.
                     18:  * Given:
                     19:  *     Name    Description                             Used
                     20:  *     str     string containing an expression
                     21:  *     mul/div default unit multiplier, divisor        if no unit given
                     22:  *     num     initial value                           if leading sign
                     23:  *     hvf     horizontal/vertical flag                if initial '|'
                     24:  *     def     default value                           if no expression
                     25:  * The expression is evaluated from left to right with no priorites
                     26:  * except parentheses.
                     27:  */
                     28: int
                     29: number(str, mul, div, num, hvf, def) char *str; long mul, div; int num, hvf, def;
                     30: {
                     31:        register int n, c;
                     32: 
                     33:        expp = str;
                     34:        expmul = mul;
                     35:        expdiv = div;
                     36:        experr = 0;
                     37:        while (isascii(*expp) && isspace(*expp))
                     38:                expp++;
                     39:        if ((c = *expp) == '\0')
                     40:                return def;
                     41:        if (index("+-|", *expp))
                     42:                ++expp;
                     43:        n = expseq();
                     44:        if (*expp != '\0')
                     45:                experr++;
                     46:        if (experr) {
                     47:                printe("syntax error");
                     48:                return 0;
                     49:        }
                     50:        switch (c) {
                     51:        case '+':
                     52:                n = num + n;
                     53:                break;
                     54:        case '-':
                     55:                n = num - n;
                     56:                break;
                     57:        case '|':
                     58:                n -= hvf ? cdivp->d_rpos : nlinsiz;
                     59:                break;
                     60:        }
                     61:        return n;
                     62: }
                     63: 
                     64: /*
                     65:  * Like number(), but fewer args, for efficiency.
                     66:  */
                     67: int
                     68: numb(str, mul, div) char *str; long mul, div;
                     69: {
                     70:        return number(str, mul, div, 0, 0, 0);
                     71: }
                     72: 
                     73: /*
                     74:  * Compute an expression sequence.
                     75:  */
                     76: expseq()
                     77: {
                     78:        register int n1, n2, c;
                     79: 
                     80:        n1 = expval();
                     81:        if (experr)
                     82:                return 0;
                     83:        for (;;) {
                     84:                while ((c = *expp++)==' ' || c == '\t')
                     85:                        ;
                     86:                switch (c) {
                     87:                case '<':
                     88:                        if (*expp == '=') {
                     89:                                expp++;
                     90:                                c = 'l';
                     91:                        }
                     92:                        break;
                     93:                case '>':
                     94:                        if (*expp == '=') {
                     95:                                expp++;
                     96:                                c = 'g';
                     97:                        }
                     98:                        break;
                     99:                case '=':
                    100:                        if (*expp == '=')
                    101:                                expp++;
                    102:                        break;
                    103:                default:
                    104:                        if ((c != 0) && index("+-/*%&:", c))
                    105:                                break;
                    106:                        --expp;
                    107:                        return n1;
                    108:                }
                    109:                n2 = expval();
                    110:                if (experr)
                    111:                        return 0;
                    112:                switch (c) {
                    113:                case '+':
                    114:                        n1 += n2;
                    115:                        break;
                    116:                case '-':
                    117:                        n1 -= n2;
                    118:                        break;
                    119:                case '*':
                    120:                        n1 *= n2;
                    121:                        break;
                    122:                case '/':
                    123:                        if (n2 == 0) {
                    124:                                printe("attempted zero divide");
                    125:                                experr++;
                    126:                                return 0;
                    127:                        }
                    128:                        n1 /= n2;
                    129:                        break;
                    130:                case '%':
                    131:                        if (n2 == 0) {
                    132:                                printe("attempted zero modulus");
                    133:                                experr++;
                    134:                                return 0;
                    135:                        }
                    136:                        n1 %= n2;
                    137:                        break;
                    138:                case '<':
                    139:                        n1 = n1 < n2;
                    140:                        break;
                    141:                case '>':
                    142:                        n1 = n1 > n2;
                    143:                        break;
                    144:                case 'l':
                    145:                        n1 = n1 <= n2;
                    146:                        break;
                    147:                case 'g':
                    148:                        n1 = n1 >= n2;
                    149:                        break;
                    150:                case '=':
                    151:                        n1 = n1 == n2;
                    152:                        break;
                    153:                case '!':
                    154:                        n1 = n1 != n2;
                    155:                        break;
                    156:                case '&':
                    157:                        n1 = n1 && n2;
                    158:                        break;
                    159:                case ':':
                    160:                        n1 = n1 || n2;
                    161:                        break;
                    162:                }
                    163:        }
                    164: }
                    165: 
                    166: /*
                    167:  * Get an operand.
                    168:  */
                    169: expval()
                    170: {
                    171:        long mul, div, m, d;
                    172:        register int n, c, s;
                    173: 
                    174:        while (isascii(c = *expp++) && isspace(c))
                    175:                ;
                    176:        if (c == '(') {
                    177:                n = expseq();
                    178:                if (*expp++ != ')') {
                    179:                        --expp;
                    180:                        experr++;
                    181:                        n = 0;
                    182:                }
                    183:                return n;
                    184:        }
                    185:        for (s = 1; c == '-'; c = *expp++)
                    186:                s = -s;
                    187:        for (m = 0; isascii(c) && isdigit(c); c = *expp++)
                    188:                m = m * 10 + c - '0';
                    189:        d = 1;
                    190:        if (c == '.') {
                    191:                while (isascii(c = *expp++) && isdigit(c)) {
                    192:                        m = m * 10 + c - '0';
                    193:                        d *= 10;
                    194:                }
                    195:        }
                    196:        switch (c) {
                    197:        case 'i':
                    198:                mul = SMINCH;
                    199:                div = SDINCH;
                    200:                break;
                    201:        case 'c':
                    202:                mul = SMCENT;
                    203:                div = SDCENT;
                    204:                break;
                    205:        case 'P':
                    206:                mul = SMPICA;
                    207:                div = SDPICA;
                    208:                break;
                    209:        case 'm':
                    210:                mul = SMEMSP;
                    211:                div = SDEMSP;
                    212:                break;
                    213:        case 'n':
                    214:                mul = SMENSP;
                    215:                div = SDENSP;
                    216:                break;
                    217:        case 'p':
                    218:                mul = SMPOIN;
                    219:                div = SDPOIN;
                    220:                break;
                    221:        case 'u':
                    222:                mul = SMUNIT;
                    223:                div = SDUNIT;
                    224:                break;
                    225:        case 'v':
                    226:                mul = SMVLSP;
                    227:                div = SDVLSP;
                    228:                break;
                    229:        default:
                    230:                --expp;
                    231:                mul = expmul;
                    232:                div = expdiv;
                    233:        }
                    234:        while (isascii(c = *expp) && isalpha(c))
                    235:                expp++;
                    236:        return unit(s*m*mul, d*div);
                    237: }
                    238: 
                    239: /*
                    240:  * Given a long numerator and denominator, divide the numerator by
                    241:  * the denominator and return an int.
                    242:  */
                    243: int
                    244: unit(mul, div) long mul, div;
                    245: {
                    246:        return ((div == 1) ? ((int) mul) : ((int) (mul/div)));
                    247: }
                    248: 
                    249: /* end of expr.c */

unix.superglobalmegacorp.com

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