|
|
1.1 root 1: /*
2: * AWK -- built-in functions.
3: * The assumption is that awk will
4: * not call the functions if there
5: * is an argument mismatch to
6: * remove some checking from each of
7: * the common single level routines.
8: */
9:
10: #include "awk.h"
11: #include <math.h>
12: #include <sys/mdata.h>
13:
14: NODE *
15: f_length(np, na)
16: NODE *np;
17: int na;
18: {
19: register CHAR *s;
20:
21: if (na == 0)
22: s = inline; else
23: s = evalstring(np);
24: return (inode((INT)strlen(s)));
25: }
26:
27: /*
28: * Square root function.
29: */
30: NODE *
31: f_sqrt(np, na)
32: register NODE *np;
33: int na;
34: {
35: return (fnode((FLOAT)sqrt((double)evalfloat(np))));
36: }
37:
38: /*
39: * Natural logarithm function.
40: */
41: NODE *
42: f_log(np, na)
43: register NODE *np;
44: int na;
45: {
46: return (fnode((FLOAT)log((double)evalfloat(np))));
47: }
48:
49: /*
50: * Exponential function.
51: */
52: NODE *
53: f_exp(np, na)
54: register NODE *np;
55: int na;
56: {
57: return (fnode((FLOAT)exp((double)evalfloat(np))));
58: }
59:
60: /*
61: * Convert FLOAT to INT
62: */
63: NODE *
64: f_int(np, na)
65: register NODE *np;
66: int na;
67: {
68: return (inode((INT)evalfloat(np)));
69: }
70:
71: /*
72: * Substring function...
73: * substr(string, n, m)
74: * If `m' is missing, it is infinity.
75: * Return the string starting at position
76: * `n' (origin 1) of `string' for `m'
77: * (or end of string) characters.
78: */
79: NODE *
80: f_substr(np, na)
81: NODE *np;
82: int na;
83: {
84: register CHAR *cp;
85: register CHAR *ocp;
86: register unsigned m;
87: register unsigned n;
88: register CHAR *acp;
89:
90: m = MAXUINT;
91: if (na > 2)
92: m = evalint(fargn(np, 3));
93: n = evalint(fargn(np, 2));
94: cp = evalstring(fargn(np, 1));
95: while (--n != 0)
96: if (*cp == '\0')
97: break;
98: else
99: cp++;
100: n = strlen(cp);
101: if (n > m)
102: n = m;
103: acp = ocp = xalloc(n + sizeof(CHAR));
104: while (n--)
105: *ocp++ = *cp++;
106: *ocp = '\0';
107: return (snode(acp, T_ALLOC));
108: }
109:
110: /*
111: * String index match function...
112: * index(s1, s2)
113: * Return the position (origin 1) where `s2'
114: * is found in string `s1' or 0.
115: */
116: NODE *
117: f_index(np, na)
118: register NODE *np;
119: int na;
120: {
121: register CHAR *s1, *s2;
122: register CHAR *ss1;
123: register unsigned n;
124:
125: ss1 = s1 = evalstring(fargn(np, 1));
126: s2 = evalstring(fargn(np, 2));
127: n = strlen(s2);
128: for ( ; *s1 != '\0'; s1++)
129: if (strncmp(s1, s2, n) == 0)
130: return (inode((INT)(s1-ss1+1)));
131: return (&xzero);
132: }
133:
134: /*
135: * Printf onto a string function.
136: * Handled by special case in the `printf'
137: * keyword.
138: */
139: NODE *
140: f_sprintf(np, na)
141: register NODE *np;
142: int na;
143: {
144: register CHAR *ap;
145:
146: xprintf(np, NULL, wordbuf);
147: ap = xalloc(strlen(wordbuf) + sizeof(CHAR));
148: strcpy(ap, wordbuf);
149: fsmapinit(FS);
150: return (snode(ap, T_ALLOC));
151: }
152:
153: /*
154: * Function to split a string into the standard
155: * fields.
156: * n = split(string, array, sep)
157: * If `sep' is missing, FS is used.
158: * `string' is split into fields into
159: * `array[1]', `array[2]', ..., `array[n]'
160: * and the number of fields (`n') is
161: * returned.
162: */
163: NODE *
164: f_split(np, na)
165: NODE *np;
166: int na;
167: {
168: register CHAR *cp;
169: register int c;
170: register CHAR *scp;
171: register CHAR *acp;
172: NODE *array;
173: NODE *index;
174: STRING string;
175:
176: index = inode((INT)0);
177: string = evalstring(fargn(np, 1));
178: array = fargn(np, 2);
179: if (array->t_op!=ATERM || (array->t_flag&T_VAR)==0)
180: awkerr("Split not given an array");
181: if (na >= 3)
182: fsmapinit(evalstring(fargn(np, 3)));
183:
184: for (cp = string; *cp;) {
185: for (scp = cp; (c = *cp) && !FSMAP[c]; cp++) /* find the end */
186: ;
187: acp = string = xalloc(1 + cp - scp); /* get space to store */
188: while (scp < cp) /* copy */
189: *acp++ = *scp++;
190: *acp = '\0';
191: index->t_INT++;
192: xassign(xarray(array, index), snode(string, T_ALLOC));
193:
194: if (c == '\0')
195: break;
196:
197: cp++;
198: if (whitesw) /* pass further the delimeters */
199: while (FSMAP[*cp])
200: cp++;
201: }
202: fsmapinit(FS);
203: return (index);
204: }
205:
206: /*
207: * Absolute value function.
208: */
209: NODE *
210: f_abs(np, na)
211: register NODE *np;
212: register int na;
213: {
214: FLOAT f;
215:
216: if ((f = evalfloat(fargn(np, 1))) < 0)
217: f = -f;
218: return (fnode(f));
219: }
220:
221: /*
222: * Return the number
223: * of args to a function.
224: */
225: fnargs(np)
226: register NODE *np;
227: {
228: register unsigned nargs;
229:
230: for (nargs = 0; np != NULL; nargs++)
231: if (np->n_op == ALIST)
232: np = np->n_O2;
233: else
234: np = NULL;
235: return (nargs);
236: }
237:
238: /*
239: * Return the n-th argument based on the
240: * list. If it is out of range, return
241: * a dummied up node.
242: */
243: NODE *
244: fargn(np, an)
245: register NODE *np;
246: register unsigned an;
247: {
248: register NODE *rnp;
249:
250: rnp = NULL;
251: while (an--!=0 && np!=NULL)
252: if (np->n_op == ALIST) {
253: rnp = np->n_O1;
254: np = np->n_O2;
255: } else {
256: rnp = np;
257: np = NULL;
258: }
259: if (rnp == NULL)
260: rnp = snode(SNULL, 0);
261: return (rnp);
262: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.