home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume18 / perl / part06 < prev    next >
Internet Message Format  |  1991-04-14  |  52KB

  1. From: lwall@netlabs.com (Larry Wall)
  2. Newsgroups: comp.sources.misc
  3. Subject: v18i024:  perl - The perl programming language, Part06/36
  4. Message-ID: <1991Apr15.015344.6777@sparky.IMD.Sterling.COM>
  5. Date: 15 Apr 91 01:53:44 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: 8df5aaf0 b41671c9 a7fde89c a0c9781f
  8.  
  9. Submitted-by: Larry Wall <lwall@netlabs.com>
  10. Posting-number: Volume 18, Issue 24
  11. Archive-name: perl/part06
  12.  
  13. [There are 36 kits for perl version 4.0.]
  14.  
  15. #! /bin/sh
  16.  
  17. # Make a new directory for the perl sources, cd to it, and run kits 1
  18. # thru 36 through sh.  When all 36 kits have been run, read README.
  19.  
  20. echo "This is perl 4.0 kit 6 (of 36).  If kit 6 is complete, the line"
  21. echo '"'"End of kit 6 (of 36)"'" will echo at the end.'
  22. echo ""
  23. export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
  24. mkdir  2>/dev/null
  25. echo Extracting eval.c:AA
  26. sed >eval.c:AA <<'!STUFFY!FUNK!' -e 's/X//'
  27. X/* $RCSfile: eval.c,v $$Revision: 4.0.1.1 $$Date: 91/04/11 17:43:48 $
  28. X *
  29. X *    Copyright (c) 1989, Larry Wall
  30. X *
  31. X *    You may distribute under the terms of the GNU General Public License
  32. X *    as specified in the README file that comes with the perl 3.0 kit.
  33. X *
  34. X * $Log:    eval.c,v $
  35. X * Revision 4.0.1.1  91/04/11  17:43:48  lwall
  36. X * patch1: fixed failed fork to return undef as documented
  37. X * patch1: reduced maximum branch distance in eval.c
  38. X * 
  39. X * Revision 4.0  91/03/20  01:16:48  lwall
  40. X * 4.0 baseline.
  41. X * 
  42. X */
  43. X
  44. X#include "EXTERN.h"
  45. X#include "perl.h"
  46. X
  47. X#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
  48. X#include <signal.h>
  49. X#endif
  50. X
  51. X#ifdef I_FCNTL
  52. X#include <fcntl.h>
  53. X#endif
  54. X#ifdef I_SYS_FILE
  55. X#include <sys/file.h>
  56. X#endif
  57. X#ifdef I_VFORK
  58. X#   include <vfork.h>
  59. X#endif
  60. X
  61. X#ifdef VOIDSIG
  62. Xstatic void (*ihand)();
  63. Xstatic void (*qhand)();
  64. X#else
  65. Xstatic int (*ihand)();
  66. Xstatic int (*qhand)();
  67. X#endif
  68. X
  69. XARG *debarg;
  70. XSTR str_args;
  71. Xstatic STAB *stab2;
  72. Xstatic STIO *stio;
  73. Xstatic struct lstring *lstr;
  74. Xstatic int old_rschar;
  75. Xstatic int old_rslen;
  76. X
  77. Xdouble sin(), cos(), atan2(), pow();
  78. X
  79. Xchar *getlogin();
  80. X
  81. Xint
  82. Xeval(arg,gimme,sp)
  83. Xregister ARG *arg;
  84. Xint gimme;
  85. Xregister int sp;
  86. X{
  87. X    register STR *str;
  88. X    register int anum;
  89. X    register int optype;
  90. X    register STR **st;
  91. X    int maxarg;
  92. X    double value;
  93. X    register char *tmps;
  94. X    char *tmps2;
  95. X    int argflags;
  96. X    int argtype;
  97. X    union argptr argptr;
  98. X    int arglast[8];    /* highest sp for arg--valid only for non-O_LIST args */
  99. X    unsigned long tmplong;
  100. X    long when;
  101. X    FILE *fp;
  102. X    STR *tmpstr;
  103. X    FCMD *form;
  104. X    STAB *stab;
  105. X    ARRAY *ary;
  106. X    bool assigning = FALSE;
  107. X    double exp(), log(), sqrt(), modf();
  108. X    char *crypt(), *getenv();
  109. X    extern void grow_dlevel();
  110. X
  111. X    if (!arg)
  112. X    goto say_undef;
  113. X    optype = arg->arg_type;
  114. X    maxarg = arg->arg_len;
  115. X    arglast[0] = sp;
  116. X    str = arg->arg_ptr.arg_str;
  117. X    if (sp + maxarg > stack->ary_max)
  118. X    astore(stack, sp + maxarg, Nullstr);
  119. X    st = stack->ary_array;
  120. X
  121. X#ifdef DEBUGGING
  122. X    if (debug) {
  123. X    if (debug & 8) {
  124. X        deb("%s (%lx) %d args:\n",opname[optype],arg,maxarg);
  125. X    }
  126. X    debname[dlevel] = opname[optype][0];
  127. X    debdelim[dlevel] = ':';
  128. X    if (++dlevel >= dlmax)
  129. X        grow_dlevel();
  130. X    }
  131. X#endif
  132. X
  133. X    for (anum = 1; anum <= maxarg; anum++) {
  134. X    argflags = arg[anum].arg_flags;
  135. X    argtype = arg[anum].arg_type;
  136. X    argptr = arg[anum].arg_ptr;
  137. X      re_eval:
  138. X    switch (argtype) {
  139. X    default:
  140. X        st[++sp] = &str_undef;
  141. X#ifdef DEBUGGING
  142. X        tmps = "NULL";
  143. X#endif
  144. X        break;
  145. X    case A_EXPR:
  146. X#ifdef DEBUGGING
  147. X        if (debug & 8) {
  148. X        tmps = "EXPR";
  149. X        deb("%d.EXPR =>\n",anum);
  150. X        }
  151. X#endif
  152. X        sp = eval(argptr.arg_arg,
  153. X        (argflags & AF_ARYOK) ? G_ARRAY : G_SCALAR, sp);
  154. X        if (sp + (maxarg - anum) > stack->ary_max)
  155. X        astore(stack, sp + (maxarg - anum), Nullstr);
  156. X        st = stack->ary_array;    /* possibly reallocated */
  157. X        break;
  158. X    case A_CMD:
  159. X#ifdef DEBUGGING
  160. X        if (debug & 8) {
  161. X        tmps = "CMD";
  162. X        deb("%d.CMD (%lx) =>\n",anum,argptr.arg_cmd);
  163. X        }
  164. X#endif
  165. X        sp = cmd_exec(argptr.arg_cmd, gimme, sp);
  166. X        if (sp + (maxarg - anum) > stack->ary_max)
  167. X        astore(stack, sp + (maxarg - anum), Nullstr);
  168. X        st = stack->ary_array;    /* possibly reallocated */
  169. X        break;
  170. X    case A_LARYSTAB:
  171. X        ++sp;
  172. X        switch (optype) {
  173. X        case O_ITEM2: argtype = 2; break;
  174. X        case O_ITEM3: argtype = 3; break;
  175. X        default:      argtype = anum; break;
  176. X        }
  177. X        str = afetch(stab_array(argptr.arg_stab),
  178. X        arg[argtype].arg_len - arybase, TRUE);
  179. X#ifdef DEBUGGING
  180. X        if (debug & 8) {
  181. X        (void)sprintf(buf,"LARYSTAB $%s[%d]",stab_name(argptr.arg_stab),
  182. X            arg[argtype].arg_len);
  183. X        tmps = buf;
  184. X        }
  185. X#endif
  186. X        goto do_crement;
  187. X    case A_ARYSTAB:
  188. X        switch (optype) {
  189. X        case O_ITEM2: argtype = 2; break;
  190. X        case O_ITEM3: argtype = 3; break;
  191. X        default:      argtype = anum; break;
  192. X        }
  193. X        st[++sp] = afetch(stab_array(argptr.arg_stab),
  194. X        arg[argtype].arg_len - arybase, FALSE);
  195. X#ifdef DEBUGGING
  196. X        if (debug & 8) {
  197. X        (void)sprintf(buf,"ARYSTAB $%s[%d]",stab_name(argptr.arg_stab),
  198. X            arg[argtype].arg_len);
  199. X        tmps = buf;
  200. X        }
  201. X#endif
  202. X        break;
  203. X    case A_STAR:
  204. X        stab = argptr.arg_stab;
  205. X        st[++sp] = (STR*)stab;
  206. X        if (!stab_xarray(stab))
  207. X        aadd(stab);
  208. X        if (!stab_xhash(stab))
  209. X        hadd(stab);
  210. X        if (!stab_io(stab))
  211. X        stab_io(stab) = stio_new();
  212. X#ifdef DEBUGGING
  213. X        if (debug & 8) {
  214. X        (void)sprintf(buf,"STAR *%s",stab_name(argptr.arg_stab));
  215. X        tmps = buf;
  216. X        }
  217. X#endif
  218. X        break;
  219. X    case A_LSTAR:
  220. X        str = st[++sp] = (STR*)argptr.arg_stab;
  221. X#ifdef DEBUGGING
  222. X        if (debug & 8) {
  223. X        (void)sprintf(buf,"LSTAR *%s",stab_name(argptr.arg_stab));
  224. X        tmps = buf;
  225. X        }
  226. X#endif
  227. X        break;
  228. X    case A_STAB:
  229. X        st[++sp] = STAB_STR(argptr.arg_stab);
  230. X#ifdef DEBUGGING
  231. X        if (debug & 8) {
  232. X        (void)sprintf(buf,"STAB $%s",stab_name(argptr.arg_stab));
  233. X        tmps = buf;
  234. X        }
  235. X#endif
  236. X        break;
  237. X    case A_LEXPR:
  238. X#ifdef DEBUGGING
  239. X        if (debug & 8) {
  240. X        tmps = "LEXPR";
  241. X        deb("%d.LEXPR =>\n",anum);
  242. X        }
  243. X#endif
  244. X        if (argflags & AF_ARYOK) {
  245. X        sp = eval(argptr.arg_arg, G_ARRAY, sp);
  246. X        if (sp + (maxarg - anum) > stack->ary_max)
  247. X            astore(stack, sp + (maxarg - anum), Nullstr);
  248. X        st = stack->ary_array;    /* possibly reallocated */
  249. X        }
  250. X        else {
  251. X        sp = eval(argptr.arg_arg, G_SCALAR, sp);
  252. X        st = stack->ary_array;    /* possibly reallocated */
  253. X        str = st[sp];
  254. X        goto do_crement;
  255. X        }
  256. X        break;
  257. X    case A_LVAL:
  258. X#ifdef DEBUGGING
  259. X        if (debug & 8) {
  260. X        (void)sprintf(buf,"LVAL $%s",stab_name(argptr.arg_stab));
  261. X        tmps = buf;
  262. X        }
  263. X#endif
  264. X        ++sp;
  265. X        str = STAB_STR(argptr.arg_stab);
  266. X        if (!str)
  267. X        fatal("panic: A_LVAL");
  268. X      do_crement:
  269. X        assigning = TRUE;
  270. X        if (argflags & AF_PRE) {
  271. X        if (argflags & AF_UP)
  272. X            str_inc(str);
  273. X        else
  274. X            str_dec(str);
  275. X        STABSET(str);
  276. X        st[sp] = str;
  277. X        str = arg->arg_ptr.arg_str;
  278. X        }
  279. X        else if (argflags & AF_POST) {
  280. X        st[sp] = str_mortal(str);
  281. X        if (argflags & AF_UP)
  282. X            str_inc(str);
  283. X        else
  284. X            str_dec(str);
  285. X        STABSET(str);
  286. X        str = arg->arg_ptr.arg_str;
  287. X        }
  288. X        else
  289. X        st[sp] = str;
  290. X        break;
  291. X    case A_LARYLEN:
  292. X        ++sp;
  293. X        stab = argptr.arg_stab;
  294. X        str = stab_array(argptr.arg_stab)->ary_magic;
  295. X        if (optype != O_SASSIGN || argflags & (AF_PRE|AF_POST))
  296. X        str_numset(str,(double)(stab_array(stab)->ary_fill+arybase));
  297. X#ifdef DEBUGGING
  298. X        tmps = "LARYLEN";
  299. X#endif
  300. X        if (!str)
  301. X        fatal("panic: A_LEXPR");
  302. X        goto do_crement;
  303. X    case A_ARYLEN:
  304. X        stab = argptr.arg_stab;
  305. X        st[++sp] = stab_array(stab)->ary_magic;
  306. X        str_numset(st[sp],(double)(stab_array(stab)->ary_fill+arybase));
  307. X#ifdef DEBUGGING
  308. X        tmps = "ARYLEN";
  309. X#endif
  310. X        break;
  311. X    case A_SINGLE:
  312. X        st[++sp] = argptr.arg_str;
  313. X#ifdef DEBUGGING
  314. X        tmps = "SINGLE";
  315. X#endif
  316. X        break;
  317. X    case A_DOUBLE:
  318. X        (void) interp(str,argptr.arg_str,sp);
  319. X        st = stack->ary_array;
  320. X        st[++sp] = str;
  321. X#ifdef DEBUGGING
  322. X        tmps = "DOUBLE";
  323. X#endif
  324. X        break;
  325. X    case A_BACKTICK:
  326. X        tmps = str_get(interp(str,argptr.arg_str,sp));
  327. X        st = stack->ary_array;
  328. X#ifdef TAINT
  329. X        taintproper("Insecure dependency in ``");
  330. X#endif
  331. X        fp = mypopen(tmps,"r");
  332. X        str_set(str,"");
  333. X        if (fp) {
  334. X        if (gimme == G_SCALAR) {
  335. X            while (str_gets(str,fp,str->str_cur) != Nullch)
  336. X            ;
  337. X        }
  338. X        else {
  339. X            for (;;) {
  340. X            if (++sp > stack->ary_max) {
  341. X                astore(stack, sp, Nullstr);
  342. X                st = stack->ary_array;
  343. X            }
  344. X            str = st[sp] = Str_new(56,80);
  345. X            if (str_gets(str,fp,0) == Nullch) {
  346. X                sp--;
  347. X                break;
  348. X            }
  349. X            if (str->str_len - str->str_cur > 20) {
  350. X                str->str_len = str->str_cur+1;
  351. X                Renew(str->str_ptr, str->str_len, char);
  352. X            }
  353. X            str_2mortal(str);
  354. X            }
  355. X        }
  356. X        statusvalue = mypclose(fp);
  357. X        }
  358. X        else
  359. X        statusvalue = -1;
  360. X
  361. X        if (gimme == G_SCALAR)
  362. X        st[++sp] = str;
  363. X#ifdef DEBUGGING
  364. X        tmps = "BACK";
  365. X#endif
  366. X        break;
  367. X    case A_WANTARRAY:
  368. X        {
  369. X        if (curcsv->wantarray == G_ARRAY)
  370. X            st[++sp] = &str_yes;
  371. X        else
  372. X            st[++sp] = &str_no;
  373. X        }
  374. X#ifdef DEBUGGING
  375. X        tmps = "WANTARRAY";
  376. X#endif
  377. X        break;
  378. X    case A_INDREAD:
  379. X        last_in_stab = stabent(str_get(STAB_STR(argptr.arg_stab)),TRUE);
  380. X        old_rschar = rschar;
  381. X        old_rslen = rslen;
  382. X        goto do_read;
  383. X    case A_GLOB:
  384. X        argflags |= AF_POST;    /* enable newline chopping */
  385. X        last_in_stab = argptr.arg_stab;
  386. X        old_rschar = rschar;
  387. X        old_rslen = rslen;
  388. X        rslen = 1;
  389. X#ifdef MSDOS
  390. X        rschar = 0;
  391. X#else
  392. X#ifdef CSH
  393. X        rschar = 0;
  394. X#else
  395. X        rschar = '\n';
  396. X#endif    /* !CSH */
  397. X#endif    /* !MSDOS */
  398. X        goto do_read;
  399. X    case A_READ:
  400. X        last_in_stab = argptr.arg_stab;
  401. X        old_rschar = rschar;
  402. X        old_rslen = rslen;
  403. X      do_read:
  404. X        if (anum > 1)        /* assign to scalar */
  405. X        gimme = G_SCALAR;    /* force context to scalar */
  406. X        if (gimme == G_ARRAY)
  407. X        str = Str_new(57,0);
  408. X        ++sp;
  409. X        fp = Nullfp;
  410. X        if (stab_io(last_in_stab)) {
  411. X        fp = stab_io(last_in_stab)->ifp;
  412. X        if (!fp) {
  413. X            if (stab_io(last_in_stab)->flags & IOF_ARGV) {
  414. X            if (stab_io(last_in_stab)->flags & IOF_START) {
  415. X                stab_io(last_in_stab)->flags &= ~IOF_START;
  416. X                stab_io(last_in_stab)->lines = 0;
  417. X                if (alen(stab_array(last_in_stab)) < 0) {
  418. X                tmpstr = str_make("-",1); /* assume stdin */
  419. X                (void)apush(stab_array(last_in_stab), tmpstr);
  420. X                }
  421. X            }
  422. X            fp = nextargv(last_in_stab);
  423. X            if (!fp) { /* Note: fp != stab_io(last_in_stab)->ifp */
  424. X                (void)do_close(last_in_stab,FALSE); /* now it does*/
  425. X                stab_io(last_in_stab)->flags |= IOF_START;
  426. X            }
  427. X            }
  428. X            else if (argtype == A_GLOB) {
  429. X            (void) interp(str,stab_val(last_in_stab),sp);
  430. X            st = stack->ary_array;
  431. X            tmpstr = Str_new(55,0);
  432. X#ifdef MSDOS
  433. X            str_set(tmpstr, "perlglob ");
  434. X            str_scat(tmpstr,str);
  435. X            str_cat(tmpstr," |");
  436. X#else
  437. X#ifdef CSH
  438. X            str_nset(tmpstr,cshname,cshlen);
  439. X            str_cat(tmpstr," -cf 'set nonomatch; glob ");
  440. X            str_scat(tmpstr,str);
  441. X            str_cat(tmpstr,"'|");
  442. X#else
  443. X            str_set(tmpstr, "echo ");
  444. X            str_scat(tmpstr,str);
  445. X            str_cat(tmpstr,
  446. X              "|tr -s ' \t\f\r' '\\012\\012\\012\\012'|");
  447. X#endif /* !CSH */
  448. X#endif /* !MSDOS */
  449. X            (void)do_open(last_in_stab,tmpstr->str_ptr,
  450. X              tmpstr->str_cur);
  451. X            fp = stab_io(last_in_stab)->ifp;
  452. X            str_free(tmpstr);
  453. X            }
  454. X        }
  455. X        }
  456. X        if (!fp && dowarn)
  457. X        warn("Read on closed filehandle <%s>",stab_name(last_in_stab));
  458. X        when = str->str_len;    /* remember if already alloced */
  459. X        if (!when)
  460. X        Str_Grow(str,80);    /* try short-buffering it */
  461. X      keepgoing:
  462. X        if (!fp)
  463. X        st[sp] = &str_undef;
  464. X        else if (!str_gets(str,fp, optype == O_RCAT ? str->str_cur : 0)) {
  465. X        clearerr(fp);
  466. X        if (stab_io(last_in_stab)->flags & IOF_ARGV) {
  467. X            fp = nextargv(last_in_stab);
  468. X            if (fp)
  469. X            goto keepgoing;
  470. X            (void)do_close(last_in_stab,FALSE);
  471. X            stab_io(last_in_stab)->flags |= IOF_START;
  472. X        }
  473. X        else if (argflags & AF_POST) {
  474. X            (void)do_close(last_in_stab,FALSE);
  475. X        }
  476. X        st[sp] = &str_undef;
  477. X        rschar = old_rschar;
  478. X        rslen = old_rslen;
  479. X        if (gimme == G_ARRAY) {
  480. X            --sp;
  481. X            str_2mortal(str);
  482. X            goto array_return;
  483. X        }
  484. X        break;
  485. X        }
  486. X        else {
  487. X        stab_io(last_in_stab)->lines++;
  488. X        st[sp] = str;
  489. X#ifdef TAINT
  490. X        str->str_tainted = 1; /* Anything from the outside world...*/
  491. X#endif
  492. X        if (argflags & AF_POST) {
  493. X            if (str->str_cur > 0)
  494. X            str->str_cur--;
  495. X            if (str->str_ptr[str->str_cur] == rschar)
  496. X            str->str_ptr[str->str_cur] = '\0';
  497. X            else
  498. X            str->str_cur++;
  499. X            for (tmps = str->str_ptr; *tmps; tmps++)
  500. X            if (!isalpha(*tmps) && !isdigit(*tmps) &&
  501. X                index("$&*(){}[]'\";\\|?<>~`",*tmps))
  502. X                break;
  503. X            if (*tmps && stat(str->str_ptr,&statbuf) < 0)
  504. X            goto keepgoing;        /* unmatched wildcard? */
  505. X        }
  506. X        if (gimme == G_ARRAY) {
  507. X            if (str->str_len - str->str_cur > 20) {
  508. X            str->str_len = str->str_cur+1;
  509. X            Renew(str->str_ptr, str->str_len, char);
  510. X            }
  511. X            str_2mortal(str);
  512. X            if (++sp > stack->ary_max) {
  513. X            astore(stack, sp, Nullstr);
  514. X            st = stack->ary_array;
  515. X            }
  516. X            str = Str_new(58,80);
  517. X            goto keepgoing;
  518. X        }
  519. X        else if (!when && str->str_len - str->str_cur > 80) {
  520. X            /* try to reclaim a bit of scalar space on 1st alloc */
  521. X            if (str->str_cur < 60)
  522. X            str->str_len = 80;
  523. X            else
  524. X            str->str_len = str->str_cur+40;    /* allow some slop */
  525. X            Renew(str->str_ptr, str->str_len, char);
  526. X        }
  527. X        }
  528. X        rschar = old_rschar;
  529. X        rslen = old_rslen;
  530. X#ifdef DEBUGGING
  531. X        tmps = "READ";
  532. X#endif
  533. X        break;
  534. X    }
  535. X#ifdef DEBUGGING
  536. X    if (debug & 8)
  537. X        deb("%d.%s = '%s'\n",anum,tmps,str_peek(st[sp]));
  538. X#endif
  539. X    if (anum < 8)
  540. X        arglast[anum] = sp;
  541. X    }
  542. X
  543. X    st += arglast[0];
  544. X#ifdef SMALLSWITCHES
  545. X    if (optype < O_CHOWN)
  546. X#endif
  547. X    switch (optype) {
  548. X    case O_RCAT:
  549. X    STABSET(str);
  550. X    break;
  551. X    case O_ITEM:
  552. X    if (gimme == G_ARRAY)
  553. X        goto array_return;
  554. X    /* FALL THROUGH */
  555. X    case O_SCALAR:
  556. X    STR_SSET(str,st[1]);
  557. X    STABSET(str);
  558. X    break;
  559. X    case O_ITEM2:
  560. X    if (gimme == G_ARRAY)
  561. X        goto array_return;
  562. X    --anum;
  563. X    STR_SSET(str,st[arglast[anum]-arglast[0]]);
  564. X    STABSET(str);
  565. X    break;
  566. X    case O_ITEM3:
  567. X    if (gimme == G_ARRAY)
  568. X    goto array_return;
  569. X    --anum;
  570. X    STR_SSET(str,st[arglast[anum]-arglast[0]]);
  571. X    STABSET(str);
  572. X    break;
  573. X    case O_CONCAT:
  574. X    STR_SSET(str,st[1]);
  575. X    str_scat(str,st[2]);
  576. X    STABSET(str);
  577. X    break;
  578. X    case O_REPEAT:
  579. X    if (gimme == G_ARRAY && arg[1].arg_flags & AF_ARYOK) {
  580. X        sp = do_repeatary(arglast);
  581. X        goto array_return;
  582. X    }
  583. X    STR_SSET(str,st[arglast[1] - arglast[0]]);
  584. X    anum = (int)str_gnum(st[arglast[2] - arglast[0]]);
  585. X    if (anum >= 1) {
  586. X        tmpstr = Str_new(50, 0);
  587. X        tmps = str_get(str);
  588. X        str_nset(tmpstr,tmps,str->str_cur);
  589. X        tmps = str_get(tmpstr);    /* force to be string */
  590. X        STR_GROW(str, (anum * str->str_cur) + 1);
  591. X        repeatcpy(str->str_ptr, tmps, tmpstr->str_cur, anum);
  592. X        str->str_cur *= anum;
  593. X        str->str_ptr[str->str_cur] = '\0';
  594. X        str->str_nok = 0;
  595. X        str_free(tmpstr);
  596. X    }
  597. X    else
  598. X        str_sset(str,&str_no);
  599. X    STABSET(str);
  600. X    break;
  601. X    case O_MATCH:
  602. X    sp = do_match(str,arg,
  603. X      gimme,arglast);
  604. X    if (gimme == G_ARRAY)
  605. X        goto array_return;
  606. X    STABSET(str);
  607. X    break;
  608. X    case O_NMATCH:
  609. X    sp = do_match(str,arg,
  610. X      G_SCALAR,arglast);
  611. X    str_sset(str, str_true(str) ? &str_no : &str_yes);
  612. X    STABSET(str);
  613. X    break;
  614. X    case O_SUBST:
  615. X    sp = do_subst(str,arg,arglast[0]);
  616. X    goto array_return;
  617. X    case O_NSUBST:
  618. X    sp = do_subst(str,arg,arglast[0]);
  619. X    str = arg->arg_ptr.arg_str;
  620. X    str_set(str, str_true(str) ? No : Yes);
  621. X    goto array_return;
  622. X    case O_ASSIGN:
  623. X    if (arg[1].arg_flags & AF_ARYOK) {
  624. X        if (arg->arg_len == 1) {
  625. X        arg->arg_type = O_LOCAL;
  626. X        goto local;
  627. X        }
  628. X        else {
  629. X        arg->arg_type = O_AASSIGN;
  630. X        goto aassign;
  631. X        }
  632. X    }
  633. X    else {
  634. X        arg->arg_type = O_SASSIGN;
  635. X        goto sassign;
  636. X    }
  637. X    case O_LOCAL:
  638. X      local:
  639. X    arglast[2] = arglast[1];    /* push a null array */
  640. X    /* FALL THROUGH */
  641. X    case O_AASSIGN:
  642. X      aassign:
  643. X    sp = do_assign(arg,
  644. X      gimme,arglast);
  645. X    goto array_return;
  646. X    case O_SASSIGN:
  647. X      sassign:
  648. X    STR_SSET(str, st[2]);
  649. X    STABSET(str);
  650. X    break;
  651. X    case O_CHOP:
  652. X    st -= arglast[0];
  653. X    str = arg->arg_ptr.arg_str;
  654. X    for (sp = arglast[0] + 1; sp <= arglast[1]; sp++)
  655. X        do_chop(str,st[sp]);
  656. X    st += arglast[0];
  657. X    break;
  658. X    case O_DEFINED:
  659. X    if (arg[1].arg_type & A_DONT) {
  660. X        sp = do_defined(str,arg,
  661. X          gimme,arglast);
  662. X        goto array_return;
  663. X    }
  664. X    else if (str->str_pok || str->str_nok)
  665. X        goto say_yes;
  666. X    goto say_no;
  667. X    case O_UNDEF:
  668. X    if (arg[1].arg_type & A_DONT) {
  669. X        sp = do_undef(str,arg,
  670. X          gimme,arglast);
  671. X        goto array_return;
  672. X    }
  673. X    else if (str != stab_val(defstab)) {
  674. X        if (str->str_len) {
  675. X        if (str->str_state == SS_INCR)
  676. X            Str_Grow(str,0);
  677. X        Safefree(str->str_ptr);
  678. X        str->str_ptr = Nullch;
  679. X        str->str_len = 0;
  680. X        }
  681. X        str->str_pok = str->str_nok = 0;
  682. X        STABSET(str);
  683. X    }
  684. X    goto say_undef;
  685. X    case O_STUDY:
  686. X    sp = do_study(str,arg,
  687. X      gimme,arglast);
  688. X    goto array_return;
  689. X    case O_POW:
  690. X    value = str_gnum(st[1]);
  691. X    value = pow(value,str_gnum(st[2]));
  692. X    goto donumset;
  693. X    case O_MULTIPLY:
  694. X    value = str_gnum(st[1]);
  695. X    value *= str_gnum(st[2]);
  696. X    goto donumset;
  697. X    case O_DIVIDE:
  698. X    if ((value = str_gnum(st[2])) == 0.0)
  699. X        fatal("Illegal division by zero");
  700. X#ifdef cray
  701. X    /* insure that 20./5. == 4. */
  702. X    {
  703. X        double x;
  704. X        int    k;
  705. X        x =  str_gnum(st[1]);
  706. X        if ((double)(int)x     == x &&
  707. X        (double)(int)value == value &&
  708. X        (k = (int)x/(int)value)*(int)value == (int)x) {
  709. X        value = k;
  710. X        } else {
  711. X        value = x/value;
  712. X        }
  713. X    }
  714. X#else
  715. X    value = str_gnum(st[1]) / value;
  716. X#endif
  717. X    goto donumset;
  718. X    case O_MODULO:
  719. X    tmplong = (long) str_gnum(st[2]);
  720. X        if (tmplong == 0L)
  721. X            fatal("Illegal modulus zero");
  722. X    when = (long)str_gnum(st[1]);
  723. X#ifndef lint
  724. X    if (when >= 0)
  725. X        value = (double)(when % tmplong);
  726. X    else
  727. X        value = (double)(tmplong - ((-when - 1) % tmplong)) - 1;
  728. X#endif
  729. X    goto donumset;
  730. X    case O_ADD:
  731. X    value = str_gnum(st[1]);
  732. X    value += str_gnum(st[2]);
  733. X    goto donumset;
  734. X    case O_SUBTRACT:
  735. X    value = str_gnum(st[1]);
  736. X    value -= str_gnum(st[2]);
  737. X    goto donumset;
  738. X    case O_LEFT_SHIFT:
  739. X    value = str_gnum(st[1]);
  740. X    anum = (int)str_gnum(st[2]);
  741. X#ifndef lint
  742. X    value = (double)(U_L(value) << anum);
  743. X#endif
  744. X    goto donumset;
  745. X    case O_RIGHT_SHIFT:
  746. X    value = str_gnum(st[1]);
  747. X    anum = (int)str_gnum(st[2]);
  748. X#ifndef lint
  749. X    value = (double)(U_L(value) >> anum);
  750. X#endif
  751. X    goto donumset;
  752. X    case O_LT:
  753. X    value = str_gnum(st[1]);
  754. X    value = (value < str_gnum(st[2])) ? 1.0 : 0.0;
  755. X    goto donumset;
  756. X    case O_GT:
  757. X    value = str_gnum(st[1]);
  758. X    value = (value > str_gnum(st[2])) ? 1.0 : 0.0;
  759. X    goto donumset;
  760. X    case O_LE:
  761. X    value = str_gnum(st[1]);
  762. X    value = (value <= str_gnum(st[2])) ? 1.0 : 0.0;
  763. X    goto donumset;
  764. X    case O_GE:
  765. X    value = str_gnum(st[1]);
  766. X    value = (value >= str_gnum(st[2])) ? 1.0 : 0.0;
  767. X    goto donumset;
  768. X    case O_EQ:
  769. X    if (dowarn) {
  770. X        if ((!st[1]->str_nok && !looks_like_number(st[1])) ||
  771. X        (!st[2]->str_nok && !looks_like_number(st[2])) )
  772. X        warn("Possible use of == on string value");
  773. X    }
  774. X    value = str_gnum(st[1]);
  775. X    value = (value == str_gnum(st[2])) ? 1.0 : 0.0;
  776. X    goto donumset;
  777. X    case O_NE:
  778. X    value = str_gnum(st[1]);
  779. X    value = (value != str_gnum(st[2])) ? 1.0 : 0.0;
  780. X    goto donumset;
  781. X    case O_NCMP:
  782. X    value = str_gnum(st[1]);
  783. X    value -= str_gnum(st[2]);
  784. X    if (value > 0.0)
  785. X        value = 1.0;
  786. X    else if (value < 0.0)
  787. X        value = -1.0;
  788. X    goto donumset;
  789. X    case O_BIT_AND:
  790. X    if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
  791. X        value = str_gnum(st[1]);
  792. X#ifndef lint
  793. X        value = (double)(U_L(value) & U_L(str_gnum(st[2])));
  794. X#endif
  795. X        goto donumset;
  796. X    }
  797. X    else
  798. X        do_vop(optype,str,st[1],st[2]);
  799. X    break;
  800. X    case O_XOR:
  801. X    if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
  802. X        value = str_gnum(st[1]);
  803. X#ifndef lint
  804. X        value = (double)(U_L(value) ^ U_L(str_gnum(st[2])));
  805. X#endif
  806. X        goto donumset;
  807. X    }
  808. X    else
  809. X        do_vop(optype,str,st[1],st[2]);
  810. X    break;
  811. X    case O_BIT_OR:
  812. X    if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
  813. X        value = str_gnum(st[1]);
  814. X#ifndef lint
  815. X        value = (double)(U_L(value) | U_L(str_gnum(st[2])));
  816. X#endif
  817. X        goto donumset;
  818. X    }
  819. X    else
  820. X        do_vop(optype,str,st[1],st[2]);
  821. X    break;
  822. X/* use register in evaluating str_true() */
  823. X    case O_AND:
  824. X    if (str_true(st[1])) {
  825. X        anum = 2;
  826. X        optype = O_ITEM2;
  827. X        argflags = arg[anum].arg_flags;
  828. X        if (gimme == G_ARRAY)
  829. X        argflags |= AF_ARYOK;
  830. X        argtype = arg[anum].arg_type & A_MASK;
  831. X        argptr = arg[anum].arg_ptr;
  832. X        maxarg = anum = 1;
  833. X        sp = arglast[0];
  834. X        st -= sp;
  835. X        goto re_eval;
  836. X    }
  837. X    else {
  838. X        if (assigning) {
  839. X        str_sset(str, st[1]);
  840. X        STABSET(str);
  841. X        }
  842. X        else
  843. X        str = st[1];
  844. X        break;
  845. X    }
  846. X    case O_OR:
  847. X    if (str_true(st[1])) {
  848. X        if (assigning) {
  849. X        str_sset(str, st[1]);
  850. X        STABSET(str);
  851. X        }
  852. X        else
  853. X        str = st[1];
  854. X        break;
  855. X    }
  856. X    else {
  857. X        anum = 2;
  858. X        optype = O_ITEM2;
  859. X        argflags = arg[anum].arg_flags;
  860. X        if (gimme == G_ARRAY)
  861. X        argflags |= AF_ARYOK;
  862. X        argtype = arg[anum].arg_type & A_MASK;
  863. X        argptr = arg[anum].arg_ptr;
  864. X        maxarg = anum = 1;
  865. X        sp = arglast[0];
  866. X        st -= sp;
  867. X        goto re_eval;
  868. X    }
  869. X    case O_COND_EXPR:
  870. X    anum = (str_true(st[1]) ? 2 : 3);
  871. X    optype = (anum == 2 ? O_ITEM2 : O_ITEM3);
  872. X    argflags = arg[anum].arg_flags;
  873. X    if (gimme == G_ARRAY)
  874. X        argflags |= AF_ARYOK;
  875. X    argtype = arg[anum].arg_type & A_MASK;
  876. X    argptr = arg[anum].arg_ptr;
  877. X    maxarg = anum = 1;
  878. X    sp = arglast[0];
  879. X    st -= sp;
  880. X    goto re_eval;
  881. X    case O_COMMA:
  882. X    if (gimme == G_ARRAY)
  883. X        goto array_return;
  884. X    str = st[2];
  885. X    break;
  886. X    case O_NEGATE:
  887. X    value = -str_gnum(st[1]);
  888. X    goto donumset;
  889. X    case O_NOT:
  890. X    value = (double) !str_true(st[1]);
  891. X    goto donumset;
  892. X    case O_COMPLEMENT:
  893. X    if (!sawvec || st[1]->str_nok) {
  894. X#ifndef lint
  895. X        value = (double) ~U_L(str_gnum(st[1]));
  896. X#endif
  897. X        goto donumset;
  898. X    }
  899. X    else {
  900. X        STR_SSET(str,st[1]);
  901. X        tmps = str_get(str);
  902. X        for (anum = str->str_cur; anum; anum--, tmps++)
  903. X        *tmps = ~*tmps;
  904. X    }
  905. X    break;
  906. X    case O_SELECT:
  907. X    stab_fullname(str,defoutstab);
  908. X    if (maxarg > 0) {
  909. X        if ((arg[1].arg_type & A_MASK) == A_WORD)
  910. X        defoutstab = arg[1].arg_ptr.arg_stab;
  911. X        else
  912. X        defoutstab = stabent(str_get(st[1]),TRUE);
  913. X        if (!stab_io(defoutstab))
  914. X        stab_io(defoutstab) = stio_new();
  915. X        curoutstab = defoutstab;
  916. X    }
  917. X    STABSET(str);
  918. X    break;
  919. X    case O_WRITE:
  920. X    if (maxarg == 0)
  921. X        stab = defoutstab;
  922. X    else if ((arg[1].arg_type & A_MASK) == A_WORD) {
  923. X        if (!(stab = arg[1].arg_ptr.arg_stab))
  924. X        stab = defoutstab;
  925. X    }
  926. X    else
  927. X        stab = stabent(str_get(st[1]),TRUE);
  928. X    if (!stab_io(stab)) {
  929. X        str_set(str, No);
  930. X        STABSET(str);
  931. X        break;
  932. X    }
  933. X    curoutstab = stab;
  934. X    fp = stab_io(stab)->ofp;
  935. X    debarg = arg;
  936. X    if (stab_io(stab)->fmt_stab)
  937. X        form = stab_form(stab_io(stab)->fmt_stab);
  938. X    else
  939. X        form = stab_form(stab);
  940. X    if (!form || !fp) {
  941. X        if (dowarn) {
  942. X        if (form)
  943. X            warn("No format for filehandle");
  944. X        else {
  945. X            if (stab_io(stab)->ifp)
  946. X            warn("Filehandle only opened for input");
  947. X            else
  948. X            warn("Write on closed filehandle");
  949. X        }
  950. X        }
  951. X        str_set(str, No);
  952. X        STABSET(str);
  953. X        break;
  954. X    }
  955. X    format(&outrec,form,sp);
  956. X    do_write(&outrec,stab_io(stab),sp);
  957. X    if (stab_io(stab)->flags & IOF_FLUSH)
  958. X        (void)fflush(fp);
  959. X    str_set(str, Yes);
  960. X    STABSET(str);
  961. X    break;
  962. X    case O_DBMOPEN:
  963. X#ifdef SOME_DBM
  964. X    anum = arg[1].arg_type & A_MASK;
  965. X    if (anum == A_WORD || anum == A_STAB)
  966. X        stab = arg[1].arg_ptr.arg_stab;
  967. X    else
  968. X        stab = stabent(str_get(st[1]),TRUE);
  969. X    if (st[3]->str_nok || st[3]->str_pok)
  970. X        anum = (int)str_gnum(st[3]);
  971. X    else
  972. X        anum = -1;
  973. X    value = (double)hdbmopen(stab_hash(stab),str_get(st[2]),anum);
  974. X    goto donumset;
  975. X#else
  976. X    fatal("No dbm or ndbm on this machine");
  977. X#endif
  978. X    case O_DBMCLOSE:
  979. X#ifdef SOME_DBM
  980. X    if ((arg[1].arg_type & A_MASK) == A_WORD)
  981. X        stab = arg[1].arg_ptr.arg_stab;
  982. X    else
  983. X        stab = stabent(str_get(st[1]),TRUE);
  984. X    hdbmclose(stab_hash(stab));
  985. X    goto say_yes;
  986. X#else
  987. X    fatal("No dbm or ndbm on this machine");
  988. X#endif
  989. X    case O_OPEN:
  990. X    if ((arg[1].arg_type & A_MASK) == A_WORD)
  991. X        stab = arg[1].arg_ptr.arg_stab;
  992. X    else
  993. X        stab = stabent(str_get(st[1]),TRUE);
  994. X    tmps = str_get(st[2]);
  995. X    if (do_open(stab,tmps,st[2]->str_cur)) {
  996. X        value = (double)forkprocess;
  997. X        stab_io(stab)->lines = 0;
  998. X        goto donumset;
  999. X    }
  1000. X    else if (forkprocess == 0)        /* we are a new child */
  1001. X        goto say_zero;
  1002. X    else
  1003. X        goto say_undef;
  1004. X    /* break; */
  1005. X    case O_TRANS:
  1006. X    value = (double) do_trans(str,arg);
  1007. X    str = arg->arg_ptr.arg_str;
  1008. X    goto donumset;
  1009. X    case O_NTRANS:
  1010. X    str_set(arg->arg_ptr.arg_str, do_trans(str,arg) == 0 ? Yes : No);
  1011. X    str = arg->arg_ptr.arg_str;
  1012. X    break;
  1013. X    case O_CLOSE:
  1014. X    if (maxarg == 0)
  1015. X        stab = defoutstab;
  1016. X    else if ((arg[1].arg_type & A_MASK) == A_WORD)
  1017. X        stab = arg[1].arg_ptr.arg_stab;
  1018. X    else
  1019. X        stab = stabent(str_get(st[1]),TRUE);
  1020. X    str_set(str, do_close(stab,TRUE) ? Yes : No );
  1021. X    STABSET(str);
  1022. X    break;
  1023. X    case O_EACH:
  1024. X    sp = do_each(str,stab_hash(arg[1].arg_ptr.arg_stab),
  1025. X      gimme,arglast);
  1026. X    goto array_return;
  1027. X    case O_VALUES:
  1028. X    case O_KEYS:
  1029. X    sp = do_kv(str,stab_hash(arg[1].arg_ptr.arg_stab), optype,
  1030. X      gimme,arglast);
  1031. X    goto array_return;
  1032. X    case O_LARRAY:
  1033. X    str->str_nok = str->str_pok = 0;
  1034. X    str->str_u.str_stab = arg[1].arg_ptr.arg_stab;
  1035. X    str->str_state = SS_ARY;
  1036. X    break;
  1037. X    case O_ARRAY:
  1038. X    ary = stab_array(arg[1].arg_ptr.arg_stab);
  1039. X    maxarg = ary->ary_fill + 1;
  1040. X    if (gimme == G_ARRAY) { /* array wanted */
  1041. X        sp = arglast[0];
  1042. X        st -= sp;
  1043. X        if (maxarg > 0 && sp + maxarg > stack->ary_max) {
  1044. X        astore(stack,sp + maxarg, Nullstr);
  1045. X        st = stack->ary_array;
  1046. X        }
  1047. X        st += sp;
  1048. X        Copy(ary->ary_array, &st[1], maxarg, STR*);
  1049. X        sp += maxarg;
  1050. X        goto array_return;
  1051. X    }
  1052. X    else {
  1053. X        value = (double)maxarg;
  1054. X        goto donumset;
  1055. X    }
  1056. X    case O_AELEM:
  1057. X    anum = ((int)str_gnum(st[2])) - arybase;
  1058. X    str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,FALSE);
  1059. X    break;
  1060. X    case O_DELETE:
  1061. X    tmpstab = arg[1].arg_ptr.arg_stab;
  1062. X    tmps = str_get(st[2]);
  1063. X    str = hdelete(stab_hash(tmpstab),tmps,st[2]->str_cur);
  1064. X    if (tmpstab == envstab)
  1065. X        setenv(tmps,Nullch);
  1066. X    if (!str)
  1067. X        goto say_undef;
  1068. X    break;
  1069. X    case O_LHASH:
  1070. X    str->str_nok = str->str_pok = 0;
  1071. X    str->str_u.str_stab = arg[1].arg_ptr.arg_stab;
  1072. X    str->str_state = SS_HASH;
  1073. X    break;
  1074. X    case O_HASH:
  1075. X    if (gimme == G_ARRAY) { /* array wanted */
  1076. X        sp = do_kv(str,stab_hash(arg[1].arg_ptr.arg_stab), optype,
  1077. X        gimme,arglast);
  1078. X        goto array_return;
  1079. X    }
  1080. X    else {
  1081. X        tmpstab = arg[1].arg_ptr.arg_stab;
  1082. X        if (!stab_hash(tmpstab)->tbl_fill)
  1083. X        goto say_zero;
  1084. X        sprintf(buf,"%d/%d",stab_hash(tmpstab)->tbl_fill,
  1085. X        stab_hash(tmpstab)->tbl_max+1);
  1086. X        str_set(str,buf);
  1087. X    }
  1088. X    break;
  1089. X    case O_HELEM:
  1090. X    tmpstab = arg[1].arg_ptr.arg_stab;
  1091. X    tmps = str_get(st[2]);
  1092. X    str = hfetch(stab_hash(tmpstab),tmps,st[2]->str_cur,FALSE);
  1093. X    break;
  1094. X    case O_LAELEM:
  1095. X    anum = ((int)str_gnum(st[2])) - arybase;
  1096. X    str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,TRUE);
  1097. X    if (!str || str == &str_undef)
  1098. X        fatal("Assignment to non-creatable value, subscript %d",anum);
  1099. X    break;
  1100. X    case O_LHELEM:
  1101. X    tmpstab = arg[1].arg_ptr.arg_stab;
  1102. X    tmps = str_get(st[2]);
  1103. X    anum = st[2]->str_cur;
  1104. X    str = hfetch(stab_hash(tmpstab),tmps,anum,TRUE);
  1105. X    if (!str || str == &str_undef)
  1106. X        fatal("Assignment to non-creatable value, subscript \"%s\"",tmps);
  1107. X    if (tmpstab == envstab)        /* heavy wizardry going on here */
  1108. X        str_magic(str, tmpstab, 'E', tmps, anum);    /* str is now magic */
  1109. X                    /* he threw the brick up into the air */
  1110. X    else if (tmpstab == sigstab)
  1111. X        str_magic(str, tmpstab, 'S', tmps, anum);
  1112. X#ifdef SOME_DBM
  1113. X    else if (stab_hash(tmpstab)->tbl_dbm)
  1114. X        str_magic(str, tmpstab, 'D', tmps, anum);
  1115. X#endif
  1116. X    else if (perldb && tmpstab == DBline)
  1117. X        str_magic(str, tmpstab, 'L', tmps, anum);
  1118. X    break;
  1119. X    case O_LSLICE:
  1120. X    anum = 2;
  1121. X    argtype = FALSE;
  1122. X    goto do_slice_already;
  1123. X    case O_ASLICE:
  1124. X    anum = 1;
  1125. X    argtype = FALSE;
  1126. X    goto do_slice_already;
  1127. X    case O_HSLICE:
  1128. X    anum = 0;
  1129. X    argtype = FALSE;
  1130. X    goto do_slice_already;
  1131. X    case O_LASLICE:
  1132. X    anum = 1;
  1133. X    argtype = TRUE;
  1134. X    goto do_slice_already;
  1135. X    case O_LHSLICE:
  1136. X    anum = 0;
  1137. X    argtype = TRUE;
  1138. X      do_slice_already:
  1139. X    sp = do_slice(arg[1].arg_ptr.arg_stab,str,anum,argtype,
  1140. X        gimme,arglast);
  1141. X    goto array_return;
  1142. X    case O_SPLICE:
  1143. X    sp = do_splice(stab_array(arg[1].arg_ptr.arg_stab),gimme,arglast);
  1144. X    goto array_return;
  1145. X    case O_PUSH:
  1146. X    if (arglast[2] - arglast[1] != 1)
  1147. X        str = do_push(stab_array(arg[1].arg_ptr.arg_stab),arglast);
  1148. X    else {
  1149. X        str = Str_new(51,0);        /* must copy the STR */
  1150. X        str_sset(str,st[2]);
  1151. X        (void)apush(stab_array(arg[1].arg_ptr.arg_stab),str);
  1152. X    }
  1153. X    break;
  1154. X    case O_POP:
  1155. X    str = apop(ary = stab_array(arg[1].arg_ptr.arg_stab));
  1156. X    goto staticalization;
  1157. X    case O_SHIFT:
  1158. X    str = ashift(ary = stab_array(arg[1].arg_ptr.arg_stab));
  1159. X      staticalization:
  1160. X    if (!str)
  1161. X        goto say_undef;
  1162. X    if (ary->ary_flags & ARF_REAL)
  1163. X        (void)str_2mortal(str);
  1164. X    break;
  1165. X    case O_UNPACK:
  1166. X    sp = do_unpack(str,gimme,arglast);
  1167. X    goto array_return;
  1168. X    case O_SPLIT:
  1169. X    value = str_gnum(st[3]);
  1170. X    sp = do_split(str, arg[2].arg_ptr.arg_spat, (int)value,
  1171. X      gimme,arglast);
  1172. X    goto array_return;
  1173. X    case O_LENGTH:
  1174. X    if (maxarg < 1)
  1175. X        value = (double)str_len(stab_val(defstab));
  1176. X    else
  1177. X        value = (double)str_len(st[1]);
  1178. X    goto donumset;
  1179. X    case O_SPRINTF:
  1180. X    do_sprintf(str, sp-arglast[0], st+1);
  1181. X    break;
  1182. X    case O_SUBSTR:
  1183. X    anum = ((int)str_gnum(st[2])) - arybase;    /* anum=where to start*/
  1184. X    tmps = str_get(st[1]);        /* force conversion to string */
  1185. X    if (argtype = (str == st[1]))
  1186. X        str = arg->arg_ptr.arg_str;
  1187. X    if (anum < 0)
  1188. X        anum += st[1]->str_cur + arybase;
  1189. X    if (anum < 0 || anum > st[1]->str_cur)
  1190. X        str_nset(str,"",0);
  1191. X    else {
  1192. X        optype = maxarg < 3 ? st[1]->str_cur : (int)str_gnum(st[3]);
  1193. X        if (optype < 0)
  1194. X        optype = 0;
  1195. X        tmps += anum;
  1196. X        anum = st[1]->str_cur - anum;    /* anum=how many bytes left*/
  1197. X        if (anum > optype)
  1198. X        anum = optype;
  1199. X        str_nset(str, tmps, anum);
  1200. X        if (argtype) {            /* it's an lvalue! */
  1201. X        lstr = (struct lstring*)str;
  1202. X        str->str_magic = st[1];
  1203. X        st[1]->str_rare = 's';
  1204. X        lstr->lstr_offset = tmps - str_get(st[1]); 
  1205. X        lstr->lstr_len = anum; 
  1206. X        }
  1207. X    }
  1208. X    break;
  1209. X    case O_PACK:
  1210. X    (void)do_pack(str,arglast);
  1211. X    break;
  1212. X    case O_GREP:
  1213. X    sp = do_grep(arg,str,gimme,arglast);
  1214. X    goto array_return;
  1215. X    case O_JOIN:
  1216. X    do_join(str,arglast);
  1217. X    break;
  1218. X    case O_SLT:
  1219. X    tmps = str_get(st[1]);
  1220. X    value = (double) (str_cmp(st[1],st[2]) < 0);
  1221. X    goto donumset;
  1222. X    case O_SGT:
  1223. X    tmps = str_get(st[1]);
  1224. X    value = (double) (str_cmp(st[1],st[2]) > 0);
  1225. X    goto donumset;
  1226. X    case O_SLE:
  1227. X    tmps = str_get(st[1]);
  1228. X    value = (double) (str_cmp(st[1],st[2]) <= 0);
  1229. X    goto donumset;
  1230. X    case O_SGE:
  1231. X    tmps = str_get(st[1]);
  1232. X    value = (double) (str_cmp(st[1],st[2]) >= 0);
  1233. X    goto donumset;
  1234. X    case O_SEQ:
  1235. X    tmps = str_get(st[1]);
  1236. X    value = (double) str_eq(st[1],st[2]);
  1237. X    goto donumset;
  1238. X    case O_SNE:
  1239. X    tmps = str_get(st[1]);
  1240. X    value = (double) !str_eq(st[1],st[2]);
  1241. X    goto donumset;
  1242. X    case O_SCMP:
  1243. X    tmps = str_get(st[1]);
  1244. X    value = (double) str_cmp(st[1],st[2]);
  1245. X    goto donumset;
  1246. X    case O_SUBR:
  1247. X    sp = do_subr(arg,gimme,arglast);
  1248. X    st = stack->ary_array + arglast[0];        /* maybe realloced */
  1249. X    goto array_return;
  1250. X    case O_DBSUBR:
  1251. X    sp = do_subr(arg,gimme,arglast);
  1252. X    st = stack->ary_array + arglast[0];        /* maybe realloced */
  1253. X    goto array_return;
  1254. X    case O_CALLER:
  1255. X    sp = do_caller(arg,maxarg,gimme,arglast);
  1256. X    st = stack->ary_array + arglast[0];        /* maybe realloced */
  1257. X    goto array_return;
  1258. X    case O_SORT:
  1259. X    if ((arg[1].arg_type & A_MASK) == A_WORD)
  1260. X        stab = arg[1].arg_ptr.arg_stab;
  1261. X    else
  1262. X        stab = stabent(str_get(st[1]),TRUE);
  1263. X    sp = do_sort(str,stab,
  1264. X      gimme,arglast);
  1265. X    goto array_return;
  1266. X    case O_REVERSE:
  1267. X    if (gimme == G_ARRAY)
  1268. X        sp = do_reverse(arglast);
  1269. X    else
  1270. X        sp = do_sreverse(str, arglast);
  1271. X    goto array_return;
  1272. X    case O_WARN:
  1273. X    if (arglast[2] - arglast[1] != 1) {
  1274. X        do_join(str,arglast);
  1275. X        tmps = str_get(str);
  1276. X    }
  1277. X    else {
  1278. X        str = st[2];
  1279. X        tmps = str_get(st[2]);
  1280. X    }
  1281. X    if (!tmps || !*tmps)
  1282. X        tmps = "Warning: something's wrong";
  1283. X    warn("%s",tmps);
  1284. X    goto say_yes;
  1285. X    case O_DIE:
  1286. X    if (arglast[2] - arglast[1] != 1) {
  1287. X        do_join(str,arglast);
  1288. X        tmps = str_get(str);
  1289. X    }
  1290. X    else {
  1291. X        str = st[2];
  1292. X        tmps = str_get(st[2]);
  1293. X    }
  1294. X    if (!tmps || !*tmps)
  1295. X        tmps = "Died";
  1296. X    fatal("%s",tmps);
  1297. X    goto say_zero;
  1298. X    case O_PRTF:
  1299. X    case O_PRINT:
  1300. X    if ((arg[1].arg_type & A_MASK) == A_WORD)
  1301. X        stab = arg[1].arg_ptr.arg_stab;
  1302. X    else
  1303. X        stab = stabent(str_get(st[1]),TRUE);
  1304. X    if (!stab)
  1305. X        stab = defoutstab;
  1306. X    if (!stab_io(stab)) {
  1307. X        if (dowarn)
  1308. X        warn("Filehandle never opened");
  1309. X        goto say_zero;
  1310. X    }
  1311. X    if (!(fp = stab_io(stab)->ofp)) {
  1312. X        if (dowarn)  {
  1313. X        if (stab_io(stab)->ifp)
  1314. X            warn("Filehandle opened only for input");
  1315. X        else
  1316. X            warn("Print on closed filehandle");
  1317. X        }
  1318. X        goto say_zero;
  1319. X    }
  1320. X    else {
  1321. X        if (optype == O_PRTF || arglast[2] - arglast[1] != 1)
  1322. X        value = (double)do_aprint(arg,fp,arglast);
  1323. X        else {
  1324. X        value = (double)do_print(st[2],fp);
  1325. X        if (orslen && optype == O_PRINT)
  1326. X            if (fwrite(ors, 1, orslen, fp) == 0)
  1327. X            goto say_zero;
  1328. X        }
  1329. X        if (stab_io(stab)->flags & IOF_FLUSH)
  1330. X        if (fflush(fp) == EOF)
  1331. X            goto say_zero;
  1332. X    }
  1333. X    goto donumset;
  1334. X    case O_CHDIR:
  1335. X    if (maxarg < 1)
  1336. X        tmps = Nullch;
  1337. X    else
  1338. X        tmps = str_get(st[1]);
  1339. X    if (!tmps || !*tmps) {
  1340. X        tmpstr = hfetch(stab_hash(envstab),"HOME",4,FALSE);
  1341. X        tmps = str_get(tmpstr);
  1342. X    }
  1343. X    if (!tmps || !*tmps) {
  1344. X        tmpstr = hfetch(stab_hash(envstab),"LOGDIR",6,FALSE);
  1345. X        tmps = str_get(tmpstr);
  1346. X    }
  1347. X#ifdef TAINT
  1348. X    taintproper("Insecure dependency in chdir");
  1349. X#endif
  1350. X    value = (double)(chdir(tmps) >= 0);
  1351. X    goto donumset;
  1352. X    case O_EXIT:
  1353. X    if (maxarg < 1)
  1354. X        anum = 0;
  1355. X    else
  1356. X        anum = (int)str_gnum(st[1]);
  1357. X    exit(anum);
  1358. X    goto say_zero;
  1359. X    case O_RESET:
  1360. X    if (maxarg < 1)
  1361. X        tmps = "";
  1362. X    else
  1363. X        tmps = str_get(st[1]);
  1364. X    str_reset(tmps,curcmd->c_stash);
  1365. X    value = 1.0;
  1366. X    goto donumset;
  1367. X    case O_LIST:
  1368. X    if (gimme == G_ARRAY)
  1369. X        goto array_return;
  1370. X    if (maxarg > 0)
  1371. X        str = st[sp - arglast[0]];    /* unwanted list, return last item */
  1372. X    else
  1373. X        str = &str_undef;
  1374. X    break;
  1375. X    case O_EOF:
  1376. X    if (maxarg <= 0)
  1377. X        stab = last_in_stab;
  1378. X    else if ((arg[1].arg_type & A_MASK) == A_WORD)
  1379. X        stab = arg[1].arg_ptr.arg_stab;
  1380. X    else
  1381. X        stab = stabent(str_get(st[1]),TRUE);
  1382. X    str_set(str, do_eof(stab) ? Yes : No);
  1383. X    STABSET(str);
  1384. X    break;
  1385. X    case O_GETC:
  1386. X    if (maxarg <= 0)
  1387. X        stab = stdinstab;
  1388. X    else if ((arg[1].arg_type & A_MASK) == A_WORD)
  1389. X        stab = arg[1].arg_ptr.arg_stab;
  1390. X    else
  1391. X        stab = stabent(str_get(st[1]),TRUE);
  1392. X    if (!stab)
  1393. X        stab = argvstab;
  1394. X    if (!stab || do_eof(stab)) /* make sure we have fp with something */
  1395. X        goto say_undef;
  1396. X    else {
  1397. X#ifdef TAINT
  1398. X        tainted = 1;
  1399. X#endif
  1400. X        str_set(str," ");
  1401. X        *str->str_ptr = getc(stab_io(stab)->ifp); /* should never be EOF */
  1402. X    }
  1403. X    STABSET(str);
  1404. X    break;
  1405. X    case O_TELL:
  1406. X    if (maxarg <= 0)
  1407. X        stab = last_in_stab;
  1408. X    else if ((arg[1].arg_type & A_MASK) == A_WORD)
  1409. X        stab = arg[1].arg_ptr.arg_stab;
  1410. X    else
  1411. X        stab = stabent(str_get(st[1]),TRUE);
  1412. X#ifndef lint
  1413. X    value = (double)do_tell(stab);
  1414. X#else
  1415. X    (void)do_tell(stab);
  1416. X#endif
  1417. X    goto donumset;
  1418. X    case O_RECV:
  1419. X    case O_READ:
  1420. X    case O_SYSREAD:
  1421. X    if ((arg[1].arg_type & A_MASK) == A_WORD)
  1422. X        stab = arg[1].arg_ptr.arg_stab;
  1423. X    else
  1424. X        stab = stabent(str_get(st[1]),TRUE);
  1425. X    tmps = str_get(st[2]);
  1426. X    anum = (int)str_gnum(st[3]);
  1427. X    errno = 0;
  1428. X    maxarg = sp - arglast[0];
  1429. X    if (maxarg > 4)
  1430. X        warn("Too many args on read");
  1431. X    if (maxarg == 4)
  1432. X        maxarg = (int)str_gnum(st[4]);
  1433. X    else
  1434. X        maxarg = 0;
  1435. X    if (!stab_io(stab) || !stab_io(stab)->ifp)
  1436. X        goto say_undef;
  1437. X#ifdef HAS_SOCKET
  1438. X    if (optype == O_RECV) {
  1439. X        argtype = sizeof buf;
  1440. X        STR_GROW(st[2], anum+1), (tmps = str_get(st[2]));  /* sneaky */
  1441. X        anum = recvfrom(fileno(stab_io(stab)->ifp), tmps, anum, maxarg,
  1442. X        buf, &argtype);
  1443. X        if (anum >= 0) {
  1444. X        st[2]->str_cur = anum;
  1445. X        st[2]->str_ptr[anum] = '\0';
  1446. X        str_nset(str,buf,argtype);
  1447. X        }
  1448. X        else
  1449. X        str_sset(str,&str_undef);
  1450. X        break;
  1451. X    }
  1452. X#else
  1453. X    if (optype == O_RECV)
  1454. X        goto badsock;
  1455. X#endif
  1456. X    STR_GROW(st[2], anum+maxarg+1), (tmps = str_get(st[2]));  /* sneaky */
  1457. X#ifdef HAS_SOCKET
  1458. X    if (stab_io(stab)->type == 's') {
  1459. X        argtype = sizeof buf;
  1460. X        anum = recvfrom(fileno(stab_io(stab)->ifp), tmps+maxarg, anum, 0,
  1461. X        buf, &argtype);
  1462. X    }
  1463. X    else
  1464. X#endif
  1465. X    if (optype == O_SYSREAD) {
  1466. X        anum = read(fileno(stab_io(stab)->ifp), tmps+maxarg, anum);
  1467. X    }
  1468. X    else
  1469. X        anum = fread(tmps+maxarg, 1, anum, stab_io(stab)->ifp);
  1470. X    if (anum < 0)
  1471. X        goto say_undef;
  1472. X    st[2]->str_cur = anum+maxarg;
  1473. X    st[2]->str_ptr[anum+maxarg] = '\0';
  1474. X    value = (double)anum;
  1475. X    goto donumset;
  1476. X    case O_SYSWRITE:
  1477. X    case O_SEND:
  1478. X    if ((arg[1].arg_type & A_MASK) == A_WORD)
  1479. X        stab = arg[1].arg_ptr.arg_stab;
  1480. X    else
  1481. X        stab = stabent(str_get(st[1]),TRUE);
  1482. X    tmps = str_get(st[2]);
  1483. X    anum = (int)str_gnum(st[3]);
  1484. X    errno = 0;
  1485. X    stio = stab_io(stab);
  1486. X    maxarg = sp - arglast[0];
  1487. X    if (!stio || !stio->ifp) {
  1488. X        anum = -1;
  1489. X        if (dowarn) {
  1490. X        if (optype == O_SYSWRITE)
  1491. X            warn("Syswrite on closed filehandle");
  1492. X        else
  1493. X            warn("Send on closed socket");
  1494. X        }
  1495. X    }
  1496. X    else if (optype == O_SYSWRITE) {
  1497. X        if (maxarg > 4)
  1498. X        warn("Too many args on syswrite");
  1499. X        if (maxarg == 4)
  1500. X        optype = (int)str_gnum(st[4]);
  1501. X        else
  1502. X        optype = 0;
  1503. X        anum = write(fileno(stab_io(stab)->ifp), tmps+optype, anum);
  1504. X    }
  1505. X#ifdef HAS_SOCKET
  1506. X    else if (maxarg >= 4) {
  1507. X        if (maxarg > 4)
  1508. X        warn("Too many args on send");
  1509. X        tmps2 = str_get(st[4]);
  1510. X        anum = sendto(fileno(stab_io(stab)->ifp), tmps, st[2]->str_cur,
  1511. X          anum, tmps2, st[4]->str_cur);
  1512. X    }
  1513. X    else
  1514. X        anum = send(fileno(stab_io(stab)->ifp), tmps, st[2]->str_cur, anum);
  1515. X#else
  1516. X    else
  1517. X        goto badsock;
  1518. X#endif
  1519. X    if (anum < 0)
  1520. X        goto say_undef;
  1521. X    value = (double)anum;
  1522. X    goto donumset;
  1523. X    case O_SEEK:
  1524. X    if ((arg[1].arg_type & A_MASK) == A_WORD)
  1525. X        stab = arg[1].arg_ptr.arg_stab;
  1526. X    else
  1527. X        stab = stabent(str_get(st[1]),TRUE);
  1528. X    value = str_gnum(st[2]);
  1529. X    str_set(str, do_seek(stab,
  1530. X      (long)value, (int)str_gnum(st[3]) ) ? Yes : No);
  1531. X    STABSET(str);
  1532. X    break;
  1533. X    case O_RETURN:
  1534. X    tmps = "_SUB_";        /* just fake up a "last _SUB_" */
  1535. X    optype = O_LAST;
  1536. X    if (curcsv && curcsv->wantarray == G_ARRAY) {
  1537. X        lastretstr = Nullstr;
  1538. X        lastspbase = arglast[1];
  1539. X        lastsize = arglast[2] - arglast[1];
  1540. X    }
  1541. X    else
  1542. X        lastretstr = str_mortal(st[arglast[2] - arglast[0]]);
  1543. X    goto dopop;
  1544. X    case O_REDO:
  1545. X    case O_NEXT:
  1546. X    case O_LAST:
  1547. X    if (maxarg > 0) {
  1548. X        tmps = str_get(arg[1].arg_ptr.arg_str);
  1549. X      dopop:
  1550. X        while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
  1551. X          strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
  1552. X#ifdef DEBUGGING
  1553. X        if (debug & 4) {
  1554. X            deb("(Skipping label #%d %s)\n",loop_ptr,
  1555. X            loop_stack[loop_ptr].loop_label);
  1556. X        }
  1557. X#endif
  1558. X        loop_ptr--;
  1559. X        }
  1560. X#ifdef DEBUGGING
  1561. X        if (debug & 4) {
  1562. X        deb("(Found label #%d %s)\n",loop_ptr,
  1563. X            loop_stack[loop_ptr].loop_label);
  1564. X        }
  1565. X#endif
  1566. X    }
  1567. X    if (loop_ptr < 0) {
  1568. X        if (tmps && strEQ(tmps, "_SUB_"))
  1569. X        fatal("Can't return outside a subroutine");
  1570. X        fatal("Bad label: %s", maxarg > 0 ? tmps : "<null>");
  1571. X    }
  1572. X    if (!lastretstr && optype == O_LAST && lastsize) {
  1573. X        st -= arglast[0];
  1574. X        st += lastspbase + 1;
  1575. X        optype = loop_stack[loop_ptr].loop_sp - lastspbase; /* negative */
  1576. X        if (optype) {
  1577. X        for (anum = lastsize; anum > 0; anum--,st++)
  1578. X            st[optype] = str_mortal(st[0]);
  1579. X        }
  1580. X        longjmp(loop_stack[loop_ptr].loop_env, O_LAST);
  1581. X    }
  1582. X    longjmp(loop_stack[loop_ptr].loop_env, optype);
  1583. X    case O_DUMP:
  1584. X    case O_GOTO:/* shudder */
  1585. X    goto_targ = str_get(arg[1].arg_ptr.arg_str);
  1586. X    if (!*goto_targ)
  1587. X        goto_targ = Nullch;        /* just restart from top */
  1588. X    if (optype == O_DUMP) {
  1589. X        do_undump = 1;
  1590. X        my_unexec();
  1591. X    }
  1592. X    longjmp(top_env, 1);
  1593. X    case O_INDEX:
  1594. X    tmps = str_get(st[1]);
  1595. X    if (maxarg < 3)
  1596. X        anum = 0;
  1597. X    else {
  1598. X        anum = (int) str_gnum(st[3]) - arybase;
  1599. X        if (anum < 0)
  1600. X        anum = 0;
  1601. X        else if (anum > st[1]->str_cur)
  1602. X        anum = st[1]->str_cur;
  1603. X    }
  1604. X#ifndef lint
  1605. X    if (!(tmps2 = fbminstr((unsigned char*)tmps + anum,
  1606. X      (unsigned char*)tmps + st[1]->str_cur, st[2])))
  1607. X#else
  1608. X    if (tmps2 = fbminstr(Null(unsigned char*),Null(unsigned char*),Nullstr))
  1609. X#endif
  1610. X        value = (double)(-1 + arybase);
  1611. X    else
  1612. X        value = (double)(tmps2 - tmps + arybase);
  1613. X    goto donumset;
  1614. X    case O_RINDEX:
  1615. X    tmps = str_get(st[1]);
  1616. X    tmps2 = str_get(st[2]);
  1617. X    if (maxarg < 3)
  1618. X        anum = st[1]->str_cur;
  1619. X    else {
  1620. X        anum = (int) str_gnum(st[3]) - arybase + st[2]->str_cur;
  1621. X        if (anum < 0)
  1622. X        anum = 0;
  1623. X        else if (anum > st[1]->str_cur)
  1624. X        anum = st[1]->str_cur;
  1625. X    }
  1626. X#ifndef lint
  1627. X    if (!(tmps2 = rninstr(tmps,  tmps  + anum,
  1628. X                  tmps2, tmps2 + st[2]->str_cur)))
  1629. X#else
  1630. X    if (tmps2 = rninstr(Nullch,Nullch,Nullch,Nullch))
  1631. X#endif
  1632. X        value = (double)(-1 + arybase);
  1633. X    else
  1634. X        value = (double)(tmps2 - tmps + arybase);
  1635. X    goto donumset;
  1636. X    case O_TIME:
  1637. X#ifndef lint
  1638. X    value = (double) time(Null(long*));
  1639. X#endif
  1640. X    goto donumset;
  1641. X    case O_TMS:
  1642. X    sp = do_tms(str,gimme,arglast);
  1643. X    goto array_return;
  1644. X    case O_LOCALTIME:
  1645. X    if (maxarg < 1)
  1646. X        (void)time(&when);
  1647. X    else
  1648. X        when = (long)str_gnum(st[1]);
  1649. X    sp = do_time(str,localtime(&when),
  1650. X      gimme,arglast);
  1651. X    goto array_return;
  1652. X    case O_GMTIME:
  1653. X    if (maxarg < 1)
  1654. X        (void)time(&when);
  1655. X    else
  1656. X        when = (long)str_gnum(st[1]);
  1657. X    sp = do_time(str,gmtime(&when),
  1658. X      gimme,arglast);
  1659. X    goto array_return;
  1660. X    case O_TRUNCATE:
  1661. X    sp = do_truncate(str,arg,
  1662. X      gimme,arglast);
  1663. X    goto array_return;
  1664. X    case O_LSTAT:
  1665. X    case O_STAT:
  1666. X    sp = do_stat(str,arg,
  1667. X      gimme,arglast);
  1668. X    goto array_return;
  1669. X    case O_CRYPT:
  1670. X#ifdef HAS_CRYPT
  1671. X    tmps = str_get(st[1]);
  1672. X#ifdef FCRYPT
  1673. X    str_set(str,fcrypt(tmps,str_get(st[2])));
  1674. X#else
  1675. X    str_set(str,crypt(tmps,str_get(st[2])));
  1676. X#endif
  1677. X#else
  1678. X    fatal(
  1679. X      "The crypt() function is unimplemented due to excessive paranoia.");
  1680. X#endif
  1681. X    break;
  1682. X    case O_ATAN2:
  1683. X    value = str_gnum(st[1]);
  1684. X    value = atan2(value,str_gnum(st[2]));
  1685. X    goto donumset;
  1686. X    case O_SIN:
  1687. X    if (maxarg < 1)
  1688. X        value = str_gnum(stab_val(defstab));
  1689. X    else
  1690. X        value = str_gnum(st[1]);
  1691. X    value = sin(value);
  1692. X    goto donumset;
  1693. X    case O_COS:
  1694. X    if (maxarg < 1)
  1695. X        value = str_gnum(stab_val(defstab));
  1696. X    else
  1697. X        value = str_gnum(st[1]);
  1698. X    value = cos(value);
  1699. X    goto donumset;
  1700. X    case O_RAND:
  1701. X    if (maxarg < 1)
  1702. X        value = 1.0;
  1703. X    else
  1704. X        value = str_gnum(st[1]);
  1705. X    if (value == 0.0)
  1706. X        value = 1.0;
  1707. X#if RANDBITS == 31
  1708. X    value = rand() * value / 2147483648.0;
  1709. X#else
  1710. X#if RANDBITS == 16
  1711. X    value = rand() * value / 65536.0;
  1712. X#else
  1713. X#if RANDBITS == 15
  1714. X    value = rand() * value / 32768.0;
  1715. X#else
  1716. X    value = rand() * value / (double)(((unsigned long)1) << RANDBITS);
  1717. X#endif
  1718. X#endif
  1719. X#endif
  1720. X    goto donumset;
  1721. X    case O_SRAND:
  1722. X    if (maxarg < 1) {
  1723. X        (void)time(&when);
  1724. X        anum = when;
  1725. X    }
  1726. X    else
  1727. X        anum = (int)str_gnum(st[1]);
  1728. X    (void)srand(anum);
  1729. X    goto say_yes;
  1730. X    case O_EXP:
  1731. X    if (maxarg < 1)
  1732. X        value = str_gnum(stab_val(defstab));
  1733. X    else
  1734. X        value = str_gnum(st[1]);
  1735. X    value = exp(value);
  1736. X    goto donumset;
  1737. X    case O_LOG:
  1738. X    if (maxarg < 1)
  1739. X        value = str_gnum(stab_val(defstab));
  1740. X    else
  1741. X        value = str_gnum(st[1]);
  1742. X    if (value <= 0.0)
  1743. X        fatal("Can't take log of %g\n", value);
  1744. X    value = log(value);
  1745. X    goto donumset;
  1746. X    case O_SQRT:
  1747. X    if (maxarg < 1)
  1748. X        value = str_gnum(stab_val(defstab));
  1749. X    else
  1750. X        value = str_gnum(st[1]);
  1751. X    if (value < 0.0)
  1752. X        fatal("Can't take sqrt of %g\n", value);
  1753. X    value = sqrt(value);
  1754. X    goto donumset;
  1755. X    case O_INT:
  1756. X    if (maxarg < 1)
  1757. X        value = str_gnum(stab_val(defstab));
  1758. X    else
  1759. X        value = str_gnum(st[1]);
  1760. X    if (value >= 0.0)
  1761. X        (void)modf(value,&value);
  1762. X    else {
  1763. X        (void)modf(-value,&value);
  1764. X        value = -value;
  1765. X    }
  1766. X    goto donumset;
  1767. X    case O_ORD:
  1768. X    if (maxarg < 1)
  1769. X        tmps = str_get(stab_val(defstab));
  1770. X    else
  1771. X        tmps = str_get(st[1]);
  1772. X#ifndef I286
  1773. X    value = (double) (*tmps & 255);
  1774. X#else
  1775. X    anum = (int) *tmps;
  1776. X    value = (double) (anum & 255);
  1777. X#endif
  1778. X    goto donumset;
  1779. X    case O_ALARM:
  1780. X#ifdef HAS_ALARM
  1781. X    if (maxarg < 1)
  1782. X        tmps = str_get(stab_val(defstab));
  1783. X    else
  1784. X        tmps = str_get(st[1]);
  1785. X    if (!tmps)
  1786. X        tmps = "0";
  1787. X    anum = alarm((unsigned int)atoi(tmps));
  1788. X    if (anum < 0)
  1789. X        goto say_undef;
  1790. X    value = (double)anum;
  1791. X    goto donumset;
  1792. X#else
  1793. X    fatal("Unsupported function alarm");
  1794. X    break;
  1795. X#endif
  1796. X    case O_SLEEP:
  1797. X    if (maxarg < 1)
  1798. X        tmps = Nullch;
  1799. X    else
  1800. X        tmps = str_get(st[1]);
  1801. X    (void)time(&when);
  1802. X    if (!tmps || !*tmps)
  1803. X        sleep((32767<<16)+32767);
  1804. X    else
  1805. X        sleep((unsigned int)atoi(tmps));
  1806. X#ifndef lint
  1807. X    value = (double)when;
  1808. X    (void)time(&when);
  1809. X    value = ((double)when) - value;
  1810. X#endif
  1811. X    goto donumset;
  1812. X    case O_RANGE:
  1813. X    sp = do_range(gimme,arglast);
  1814. X    goto array_return;
  1815. X    case O_F_OR_R:
  1816. X    if (gimme == G_ARRAY) {        /* it's a range */
  1817. X        /* can we optimize to constant array? */
  1818. X        if ((arg[1].arg_type & A_MASK) == A_SINGLE &&
  1819. X          (arg[2].arg_type & A_MASK) == A_SINGLE) {
  1820. X        st[2] = arg[2].arg_ptr.arg_str;
  1821. X        sp = do_range(gimme,arglast);
  1822. X        st = stack->ary_array;
  1823. X        maxarg = sp - arglast[0];
  1824. X        str_free(arg[1].arg_ptr.arg_str);
  1825. X        arg[1].arg_ptr.arg_str = Nullstr;
  1826. X        str_free(arg[2].arg_ptr.arg_str);
  1827. X        arg[2].arg_ptr.arg_str = Nullstr;
  1828. X        arg->arg_type = O_ARRAY;
  1829. X        arg[1].arg_type = A_STAB|A_DONT;
  1830. X        arg->arg_len = 1;
  1831. X        stab = arg[1].arg_ptr.arg_stab = aadd(genstab());
  1832. X        ary = stab_array(stab);
  1833. X        afill(ary,maxarg - 1);
  1834. X        anum = maxarg;
  1835. X        st += arglast[0]+1;
  1836. X        while (maxarg-- > 0)
  1837. X            ary->ary_array[maxarg] = str_smake(st[maxarg]);
  1838. X        st -= arglast[0]+1;
  1839. X        goto array_return;
  1840. X        }
  1841. X        arg->arg_type = optype = O_RANGE;
  1842. X        maxarg = arg->arg_len = 2;
  1843. X        anum = 2;
  1844. X        arg[anum].arg_flags &= ~AF_ARYOK;
  1845. X        argflags = arg[anum].arg_flags;
  1846. X        argtype = arg[anum].arg_type & A_MASK;
  1847. X        arg[anum].arg_type = argtype;
  1848. X        argptr = arg[anum].arg_ptr;
  1849. X        sp = arglast[0];
  1850. X        st -= sp;
  1851. X        sp++;
  1852. X        goto re_eval;
  1853. X    }
  1854. X    arg->arg_type = O_FLIP;
  1855. X    /* FALL THROUGH */
  1856. X    case O_FLIP:
  1857. X    if ((arg[1].arg_type & A_MASK) == A_SINGLE ?
  1858. X      last_in_stab && (int)str_gnum(st[1]) == stab_io(last_in_stab)->lines
  1859. X      :
  1860. X      str_true(st[1]) ) {
  1861. X        str_numset(str,0.0);
  1862. X        anum = 2;
  1863. X        arg->arg_type = optype = O_FLOP;
  1864. X        arg[2].arg_type &= ~A_DONT;
  1865. X        arg[1].arg_type |= A_DONT;
  1866. X        argflags = arg[2].arg_flags;
  1867. X        argtype = arg[2].arg_type & A_MASK;
  1868. X        argptr = arg[2].arg_ptr;
  1869. X        sp = arglast[0];
  1870. X        st -= sp++;
  1871. X        goto re_eval;
  1872. X    }
  1873. X    str_set(str,"");
  1874. X    break;
  1875. X    case O_FLOP:
  1876. X    str_inc(str);
  1877. X    if ((arg[2].arg_type & A_MASK) == A_SINGLE ?
  1878. X      last_in_stab && (int)str_gnum(st[2]) == stab_io(last_in_stab)->lines
  1879. X      :
  1880. X      str_true(st[2]) ) {
  1881. X        arg->arg_type = O_FLIP;
  1882. X        arg[1].arg_type &= ~A_DONT;
  1883. X        arg[2].arg_type |= A_DONT;
  1884. X        str_cat(str,"E0");
  1885. X    }
  1886. X    break;
  1887. X    case O_FORK:
  1888. X#ifdef HAS_FORK
  1889. X    anum = fork();
  1890. X    if (anum < 0)
  1891. X        goto say_undef;
  1892. X    if (!anum) {
  1893. X        if (tmpstab = stabent("$",allstabs))
  1894. X        str_numset(STAB_STR(tmpstab),(double)getpid());
  1895. X        hclear(pidstatus);    /* no kids, so don't wait for 'em */
  1896. X    }
  1897. X    value = (double)anum;
  1898. X    goto donumset;
  1899. X#else
  1900. X    fatal("Unsupported function fork");
  1901. X    break;
  1902. X#endif
  1903. X    case O_WAIT:
  1904. X#ifdef HAS_WAIT
  1905. X#ifndef lint
  1906. X    anum = wait(&argflags);
  1907. X    if (anum > 0)
  1908. X        pidgone(anum,argflags);
  1909. X    value = (double)anum;
  1910. X#endif
  1911. X    statusvalue = (unsigned short)argflags;
  1912. X    goto donumset;
  1913. X#else
  1914. X    fatal("Unsupported function wait");
  1915. X    break;
  1916. X#endif
  1917. X    case O_WAITPID:
  1918. X#ifdef HAS_WAIT
  1919. X#ifndef lint
  1920. X    anum = (int)str_gnum(st[1]);
  1921. X    optype = (int)str_gnum(st[2]);
  1922. X    anum = wait4pid(anum, &argflags,optype);
  1923. X    value = (double)anum;
  1924. X#endif
  1925. X    statusvalue = (unsigned short)argflags;
  1926. X    goto donumset;
  1927. X#else
  1928. X    fatal("Unsupported function wait");
  1929. X    break;
  1930. X#endif
  1931. X    case O_SYSTEM:
  1932. X#ifdef HAS_FORK
  1933. X#ifdef TAINT
  1934. X    if (arglast[2] - arglast[1] == 1) {
  1935. X        taintenv();
  1936. X        tainted |= st[2]->str_tainted;
  1937. X        taintproper("Insecure dependency in system");
  1938. X    }
  1939. X#endif
  1940. X    while ((anum = vfork()) == -1) {
  1941. X        if (errno != EAGAIN) {
  1942. X        value = -1.0;
  1943. X        goto donumset;
  1944. X        }
  1945. X        sleep(5);
  1946. X    }
  1947. X    if (anum > 0) {
  1948. X#ifndef lint
  1949. X        ihand = signal(SIGINT, SIG_IGN);
  1950. X        qhand = signal(SIGQUIT, SIG_IGN);
  1951. X        argtype = wait4pid(anum, &argflags, 0);
  1952. X#else
  1953. X        ihand = qhand = 0;
  1954. X#endif
  1955. X        (void)signal(SIGINT, ihand);
  1956. X        (void)signal(SIGQUIT, qhand);
  1957. X        statusvalue = (unsigned short)argflags;
  1958. X        if (argtype < 0)
  1959. X        value = -1.0;
  1960. X        else {
  1961. X        value = (double)((unsigned int)argflags & 0xffff);
  1962. X        }
  1963. X        do_execfree();    /* free any memory child malloced on vfork */
  1964. X        goto donumset;
  1965. X    }
  1966. X    if ((arg[1].arg_type & A_MASK) == A_STAB)
  1967. X        value = (double)do_aexec(st[1],arglast);
  1968. X    else if (arglast[2] - arglast[1] != 1)
  1969. X        value = (double)do_aexec(Nullstr,arglast);
  1970. X    else {
  1971. X        value = (double)do_exec(str_get(str_mortal(st[2])));
  1972. X    }
  1973. X    _exit(-1);
  1974. X#else /* ! FORK */
  1975. X    if ((arg[1].arg_type & A_MASK) == A_STAB)
  1976. X        value = (double)do_aspawn(st[1],arglast);
  1977. X    else if (arglast[2] - arglast[1] != 1)
  1978. X        value = (double)do_aspawn(Nullstr,arglast);
  1979. X    else {
  1980. X        value = (double)do_spawn(str_get(str_mortal(st[2])));
  1981. X    }
  1982. X    goto donumset;
  1983. X#endif /* FORK */
  1984. X    case O_EXEC_OP:
  1985. X    if ((arg[1].arg_type & A_MASK) == A_STAB)
  1986. X        value = (double)do_aexec(st[1],arglast);
  1987. X    else if (arglast[2] - arglast[1] != 1)
  1988. X        value = (double)do_aexec(Nullstr,arglast);
  1989. X    else {
  1990. X        value = (double)do_exec(str_get(str_mortal(st[2])));
  1991. X    }
  1992. X    goto donumset;
  1993. X    case O_HEX:
  1994. X    if (maxarg < 1)
  1995. X        tmps = str_get(stab_val(defstab));
  1996. X    else
  1997. X        tmps = str_get(st[1]);
  1998. X    value = (double)scanhex(tmps, 99, &argtype);
  1999. X    goto donumset;
  2000. X
  2001. X    case O_OCT:
  2002. X    if (maxarg < 1)
  2003. X        tmps = str_get(stab_val(defstab));
  2004. X    else
  2005. X        tmps = str_get(st[1]);
  2006. X    while (*tmps && isascii(*tmps) && (isspace(*tmps) || *tmps == '0'))
  2007. X        tmps++;
  2008. X    if (*tmps == 'x')
  2009. X        value = (double)scanhex(++tmps, 99, &argtype);
  2010. X    else
  2011. X        value = (double)scanoct(tmps, 99, &argtype);
  2012. X    goto donumset;
  2013. X
  2014. X/* These common exits are hidden here in the middle of the switches for the
  2015. X/* benefit of those machines with limited branch addressing.  Sigh.  */
  2016. X
  2017. Xarray_return:
  2018. X#ifdef DEBUGGING
  2019. X    if (debug) {
  2020. X    dlevel--;
  2021. X    if (debug & 8) {
  2022. !STUFFY!FUNK!
  2023. echo " "
  2024. echo "End of kit 6 (of 36)"
  2025. cat /dev/null >kit6isdone
  2026. run=''
  2027. config=''
  2028. 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 25 26 27 28 29 30 31 32 33 34 35 36; do
  2029.     if test -f kit${iskit}isdone; then
  2030.     run="$run $iskit"
  2031.     else
  2032.     todo="$todo $iskit"
  2033.     fi
  2034. done
  2035. case $todo in
  2036.     '')
  2037.     echo "You have run all your kits.  Please read README and then type Configure."
  2038.     for combo in *:AA; do
  2039.         if test -f "$combo"; then
  2040.         realfile=`basename $combo :AA`
  2041.         cat $realfile:[A-Z][A-Z] >$realfile
  2042.         rm -rf $realfile:[A-Z][A-Z]
  2043.         fi
  2044.     done
  2045.     rm -rf kit*isdone
  2046.     chmod 755 Configure
  2047.     ;;
  2048.     *)  echo "You have run$run."
  2049.     echo "You still need to run$todo."
  2050.     ;;
  2051. esac
  2052. : Someone might mail this, so...
  2053. exit
  2054.  
  2055. exit 0 # Just in case...
  2056. -- 
  2057. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2058. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2059. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2060. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2061.