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