Annotation of coherent/b/bin/troff/expr.c, revision 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.