|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include "ctype.h" ! 3: #include "typedef.h" ! 4: #include "basic.h" ! 5: #include "tokens.h" ! 6: ! 7: #define MAXRAND 2147483647 ! 8: ! 9: double sqrt(), exp(), log(), atan(), sin(), cos(), fabs(); ! 10: double popfloat(), cvtnumber(); ! 11: static char str[MAXSTRING]; ! 12: Stkptr pop(), pushstring(); ! 13: char *allocstr(), *fprint(), *strpop(); ! 14: ! 15: ! 16: /* ! 17: * function --- interpret builtin function calls ! 18: */ ! 19: ! 20: function() ! 21: { ! 22: switch (*inptr) { ! 23: case LEFT: ! 24: fnarg("si"); ! 25: break; ! 26: case RIGHT: ! 27: fnarg("si"); ! 28: break; ! 29: case MID: ! 30: fnarg("sii"); ! 31: break; ! 32: case UPSHIFT: ! 33: case UNBLANK: ! 34: case SYSTEM: ! 35: case LEN: ! 36: case VAL: ! 37: case ASCII: ! 38: fnarg("s"); ! 39: break; ! 40: case RND: ! 41: case ARG: ! 42: case CHR: ! 43: case RAND: ! 44: fnarg("i"); ! 45: break; ! 46: case SIN: ! 47: case COS: ! 48: case TAN: ! 49: case ATN: ! 50: case SQR: ! 51: case EXPFN: ! 52: case LOG: ! 53: case INTFN: ! 54: case ABS: ! 55: case STR: ! 56: case SGN: ! 57: fnarg("f"); ! 58: break; ! 59: default: ! 60: return(0); ! 61: } ! 62: return(1); ! 63: } ! 64: ! 65: ! 66: /* ! 67: * fnarg --- do type checking and evaluation of builtin functions ! 68: */ ! 69: ! 70: fnarg(args) ! 71: char *args; ! 72: { ! 73: register int op, i; ! 74: register Stkptr s; ! 75: register char *q; ! 76: char *p; ! 77: double x, t; ! 78: int k, nc, n, ch, len; ! 79: ! 80: op = *inptr++; ! 81: for (p = args; *p; ) { ! 82: expr(); ! 83: switch (*p++) { ! 84: ! 85: case 's': ! 86: if (((Stkptr)stkptr)->k_type != STRINGEXPR) ! 87: err("string argument required"); ! 88: break; ! 89: case 'i': ! 90: case 'f': ! 91: if (((Stkptr)stkptr)->k_type != FLOATEXPR) ! 92: err("numeric argument required"); ! 93: break; ! 94: default: ! 95: badtype(); ! 96: } ! 97: if (*p) ! 98: expectc(COMMA); ! 99: } ! 100: expectc(RPAR); ! 101: switch (op) { ! 102: case SYSTEM: ! 103: p = strpop(); /* got a string in UNIX format */ ! 104: i = exec("/bin/sh", "sh", "-c", p, 0); ! 105: pushint(i); ! 106: break; ! 107: case LEFT: ! 108: if ((i = popint()) < 0) ! 109: i = 0; ! 110: s = (Stkptr)stkptr; ! 111: if (i > s->k_un.k_str.s_len) ! 112: i = s->k_un.k_str.s_len; ! 113: n = 0; ! 114: goto common; ! 115: case RIGHT: ! 116: if ((i = popint()) < 0) ! 117: i = 0; ! 118: s = (Stkptr)stkptr; ! 119: if (i > s->k_un.k_str.s_len) ! 120: i = s->k_un.k_str.s_len; ! 121: n = s->k_un.k_str.s_len - i; ! 122: goto common; ! 123: case MID: ! 124: if ((i = popint()) < 0) ! 125: i = 0; ! 126: if ((n = popint() - 1) < 0) ! 127: n = 0; ! 128: s = (Stkptr)stkptr; ! 129: if (n > s->k_un.k_str.s_len) ! 130: n = s->k_un.k_str.s_len; ! 131: if (i > s->k_un.k_str.s_len - n) ! 132: i = s->k_un.k_str.s_len - n; ! 133: common: ! 134: if (n > 0 || i < s->k_un.k_str.s_len) { ! 135: if (isstring(s->k_un.k_str.s_ptr)) { ! 136: p = allocstr(NULL, i, 0); ! 137: if (i) ! 138: move(i, s->k_un.k_str.s_ptr+n, p); ! 139: s->k_un.k_str.s_ptr = p; ! 140: } ! 141: else ! 142: s->k_un.k_str.s_ptr += n; ! 143: s->k_un.k_str.s_len = i; ! 144: } ! 145: break; ! 146: case UPSHIFT: ! 147: p = strpop(); ! 148: len = strlen(p); ! 149: for (k = 0; k <= len; k++) ! 150: if (!isalpha(*(p+k)) || isupper(*(p+k))) ! 151: str[k] = p[k]; ! 152: else ! 153: str[k] = toupper(p[k]); ! 154: s = pushstring(str, len); ! 155: s->k_un.k_str.s_ptr = str; ! 156: s->k_un.k_str.s_len = len; ! 157: break; ! 158: case UNBLANK: ! 159: p = strpop(); ! 160: len = strlen(p); ! 161: for (k = nc = 0; k <= len; k++) ! 162: if (*(p+k) != ' ') ! 163: str[nc++] = p[k]; ! 164: s = pushstring(str, nc - 1); ! 165: s->k_un.k_str.s_ptr = str; ! 166: s->k_un.k_str.s_len = nc - 1; ! 167: break; ! 168: case LEN: ! 169: s = pop(ANYTYPE); ! 170: pushint(s->k_un.k_str.s_len); ! 171: break; ! 172: case CHR: ! 173: ch = popint(); ! 174: s = pushstring(&ch, 1); ! 175: s->k_un.k_str.s_ptr = allocstr(&ch, 1, 1); ! 176: break; ! 177: case STR: ! 178: p = fprint(popfloat()); ! 179: len = strlen(p); ! 180: s = pushstring(p, len); ! 181: s->k_un.k_str.s_ptr = allocstr(p, len, len); ! 182: break; ! 183: case ARG: ! 184: len = popint(); ! 185: p = (len > argcnt)? "" : argvec[len]; ! 186: len = strlen(p); ! 187: s = pushstring(p, len); ! 188: s->k_un.k_str.s_ptr = allocstr(p, len, len); ! 189: break; ! 190: case ASCII: ! 191: s = pop(ANYTYPE); ! 192: pushint(*s->k_un.k_str.s_ptr); ! 193: break; ! 194: case VAL: ! 195: s = pop(ANYTYPE); ! 196: p = q = s->k_un.k_str.s_ptr; ! 197: i = s->k_un.k_str.s_len; ! 198: pushfloat(cvtnumber(&p, i)); ! 199: if (p - q != i) ! 200: err("invalid number %.*s", i, q); ! 201: break; ! 202: case SIN: ! 203: pushfloat(sin(popfloat())); ! 204: break; ! 205: case COS: ! 206: pushfloat(cos(popfloat())); ! 207: break; ! 208: case TAN: ! 209: x = popfloat(); ! 210: pushfloat(sin(x)/cos(x)); ! 211: break; ! 212: case SGN: ! 213: x = popfloat(); ! 214: if (x > 0) ! 215: t = 1; ! 216: else ! 217: if (x < 0) ! 218: t = -1; ! 219: else ! 220: t = 0; ! 221: pushfloat(t); ! 222: break; ! 223: case SQR: ! 224: if ((x = popfloat()) >= 0) ! 225: pushfloat(sqrt(x)); ! 226: else ! 227: err("sqr of negatives undefined. check"); ! 228: break; ! 229: case LOG: ! 230: if ((x = popfloat()) != 0) ! 231: pushfloat(log(fabs(x))); ! 232: else ! 233: err("log of zero is undefined. check"); ! 234: break; ! 235: case EXPFN: ! 236: pushfloat(exp(popfloat())); ! 237: break; ! 238: case ATN: ! 239: pushfloat(atan(popfloat())); ! 240: break; ! 241: case ABS: ! 242: pushfloat(fabs(popfloat())); ! 243: break; ! 244: case INTFN: ! 245: pushfloat((double)(int)popfloat()); ! 246: break; ! 247: case RND: ! 248: if ((i = popint()) != 0) ! 249: srand(i); ! 250: pushfloat((double)rand() / MAXRAND); ! 251: break; ! 252: case RAND: ! 253: i = popint(); ! 254: srand((int)time(0) + i); ! 255: pushfloat(x = ((double)rand() / MAXRAND)); ! 256: break; ! 257: default: ! 258: err("function not found"); ! 259: } ! 260: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.