home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume20 / perl3.0 / part11 < prev    next >
Encoding:
Internet Message Format  |  1989-10-30  |  49.1 KB

  1. Subject:  v20i094:  Perl, a language with features of C/sed/awk/shell/etc, Part11/24
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Larry Wall <lwall@jpl-devvax.jpl.nasa.gov>
  7. Posting-number: Volume 20, Issue 94
  8. Archive-name: perl3.0/part11
  9.  
  10. #! /bin/sh
  11.  
  12. # Make a new directory for the perl sources, cd to it, and run kits 1
  13. # thru 24 through sh.  When all 24 kits have been run, read README.
  14.  
  15. echo "This is perl 3.0 kit 11 (of 24).  If kit 11 is complete, the line"
  16. echo '"'"End of kit 11 (of 24)"'" will echo at the end.'
  17. echo ""
  18. export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
  19. mkdir  2>/dev/null
  20. echo Extracting doarg.c
  21. sed >doarg.c <<'!STUFFY!FUNK!' -e 's/X//'
  22. X/* $Header: doarg.c,v 3.0 89/10/18 15:10:41 lwall Locked $
  23. X *
  24. X *    Copyright (c) 1989, Larry Wall
  25. X *
  26. X *    You may distribute under the terms of the GNU General Public License
  27. X *    as specified in the README file that comes with the perl 3.0 kit.
  28. X *
  29. X * $Log:    doarg.c,v $
  30. X * Revision 3.0  89/10/18  15:10:41  lwall
  31. X * 3.0 baseline
  32. X * 
  33. X */
  34. X
  35. X#include "EXTERN.h"
  36. X#include "perl.h"
  37. X
  38. X#include <signal.h>
  39. X
  40. Xextern unsigned char fold[];
  41. X
  42. Xint wantarray;
  43. X
  44. Xint
  45. Xdo_subst(str,arg,sp)
  46. XSTR *str;
  47. XARG *arg;
  48. Xint sp;
  49. X{
  50. X    register SPAT *spat;
  51. X    SPAT *rspat;
  52. X    register STR *dstr;
  53. X    register char *s = str_get(str);
  54. X    char *strend = s + str->str_cur;
  55. X    register char *m;
  56. X    char *c;
  57. X    register char *d;
  58. X    int clen;
  59. X    int iters = 0;
  60. X    register int i;
  61. X    bool once;
  62. X    char *orig;
  63. X    int safebase;
  64. X
  65. X    rspat = spat = arg[2].arg_ptr.arg_spat;
  66. X    if (!spat || !s)
  67. X    fatal("panic: do_subst");
  68. X    else if (spat->spat_runtime) {
  69. X    nointrp = "|)";
  70. X    (void)eval(spat->spat_runtime,G_SCALAR,sp);
  71. X    m = str_get(dstr = stack->ary_array[sp+1]);
  72. X    nointrp = "";
  73. X    if (spat->spat_regexp)
  74. X        regfree(spat->spat_regexp);
  75. X    spat->spat_regexp = regcomp(m,m+dstr->str_cur,
  76. X        spat->spat_flags & SPAT_FOLD,1);
  77. X    if (spat->spat_flags & SPAT_KEEP) {
  78. X        arg_free(spat->spat_runtime);    /* it won't change, so */
  79. X        spat->spat_runtime = Nullarg;    /* no point compiling again */
  80. X    }
  81. X    }
  82. X#ifdef DEBUGGING
  83. X    if (debug & 8) {
  84. X    deb("2.SPAT /%s/\n",spat->spat_regexp->precomp);
  85. X    }
  86. X#endif
  87. X    safebase = ((!spat->spat_regexp || !spat->spat_regexp->nparens) &&
  88. X      !sawampersand);
  89. X    if (!*spat->spat_regexp->precomp && lastspat)
  90. X    spat = lastspat;
  91. X    orig = m = s;
  92. X    if (hint) {
  93. X    if (hint < s || hint > strend)
  94. X        fatal("panic: hint in do_match");
  95. X    s = hint;
  96. X    hint = Nullch;
  97. X    if (spat->spat_regexp->regback >= 0) {
  98. X        s -= spat->spat_regexp->regback;
  99. X        if (s < m)
  100. X        s = m;
  101. X    }
  102. X    else
  103. X        s = m;
  104. X    }
  105. X    else if (spat->spat_short) {
  106. X    if (spat->spat_flags & SPAT_SCANFIRST) {
  107. X        if (str->str_pok & SP_STUDIED) {
  108. X        if (screamfirst[spat->spat_short->str_rare] < 0)
  109. X            goto nope;
  110. X        else if (!(s = screaminstr(str,spat->spat_short)))
  111. X            goto nope;
  112. X        }
  113. X#ifndef lint
  114. X        else if (!(s = fbminstr((unsigned char*)s, (unsigned char*)strend,
  115. X          spat->spat_short)))
  116. X        goto nope;
  117. X#endif
  118. X        if (s && spat->spat_regexp->regback >= 0) {
  119. X        ++spat->spat_short->str_u.str_useful;
  120. X        s -= spat->spat_regexp->regback;
  121. X        if (s < m)
  122. X            s = m;
  123. X        }
  124. X        else
  125. X        s = m;
  126. X    }
  127. X    else if (!multiline && (*spat->spat_short->str_ptr != *s ||
  128. X      bcmp(spat->spat_short->str_ptr, s, spat->spat_slen) ))
  129. X        goto nope;
  130. X    if (--spat->spat_short->str_u.str_useful < 0) {
  131. X        str_free(spat->spat_short);
  132. X        spat->spat_short = Nullstr;    /* opt is being useless */
  133. X    }
  134. X    }
  135. X    once = ((rspat->spat_flags & SPAT_ONCE) != 0);
  136. X    if (rspat->spat_flags & SPAT_CONST) {    /* known replacement string? */
  137. X    if ((rspat->spat_repl[1].arg_type & A_MASK) == A_SINGLE)
  138. X        dstr = rspat->spat_repl[1].arg_ptr.arg_str;
  139. X    else {                    /* constant over loop, anyway */
  140. X        (void)eval(rspat->spat_repl,G_SCALAR,sp);
  141. X        dstr = stack->ary_array[sp+1];
  142. X    }
  143. X    c = str_get(dstr);
  144. X    clen = dstr->str_cur;
  145. X    if (clen <= spat->spat_slen + spat->spat_regexp->regback) {
  146. X                    /* can do inplace substitution */
  147. X        if (regexec(spat->spat_regexp, s, strend, orig, 1,
  148. X          str->str_pok & SP_STUDIED ? str : Nullstr, safebase)) {
  149. X        if (spat->spat_regexp->subbase) /* oops, no we can't */
  150. X            goto long_way;
  151. X        d = s;
  152. X        lastspat = spat;
  153. X        str->str_pok = SP_VALID;    /* disable possible screamer */
  154. X        if (once) {
  155. X            m = spat->spat_regexp->startp[0];
  156. X            d = spat->spat_regexp->endp[0];
  157. X            s = orig;
  158. X            if (m - s > strend - d) {    /* faster to shorten from end */
  159. X            if (clen) {
  160. X                (void)bcopy(c, m, clen);
  161. X                m += clen;
  162. X            }
  163. X            i = strend - d;
  164. X            if (i > 0) {
  165. X                (void)bcopy(d, m, i);
  166. X                m += i;
  167. X            }
  168. X            *m = '\0';
  169. X            str->str_cur = m - s;
  170. X            STABSET(str);
  171. X            str_numset(arg->arg_ptr.arg_str, 1.0);
  172. X            stack->ary_array[++sp] = arg->arg_ptr.arg_str;
  173. X            return sp;
  174. X            }
  175. X            else if (i = m - s) {    /* faster from front */
  176. X            d -= clen;
  177. X            m = d;
  178. X            str_chop(str,d-i);
  179. X            s += i;
  180. X            while (i--)
  181. X                *--d = *--s;
  182. X            if (clen)
  183. X                (void)bcopy(c, m, clen);
  184. X            STABSET(str);
  185. X            str_numset(arg->arg_ptr.arg_str, 1.0);
  186. X            stack->ary_array[++sp] = arg->arg_ptr.arg_str;
  187. X            return sp;
  188. X            }
  189. X            else if (clen) {
  190. X            d -= clen;
  191. X            str_chop(str,d);
  192. X            (void)bcopy(c,d,clen);
  193. X            STABSET(str);
  194. X            str_numset(arg->arg_ptr.arg_str, 1.0);
  195. X            stack->ary_array[++sp] = arg->arg_ptr.arg_str;
  196. X            return sp;
  197. X            }
  198. X            else {
  199. X            str_chop(str,d);
  200. X            STABSET(str);
  201. X            str_numset(arg->arg_ptr.arg_str, 1.0);
  202. X            stack->ary_array[++sp] = arg->arg_ptr.arg_str;
  203. X            return sp;
  204. X            }
  205. X            /* NOTREACHED */
  206. X        }
  207. X        do {
  208. X            if (iters++ > 10000)
  209. X            fatal("Substitution loop");
  210. X            m = spat->spat_regexp->startp[0];
  211. X            if (i = m - s) {
  212. X            if (s != d)
  213. X                (void)bcopy(s,d,i);
  214. X            d += i;
  215. X            }
  216. X            if (clen) {
  217. X            (void)bcopy(c,d,clen);
  218. X            d += clen;
  219. X            }
  220. X            s = spat->spat_regexp->endp[0];
  221. X        } while (regexec(spat->spat_regexp, s, strend, orig, 1, Nullstr,
  222. X            TRUE));
  223. X        if (s != d) {
  224. X            i = strend - s;
  225. X            str->str_cur = d - str->str_ptr + i;
  226. X            (void)bcopy(s,d,i+1);        /* include the Null */
  227. X        }
  228. X        STABSET(str);
  229. X        str_numset(arg->arg_ptr.arg_str, (double)iters);
  230. X        stack->ary_array[++sp] = arg->arg_ptr.arg_str;
  231. X        return sp;
  232. X        }
  233. X        str_numset(arg->arg_ptr.arg_str, 0.0);
  234. X        stack->ary_array[++sp] = arg->arg_ptr.arg_str;
  235. X        return sp;
  236. X    }
  237. X    }
  238. X    else
  239. X    c = Nullch;
  240. X    if (regexec(spat->spat_regexp, s, strend, orig, 1,
  241. X      str->str_pok & SP_STUDIED ? str : Nullstr, safebase)) {
  242. X    long_way:
  243. X    dstr = Str_new(25,str_len(str));
  244. X    str_nset(dstr,m,s-m);
  245. X    if (spat->spat_regexp->subbase)
  246. X        curspat = spat;
  247. X    lastspat = spat;
  248. X    do {
  249. X        if (iters++ > 10000)
  250. X        fatal("Substitution loop");
  251. X        if (spat->spat_regexp->subbase
  252. X          && spat->spat_regexp->subbase != orig) {
  253. X        m = s;
  254. X        s = orig;
  255. X        orig = spat->spat_regexp->subbase;
  256. X        s = orig + (m - s);
  257. X        strend = s + (strend - m);
  258. X        }
  259. X        m = spat->spat_regexp->startp[0];
  260. X        str_ncat(dstr,s,m-s);
  261. X        s = spat->spat_regexp->endp[0];
  262. X        if (c) {
  263. X        if (clen)
  264. X            str_ncat(dstr,c,clen);
  265. X        }
  266. X        else {
  267. X        (void)eval(rspat->spat_repl,G_SCALAR,sp);
  268. X        str_scat(dstr,stack->ary_array[sp+1]);
  269. X        }
  270. X        if (once)
  271. X        break;
  272. X    } while (regexec(spat->spat_regexp, s, strend, orig, 1, Nullstr,
  273. X        safebase));
  274. X    str_ncat(dstr,s,strend - s);
  275. X    str_replace(str,dstr);
  276. X    STABSET(str);
  277. X    str_numset(arg->arg_ptr.arg_str, (double)iters);
  278. X    stack->ary_array[++sp] = arg->arg_ptr.arg_str;
  279. X    return sp;
  280. X    }
  281. X    str_numset(arg->arg_ptr.arg_str, 0.0);
  282. X    stack->ary_array[++sp] = arg->arg_ptr.arg_str;
  283. X    return sp;
  284. X
  285. Xnope:
  286. X    ++spat->spat_short->str_u.str_useful;
  287. X    str_numset(arg->arg_ptr.arg_str, 0.0);
  288. X    stack->ary_array[++sp] = arg->arg_ptr.arg_str;
  289. X    return sp;
  290. X}
  291. X
  292. Xint
  293. Xdo_trans(str,arg)
  294. XSTR *str;
  295. Xregister ARG *arg;
  296. X{
  297. X    register char *tbl;
  298. X    register char *s;
  299. X    register int matches = 0;
  300. X    register int ch;
  301. X    register char *send;
  302. X
  303. X    tbl = arg[2].arg_ptr.arg_cval;
  304. X    s = str_get(str);
  305. X    send = s + str->str_cur;
  306. X    if (!tbl || !s)
  307. X    fatal("panic: do_trans");
  308. X#ifdef DEBUGGING
  309. X    if (debug & 8) {
  310. X    deb("2.TBL\n");
  311. X    }
  312. X#endif
  313. X    while (s < send) {
  314. X    if (ch = tbl[*s & 0377]) {
  315. X        matches++;
  316. X        *s = ch;
  317. X    }
  318. X    s++;
  319. X    }
  320. X    STABSET(str);
  321. X    return matches;
  322. X}
  323. X
  324. Xvoid
  325. Xdo_join(str,arglast)
  326. Xregister STR *str;
  327. Xint *arglast;
  328. X{
  329. X    register STR **st = stack->ary_array;
  330. X    register int sp = arglast[1];
  331. X    register int items = arglast[2] - sp;
  332. X    register char *delim = str_get(st[sp]);
  333. X    int delimlen = st[sp]->str_cur;
  334. X
  335. X    st += ++sp;
  336. X    if (items-- > 0)
  337. X    str_sset(str,*st++);
  338. X    else
  339. X    str_set(str,"");
  340. X    for (; items > 0; items--,st++) {
  341. X    str_ncat(str,delim,delimlen);
  342. X    str_scat(str,*st);
  343. X    }
  344. X    STABSET(str);
  345. X}
  346. X
  347. Xvoid
  348. Xdo_pack(str,arglast)
  349. Xregister STR *str;
  350. Xint *arglast;
  351. X{
  352. X    register STR **st = stack->ary_array;
  353. X    register int sp = arglast[1];
  354. X    register int items;
  355. X    register char *pat = str_get(st[sp]);
  356. X    register char *patend = pat + st[sp]->str_cur;
  357. X    register int len;
  358. X    int datumtype;
  359. X    STR *fromstr;
  360. X    static char *null10 = "\0\0\0\0\0\0\0\0\0\0";
  361. X    static char *space10 = "          ";
  362. X
  363. X    /* These must not be in registers: */
  364. X    char achar;
  365. X    short ashort;
  366. X    int aint;
  367. X    long along;
  368. X    char *aptr;
  369. X
  370. X    items = arglast[2] - sp;
  371. X    st += ++sp;
  372. X    str_nset(str,"",0);
  373. X    while (pat < patend) {
  374. X#define NEXTFROM (items-- > 0 ? *st++ : &str_no)
  375. X    datumtype = *pat++;
  376. X    if (isdigit(*pat)) {
  377. X        len = atoi(pat);
  378. X        while (isdigit(*pat))
  379. X        pat++;
  380. X    }
  381. X    else
  382. X        len = 1;
  383. X    switch(datumtype) {
  384. X    default:
  385. X        break;
  386. X    case 'x':
  387. X        while (len >= 10) {
  388. X        str_ncat(str,null10,10);
  389. X        len -= 10;
  390. X        }
  391. X        str_ncat(str,null10,len);
  392. X        break;
  393. X    case 'A':
  394. X    case 'a':
  395. X        fromstr = NEXTFROM;
  396. X        aptr = str_get(fromstr);
  397. X        if (fromstr->str_cur > len)
  398. X        str_ncat(str,aptr,len);
  399. X        else
  400. X        str_ncat(str,aptr,fromstr->str_cur);
  401. X        len -= fromstr->str_cur;
  402. X        if (datumtype == 'A') {
  403. X        while (len >= 10) {
  404. X            str_ncat(str,space10,10);
  405. X            len -= 10;
  406. X        }
  407. X        str_ncat(str,space10,len);
  408. X        }
  409. X        else {
  410. X        while (len >= 10) {
  411. X            str_ncat(str,null10,10);
  412. X            len -= 10;
  413. X        }
  414. X        str_ncat(str,null10,len);
  415. X        }
  416. X        break;
  417. X    case 'C':
  418. X    case 'c':
  419. X        while (len-- > 0) {
  420. X        fromstr = NEXTFROM;
  421. X        aint = (int)str_gnum(fromstr);
  422. X        achar = aint;
  423. X        str_ncat(str,&achar,sizeof(char));
  424. X        }
  425. X        break;
  426. X    case 'n':
  427. X        while (len-- > 0) {
  428. X        fromstr = NEXTFROM;
  429. X        ashort = (short)str_gnum(fromstr);
  430. X#ifdef HTONS
  431. X        ashort = htons(ashort);
  432. X#endif
  433. X        str_ncat(str,(char*)&ashort,sizeof(short));
  434. X        }
  435. X        break;
  436. X    case 'S':
  437. X    case 's':
  438. X        while (len-- > 0) {
  439. X        fromstr = NEXTFROM;
  440. X        ashort = (short)str_gnum(fromstr);
  441. X        str_ncat(str,(char*)&ashort,sizeof(short));
  442. X        }
  443. X        break;
  444. X    case 'I':
  445. X    case 'i':
  446. X        while (len-- > 0) {
  447. X        fromstr = NEXTFROM;
  448. X        aint = (int)str_gnum(fromstr);
  449. X        str_ncat(str,(char*)&aint,sizeof(int));
  450. X        }
  451. X        break;
  452. X    case 'N':
  453. X        while (len-- > 0) {
  454. X        fromstr = NEXTFROM;
  455. X        along = (long)str_gnum(fromstr);
  456. X#ifdef HTONL
  457. X        along = htonl(along);
  458. X#endif
  459. X        str_ncat(str,(char*)&along,sizeof(long));
  460. X        }
  461. X        break;
  462. X    case 'L':
  463. X    case 'l':
  464. X        while (len-- > 0) {
  465. X        fromstr = NEXTFROM;
  466. X        along = (long)str_gnum(fromstr);
  467. X        str_ncat(str,(char*)&along,sizeof(long));
  468. X        }
  469. X        break;
  470. X    case 'p':
  471. X        while (len-- > 0) {
  472. X        fromstr = NEXTFROM;
  473. X        aptr = str_get(fromstr);
  474. X        str_ncat(str,(char*)&aptr,sizeof(char*));
  475. X        }
  476. X        break;
  477. X    }
  478. X    }
  479. X    STABSET(str);
  480. X}
  481. X#undef NEXTFROM
  482. X
  483. Xvoid
  484. Xdo_sprintf(str,len,sarg)
  485. Xregister STR *str;
  486. Xregister int len;
  487. Xregister STR **sarg;
  488. X{
  489. X    register char *s;
  490. X    register char *t;
  491. X    bool dolong;
  492. X    char ch;
  493. X    static STR *sargnull = &str_no;
  494. X    register char *send;
  495. X    char *xs;
  496. X    int xlen;
  497. X
  498. X    str_set(str,"");
  499. X    len--;            /* don't count pattern string */
  500. X    s = str_get(*sarg);
  501. X    send = s + (*sarg)->str_cur;
  502. X    sarg++;
  503. X    for ( ; s < send; len--) {
  504. X    if (len <= 0 || !*sarg) {
  505. X        sarg = &sargnull;
  506. X        len = 0;
  507. X    }
  508. X    dolong = FALSE;
  509. X    for (t = s; t < send && *t != '%'; t++) ;
  510. X    if (t >= send)
  511. X        break;        /* not enough % patterns, oh well */
  512. X    for (t++; *sarg && t < send && t != s; t++) {
  513. X        switch (*t) {
  514. X        default:
  515. X        ch = *(++t);
  516. X        *t = '\0';
  517. X        (void)sprintf(buf,s);
  518. X        s = t;
  519. X        *(t--) = ch;
  520. X        len++;
  521. X        break;
  522. X        case '0': case '1': case '2': case '3': case '4':
  523. X        case '5': case '6': case '7': case '8': case '9': 
  524. X        case '.': case '#': case '-': case '+':
  525. X        break;
  526. X        case 'l':
  527. X        dolong = TRUE;
  528. X        break;
  529. X        case 'D': case 'X': case 'O':
  530. X        dolong = TRUE;
  531. X        /* FALL THROUGH */
  532. X        case 'c':
  533. X        *buf = (int)str_gnum(*(sarg++));
  534. X        str_ncat(str,buf,1);    /* force even if null */
  535. X        *buf = '\0';
  536. X        s = t+1;
  537. X        break;
  538. X        case 'd': case 'x': case 'o': case 'u':
  539. X        ch = *(++t);
  540. X        *t = '\0';
  541. X        if (dolong)
  542. X            (void)sprintf(buf,s,(long)str_gnum(*(sarg++)));
  543. X        else
  544. X            (void)sprintf(buf,s,(int)str_gnum(*(sarg++)));
  545. X        s = t;
  546. X        *(t--) = ch;
  547. X        break;
  548. X        case 'E': case 'e': case 'f': case 'G': case 'g':
  549. X        ch = *(++t);
  550. X        *t = '\0';
  551. X        (void)sprintf(buf,s,str_gnum(*(sarg++)));
  552. X        s = t;
  553. X        *(t--) = ch;
  554. X        break;
  555. X        case 's':
  556. X        ch = *(++t);
  557. X        *t = '\0';
  558. X        xs = str_get(*sarg);
  559. X        xlen = (*sarg)->str_cur;
  560. X        if (*xs == 'S' && xs[1] == 't' && xs[2] == 'a' && xs[3] == 'b'
  561. X          && xlen == sizeof(STBP) && strlen(xs) < xlen) {
  562. X            xs = stab_name(((STAB*)(*sarg))); /* a stab value! */
  563. X            sprintf(tokenbuf,"*%s",xs);    /* reformat to non-binary */
  564. X            xs = tokenbuf;
  565. X            xlen = strlen(tokenbuf);
  566. X        }
  567. X        if (strEQ(t-2,"%s")) {    /* some printfs fail on >128 chars */
  568. X            *buf = '\0';
  569. X            str_ncat(str,s,t - s - 2);
  570. X            str_ncat(str,xs,xlen);  /* so handle simple case */
  571. X        }
  572. X        else
  573. X            (void)sprintf(buf,s,xs);
  574. X        sarg++;
  575. X        s = t;
  576. X        *(t--) = ch;
  577. X        break;
  578. X        }
  579. X    }
  580. X    if (s < t && t >= send) {
  581. X        str_cat(str,s);
  582. X        s = t;
  583. X        break;
  584. X    }
  585. X    str_cat(str,buf);
  586. X    }
  587. X    if (*s) {
  588. X    (void)sprintf(buf,s,0,0,0,0);
  589. X    str_cat(str,buf);
  590. X    }
  591. X    STABSET(str);
  592. X}
  593. X
  594. XSTR *
  595. Xdo_push(ary,arglast)
  596. Xregister ARRAY *ary;
  597. Xint *arglast;
  598. X{
  599. X    register STR **st = stack->ary_array;
  600. X    register int sp = arglast[1];
  601. X    register int items = arglast[2] - sp;
  602. X    register STR *str = &str_undef;
  603. X
  604. X    for (st += ++sp; items > 0; items--,st++) {
  605. X    str = Str_new(26,0);
  606. X    if (*st)
  607. X        str_sset(str,*st);
  608. X    (void)apush(ary,str);
  609. X    }
  610. X    return str;
  611. X}
  612. X
  613. Xint
  614. Xdo_unshift(ary,arglast)
  615. Xregister ARRAY *ary;
  616. Xint *arglast;
  617. X{
  618. X    register STR **st = stack->ary_array;
  619. X    register int sp = arglast[1];
  620. X    register int items = arglast[2] - sp;
  621. X    register STR *str;
  622. X    register int i;
  623. X
  624. X    aunshift(ary,items);
  625. X    i = 0;
  626. X    for (st += ++sp; i < items; i++,st++) {
  627. X    str = Str_new(27,0);
  628. X    str_sset(str,*st);
  629. X    (void)astore(ary,i,str);
  630. X    }
  631. X}
  632. X
  633. Xint
  634. Xdo_subr(arg,gimme,arglast)
  635. Xregister ARG *arg;
  636. Xint gimme;
  637. Xint *arglast;
  638. X{
  639. X    register STR **st = stack->ary_array;
  640. X    register int sp = arglast[1];
  641. X    register int items = arglast[2] - sp;
  642. X    register SUBR *sub;
  643. X    ARRAY *savearray;
  644. X    STAB *stab;
  645. X    char *oldfile = filename;
  646. X    int oldsave = savestack->ary_fill;
  647. X    int oldtmps_base = tmps_base;
  648. X
  649. X    if ((arg[1].arg_type & A_MASK) == A_WORD)
  650. X    stab = arg[1].arg_ptr.arg_stab;
  651. X    else {
  652. X    STR *tmpstr = stab_val(arg[1].arg_ptr.arg_stab);
  653. X
  654. X    if (tmpstr)
  655. X        stab = stabent(str_get(tmpstr),TRUE);
  656. X    else
  657. X        stab = Nullstab;
  658. X    }
  659. X    if (!stab)
  660. X    fatal("Undefined subroutine called");
  661. X    sub = stab_sub(stab);
  662. X    if (!sub)
  663. X    fatal("Undefined subroutine \"%s\" called", stab_name(stab));
  664. X    if ((arg[2].arg_type & A_MASK) != A_NULL) {
  665. X    savearray = stab_xarray(defstab);
  666. X    stab_xarray(defstab) = afake(defstab, items, &st[sp+1]);
  667. X    }
  668. X    savelong(&sub->depth);
  669. X    sub->depth++;
  670. X    saveint(&wantarray);
  671. X    wantarray = gimme;
  672. X    if (sub->depth >= 2) {    /* save temporaries on recursion? */
  673. X    if (sub->depth == 100 && dowarn)
  674. X        warn("Deep recursion on subroutine \"%s\"",stab_name(stab));
  675. X    savelist(sub->tosave->ary_array,sub->tosave->ary_fill);
  676. X    }
  677. X    filename = sub->filename;
  678. X    tmps_base = tmps_max;
  679. X    sp = cmd_exec(sub->cmd,gimme,--sp);        /* so do it already */
  680. X    st = stack->ary_array;
  681. X
  682. X    if ((arg[2].arg_type & A_MASK) != A_NULL) {
  683. X    afree(stab_xarray(defstab));  /* put back old $_[] */
  684. X    stab_xarray(defstab) = savearray;
  685. X    }
  686. X    filename = oldfile;
  687. X    tmps_base = oldtmps_base;
  688. X    if (savestack->ary_fill > oldsave) {
  689. X    for (items = arglast[0] + 1; items <= sp; items++)
  690. X        st[items] = str_static(st[items]);
  691. X        /* in case restore wipes old str */
  692. X    restorelist(oldsave);
  693. X    }
  694. X    return sp;
  695. X}
  696. X
  697. Xint
  698. Xdo_dbsubr(arg,gimme,arglast)
  699. Xregister ARG *arg;
  700. Xint gimme;
  701. Xint *arglast;
  702. X{
  703. X    register STR **st = stack->ary_array;
  704. X    register int sp = arglast[1];
  705. X    register int items = arglast[2] - sp;
  706. X    register SUBR *sub;
  707. X    ARRAY *savearray;
  708. X    STR *str;
  709. X    STAB *stab;
  710. X    char *oldfile = filename;
  711. X    int oldsave = savestack->ary_fill;
  712. X    int oldtmps_base = tmps_base;
  713. X
  714. X    if ((arg[1].arg_type & A_MASK) == A_WORD)
  715. X    stab = arg[1].arg_ptr.arg_stab;
  716. X    else {
  717. X    STR *tmpstr = stab_val(arg[1].arg_ptr.arg_stab);
  718. X
  719. X    if (tmpstr)
  720. X        stab = stabent(str_get(tmpstr),TRUE);
  721. X    else
  722. X        stab = Nullstab;
  723. X    }
  724. X    if (!stab)
  725. X    fatal("Undefined subroutine called");
  726. X    sub = stab_sub(stab);
  727. X    if (!sub)
  728. X    fatal("Undefined subroutine \"%s\" called", stab_name(stab));
  729. X/* begin differences */
  730. X    str = stab_val(DBsub);
  731. X    saveitem(str);
  732. X    str_set(str,stab_name(stab));
  733. X    sub = stab_sub(DBsub);
  734. X    if (!sub)
  735. X    fatal("No DBsub routine");
  736. X/* end differences */
  737. X    if ((arg[2].arg_type & A_MASK) != A_NULL) {
  738. X    savearray = stab_xarray(defstab);
  739. X    stab_xarray(defstab) = afake(defstab, items, &st[sp+1]);
  740. X    }
  741. X    savelong(&sub->depth);
  742. X    sub->depth++;
  743. X    saveint(&wantarray);
  744. X    wantarray = gimme;
  745. X    if (sub->depth >= 2) {    /* save temporaries on recursion? */
  746. X    if (sub->depth == 100 && dowarn)
  747. X        warn("Deep recursion on subroutine \"%s\"",stab_name(stab));
  748. X    savelist(sub->tosave->ary_array,sub->tosave->ary_fill);
  749. X    }
  750. X    filename = sub->filename;
  751. X    tmps_base = tmps_max;
  752. X    sp = cmd_exec(sub->cmd,gimme, --sp);    /* so do it already */
  753. X    st = stack->ary_array;
  754. X
  755. X    if ((arg[2].arg_type & A_MASK) != A_NULL) {
  756. X    afree(stab_xarray(defstab));  /* put back old $_[] */
  757. X    stab_xarray(defstab) = savearray;
  758. X    }
  759. X    filename = oldfile;
  760. X    tmps_base = oldtmps_base;
  761. X    if (savestack->ary_fill > oldsave) {
  762. X    for (items = arglast[0] + 1; items <= sp; items++)
  763. X        st[items] = str_static(st[items]);
  764. X        /* in case restore wipes old str */
  765. X    restorelist(oldsave);
  766. X    }
  767. X    return sp;
  768. X}
  769. X
  770. Xint
  771. Xdo_assign(arg,gimme,arglast)
  772. Xregister ARG *arg;
  773. Xint gimme;
  774. Xint *arglast;
  775. X{
  776. X
  777. X    register STR **st = stack->ary_array;
  778. X    STR **firstrelem = st + arglast[1] + 1;
  779. X    STR **firstlelem = st + arglast[0] + 1;
  780. X    STR **lastrelem = st + arglast[2];
  781. X    STR **lastlelem = st + arglast[1];
  782. X    register STR **relem;
  783. X    register STR **lelem;
  784. X
  785. X    register STR *str;
  786. X    register ARRAY *ary;
  787. X    register int makelocal;
  788. X    HASH *hash;
  789. X    int i;
  790. X
  791. X    makelocal = (arg->arg_flags & AF_LOCAL);
  792. X    delaymagic = DM_DELAY;        /* catch simultaneous items */
  793. X
  794. X    /* If there's a common identifier on both sides we have to take
  795. X     * special care that assigning the identifier on the left doesn't
  796. X     * clobber a value on the right that's used later in the list.
  797. X     */
  798. X    if (arg->arg_flags & AF_COMMON) {
  799. X    for (relem = firstrelem; relem <= lastrelem; relem++) {
  800. X        if (str = *relem)
  801. X        *relem = str_static(str);
  802. X    }
  803. X    }
  804. X    relem = firstrelem;
  805. X    lelem = firstlelem;
  806. X    ary = Null(ARRAY*);
  807. X    hash = Null(HASH*);
  808. X    while (lelem <= lastlelem) {
  809. X    str = *lelem++;
  810. X    if (str->str_state >= SS_HASH) {
  811. X        if (str->str_state == SS_ARY) {
  812. X        if (makelocal)
  813. X            ary = saveary(str->str_u.str_stab);
  814. X        else {
  815. X            ary = stab_array(str->str_u.str_stab);
  816. X            ary->ary_fill = -1;
  817. X        }
  818. X        i = 0;
  819. X        while (relem <= lastrelem) {    /* gobble up all the rest */
  820. X            str = Str_new(28,0);
  821. X            if (*relem)
  822. X            str_sset(str,*(relem++));
  823. X            else
  824. X            relem++;
  825. X            (void)astore(ary,i++,str);
  826. X        }
  827. X        }
  828. X        else if (str->str_state == SS_HASH) {
  829. X        char *tmps;
  830. X        STR *tmpstr;
  831. X
  832. X        if (makelocal)
  833. X            hash = savehash(str->str_u.str_stab);
  834. X        else {
  835. X            hash = stab_hash(str->str_u.str_stab);
  836. X            hclear(hash);
  837. X        }
  838. X        while (relem < lastrelem) {    /* gobble up all the rest */
  839. X            if (*relem)
  840. X            str = *(relem++);
  841. X            else
  842. X            str = &str_no, relem++;
  843. X            tmps = str_get(str);
  844. X            tmpstr = Str_new(29,0);
  845. X            if (*relem)
  846. X            str_sset(tmpstr,*(relem++));    /* value */
  847. X            else
  848. X            relem++;
  849. X            (void)hstore(hash,tmps,str->str_cur,tmpstr,0);
  850. X        }
  851. X        }
  852. X        else
  853. X        fatal("panic: do_assign");
  854. X    }
  855. X    else {
  856. X        if (makelocal)
  857. X        saveitem(str);
  858. X        if (relem <= lastrelem)
  859. X        str_sset(str, *(relem++));
  860. X        else
  861. X        str_nset(str, "", 0);
  862. X        STABSET(str);
  863. X    }
  864. X    }
  865. X    if (delaymagic > 1) {
  866. X#ifdef SETREUID
  867. X    if (delaymagic & DM_REUID)
  868. X        setreuid(uid,euid);
  869. X#endif
  870. X#ifdef SETREGID
  871. X    if (delaymagic & DM_REGID)
  872. X        setregid(gid,egid);
  873. X#endif
  874. X    }
  875. X    delaymagic = 0;
  876. X    if (gimme == G_ARRAY) {
  877. X    i = lastrelem - firstrelem + 1;
  878. X    if (ary || hash)
  879. X        Copy(firstrelem, firstlelem, i, STR*);
  880. X    return arglast[0] + i;
  881. X    }
  882. X    else {
  883. X    str_numset(arg->arg_ptr.arg_str,(double)(arglast[2] - arglast[1]));
  884. X    *firstlelem = arg->arg_ptr.arg_str;
  885. X    return arglast[0] + 1;
  886. X    }
  887. X}
  888. X
  889. Xint
  890. Xdo_study(str,arg,gimme,arglast)
  891. XSTR *str;
  892. XARG *arg;
  893. Xint gimme;
  894. Xint *arglast;
  895. X{
  896. X    register unsigned char *s;
  897. X    register int pos = str->str_cur;
  898. X    register int ch;
  899. X    register int *sfirst;
  900. X    register int *snext;
  901. X    static int maxscream = -1;
  902. X    static STR *lastscream = Nullstr;
  903. X    int retval;
  904. X    int retarg = arglast[0] + 1;
  905. X
  906. X#ifndef lint
  907. X    s = (unsigned char*)(str_get(str));
  908. X#else
  909. X    s = Null(unsigned char*);
  910. X#endif
  911. X    if (lastscream)
  912. X    lastscream->str_pok &= ~SP_STUDIED;
  913. X    lastscream = str;
  914. X    if (pos <= 0) {
  915. X    retval = 0;
  916. X    goto ret;
  917. X    }
  918. X    if (pos > maxscream) {
  919. X    if (maxscream < 0) {
  920. X        maxscream = pos + 80;
  921. X        New(301,screamfirst, 256, int);
  922. X        New(302,screamnext, maxscream, int);
  923. X    }
  924. X    else {
  925. X        maxscream = pos + pos / 4;
  926. X        Renew(screamnext, maxscream, int);
  927. X    }
  928. X    }
  929. X
  930. X    sfirst = screamfirst;
  931. X    snext = screamnext;
  932. X
  933. X    if (!sfirst || !snext)
  934. X    fatal("do_study: out of memory");
  935. X
  936. X    for (ch = 256; ch; --ch)
  937. X    *sfirst++ = -1;
  938. X    sfirst -= 256;
  939. X
  940. X    while (--pos >= 0) {
  941. X    ch = s[pos];
  942. X    if (sfirst[ch] >= 0)
  943. X        snext[pos] = sfirst[ch] - pos;
  944. X    else
  945. X        snext[pos] = -pos;
  946. X    sfirst[ch] = pos;
  947. X
  948. X    /* If there were any case insensitive searches, we must assume they
  949. X     * all are.  This speeds up insensitive searches much more than
  950. X     * it slows down sensitive ones.
  951. X     */
  952. X    if (sawi)
  953. X        sfirst[fold[ch]] = pos;
  954. X    }
  955. X
  956. X    str->str_pok |= SP_STUDIED;
  957. X    retval = 1;
  958. X  ret:
  959. X    str_numset(arg->arg_ptr.arg_str,(double)retval);
  960. X    stack->ary_array[retarg] = arg->arg_ptr.arg_str;
  961. X    return retarg;
  962. X}
  963. X
  964. Xint
  965. Xdo_defined(str,arg,gimme,arglast)
  966. XSTR *str;
  967. Xregister ARG *arg;
  968. Xint gimme;
  969. Xint *arglast;
  970. X{
  971. X    register int type;
  972. X    register int retarg = arglast[0] + 1;
  973. X    int retval;
  974. X
  975. X    if ((arg[1].arg_type & A_MASK) != A_LEXPR)
  976. X    fatal("Illegal argument to defined()");
  977. X    arg = arg[1].arg_ptr.arg_arg;
  978. X    type = arg->arg_type;
  979. X
  980. X    if (type == O_ARRAY || type == O_LARRAY)
  981. X    retval = stab_xarray(arg[1].arg_ptr.arg_stab) != 0;
  982. X    else if (type == O_HASH || type == O_LHASH)
  983. X    retval = stab_xhash(arg[1].arg_ptr.arg_stab) != 0;
  984. X    else if (type == O_SUBR || type == O_DBSUBR)
  985. X    retval = stab_sub(arg[1].arg_ptr.arg_stab) != 0;
  986. X    else if (type == O_ASLICE || type == O_LASLICE)
  987. X    retval = stab_xarray(arg[1].arg_ptr.arg_stab) != 0;
  988. X    else if (type == O_HSLICE || type == O_LHSLICE)
  989. X    retval = stab_xhash(arg[1].arg_ptr.arg_stab) != 0;
  990. X    else
  991. X    retval = FALSE;
  992. X    str_numset(str,(double)retval);
  993. X    stack->ary_array[retarg] = str;
  994. X    return retarg;
  995. X}
  996. X
  997. Xint
  998. Xdo_undef(str,arg,gimme,arglast)
  999. XSTR *str;
  1000. Xregister ARG *arg;
  1001. Xint gimme;
  1002. Xint *arglast;
  1003. X{
  1004. X    register int type;
  1005. X    register STAB *stab;
  1006. X    int retarg = arglast[0] + 1;
  1007. X
  1008. X    if ((arg[1].arg_type & A_MASK) != A_LEXPR)
  1009. X    fatal("Illegal argument to undef()");
  1010. X    arg = arg[1].arg_ptr.arg_arg;
  1011. X    type = arg->arg_type;
  1012. X
  1013. X    if (type == O_ARRAY || type == O_LARRAY) {
  1014. X    stab = arg[1].arg_ptr.arg_stab;
  1015. X    afree(stab_xarray(stab));
  1016. X    stab_xarray(stab) = Null(ARRAY*);
  1017. X    }
  1018. X    else if (type == O_HASH || type == O_LHASH) {
  1019. X    stab = arg[1].arg_ptr.arg_stab;
  1020. X    (void)hfree(stab_xhash(stab));
  1021. X    stab_xhash(stab) = Null(HASH*);
  1022. X    }
  1023. X    else if (type == O_SUBR || type == O_DBSUBR) {
  1024. X    stab = arg[1].arg_ptr.arg_stab;
  1025. X    cmd_free(stab_sub(stab)->cmd);
  1026. X    afree(stab_sub(stab)->tosave);
  1027. X    Safefree(stab_sub(stab));
  1028. X    stab_sub(stab) = Null(SUBR*);
  1029. X    }
  1030. X    else
  1031. X    fatal("Can't undefine that kind of object");
  1032. X    str_numset(str,0.0);
  1033. X    stack->ary_array[retarg] = str;
  1034. X    return retarg;
  1035. X}
  1036. X
  1037. Xint
  1038. Xdo_vec(lvalue,astr,arglast)
  1039. Xint lvalue;
  1040. XSTR *astr;
  1041. Xint *arglast;
  1042. X{
  1043. X    STR **st = stack->ary_array;
  1044. X    int sp = arglast[0];
  1045. X    register STR *str = st[++sp];
  1046. X    register int offset = (int)str_gnum(st[++sp]);
  1047. X    register int size = (int)str_gnum(st[++sp]);
  1048. X    unsigned char *s = (unsigned char*)str_get(str);
  1049. X    unsigned long retnum;
  1050. X    int len;
  1051. X
  1052. X    sp = arglast[1];
  1053. X    offset *= size;        /* turn into bit offset */
  1054. X    len = (offset + size + 7) / 8;
  1055. X    if (offset < 0 || size < 1)
  1056. X    retnum = 0;
  1057. X    else if (!lvalue && len > str->str_cur)
  1058. X    retnum = 0;
  1059. X    else {
  1060. X    if (len > str->str_cur) {
  1061. X        STR_GROW(str,len);
  1062. X        (void)bzero(str->str_ptr + str->str_cur, len - str->str_cur);
  1063. X        str->str_cur = len;
  1064. X    }
  1065. X    s = (unsigned char*)str_get(str);
  1066. X    if (size < 8)
  1067. X        retnum = (s[offset >> 3] >> (offset & 7)) & ((1 << size) - 1);
  1068. X    else {
  1069. X        offset >>= 3;
  1070. X        if (size == 8)
  1071. X        retnum = s[offset];
  1072. X        else if (size == 16)
  1073. X        retnum = (s[offset] << 8) + s[offset+1];
  1074. X        else if (size == 32)
  1075. X        retnum = (s[offset] << 24) + (s[offset + 1] << 16) +
  1076. X            (s[offset + 2] << 8) + s[offset+3];
  1077. X    }
  1078. X
  1079. X    if (lvalue) {                      /* it's an lvalue! */
  1080. X        struct lstring *lstr = (struct lstring*)astr;
  1081. X
  1082. X        astr->str_magic = str;
  1083. X        st[sp]->str_rare = 'v';
  1084. X        lstr->lstr_offset = offset;
  1085. X        lstr->lstr_len = size;
  1086. X    }
  1087. X    }
  1088. X
  1089. X    str_numset(astr,(double)retnum);
  1090. X    st[sp] = astr;
  1091. X    return sp;
  1092. X}
  1093. X
  1094. Xvoid
  1095. Xdo_vecset(mstr,str)
  1096. XSTR *mstr;
  1097. XSTR *str;
  1098. X{
  1099. X    struct lstring *lstr = (struct lstring*)str;
  1100. X    register int offset;
  1101. X    register int size;
  1102. X    register unsigned char *s = (unsigned char*)mstr->str_ptr;
  1103. X    register unsigned long lval = (unsigned long)str_gnum(str);
  1104. X    int mask;
  1105. X
  1106. X    mstr->str_rare = 0;
  1107. X    str->str_magic = Nullstr;
  1108. X    offset = lstr->lstr_offset;
  1109. X    size = lstr->lstr_len;
  1110. X    if (size < 8) {
  1111. X    mask = (1 << size) - 1;
  1112. X    size = offset & 7;
  1113. X    lval &= mask;
  1114. X    offset >>= 3;
  1115. X    s[offset] &= ~(mask << size);
  1116. X    s[offset] |= lval << size;
  1117. X    }
  1118. X    else {
  1119. X    if (size == 8)
  1120. X        s[offset] = lval & 255;
  1121. X    else if (size == 16) {
  1122. X        s[offset] = (lval >> 8) & 255;
  1123. X        s[offset+1] = lval & 255;
  1124. X    }
  1125. X    else if (size == 32) {
  1126. X        s[offset] = (lval >> 24) & 255;
  1127. X        s[offset+1] = (lval >> 16) & 255;
  1128. X        s[offset+2] = (lval >> 8) & 255;
  1129. X        s[offset+3] = lval & 255;
  1130. X    }
  1131. X    }
  1132. X}
  1133. X
  1134. Xdo_chop(astr,str)
  1135. Xregister STR *astr;
  1136. Xregister STR *str;
  1137. X{
  1138. X    register char *tmps;
  1139. X    register int i;
  1140. X    ARRAY *ary;
  1141. X    HASH *hash;
  1142. X    HENT *entry;
  1143. X
  1144. X    if (!str)
  1145. X    return;
  1146. X    if (str->str_state == SS_ARY) {
  1147. X    ary = stab_array(str->str_u.str_stab);
  1148. X    for (i = 0; i <= ary->ary_fill; i++)
  1149. X        do_chop(astr,ary->ary_array[i]);
  1150. X    return;
  1151. X    }
  1152. X    if (str->str_state == SS_HASH) {
  1153. X    hash = stab_hash(str->str_u.str_stab);
  1154. X    (void)hiterinit(hash);
  1155. X    while (entry = hiternext(hash))
  1156. X        do_chop(astr,hiterval(hash,entry));
  1157. X    return;
  1158. X    }
  1159. X    tmps = str_get(str);
  1160. X    if (!tmps)
  1161. X    return;
  1162. X    tmps += str->str_cur - (str->str_cur != 0);
  1163. X    str_nset(astr,tmps,1);    /* remember last char */
  1164. X    *tmps = '\0';                /* wipe it out */
  1165. X    str->str_cur = tmps - str->str_ptr;
  1166. X    str->str_nok = 0;
  1167. X}
  1168. X
  1169. Xdo_vop(optype,str,left,right)
  1170. XSTR *str;
  1171. XSTR *left;
  1172. XSTR *right;
  1173. X{
  1174. X    register char *s = str_get(str);
  1175. X    register char *l = str_get(left);
  1176. X    register char *r = str_get(right);
  1177. X    register int len;
  1178. X
  1179. X    len = left->str_cur;
  1180. X    if (len > right->str_cur)
  1181. X    len = right->str_cur;
  1182. X    if (str->str_cur > len)
  1183. X    str->str_cur = len;
  1184. X    else if (str->str_cur < len) {
  1185. X    STR_GROW(str,len);
  1186. X    (void)bzero(str->str_ptr + str->str_cur, len - str->str_cur);
  1187. X    str->str_cur = len;
  1188. X    s = str_get(str);
  1189. X    }
  1190. X    switch (optype) {
  1191. X    case O_BIT_AND:
  1192. X    while (len--)
  1193. X        *s++ = *l++ & *r++;
  1194. X    break;
  1195. X    case O_XOR:
  1196. X    while (len--)
  1197. X        *s++ = *l++ ^ *r++;
  1198. X    goto mop_up;
  1199. X    case O_BIT_OR:
  1200. X    while (len--)
  1201. X        *s++ = *l++ | *r++;
  1202. X      mop_up:
  1203. X    len = str->str_cur;
  1204. X    if (right->str_cur > len)
  1205. X        str_ncat(str,right->str_ptr+len,right->str_cur - len);
  1206. X    else if (left->str_cur > len)
  1207. X        str_ncat(str,left->str_ptr+len,left->str_cur - len);
  1208. X    break;
  1209. X    }
  1210. X}
  1211. X
  1212. Xint
  1213. Xdo_syscall(arglast)
  1214. Xint *arglast;
  1215. X{
  1216. X    register STR **st = stack->ary_array;
  1217. X    register int sp = arglast[1];
  1218. X    register int items = arglast[2] - sp;
  1219. X    long arg[8];
  1220. X    register int i = 0;
  1221. X    int retval = -1;
  1222. X
  1223. X#ifdef SYSCALL
  1224. X#ifdef TAINT
  1225. X    for (st += ++sp; items--; st++)
  1226. X    tainted |= (*st)->str_tainted;
  1227. X    st = stack->ary_array;
  1228. X    sp = arglast[1];
  1229. X    items = arglast[2] - sp;
  1230. X#endif
  1231. X#ifdef TAINT
  1232. X    taintproper("Insecure dependency in syscall");
  1233. X#endif
  1234. X    /* This probably won't work on machines where sizeof(long) != sizeof(int)
  1235. X     * or where sizeof(long) != sizeof(char*).  But such machines will
  1236. X     * not likely have syscall implemented either, so who cares?
  1237. X     */
  1238. X    while (items--) {
  1239. X    if (st[++sp]->str_nok || !i)
  1240. X        arg[i++] = (long)str_gnum(st[sp]);
  1241. X#ifndef lint
  1242. X    else
  1243. X        arg[i++] = (long)st[sp]->str_ptr;
  1244. X#endif /* lint */
  1245. X    }
  1246. X    sp = arglast[1];
  1247. X    items = arglast[2] - sp;
  1248. X    switch (items) {
  1249. X    case 0:
  1250. X    fatal("Too few args to syscall");
  1251. X    case 1:
  1252. X    retval = syscall(arg[0]);
  1253. X    break;
  1254. X    case 2:
  1255. X    retval = syscall(arg[0],arg[1]);
  1256. X    break;
  1257. X    case 3:
  1258. X    retval = syscall(arg[0],arg[1],arg[2]);
  1259. X    break;
  1260. X    case 4:
  1261. X    retval = syscall(arg[0],arg[1],arg[2],arg[3]);
  1262. X    break;
  1263. X    case 5:
  1264. X    retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4]);
  1265. X    break;
  1266. X    case 6:
  1267. X    retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5]);
  1268. X    break;
  1269. X    case 7:
  1270. X    retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6]);
  1271. X    break;
  1272. X    case 8:
  1273. X    retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
  1274. X      arg[7]);
  1275. X    break;
  1276. X    }
  1277. X    st[sp] = str_static(&str_undef);
  1278. X    str_numset(st[sp], (double)retval);
  1279. X    return sp;
  1280. X#else
  1281. X    fatal("syscall() unimplemented");
  1282. X#endif
  1283. X}
  1284. X
  1285. X
  1286. !STUFFY!FUNK!
  1287. echo Extracting arg.h
  1288. sed >arg.h <<'!STUFFY!FUNK!' -e 's/X//'
  1289. X/* $Header: arg.h,v 3.0 89/10/18 15:08:27 lwall Locked $
  1290. X *
  1291. X *    Copyright (c) 1989, Larry Wall
  1292. X *
  1293. X *    You may distribute under the terms of the GNU General Public License
  1294. X *    as specified in the README file that comes with the perl 3.0 kit.
  1295. X *
  1296. X * $Log:    arg.h,v $
  1297. X * Revision 3.0  89/10/18  15:08:27  lwall
  1298. X * 3.0 baseline
  1299. X * 
  1300. X */
  1301. X
  1302. X#define O_NULL 0
  1303. X#define O_ITEM 1
  1304. X#define O_ITEM2 2
  1305. X#define O_ITEM3 3
  1306. X#define O_CONCAT 4
  1307. X#define O_MATCH 5
  1308. X#define O_NMATCH 6
  1309. X#define O_SUBST 7
  1310. X#define O_NSUBST 8
  1311. X#define O_ASSIGN 9
  1312. X#define O_MULTIPLY 10
  1313. X#define O_DIVIDE 11
  1314. X#define O_MODULO 12
  1315. X#define O_ADD 13
  1316. X#define O_SUBTRACT 14
  1317. X#define O_LEFT_SHIFT 15
  1318. X#define O_RIGHT_SHIFT 16
  1319. X#define O_LT 17
  1320. X#define O_GT 18
  1321. X#define O_LE 19
  1322. X#define O_GE 20
  1323. X#define O_EQ 21
  1324. X#define O_NE 22
  1325. X#define O_BIT_AND 23
  1326. X#define O_XOR 24
  1327. X#define O_BIT_OR 25
  1328. X#define O_AND 26
  1329. X#define O_OR 27
  1330. X#define O_COND_EXPR 28
  1331. X#define O_COMMA 29
  1332. X#define O_NEGATE 30
  1333. X#define O_NOT 31
  1334. X#define O_COMPLEMENT 32
  1335. X#define O_WRITE 33
  1336. X#define O_OPEN 34
  1337. X#define O_TRANS 35
  1338. X#define O_NTRANS 36
  1339. X#define O_CLOSE 37
  1340. X#define O_ARRAY 38
  1341. X#define O_HASH 39
  1342. X#define O_LARRAY 40
  1343. X#define O_LHASH 41
  1344. X#define O_PUSH 42
  1345. X#define O_POP 43
  1346. X#define O_SHIFT 44
  1347. X#define O_SPLIT 45
  1348. X#define O_LENGTH 46
  1349. X#define O_SPRINTF 47
  1350. X#define O_SUBSTR 48
  1351. X#define O_JOIN 49
  1352. X#define O_SLT 50
  1353. X#define O_SGT 51
  1354. X#define O_SLE 52
  1355. X#define O_SGE 53
  1356. X#define O_SEQ 54
  1357. X#define O_SNE 55
  1358. X#define O_SUBR 56
  1359. X#define O_PRINT 57
  1360. X#define O_CHDIR 58
  1361. X#define O_DIE 59
  1362. X#define O_EXIT 60
  1363. X#define O_RESET 61
  1364. X#define O_LIST 62
  1365. X#define O_SELECT 63
  1366. X#define O_EOF 64
  1367. X#define O_TELL 65
  1368. X#define O_SEEK 66
  1369. X#define O_LAST 67
  1370. X#define O_NEXT 68
  1371. X#define O_REDO 69
  1372. X#define O_GOTO 70
  1373. X#define O_INDEX 71
  1374. X#define O_TIME 72
  1375. X#define O_TMS 73
  1376. X#define O_LOCALTIME 74
  1377. X#define O_GMTIME 75
  1378. X#define O_STAT 76
  1379. X#define O_CRYPT 77
  1380. X#define O_EXP 78
  1381. X#define O_LOG 79
  1382. X#define O_SQRT 80
  1383. X#define O_INT 81
  1384. X#define O_PRTF 82
  1385. X#define O_ORD 83
  1386. X#define O_SLEEP 84
  1387. X#define O_FLIP 85
  1388. X#define O_FLOP 86
  1389. X#define O_KEYS 87
  1390. X#define O_VALUES 88
  1391. X#define O_EACH 89
  1392. X#define O_CHOP 90
  1393. X#define O_FORK 91
  1394. X#define O_EXEC 92
  1395. X#define O_SYSTEM 93
  1396. X#define O_OCT 94
  1397. X#define O_HEX 95
  1398. X#define O_CHMOD 96
  1399. X#define O_CHOWN 97
  1400. X#define O_KILL 98
  1401. X#define O_RENAME 99
  1402. X#define O_UNLINK 100
  1403. X#define O_UMASK 101
  1404. X#define O_UNSHIFT 102
  1405. X#define O_LINK 103
  1406. X#define O_REPEAT 104
  1407. X#define O_EVAL 105
  1408. X#define O_FTEREAD 106
  1409. X#define O_FTEWRITE 107
  1410. X#define O_FTEEXEC 108
  1411. X#define O_FTEOWNED 109
  1412. X#define O_FTRREAD 110
  1413. X#define O_FTRWRITE 111
  1414. X#define O_FTREXEC 112
  1415. X#define O_FTROWNED 113
  1416. X#define O_FTIS 114
  1417. X#define O_FTZERO 115
  1418. X#define O_FTSIZE 116
  1419. X#define O_FTFILE 117
  1420. X#define O_FTDIR 118
  1421. X#define O_FTLINK 119
  1422. X#define O_SYMLINK 120
  1423. X#define O_FTPIPE 121
  1424. X#define O_FTSOCK 122
  1425. X#define O_FTBLK 123
  1426. X#define O_FTCHR 124
  1427. X#define O_FTSUID 125
  1428. X#define O_FTSGID 126
  1429. X#define O_FTSVTX 127
  1430. X#define O_FTTTY 128
  1431. X#define O_DOFILE 129
  1432. X#define O_FTTEXT 130
  1433. X#define O_FTBINARY 131
  1434. X#define O_UTIME 132
  1435. X#define O_WAIT 133
  1436. X#define O_SORT 134
  1437. X#define O_DELETE 135
  1438. X#define O_STUDY 136
  1439. X#define O_ATAN2 137
  1440. X#define O_SIN 138
  1441. X#define O_COS 139
  1442. X#define O_RAND 140
  1443. X#define O_SRAND 141
  1444. X#define O_POW 142
  1445. X#define O_RETURN 143
  1446. X#define O_GETC 144
  1447. X#define O_MKDIR 145
  1448. X#define O_RMDIR 146
  1449. X#define O_GETPPID 147
  1450. X#define O_GETPGRP 148
  1451. X#define O_SETPGRP 149
  1452. X#define O_GETPRIORITY 150
  1453. X#define O_SETPRIORITY 151
  1454. X#define O_CHROOT 152
  1455. X#define O_IOCTL 153
  1456. X#define O_FCNTL 154
  1457. X#define O_FLOCK 155
  1458. X#define O_RINDEX 156
  1459. X#define O_PACK 157
  1460. X#define O_UNPACK 158
  1461. X#define O_READ 159
  1462. X#define O_WARN 160
  1463. X#define O_DBMOPEN 161
  1464. X#define O_DBMCLOSE 162
  1465. X#define O_ASLICE 163
  1466. X#define O_HSLICE 164
  1467. X#define O_LASLICE 165
  1468. X#define O_LHSLICE 166
  1469. X#define O_F_OR_R 167
  1470. X#define O_RANGE 168
  1471. X#define O_RCAT 169
  1472. X#define O_AASSIGN 170
  1473. X#define O_SASSIGN 171
  1474. X#define O_DUMP 172
  1475. X#define O_REVERSE 173
  1476. X#define O_ADDROF 174
  1477. X#define O_SOCKET 175
  1478. X#define O_BIND 176
  1479. X#define O_CONNECT 177
  1480. X#define O_LISTEN 178
  1481. X#define O_ACCEPT 179
  1482. X#define O_SEND 180
  1483. X#define O_RECV 181
  1484. X#define O_SSELECT 182
  1485. X#define O_SOCKETPAIR 183
  1486. X#define O_DBSUBR 184
  1487. X#define O_DEFINED 185
  1488. X#define O_UNDEF 186
  1489. X#define O_READLINK 187
  1490. X#define O_LSTAT 188
  1491. X#define O_AELEM 189
  1492. X#define O_HELEM 190
  1493. X#define O_LAELEM 191
  1494. X#define O_LHELEM 192
  1495. X#define O_LOCAL 193
  1496. X#define O_UNUSED 194
  1497. X#define O_FILENO 195
  1498. X#define O_GHBYNAME 196
  1499. X#define O_GHBYADDR 197
  1500. X#define O_GHOSTENT 198
  1501. X#define O_SHOSTENT 199
  1502. X#define O_EHOSTENT 200
  1503. X#define O_GSBYNAME 201
  1504. X#define O_GSBYPORT 202
  1505. X#define O_GSERVENT 203
  1506. X#define O_SSERVENT 204
  1507. X#define O_ESERVENT 205
  1508. X#define O_GPBYNAME 206
  1509. X#define O_GPBYNUMBER 207
  1510. X#define O_GPROTOENT 208
  1511. X#define O_SPROTOENT 209
  1512. X#define O_EPROTOENT 210
  1513. X#define O_GNBYNAME 211
  1514. X#define O_GNBYADDR 212
  1515. X#define O_GNETENT 213
  1516. X#define O_SNETENT 214
  1517. X#define O_ENETENT 215
  1518. X#define O_VEC 216
  1519. X#define O_GREP 217
  1520. X#define O_GPWNAM 218
  1521. X#define O_GPWUID 219
  1522. X#define O_GPWENT 220
  1523. X#define O_SPWENT 221
  1524. X#define O_EPWENT 222
  1525. X#define O_GGRNAM 223
  1526. X#define O_GGRGID 224
  1527. X#define O_GGRENT 225
  1528. X#define O_SGRENT 226
  1529. X#define O_EGRENT 227
  1530. X#define O_SHUTDOWN 228
  1531. X#define O_OPENDIR 229
  1532. X#define O_READDIR 230
  1533. X#define O_TELLDIR 231
  1534. X#define O_SEEKDIR 232
  1535. X#define O_REWINDDIR 233
  1536. X#define O_CLOSEDIR 234
  1537. X#define O_GETLOGIN 235
  1538. X#define O_SYSCALL 236
  1539. X#define O_GSOCKOPT 237
  1540. X#define O_SSOCKOPT 238
  1541. X#define O_GETSOCKNAME 239
  1542. X#define O_GETPEERNAME 240
  1543. X#define MAXO 241
  1544. X
  1545. X#ifndef DOINIT
  1546. Xextern char *opname[];
  1547. X#else
  1548. Xchar *opname[] = {
  1549. X    "NULL",
  1550. X    "ITEM",
  1551. X    "ITEM2",
  1552. X    "ITEM3",
  1553. X    "CONCAT",
  1554. X    "MATCH",
  1555. X    "NMATCH",
  1556. X    "SUBST",
  1557. X    "NSUBST",
  1558. X    "ASSIGN",
  1559. X    "MULTIPLY",
  1560. X    "DIVIDE",
  1561. X    "MODULO",
  1562. X    "ADD",
  1563. X    "SUBTRACT",
  1564. X    "LEFT_SHIFT",
  1565. X    "RIGHT_SHIFT",
  1566. X    "LT",
  1567. X    "GT",
  1568. X    "LE",
  1569. X    "GE",
  1570. X    "EQ",
  1571. X    "NE",
  1572. X    "BIT_AND",
  1573. X    "XOR",
  1574. X    "BIT_OR",
  1575. X    "AND",
  1576. X    "OR",
  1577. X    "COND_EXPR",
  1578. X    "COMMA",
  1579. X    "NEGATE",
  1580. X    "NOT",
  1581. X    "COMPLEMENT",
  1582. X    "WRITE",
  1583. X    "OPEN",
  1584. X    "TRANS",
  1585. X    "NTRANS",
  1586. X    "CLOSE",
  1587. X    "ARRAY",
  1588. X    "HASH",
  1589. X    "LARRAY",
  1590. X    "LHASH",
  1591. X    "PUSH",
  1592. X    "POP",
  1593. X    "SHIFT",
  1594. X    "SPLIT",
  1595. X    "LENGTH",
  1596. X    "SPRINTF",
  1597. X    "SUBSTR",
  1598. X    "JOIN",
  1599. X    "SLT",
  1600. X    "SGT",
  1601. X    "SLE",
  1602. X    "SGE",
  1603. X    "SEQ",
  1604. X    "SNE",
  1605. X    "SUBR",
  1606. X    "PRINT",
  1607. X    "CHDIR",
  1608. X    "DIE",
  1609. X    "EXIT",
  1610. X    "RESET",
  1611. X    "LIST",
  1612. X    "SELECT",
  1613. X    "EOF",
  1614. X    "TELL",
  1615. X    "SEEK",
  1616. X    "LAST",
  1617. X    "NEXT",
  1618. X    "REDO",
  1619. X    "GOTO",/* shudder */
  1620. X    "INDEX",
  1621. X    "TIME",
  1622. X    "TIMES",
  1623. X    "LOCALTIME",
  1624. X    "GMTIME",
  1625. X    "STAT",
  1626. X    "CRYPT",
  1627. X    "EXP",
  1628. X    "LOG",
  1629. X    "SQRT",
  1630. X    "INT",
  1631. X    "PRINTF",
  1632. X    "ORD",
  1633. X    "SLEEP",
  1634. X    "FLIP",
  1635. X    "FLOP",
  1636. X    "KEYS",
  1637. X    "VALUES",
  1638. X    "EACH",
  1639. X    "CHOP",
  1640. X    "FORK",
  1641. X    "EXEC",
  1642. X    "SYSTEM",
  1643. X    "OCT",
  1644. X    "HEX",
  1645. X    "CHMOD",
  1646. X    "CHOWN",
  1647. X    "KILL",
  1648. X    "RENAME",
  1649. X    "UNLINK",
  1650. X    "UMASK",
  1651. X    "UNSHIFT",
  1652. X    "LINK",
  1653. X    "REPEAT",
  1654. X    "EVAL",
  1655. X    "FTEREAD",
  1656. X    "FTEWRITE",
  1657. X    "FTEEXEC",
  1658. X    "FTEOWNED",
  1659. X    "FTRREAD",
  1660. X    "FTRWRITE",
  1661. X    "FTREXEC",
  1662. X    "FTROWNED",
  1663. X    "FTIS",
  1664. X    "FTZERO",
  1665. X    "FTSIZE",
  1666. X    "FTFILE",
  1667. X    "FTDIR",
  1668. X    "FTLINK",
  1669. X    "SYMLINK",
  1670. X    "FTPIPE",
  1671. X    "FTSOCK",
  1672. X    "FTBLK",
  1673. X    "FTCHR",
  1674. X    "FTSUID",
  1675. X    "FTSGID",
  1676. X    "FTSVTX",
  1677. X    "FTTTY",
  1678. X    "DOFILE",
  1679. X    "FTTEXT",
  1680. X    "FTBINARY",
  1681. X    "UTIME",
  1682. X    "WAIT",
  1683. X    "SORT",
  1684. X    "DELETE",
  1685. X    "STUDY",
  1686. X    "ATAN2",
  1687. X    "SIN",
  1688. X    "COS",
  1689. X    "RAND",
  1690. X    "SRAND",
  1691. X    "POW",
  1692. X    "RETURN",
  1693. X    "GETC",
  1694. X    "MKDIR",
  1695. X    "RMDIR",
  1696. X    "GETPPID",
  1697. X    "GETPGRP",
  1698. X    "SETPGRP",
  1699. X    "GETPRIORITY",
  1700. X    "SETPRIORITY",
  1701. X    "CHROOT",
  1702. X    "IOCTL",
  1703. X    "FCNTL",
  1704. X    "FLOCK",
  1705. X    "RINDEX",
  1706. X    "PACK",
  1707. X    "UNPACK",
  1708. X    "READ",
  1709. X    "WARN",
  1710. X    "DBMOPEN",
  1711. X    "DBMCLOSE",
  1712. X    "ASLICE",
  1713. X    "HSLICE",
  1714. X    "LASLICE",
  1715. X    "LHSLICE",
  1716. X    "FLIP_OR_RANGE",
  1717. X    "RANGE",
  1718. X    "RCAT",
  1719. X    "AASSIGN",
  1720. X    "SASSIGN",
  1721. X    "DUMP",
  1722. X    "REVERSE",
  1723. X    "ADDRESS_OF",
  1724. X    "SOCKET",
  1725. X    "BIND",
  1726. X    "CONNECT",
  1727. X    "LISTEN",
  1728. X    "ACCEPT",
  1729. X    "SEND",
  1730. X    "RECV",
  1731. X    "SSELECT",
  1732. X    "SOCKETPAIR",
  1733. X    "DBSUBR",
  1734. X    "DEFINED",
  1735. X    "UNDEF",
  1736. X    "READLINK",
  1737. X    "LSTAT",
  1738. X    "AELEM",
  1739. X    "HELEM",
  1740. X    "LAELEM",
  1741. X    "LHELEM",
  1742. X    "LOCAL",
  1743. X    "UNUSED",
  1744. X    "FILENO",
  1745. X    "GHBYNAME",
  1746. X    "GHBYADDR",
  1747. X    "GHOSTENT",
  1748. X    "SHOSTENT",
  1749. X    "EHOSTENT",
  1750. X    "GSBYNAME",
  1751. X    "GSBYPORT",
  1752. X    "GSERVENT",
  1753. X    "SSERVENT",
  1754. X    "ESERVENT",
  1755. X    "GPBYNAME",
  1756. X    "GPBYNUMBER",
  1757. X    "GPROTOENT",
  1758. X    "SPROTOENT",
  1759. X    "EPROTOENT",
  1760. X    "GNBYNAME",
  1761. X    "GNBYADDR",
  1762. X    "GNETENT",
  1763. X    "SNETENT",
  1764. X    "ENETENT",
  1765. X    "VEC",
  1766. X    "GREP",
  1767. X    "GPWNAM",
  1768. X    "GPWUID",
  1769. X    "GPWENT",
  1770. X    "SPWENT",
  1771. X    "EPWENT",
  1772. X    "GGRNAM",
  1773. X    "GGRGID",
  1774. X    "GGRENT",
  1775. X    "SGRENT",
  1776. X    "EGRENT",
  1777. X    "SHUTDOWN",
  1778. X    "OPENDIR",
  1779. X    "READDIR",
  1780. X    "TELLDIR",
  1781. X    "SEEKDIR",
  1782. X    "REWINDDIR",
  1783. X    "CLOSEDIR",
  1784. X    "GETLOGIN",
  1785. X    "SYSCALL",
  1786. X    "GSOCKOPT",
  1787. X    "SSOCKOPT",
  1788. X    "GETSOCKNAME",
  1789. X    "GETPEERNAME",
  1790. X    "241"
  1791. X};
  1792. X#endif
  1793. X
  1794. X#define A_NULL 0
  1795. X#define A_EXPR 1
  1796. X#define A_CMD 2
  1797. X#define A_STAB 3
  1798. X#define A_LVAL 4
  1799. X#define A_SINGLE 5
  1800. X#define A_DOUBLE 6
  1801. X#define A_BACKTICK 7
  1802. X#define A_READ 8
  1803. X#define A_SPAT 9
  1804. X#define A_LEXPR 10
  1805. X#define A_ARYLEN 11
  1806. X#define A_ARYSTAB 12
  1807. X#define A_LARYLEN 13
  1808. X#define A_GLOB 14
  1809. X#define A_WORD 15
  1810. X#define A_INDREAD 16
  1811. X#define A_LARYSTAB 17
  1812. X#define A_STAR 18
  1813. X#define A_LSTAR 19
  1814. X#define A_WANTARRAY 20
  1815. X
  1816. X#define A_MASK 31
  1817. X#define A_DONT 32        /* or this into type to suppress evaluation */
  1818. X
  1819. X#ifndef DOINIT
  1820. Xextern char *argname[];
  1821. X#else
  1822. Xchar *argname[] = {
  1823. X    "A_NULL",
  1824. X    "EXPR",
  1825. X    "CMD",
  1826. X    "STAB",
  1827. X    "LVAL",
  1828. X    "SINGLE",
  1829. X    "DOUBLE",
  1830. X    "BACKTICK",
  1831. X    "READ",
  1832. X    "SPAT",
  1833. X    "LEXPR",
  1834. X    "ARYLEN",
  1835. X    "ARYSTAB",
  1836. X    "LARYLEN",
  1837. X    "GLOB",
  1838. X    "WORD",
  1839. X    "INDREAD",
  1840. X    "LARYSTAB",
  1841. X    "STAR",
  1842. X    "LSTAR",
  1843. X    "WANTARRAY",
  1844. X    "21"
  1845. X};
  1846. X#endif
  1847. X
  1848. X#ifndef DOINIT
  1849. Xextern bool hoistable[];
  1850. X#else
  1851. Xbool hoistable[] =
  1852. X  {0,    /* A_NULL */
  1853. X   0,    /* EXPR */
  1854. X   1,    /* CMD */
  1855. X   1,    /* STAB */
  1856. X   0,    /* LVAL */
  1857. X   1,    /* SINGLE */
  1858. X   0,    /* DOUBLE */
  1859. X   0,    /* BACKTICK */
  1860. X   0,    /* READ */
  1861. X   0,    /* SPAT */
  1862. X   0,    /* LEXPR */
  1863. X   1,    /* ARYLEN */
  1864. X   1,    /* ARYSTAB */
  1865. X   0,    /* LARYLEN */
  1866. X   0,    /* GLOB */
  1867. X   1,    /* WORD */
  1868. X   0,    /* INDREAD */
  1869. X   0,    /* LARYSTAB */
  1870. X   1,    /* STAR */
  1871. X   1,    /* LSTAR */
  1872. X   1,    /* WANTARRAY */
  1873. X   0,    /* 21 */
  1874. X};
  1875. X#endif
  1876. X
  1877. Xunion argptr {
  1878. X    ARG        *arg_arg;
  1879. X    char    *arg_cval;
  1880. X    STAB    *arg_stab;
  1881. X    SPAT    *arg_spat;
  1882. X    CMD        *arg_cmd;
  1883. X    STR        *arg_str;
  1884. X    HASH    *arg_hash;
  1885. X};
  1886. X
  1887. Xstruct arg {
  1888. X    union argptr arg_ptr;
  1889. X    short    arg_len;
  1890. X#ifdef mips
  1891. X    short    pad;
  1892. X#endif
  1893. X    unsigned char arg_type;
  1894. X    unsigned char arg_flags;
  1895. X};
  1896. X
  1897. X#define AF_ARYOK 1        /* op can handle multiple values here */
  1898. X#define AF_POST 2        /* post *crement this item */
  1899. X#define AF_PRE 4        /* pre *crement this item */
  1900. X#define AF_UP 8            /* increment rather than decrement */
  1901. X#define AF_COMMON 16        /* left and right have symbols in common */
  1902. X#define AF_UNUSED 32        /*  */
  1903. X#define AF_LISTISH 64        /* turn into list if important */
  1904. X#define AF_LOCAL 128        /* list of local variables */
  1905. X
  1906. X/*
  1907. X * Most of the ARG pointers are used as pointers to arrays of ARG.  When
  1908. X * so used, the 0th element is special, and represents the operator to
  1909. X * use on the list of arguments following.  The arg_len in the 0th element
  1910. X * gives the maximum argument number, and the arg_str is used to store
  1911. X * the return value in a more-or-less static location.  Sorry it's not
  1912. X * re-entrant (yet), but it sure makes it efficient.  The arg_type of the
  1913. X * 0th element is an operator (O_*) rather than an argument type (A_*).
  1914. X */
  1915. X
  1916. X#define Nullarg Null(ARG*)
  1917. X
  1918. X#ifndef DOINIT
  1919. XEXT char opargs[MAXO+1];
  1920. X#else
  1921. X#define A(e1,e2,e3) (e1+(e2<<2)+(e3<<4))
  1922. Xchar opargs[MAXO+1] = {
  1923. X    A(0,0,0),    /* NULL */
  1924. X    A(1,0,0),    /* ITEM */
  1925. X    A(0,0,0),    /* ITEM2 */
  1926. X    A(0,0,0),    /* ITEM3 */
  1927. X    A(1,1,0),    /* CONCAT */
  1928. X    A(1,0,0),    /* MATCH */
  1929. X    A(1,0,0),    /* NMATCH */
  1930. X    A(1,0,0),    /* SUBST */
  1931. X    A(1,0,0),    /* NSUBST */
  1932. X    A(1,1,0),    /* ASSIGN */
  1933. X    A(1,1,0),    /* MULTIPLY */
  1934. X    A(1,1,0),    /* DIVIDE */
  1935. X    A(1,1,0),    /* MODULO */
  1936. X    A(1,1,0),    /* ADD */
  1937. X    A(1,1,0),    /* SUBTRACT */
  1938. X    A(1,1,0),    /* LEFT_SHIFT */
  1939. X    A(1,1,0),    /* RIGHT_SHIFT */
  1940. X    A(1,1,0),    /* LT */
  1941. X    A(1,1,0),    /* GT */
  1942. X    A(1,1,0),    /* LE */
  1943. X    A(1,1,0),    /* GE */
  1944. X    A(1,1,0),    /* EQ */
  1945. X    A(1,1,0),    /* NE */
  1946. X    A(1,1,0),    /* BIT_AND */
  1947. X    A(1,1,0),    /* XOR */
  1948. X    A(1,1,0),    /* BIT_OR */
  1949. X    A(1,0,0),    /* AND */
  1950. X    A(1,0,0),    /* OR */
  1951. X    A(1,0,0),    /* COND_EXPR */
  1952. X    A(1,1,0),    /* COMMA */
  1953. X    A(1,0,0),    /* NEGATE */
  1954. X    A(1,0,0),    /* NOT */
  1955. X    A(1,0,0),    /* COMPLEMENT */
  1956. X    A(1,0,0),    /* WRITE */
  1957. X    A(1,1,0),    /* OPEN */
  1958. X    A(1,0,0),    /* TRANS */
  1959. X    A(1,0,0),    /* NTRANS */
  1960. X    A(1,0,0),    /* CLOSE */
  1961. X    A(0,0,0),    /* ARRAY */
  1962. X    A(0,0,0),    /* HASH */
  1963. X    A(0,0,0),    /* LARRAY */
  1964. X    A(0,0,0),    /* LHASH */
  1965. X    A(0,3,0),    /* PUSH */
  1966. X    A(0,0,0),    /* POP */
  1967. X    A(0,0,0),    /* SHIFT */
  1968. X    A(1,0,1),    /* SPLIT */
  1969. X    A(1,0,0),    /* LENGTH */
  1970. X    A(3,0,0),    /* SPRINTF */
  1971. X    A(1,1,1),    /* SUBSTR */
  1972. X    A(1,3,0),    /* JOIN */
  1973. X    A(1,1,0),    /* SLT */
  1974. X    A(1,1,0),    /* SGT */
  1975. X    A(1,1,0),    /* SLE */
  1976. X    A(1,1,0),    /* SGE */
  1977. X    A(1,1,0),    /* SEQ */
  1978. X    A(1,1,0),    /* SNE */
  1979. X    A(0,3,0),    /* SUBR */
  1980. X    A(1,3,0),    /* PRINT */
  1981. X    A(1,0,0),    /* CHDIR */
  1982. X    A(0,3,0),    /* DIE */
  1983. X    A(1,0,0),    /* EXIT */
  1984. X    A(1,0,0),    /* RESET */
  1985. X    A(3,0,0),    /* LIST */
  1986. X    A(1,0,0),    /* SELECT */
  1987. X    A(1,0,0),    /* EOF */
  1988. X    A(1,0,0),    /* TELL */
  1989. X    A(1,1,1),    /* SEEK */
  1990. X    A(0,0,0),    /* LAST */
  1991. X    A(0,0,0),    /* NEXT */
  1992. X    A(0,0,0),    /* REDO */
  1993. X    A(0,0,0),    /* GOTO */
  1994. X    A(1,1,0),    /* INDEX */
  1995. X    A(0,0,0),    /* TIME */
  1996. X    A(0,0,0),    /* TIMES */
  1997. X    A(1,0,0),    /* LOCALTIME */
  1998. X    A(1,0,0),    /* GMTIME */
  1999. X    A(1,0,0),    /* STAT */
  2000. X    A(1,1,0),    /* CRYPT */
  2001. X    A(1,0,0),    /* EXP */
  2002. X    A(1,0,0),    /* LOG */
  2003. X    A(1,0,0),    /* SQRT */
  2004. X    A(1,0,0),    /* INT */
  2005. X    A(1,3,0),    /* PRINTF */
  2006. X    A(1,0,0),    /* ORD */
  2007. X    A(1,0,0),    /* SLEEP */
  2008. X    A(1,0,0),    /* FLIP */
  2009. X    A(0,1,0),    /* FLOP */
  2010. X    A(0,0,0),    /* KEYS */
  2011. X    A(0,0,0),    /* VALUES */
  2012. X    A(0,0,0),    /* EACH */
  2013. X    A(3,0,0),    /* CHOP */
  2014. X    A(0,0,0),    /* FORK */
  2015. X    A(1,3,0),    /* EXEC */
  2016. X    A(1,3,0),    /* SYSTEM */
  2017. X    A(1,0,0),    /* OCT */
  2018. X    A(1,0,0),    /* HEX */
  2019. X    A(0,3,0),    /* CHMOD */
  2020. X    A(0,3,0),    /* CHOWN */
  2021. X    A(0,3,0),    /* KILL */
  2022. X    A(1,1,0),    /* RENAME */
  2023. X    A(0,3,0),    /* UNLINK */
  2024. X    A(1,0,0),    /* UMASK */
  2025. X    A(0,3,0),    /* UNSHIFT */
  2026. X    A(1,1,0),    /* LINK */
  2027. X    A(1,1,0),    /* REPEAT */
  2028. X    A(1,0,0),    /* EVAL */
  2029. X    A(1,0,0),    /* FTEREAD */
  2030. X    A(1,0,0),    /* FTEWRITE */
  2031. X    A(1,0,0),    /* FTEEXEC */
  2032. X    A(1,0,0),    /* FTEOWNED */
  2033. X    A(1,0,0),    /* FTRREAD */
  2034. X    A(1,0,0),    /* FTRWRITE */
  2035. X    A(1,0,0),    /* FTREXEC */
  2036. X    A(1,0,0),    /* FTROWNED */
  2037. X    A(1,0,0),    /* FTIS */
  2038. X    A(1,0,0),    /* FTZERO */
  2039. X    A(1,0,0),    /* FTSIZE */
  2040. X    A(1,0,0),    /* FTFILE */
  2041. X    A(1,0,0),    /* FTDIR */
  2042. X    A(1,0,0),    /* FTLINK */
  2043. X    A(1,1,0),    /* SYMLINK */
  2044. X    A(1,0,0),    /* FTPIPE */
  2045. X    A(1,0,0),    /* FTSOCK */
  2046. X    A(1,0,0),    /* FTBLK */
  2047. X    A(1,0,0),    /* FTCHR */
  2048. X    A(1,0,0),    /* FTSUID */
  2049. X    A(1,0,0),    /* FTSGID */
  2050. X    A(1,0,0),    /* FTSVTX */
  2051. X    A(1,0,0),    /* FTTTY */
  2052. X    A(1,0,0),    /* DOFILE */
  2053. X    A(1,0,0),    /* FTTEXT */
  2054. X    A(1,0,0),    /* FTBINARY */
  2055. X    A(0,3,0),    /* UTIME */
  2056. X    A(0,0,0),    /* WAIT */
  2057. X    A(1,3,0),    /* SORT */
  2058. X    A(0,1,0),    /* DELETE */
  2059. X    A(1,0,0),    /* STUDY */
  2060. X    A(1,1,0),    /* ATAN2 */
  2061. X    A(1,0,0),    /* SIN */
  2062. X    A(1,0,0),    /* COS */
  2063. X    A(1,0,0),    /* RAND */
  2064. X    A(1,0,0),    /* SRAND */
  2065. X    A(1,1,0),    /* POW */
  2066. X    A(0,3,0),    /* RETURN */
  2067. X    A(1,0,0),    /* GETC */
  2068. X    A(1,1,0),    /* MKDIR */
  2069. X    A(1,0,0),    /* RMDIR */
  2070. X    A(0,0,0),    /* GETPPID */
  2071. X    A(1,0,0),    /* GETPGRP */
  2072. X    A(1,1,0),    /* SETPGRP */
  2073. X    A(1,1,0),    /* GETPRIORITY */
  2074. X    A(1,1,1),    /* SETPRIORITY */
  2075. X    A(1,0,0),    /* CHROOT */
  2076. X    A(1,1,1),    /* IOCTL */
  2077. X    A(1,1,1),    /* FCNTL */
  2078. X    A(1,1,0),    /* FLOCK */
  2079. X    A(1,1,0),    /* RINDEX */
  2080. X    A(1,3,0),    /* PACK */
  2081. X    A(1,1,0),    /* UNPACK */
  2082. X    A(1,1,1),    /* READ */
  2083. X    A(0,3,0),    /* WARN */
  2084. X    A(1,1,1),    /* DBMOPEN */
  2085. X    A(1,0,0),    /* DBMCLOSE */
  2086. X    A(0,3,0),    /* ASLICE */
  2087. X    A(0,3,0),    /* HSLICE */
  2088. X    A(0,3,0),    /* LASLICE */
  2089. X    A(0,3,0),    /* LHSLICE */
  2090. X    A(1,0,0),    /* F_OR_R */
  2091. X    A(1,1,0),    /* RANGE */
  2092. X    A(1,1,0),    /* RCAT */
  2093. X    A(3,3,0),    /* AASSIGN */
  2094. X    A(0,0,0),    /* SASSIGN */
  2095. X    A(0,0,0),    /* DUMP */
  2096. X    A(0,0,0),    /* REVERSE */
  2097. X    A(1,0,0),    /* ADDROF */
  2098. X    A(1,1,1),    /* SOCKET */
  2099. X    A(1,1,0),    /* BIND */
  2100. X    A(1,1,0),    /* CONNECT */
  2101. X    A(1,1,0),    /* LISTEN */
  2102. X    A(1,1,0),    /* ACCEPT */
  2103. X    A(1,1,2),    /* SEND */
  2104. X    A(1,1,1),    /* RECV */
  2105. X    A(1,1,1),    /* SSELECT */
  2106. X    A(1,1,1),    /* SOCKETPAIR */
  2107. X    A(0,3,0),    /* DBSUBR */
  2108. X    A(1,0,0),    /* DEFINED */
  2109. X    A(1,0,0),    /* UNDEF */
  2110. X    A(1,0,0),    /* READLINK */
  2111. X    A(1,0,0),    /* LSTAT */
  2112. X    A(0,1,0),    /* AELEM */
  2113. X    A(0,1,0),    /* HELEM */
  2114. X    A(0,1,0),    /* LAELEM */
  2115. X    A(0,1,0),    /* LHELEM */
  2116. X    A(1,0,0),    /* LOCAL */
  2117. X    A(0,0,0),    /* UNUSED */
  2118. X    A(1,0,0),    /* FILENO */
  2119. X    A(1,0,0),    /* GHBYNAME */
  2120. X    A(1,1,0),    /* GHBYADDR */
  2121. X    A(0,0,0),    /* GHOSTENT */
  2122. X    A(1,0,0),    /* SHOSTENT */
  2123. X    A(0,0,0),    /* EHOSTENT */
  2124. X    A(1,1,0),    /* GSBYNAME */
  2125. X    A(1,1,0),    /* GSBYPORT */
  2126. X    A(0,0,0),    /* GSERVENT */
  2127. X    A(1,0,0),    /* SSERVENT */
  2128. X    A(0,0,0),    /* ESERVENT */
  2129. X    A(1,0,0),    /* GPBYNAME */
  2130. X    A(1,0,0),    /* GPBYNUMBER */
  2131. X    A(0,0,0),    /* GPROTOENT */
  2132. X    A(1,0,0),    /* SPROTOENT */
  2133. X    A(0,0,0),    /* EPROTOENT */
  2134. X    A(1,0,0),    /* GNBYNAME */
  2135. X    A(1,1,0),    /* GNBYADDR */
  2136. X    A(0,0,0),    /* GNETENT */
  2137. X    A(1,0,0),    /* SNETENT */
  2138. X    A(0,0,0),    /* ENETENT */
  2139. X    A(1,1,1),    /* VEC */
  2140. X    A(0,3,0),    /* GREP */
  2141. X    A(1,0,0),    /* GPWNAM */
  2142. X    A(1,0,0),    /* GPWUID */
  2143. X    A(0,0,0),    /* GPWENT */
  2144. X    A(0,0,0),    /* SPWENT */
  2145. X    A(0,0,0),    /* EPWENT */
  2146. X    A(1,0,0),    /* GGRNAM */
  2147. X    A(1,0,0),    /* GGRGID */
  2148. X    A(0,0,0),    /* GGRENT */
  2149. X    A(0,0,0),    /* SGRENT */
  2150. X    A(0,0,0),    /* EGRENT */
  2151. X    A(1,1,0),    /* SHUTDOWN */
  2152. X    A(1,1,0),    /* OPENDIR */
  2153. X    A(1,0,0),    /* READDIR */
  2154. X    A(1,0,0),    /* TELLDIR */
  2155. X    A(1,1,0),    /* SEEKDIR */
  2156. X    A(1,0,0),    /* REWINDDIR */
  2157. X    A(1,0,0),    /* CLOSEDIR */
  2158. X    A(0,0,0),    /* GETLOGIN */
  2159. X    A(1,3,0),    /* SYSCALL */
  2160. X    A(1,1,1),    /* GSOCKOPT */
  2161. X    A(1,1,1),    /* SSOCKOPT */
  2162. X    A(1,0,0),    /* GETSOCKNAME */
  2163. X    A(1,0,0),    /* GETPEERNAME */
  2164. X    0
  2165. X};
  2166. X#undef A
  2167. X#endif
  2168. X
  2169. Xint do_trans();
  2170. Xint do_split();
  2171. Xbool do_eof();
  2172. Xlong do_tell();
  2173. Xbool do_seek();
  2174. Xint do_tms();
  2175. Xint do_time();
  2176. Xint do_stat();
  2177. XSTR *do_push();
  2178. XFILE *nextargv();
  2179. XSTR *do_fttext();
  2180. Xint do_slice();
  2181. !STUFFY!FUNK!
  2182. echo ""
  2183. echo "End of kit 11 (of 24)"
  2184. cat /dev/null >kit11isdone
  2185. run=''
  2186. config=''
  2187. for iskit in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24; do
  2188.     if test -f kit${iskit}isdone; then
  2189.     run="$run $iskit"
  2190.     else
  2191.     todo="$todo $iskit"
  2192.     fi
  2193. done
  2194. case $todo in
  2195.     '')
  2196.     echo "You have run all your kits.  Please read README and then type Configure."
  2197.     chmod 755 Configure
  2198.     ;;
  2199.     *)  echo "You have run$run."
  2200.     echo "You still need to run$todo."
  2201.     ;;
  2202. esac
  2203. : Someone might mail this, so...
  2204. exit
  2205.  
  2206.