|
|
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.