home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume24 / zsh2.1 / part07 < prev    next >
Text File  |  1991-10-24  |  49KB  |  2,524 lines

  1. Newsgroups: comp.sources.misc
  2. From: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
  3. Subject:  v24i007:  zsh2.1 - The Z shell, Part07/19
  4. Message-ID: <1991Oct24.190901.25780@sparky.imd.sterling.com>
  5. X-Md4-Signature: 3b9e9db3e226c0bd3652e4886dcb6cca
  6. Date: Thu, 24 Oct 1991 19:09:01 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
  10. Posting-number: Volume 24, Issue 7
  11. Archive-name: zsh2.1/part07
  12. Environment: BSD
  13. Supersedes: zsh2.00: Volume 18, Issue 84-98
  14.  
  15. #!/bin/sh
  16. # this is zshar.07 (part 7 of zsh2.1.0)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file zsh2.1/src/glob.c continued
  19. #
  20. if test ! -r _shar_seq_.tmp; then
  21.     echo 'Please unpack part 1 first!'
  22.     exit 1
  23. fi
  24. (read Scheck
  25.  if test "$Scheck" != 7; then
  26.     echo Please unpack part "$Scheck" next!
  27.     exit 1
  28.  else
  29.     exit 0
  30.  fi
  31. ) < _shar_seq_.tmp || exit 1
  32. if test ! -f _shar_wnt_.tmp; then
  33.     echo 'x - still skipping zsh2.1/src/glob.c'
  34. else
  35. echo 'x - continuing file zsh2.1/src/glob.c'
  36. sed 's/^X//' << 'SHAR_EOF' >> 'zsh2.1/src/glob.c' &&
  37. X                }
  38. X                if (*pat == Outbrack)
  39. X                    break;
  40. X                for (pptr++; *pat != Outbrack; pat++);
  41. X                pat++;
  42. X                continue;
  43. X            }
  44. X        }
  45. X        if (*pat == Inang)
  46. X            {
  47. X            int t1,t2,t3;
  48. X            char *ptr;
  49. X
  50. X            if (*++pat == Outang)    /* handle <> case */
  51. X                {
  52. X                ( void ) zstrtol(pptr,&ptr,10);
  53. X                if (ptr == pptr)
  54. X                    break;
  55. X                pptr = ptr;
  56. X                pat++;
  57. X                }
  58. X            else
  59. X                {
  60. X                t1 = zstrtol(pptr,&ptr,10);
  61. X                if (ptr == pptr)
  62. X                    break;
  63. X                pptr = ptr;
  64. X                t2 = zstrtol(pat,&ptr,10);
  65. X                if (*ptr != '-')
  66. X                    exit(31);
  67. X                t3 = zstrtol(ptr+1,&pat,10);
  68. X                if (!t3)
  69. X                    t3 = -1;
  70. X                if (*pat++ != Outang)
  71. X                    exit(21);
  72. X                if (t1 < t2 || (t3 != -1 && t1 > t3))
  73. X                    break;
  74. X                }
  75. X            continue;
  76. X            }
  77. X        if (*pptr == *pat)
  78. X            {
  79. X            pptr++;
  80. X            pat++;
  81. X            continue;
  82. X            }
  83. X        break;
  84. X        }
  85. X    return 0;
  86. X}
  87. X
  88. XComplist parsepat(str) /**/
  89. Xchar *str;
  90. X{
  91. X    mode = 0;
  92. X    pptr = str;
  93. X    return parsecomplist();
  94. X}
  95. X
  96. XComp parsereg(str) /**/
  97. Xchar *str;
  98. X{
  99. X    mode = 1;
  100. X    pptr = str;
  101. X    return parsecompsw();
  102. X}
  103. X
  104. XComplist parsecomplist() /**/
  105. X{
  106. XComp c1;
  107. XComplist p1;
  108. X
  109. X    if (pptr[0] == Star && pptr[1] == Star &&
  110. X         pptr[2] == Star && pptr[3] == Star &&
  111. X         pptr[4] == '/')
  112. X        {
  113. X        pptr[0] = Inpar;
  114. X        pptr[1] = Star;
  115. X        pptr[2] = '/';
  116. X        pptr[3] = Outpar;
  117. X        pptr[4] = Pound;    /* "####/" -> "( * /)#" */
  118. X        }
  119. X    if (*pptr == Inpar)
  120. X        {
  121. X        char *str;
  122. X        int pars = 1;
  123. X
  124. X        for (str = pptr+1; *str && pars; str++)
  125. X            if (*str == Inpar)
  126. X                pars++;
  127. X            else if (*str == Outpar)
  128. X                pars--;
  129. X        if (str[0] != Pound || str[-1] != Outpar || str[-2] != '/')
  130. X            goto kludge;
  131. X        pptr++;
  132. X        if (!(c1 = parsecompsw()))
  133. X            return NULL;
  134. X        if (pptr[0] == '/' && pptr[1] == Outpar && pptr[2] == Pound)
  135. X            {
  136. X            int pdflag = 0;
  137. X
  138. X            pptr += 3;
  139. X            if (*pptr == Pound)
  140. X                {
  141. X                pdflag = 1;
  142. X                pptr++;
  143. X                }
  144. X            p1 = (Complist) alloc(sizeof *p1);
  145. X            p1->comp = c1;
  146. X            p1->closure = 1+pdflag;
  147. X            p1->next = parsecomplist();
  148. X            return (p1->comp) ? p1 : NULL;
  149. X            }
  150. X        }
  151. X    else
  152. X        {
  153. Xkludge:
  154. X        if (!(c1 = parsecompsw()))
  155. X            return NULL;
  156. X        if (*pptr == '/' || !*pptr)
  157. X            {
  158. X            int ef = *pptr == '/';
  159. X
  160. X            p1 = (Complist) alloc(sizeof *p1);
  161. X            p1->comp = c1;
  162. X            p1->closure = 0;
  163. X            p1->next = (*pptr == '/') ? (pptr++,parsecomplist()) : NULL;
  164. X            return (ef && !p1->next) ? NULL : p1;
  165. X            }
  166. X        }
  167. X    errflag = 1;
  168. X    return NULL;
  169. X}
  170. X
  171. XComp parsecomp() /**/
  172. X{
  173. XComp c = (Comp) alloc(sizeof *c),c1,c2;
  174. Xchar *s = c->str = alloc(MAXPATHLEN*2),*ls = NULL;
  175. X
  176. X    c->next = tail;
  177. X
  178. X    while (*pptr && (mode || *pptr != '/') && *pptr != Bar &&
  179. X            *pptr != Outpar)
  180. X        {
  181. X        if (*pptr == Hat)
  182. X            {
  183. X            *s++ = Hat;
  184. X            *s++ = '\0';
  185. X            pptr++;
  186. X            if (!(c->next = parsecomp()))
  187. X                return NULL;
  188. X            return c;
  189. X            }
  190. X        if (*pptr == Star && pptr[1] && (mode || pptr[1] != '/'))
  191. X            {
  192. X            *s++ = '\0';
  193. X            pptr++;
  194. X            c1 = (Comp) alloc(sizeof *c1);
  195. X            *(c1->str = strdup("?")) = Quest;
  196. X            c1->closure = 1;
  197. X            if (!(c2 = parsecomp())) return NULL;
  198. X            c1->next = c2;
  199. X            c->next = c1;
  200. X            return c;
  201. X            }
  202. X        if (*pptr == Inpar)
  203. X            {
  204. X            int pars = 1;
  205. X            char *startp = pptr, *endp;
  206. X            Comp stail = tail;
  207. X            int dpnd = 0;
  208. X
  209. X            for (pptr = pptr+1; *pptr && pars; pptr++)
  210. X                if (*pptr == Inpar)
  211. X                    pars++;
  212. X                else if (*pptr == Outpar)
  213. X                    pars--;
  214. X            if (pptr[-1] != Outpar)
  215. X                {
  216. X                errflag = 1;
  217. X                return NULL;
  218. X                }
  219. X            if (*pptr == Pound)
  220. X                {
  221. X                dpnd = 1;
  222. X                pptr++;
  223. X                if (*pptr == Pound)
  224. X                    {
  225. X                    pptr++;
  226. X                    dpnd = 2;
  227. X                    }
  228. X                }
  229. X            if (!(c1 = parsecomp())) return NULL;
  230. X            tail = c1;
  231. X            endp = pptr;
  232. X            pptr = startp;
  233. X            pptr++;
  234. X            *s++ = '\0';
  235. X            c->next = (Comp) alloc(sizeof *c);
  236. X            c->next->left = parsecompsw();
  237. X            c->next->closure = dpnd;
  238. X            c->next->next = (Comp) alloc(sizeof *c);
  239. X            pptr = endp;
  240. X            tail = stail;
  241. X            return c;
  242. X            }
  243. X        if (*pptr == Pound)
  244. X            {
  245. X            *s = '\0';
  246. X            pptr++;
  247. X            if (!ls)
  248. X                return NULL;
  249. X            if (*pptr == Pound) 
  250. X                {
  251. X                pptr++;
  252. X                c->next = c1 = (Comp) alloc(sizeof *c);
  253. X                c1->str = strdup(ls);
  254. X                }
  255. X            else
  256. X                c1 = c;
  257. X            c1->next = c2 = (Comp) alloc(sizeof *c);
  258. X            c2->str = strdup(ls);
  259. X            c2->closure = 1;
  260. X            c2->next = parsecomp();
  261. X            if (!c2->next)
  262. X                return NULL;
  263. X            *ls++ = '\0';
  264. X            return c;
  265. X            }
  266. X        ls = s;
  267. X        if (*pptr == Inang)
  268. X            {
  269. X            int dshct;
  270. X
  271. X            dshct = (pptr[1] == Outang);
  272. X            *s++ = *pptr++;
  273. X            while (*pptr && (*s++ = *pptr++) != Outang)
  274. X                if (s[-1] == '-')
  275. X                    dshct++;
  276. X                else if (!idigit(s[-1]))
  277. X                    break;
  278. X            if (s[-1] != Outang || dshct != 1)
  279. X                return NULL;
  280. X            }
  281. X        else if (*pptr == Inbrack)
  282. X            {
  283. X            while (*pptr && (*s++ = *pptr++) != Outbrack);
  284. X            if (s[-1] != Outbrack)
  285. X                return NULL;
  286. X            }
  287. X        else if (itok(*pptr) && *pptr != Star && *pptr != Quest)
  288. X            *s++ = ztokens[*pptr++-Pound];
  289. X        else
  290. X            *s++ = *pptr++;
  291. X        }
  292. X    if (*pptr == '/' || !*pptr)
  293. X        c->last = 1;
  294. X    *s++ = '\0';
  295. X    return c;
  296. X}
  297. X
  298. XComp parsecompsw() /**/
  299. X{
  300. XComp c1,c2,c3;
  301. X
  302. X    c1 = parsecomp();
  303. X    if (!c1)
  304. X        return NULL;
  305. X    if (*pptr == Bar)
  306. X        {
  307. X        c2 = (Comp) alloc(sizeof *c2);
  308. X        pptr++;
  309. X        c3 = parsecompsw();
  310. X        if (!c3)
  311. X            return NULL;
  312. X        c2->str = strdup("");
  313. X        c2->left = c1;
  314. X        c2->right = c3;
  315. X        return c2;
  316. X        }
  317. X    return c1;
  318. X}
  319. X
  320. X/* tokenize and see if ss matches tt */
  321. X
  322. Xint patmatch(ss,tt) /**/
  323. Xchar *ss;char *tt;
  324. X{
  325. Xchar *s = ss,*t;
  326. X
  327. X    for (; *s; s++)
  328. X        if (*s == '\\')
  329. X            chuck(s);
  330. X        else
  331. X            for (t = ztokens; *t; t++)
  332. X                if (*t == *s)
  333. X                    {
  334. X                    *s = (t-ztokens)+Pound;
  335. X                    break;
  336. X                    }
  337. X    return matchpat(ss,tt);
  338. X}
  339. X
  340. X/* remove unnecessary Nulargs */
  341. X
  342. Xvoid remnulargs(s) /**/
  343. Xchar *s;
  344. X{
  345. Xint nl = *s;
  346. Xchar *t = s;
  347. X
  348. X    while (*s)
  349. X        if (*s == Nularg)
  350. X            chuck(s);
  351. X        else
  352. X            s++;
  353. X    if (!*t && nl)
  354. X        {
  355. X        t[0] = Nularg;
  356. X        t[1] = '\0';
  357. X        }
  358. X}
  359. X
  360. X/* qualifier functions */
  361. X
  362. Xint qualdev(buf,dv) /**/
  363. Xstruct stat *buf;long dv;
  364. X{
  365. X    return buf->st_dev == dv;
  366. X}
  367. X
  368. Xint qualnlink(buf,ct) /**/
  369. Xstruct stat *buf;long ct;
  370. X{
  371. X    return buf->st_nlink == ct;
  372. X}
  373. X
  374. Xint qualuid(buf,uid) /**/
  375. Xstruct stat *buf;long uid;
  376. X{
  377. X    return buf->st_uid == uid;
  378. X}
  379. X
  380. Xint qualgid(buf,gid) /**/
  381. Xstruct stat *buf;long gid;
  382. X{
  383. X    return buf->st_gid == gid;
  384. X}
  385. X
  386. Xint qualisdev(buf,junk) /**/
  387. Xstruct stat *buf;long junk;
  388. X{
  389. X    junk = buf->st_mode & S_IFMT;
  390. X    return junk == S_IFBLK || junk == S_IFCHR;
  391. X}
  392. X
  393. Xint qualmode(buf,mod) /**/
  394. Xstruct stat *buf;long mod;
  395. X{
  396. X    return (buf->st_mode & S_IFMT) == mod;
  397. X}
  398. X
  399. Xint qualflags(buf,mod) /**/
  400. Xstruct stat *buf;long mod;
  401. X{
  402. X    return buf->st_mode & mod;
  403. X}
  404. X
  405. Xint qualiscom(buf,mod) /**/
  406. Xstruct stat *buf;long mod;
  407. X{
  408. X    return (buf->st_mode & (S_IFMT|S_IEXEC)) == (S_IFREG|S_IEXEC);
  409. X}
  410. X
  411. SHAR_EOF
  412. echo 'File zsh2.1/src/glob.c is complete' &&
  413. chmod 0644 zsh2.1/src/glob.c ||
  414. echo 'restore of zsh2.1/src/glob.c failed'
  415. Wc_c="`wc -c < 'zsh2.1/src/glob.c'`"
  416. test 23323 -eq "$Wc_c" ||
  417.     echo 'zsh2.1/src/glob.c: original size 23323, current size' "$Wc_c"
  418. rm -f _shar_wnt_.tmp
  419. fi
  420. # ============= zsh2.1/src/hist.c ==============
  421. if test -f 'zsh2.1/src/hist.c' -a X"$1" != X"-c"; then
  422.     echo 'x - skipping zsh2.1/src/hist.c (File already exists)'
  423.     rm -f _shar_wnt_.tmp
  424. else
  425. > _shar_wnt_.tmp
  426. echo 'x - extracting zsh2.1/src/hist.c (Text)'
  427. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.1/src/hist.c' &&
  428. X/*
  429. X
  430. X    hist.c - history expansion
  431. X
  432. X    This file is part of zsh, the Z shell.
  433. X
  434. X    zsh is free software; no one can prevent you from reading the source
  435. X   code, or giving it to someone else.
  436. X
  437. X   This file is copyrighted under the GNU General Public License, which
  438. X   can be found in the file called COPYING.
  439. X
  440. X   Copyright (C) 1990, 1991 Paul Falstad
  441. X
  442. X   zsh is distributed in the hope that it will be useful, but
  443. X   WITHOUT ANY WARRANTY.  No author or distributor accepts
  444. X   responsibility to anyone for the consequences of using it or for
  445. X   whether it serves any particular purpose or works at all, unless he
  446. X   says so in writing.  Refer to the GNU General Public License
  447. X   for full details.
  448. X
  449. X   Everyone is granted permission to copy, modify and redistribute
  450. X   zsh, but only under the conditions described in the GNU General Public
  451. X   License.   A copy of this license is supposed to have been given to you
  452. X   along with zsh so you can know your rights and responsibilities.
  453. X   It should be in a file named COPYING.
  454. X
  455. X   Among other things, the copyright notice and this notice must be
  456. X   preserved on all copies.
  457. X
  458. X*/
  459. X
  460. X#include "zsh.h"
  461. X
  462. Xstatic int lastc;
  463. X
  464. X/* add a character to the current history word */
  465. X
  466. Xvoid hwaddc(c) /**/
  467. Xint c;
  468. X{
  469. X    if (hlastw && hline && (!(errflag || lexstop) || c == HISTSPACE))
  470. X        {
  471. X        *hptr++ = c;
  472. X        if (hptr-hline >= hlinesz)
  473. X            {
  474. X            int ll,flag = 0;
  475. X
  476. X            ll = hptr-hlastw;
  477. X            if (full(histlist) && getdata(lastnode(histlist)) == hline)
  478. X                flag = 1;
  479. X            hline = realloc(hline,hlinesz *= 4);
  480. X            if (flag)
  481. X                setdata(lastnode(histlist),hline);
  482. X            hptr = hline+(hlinesz/4);
  483. X            hlastw = hptr-ll;
  484. X            }
  485. X        }
  486. X}
  487. X
  488. X#define habort() { errflag = lexstop = 1; return ' '; }
  489. X
  490. X/* get a character after performing history substitution */
  491. X
  492. Xint hgetc() /**/
  493. X{
  494. Xint c,ev,farg,larg,argc,marg = -1,cflag = 0,bflag = 0;
  495. Xchar buf[256],*ptr;
  496. Xchar *sline,*eline;
  497. X
  498. Xtailrec:
  499. X    c = hgetch();
  500. X    if (stophist || alstackind)
  501. X        {
  502. X        hwaddc(c);
  503. X        return c;
  504. X        }
  505. X    if (isfirstch && c == hatchar)
  506. X        {
  507. X        isfirstch = 0;
  508. X        hungetch(hatchar);
  509. X        hungets(":s");
  510. X        c = bangchar;
  511. X        goto hatskip;
  512. X        }
  513. X    if (c != ' ')
  514. X        isfirstch = 0;
  515. X    if (c == '\\')
  516. X        {
  517. X        int g = hgetch();
  518. X        
  519. X        if (g != bangchar)
  520. X            hungetch(g);
  521. X        else
  522. X            {
  523. X            hwaddc(bangchar);
  524. X            return bangchar;
  525. X            }
  526. X        }
  527. X    if (c != bangchar)
  528. X        {
  529. X        hwaddc(c);
  530. X        return c;
  531. X        }
  532. Xhatskip:
  533. X    *hptr = '\0';
  534. X    if ((c = hgetch()) == '{')
  535. X        {
  536. X        bflag = cflag = 1;
  537. X        c = hgetch();
  538. X        }
  539. X    if (c == '\"')
  540. X        {
  541. X        stophist = 1;
  542. X        goto tailrec;
  543. X        }
  544. X    if (!cflag && inblank(c) || c == '=' || c == '(' || lexstop)
  545. X        {
  546. X        if (lexstop)
  547. X            lexstop = 0;
  548. X        else
  549. X            hungetch(c);
  550. X        hwaddc(bangchar);
  551. X        return bangchar;
  552. X        }
  553. X    cflag = 0;
  554. X    ptr = buf;
  555. X
  556. X    /* get event number */
  557. X
  558. X    if (c == '?')
  559. X        {
  560. X        for(;;)
  561. X            {
  562. X            c = hgetch();
  563. X            if (c == '?' || c == '\n' || lexstop)
  564. X                break;
  565. X            else
  566. X                *ptr++ = c;
  567. X            }
  568. X        if (c != '\n' && !lexstop)
  569. X            c = hgetch();
  570. X        *ptr = '\0';
  571. X        ev = hconsearch(hsubl = ztrdup(buf),&marg);
  572. X        if (ev == -1)
  573. X            {
  574. X            herrflush();
  575. X            zerr("no such event: %s",buf,0);
  576. X            habort();
  577. X            }
  578. X        }
  579. X    else
  580. X        {
  581. X        int t0;
  582. X        for (;;)
  583. X            {
  584. X            if (inblank(c) || c == ';' || c == ':' || c == '^' || c == '$' ||
  585. X                    c == '*' || c == '%' || c == '}' || lexstop)
  586. X                break;
  587. X            if (ptr != buf) {
  588. X                if (c == '-') break;
  589. X                if (idigit(buf[0]) && !idigit(c)) break;
  590. X            }
  591. X            *ptr++ = c;
  592. X            if (c == '#' || c == bangchar)
  593. X                {
  594. X                c = hgetch();
  595. X                break;
  596. X                }
  597. X            c = hgetch();
  598. X            }
  599. X        *ptr = 0;
  600. X        if (!*buf)
  601. X            ev = defev;
  602. X        else if (t0 = atoi(buf))
  603. X            ev = (t0 < 0) ? curhist+t0 : t0;
  604. X        else if (*buf == bangchar)
  605. X            ev = curhist-1;
  606. X        else if (*buf == '#')
  607. X            ev = curhist;
  608. X        else if ((ev = hcomsearch(buf)) == -1)
  609. X            {
  610. X            zerr("event not found: %s",buf,0);
  611. X            while (c != '\n' && !lexstop)
  612. X                c = hgetch();
  613. X            habort();
  614. X            }
  615. X        }
  616. X
  617. X    /* get the event */
  618. X
  619. X    if (!(eline = getevent(defev = ev)))
  620. X        habort();
  621. X
  622. X    /* extract the relevant arguments */
  623. X
  624. X    argc = getargc(eline);
  625. X    if (c == ':')
  626. X        {
  627. X        cflag = 1;
  628. X        c = hgetch();
  629. X        }
  630. X    if (c == '*')
  631. X        {
  632. X        farg = 1;
  633. X        larg = argc;
  634. X        cflag = 0;
  635. X        }
  636. X    else
  637. X        {
  638. X        hungetch(c);
  639. X        larg = farg = getargspec(argc,marg);
  640. X        if (larg == -2)
  641. X            habort();
  642. X        if (farg != -1)
  643. X            cflag = 0;
  644. X        c = hgetch();
  645. X        if (c == '*')
  646. X            {
  647. X            cflag = 0;
  648. X            larg = argc;
  649. X            }
  650. X        else if (c == '-')
  651. X            {
  652. X            cflag = 0;
  653. X            larg = getargspec(argc,marg);
  654. X            if (larg == -2)
  655. X                habort();
  656. X            if (larg == -1)
  657. X                larg = argc-1;
  658. X            }
  659. X        else
  660. X            hungetch(c);
  661. X        }
  662. X    if (farg == -1)
  663. X        farg = 0;
  664. X    if (larg == -1)
  665. X        larg = argc;
  666. X    if (!(sline = getargs(eline,farg,larg)))
  667. X        habort();
  668. X
  669. X    /* do the modifiers */
  670. X
  671. X    for(;;)
  672. X        {
  673. X        c = (cflag) ? ':' : hgetch();
  674. X        cflag = 0;
  675. X        if (c == ':')
  676. X            {
  677. X            int gbal = 0;
  678. X        
  679. X            if ((c = hgetch()) == 'g')
  680. X                {
  681. X                gbal = 1;
  682. X                c = hgetch();
  683. X                }
  684. X            switch(c)
  685. X                {
  686. X                case 'p':
  687. X                    histdone = HISTFLAG_DONE|HISTFLAG_NOEXEC;
  688. X                    break;
  689. X                case 'h':
  690. X                    if (!remtpath(&sline))
  691. X                        {
  692. X                        herrflush();
  693. X                        zerr("modifier failed: h",NULL,0);
  694. X                        habort();
  695. X                        }
  696. X                    break;
  697. X                case 'e':
  698. X                    if (!rembutext(&sline))
  699. X                        {
  700. X                        herrflush();
  701. X                        zerr("modifier failed: e",NULL,0);
  702. X                        habort();
  703. X                        }
  704. X                    break;
  705. X                case 'r':
  706. X                    if (!remtext(&sline))
  707. X                        {
  708. X                        herrflush();
  709. X                        zerr("modifier failed: r",NULL,0);
  710. X                        habort();
  711. X                        }
  712. X                    break;
  713. X                case 't':
  714. X                    if (!remlpaths(&sline))
  715. X                        {
  716. X                        herrflush();
  717. X                        zerr("modifier failed: t",NULL,0);
  718. X                        habort();
  719. X                        }
  720. X                    break;
  721. X                case 's':
  722. X                    {
  723. X                    int del;
  724. X                    char *ptr1,*ptr2;
  725. X                
  726. X                    del = hgetch();
  727. X                    ptr1 = hdynread2(del);
  728. X                    if (!ptr1)
  729. X                        habort();
  730. X                    ptr2 = hdynread2(del);
  731. X                    if (strlen(ptr1))
  732. X                        {
  733. X                        if (hsubl)
  734. X                            free(hsubl);
  735. X                        hsubl = ptr1;
  736. X                        }
  737. X                    if (hsubr)
  738. X                        free(hsubr);
  739. X                    hsubr = ptr2;
  740. X                    }
  741. X                case '&':
  742. X                    if (hsubl && hsubr)
  743. X                        subst(&sline,hsubl,hsubr,gbal);
  744. X                    else
  745. X                        {
  746. X                        herrflush();
  747. X                        zerr("no previous substitution with &",NULL,0);
  748. X                        habort();
  749. X                        }
  750. X                    break;
  751. X                case 'q':
  752. X                    quote(&sline);
  753. X                    break;
  754. X                case 'x':
  755. X                    quotebreak(&sline);
  756. X                    break;
  757. X                case 'l':
  758. X                    downcase(&sline);
  759. X                    break;
  760. X                case 'u':
  761. X                    upcase(&sline);
  762. X                    break;
  763. X                default:
  764. X                    herrflush();
  765. X                    zerr("illegal modifier: %c",NULL,c);
  766. X                habort();
  767. X                break;
  768. X            }
  769. X        }
  770. X    else
  771. X        {
  772. X        if (c != '}' || !bflag)
  773. X            hungetch(c);
  774. X        if (c != '}' && bflag)
  775. X            {
  776. X            zerr("'}' expected",NULL,0);
  777. X            habort();
  778. X            }
  779. X        break;
  780. X        }
  781. X    }
  782. X
  783. X    /* stuff the resulting string in the input queue and start over */
  784. X
  785. X    lexstop = 0;
  786. X    if (alstackind != MAXAL)
  787. X        {
  788. X        hungets(HISTMARK);
  789. X        alstack[alstackind++] = NULL;
  790. X        }
  791. X    hungets(sline);
  792. X    histdone |= HISTFLAG_DONE;
  793. X    if (isset(HISTVERIFY)) {
  794. X        histdone |= HISTFLAG_NOEXEC;
  795. X        zrecall = 1;
  796. X    }
  797. X    goto tailrec;
  798. X}
  799. X
  800. X/* reset the alias stack for lexrestore () */
  801. X
  802. Xvoid clearalstack() /**/
  803. X{
  804. XAlias ix;
  805. X
  806. X    while (alstackind)
  807. X        {
  808. X        ix = alstack[--alstackind];
  809. X        ix->inuse = 0;
  810. X        }
  811. X}
  812. X
  813. X/* get a character without history expansion */
  814. X
  815. Xint hgetch() /**/
  816. X{
  817. Xchar *line,*pmpt,*pmpt2 = NULL;
  818. Xint plen;
  819. X
  820. Xstart:
  821. X    if (inbufct)
  822. X        {
  823. X        inbufct--;
  824. X        if ((lastc = *inbufptr++) == ALPOP)
  825. X            {
  826. X            Alias ix;
  827. X            char *t;
  828. X
  829. X            if (!alstackind)
  830. X                {
  831. X                zerr("alias stack underflow",NULL,0);
  832. X                errflag = lexstop = 1;
  833. X                return lastc = ' ';
  834. X                }
  835. X            ix = alstack[--alstackind];
  836. X            if (ix)
  837. X                {
  838. X                ix->inuse = 0;
  839. X                t = ix->text;
  840. X                if (*t && t[strlen(t)-1] == ' ')
  841. X                    alstat = ALSTAT_MORE;
  842. X                else
  843. X                    alstat = ALSTAT_JUNK;
  844. X                }
  845. X            goto start;
  846. X            }
  847. X        if (itok(lastc))
  848. X            goto start;
  849. X        return lastc;
  850. X        }
  851. X    if (strin || errflag)
  852. X        {
  853. X        lexstop = 1;
  854. X        return lastc = ' ';
  855. X        }
  856. X    if (interact && isset(SHINSTDIN))
  857. X        if (!isfirstln)
  858. X            pmpt = putprompt(prompt2,&plen);
  859. X        else
  860. X            {
  861. X            int foo;
  862. X
  863. X            pmpt = putprompt(prompt,&plen);
  864. X            pmpt2 = (rprompt) ? putprompt(rprompt,&foo) : NULL;
  865. X            }
  866. X    if (!(interact && isset(SHINSTDIN) && SHTTY != -1 && isset(USEZLE)))
  867. X        {
  868. X        if (interact && isset(SHINSTDIN))
  869. X            write(2,pmpt,strlen(pmpt));
  870. X        line = fgets(zalloc(256),256,bshin);
  871. X        }
  872. X    else
  873. X        line = zleread(pmpt,pmpt2,plen);
  874. X    if (!line)
  875. X        {
  876. X        lexstop = 1;
  877. X        return lastc = ' ';
  878. X        }
  879. X    if (errflag)
  880. X        {
  881. X        lexstop = errflag = 1;
  882. X        return lastc = ' ';
  883. X        }
  884. X    if (interact && isset(SHINSTDIN))
  885. X        {
  886. X        char *s = getdata(lastnode(lithistlist));
  887. X
  888. X        if (!*s)
  889. X            {
  890. X            free(s);
  891. X            setdata(lastnode(lithistlist),ztrdup(line));
  892. X            }
  893. X        else
  894. X            {
  895. X            char *t = zalloc(strlen(s)+strlen(line)+3);
  896. X
  897. X            strcpy(t,s);
  898. X            strcat(t,line);
  899. X            free(s);
  900. X            setdata(lastnode(lithistlist),t);
  901. X            }
  902. X        }
  903. X    if (isfirstln)
  904. X        spaceflag = *line == ' ';
  905. X    if (isset(VERBOSE))
  906. X        {
  907. X        fputs(line,stderr);
  908. X        fflush(stderr);
  909. X        }
  910. X    if (line[strlen(line)-1] == '\n')
  911. X        {
  912. X        lineno++;
  913. X        if (interact && isset(SUNKEYBOARDHACK) && isset(SHINSTDIN) && 
  914. X                SHTTY != -1 && *line && line[1] && line[strlen(line)-2] == '`')
  915. X            {
  916. X            int ct;
  917. X            char *ptr;
  918. X
  919. X            for (ct = 0, ptr = line; *ptr; ptr++)
  920. X                if (*ptr == '`')
  921. X                    ct++;
  922. X            if (ct & 1)
  923. X                {
  924. X                ptr[-2] = '\n';
  925. X                ptr[-1] = '\0';
  926. X                }
  927. X            }
  928. X        }
  929. X    isfirstch = 1;
  930. X    hungets(line);
  931. X    free(line);
  932. X    goto start;
  933. X}
  934. X
  935. X/* put a string in the input queue */
  936. X
  937. Xvoid hungets(str) /**/
  938. Xchar *str;
  939. X{
  940. Xint slen = strlen(str);
  941. X
  942. X/* shrink inbuf if it gets too big */
  943. X
  944. X    if (!inbufct && inbufsz > 65536)
  945. X        {
  946. X        free(inbuf);
  947. X        inbuf = zalloc(inbufsz = 256);
  948. X        inbufptr = inbuf+inbufsz;
  949. X        inbufct = 0;
  950. X        }
  951. X    if (slen+inbufct > inbufsz)
  952. X        {
  953. X        char *x;
  954. X
  955. X        while (slen+inbufct > inbufsz)
  956. X            inbufsz *= 4;
  957. X        x = zalloc(inbufsz);
  958. X        memcpy(x+inbufsz-inbufct,inbufptr,inbufct);
  959. X        inbufptr = x+inbufsz-inbufct;
  960. X        free(inbuf);
  961. X        inbuf = x;
  962. X        }
  963. X    memcpy(inbufptr -= slen,str,slen);
  964. X    inbufct += slen;
  965. X}
  966. X
  967. X/* unget a char and remove it from hline */
  968. X
  969. Xvoid hungetc(c) /**/
  970. Xint c;
  971. X{
  972. X    if (lexstop)
  973. X        return;
  974. X    if (hlastw)
  975. X        {
  976. X        if (hlastw == hptr)
  977. X            zerr("hungetc attempted at buffer start",NULL,0);
  978. X        else
  979. X            hptr--;
  980. X        }
  981. X    hungetch(c);
  982. X}
  983. X
  984. Xvoid hungetch(c) /**/
  985. Xint c;
  986. X{
  987. X    if (lexstop)
  988. X        return;
  989. X    if (inbufct == inbufsz)
  990. X        {
  991. X        hungets(" ");
  992. X        *inbufptr = c;
  993. X        }
  994. X    else
  995. X        {
  996. X        *--inbufptr = c;
  997. X        inbufct++;
  998. X        }
  999. X}
  1000. X
  1001. X/* begin reading a string */
  1002. X
  1003. Xvoid strinbeg() /**/
  1004. X{
  1005. X    strin = 1;
  1006. X    hbegin();
  1007. X    lexinit();
  1008. X}
  1009. X
  1010. X/* done reading a string */
  1011. X
  1012. Xvoid strinend() /**/
  1013. X{
  1014. X    strin = 0;
  1015. X    isfirstch = 1;
  1016. X    histdone = 0;
  1017. X    hend();
  1018. X}
  1019. X
  1020. X/* stuff a whole file into the input queue and print it */
  1021. X
  1022. Xint stuff(fn) /**/
  1023. Xchar *fn;
  1024. X{
  1025. XFILE *in;
  1026. Xchar *buf;
  1027. Xint len;
  1028. X
  1029. X    if (!(in = fopen(fn,"r")))
  1030. X        {
  1031. X        zerr("can't open %s",fn,0);
  1032. X        return 1;
  1033. X        }
  1034. X    fseek(in,0,2);
  1035. X    len = ftell(in);
  1036. X    fseek(in,0,0);
  1037. X    buf = alloc(len+1);
  1038. X    if (!(fread(buf,len,1,in)))
  1039. X        {
  1040. X        zerr("read error on %s",fn,0);
  1041. X        fclose(in);
  1042. X        free(buf);
  1043. X        return 1;
  1044. X        }
  1045. X    fclose(in);
  1046. X    buf[len] = '\0';
  1047. X    fwrite(buf,len,1,stdout);
  1048. X    hungets(buf);
  1049. X    return 0;
  1050. X}
  1051. X
  1052. X/* flush input queue */
  1053. X
  1054. Xvoid hflush() /**/
  1055. X{
  1056. X    inbufptr += inbufct;
  1057. X    inbufct = 0;
  1058. X}
  1059. X
  1060. X/* initialize the history mechanism */
  1061. X
  1062. Xvoid hbegin() /**/
  1063. X{
  1064. X    isfirstln = isfirstch = 1;
  1065. X    histremmed = errflag = histdone = spaceflag = 0;
  1066. X    stophist = isset(NOBANGHIST);
  1067. X    lithist = isset(HISTLIT);
  1068. X    hline = hptr = zalloc(hlinesz = 32);
  1069. X    if (interact && isset(SHINSTDIN) && !strin) {
  1070. X        inittty();
  1071. X        defev = curhist++;
  1072. X        while (curhist-firsthist >= histsiz) {
  1073. X            free(getnode(histlist));
  1074. X            firsthist++;
  1075. X        }
  1076. X        while (curhist-firstlithist >= lithistsiz) {
  1077. X            free(getnode(lithistlist));
  1078. X            firstlithist++;
  1079. X        }
  1080. X        permalloc();
  1081. X        addnode(histlist,hline);
  1082. X        addnode(lithistlist,ztrdup(""));
  1083. X        heapalloc();
  1084. X    } else
  1085. X        histremmed = 1;
  1086. X}
  1087. X
  1088. Xvoid inittty() /**/
  1089. X{
  1090. X    attachtty(mypgrp);
  1091. X}
  1092. X
  1093. X/* say we're done using the history mechanism */
  1094. X
  1095. Xint hend() /**/
  1096. X{
  1097. Xint flag,save = 1;
  1098. X
  1099. X    if (!hline)
  1100. X        return 1;
  1101. X    if (!interact || strin || unset(SHINSTDIN)) {
  1102. X        free(hline);
  1103. X        return 1;
  1104. X    }
  1105. X    flag = histdone;
  1106. X    histdone = 0;
  1107. X    if (hptr < hline+2)
  1108. X        save = 0;
  1109. X    else {
  1110. X        char *s = getdata(lastnode(lithistlist));
  1111. X
  1112. X        if (*s)
  1113. X            s[strlen(s)-1] = '\0';
  1114. X        hptr[-1] = '\0';
  1115. X        if (hptr[-2] == '\n')
  1116. X            if (hline[1])
  1117. X                hptr[-3] = '\0';
  1118. X            else
  1119. X                save = 0;
  1120. X        if (!strcmp(hline,"\n") ||
  1121. X                (isset(HISTIGNOREDUPS) && firstnode(histlist) &&
  1122. X                nextnode(firstnode(histlist)) &&
  1123. X                !strcmp(hline,getdata(prevnode(lastnode(histlist))))) ||
  1124. X                (isset(HISTIGNORESPACE) && spaceflag) )
  1125. X            save = 0;
  1126. X    }
  1127. X    if (flag & HISTFLAG_DONE) {
  1128. X        char *ptr,*p;
  1129. X
  1130. X        p = ptr = ztrdup(hline);
  1131. X        for (;*p;p++)
  1132. X            if (*p == HISTSPACE)
  1133. X                *p = ' ';
  1134. X        fprintf(stderr,"%s\n",ptr);
  1135. X        fflush(stderr);
  1136. X        free(ptr);
  1137. X    }
  1138. X    if (!save) {
  1139. X        free(hline);
  1140. X        if (!histremmed) {
  1141. X            remnode(histlist,lastnode(histlist));
  1142. X            free(remnode(lithistlist,lastnode(lithistlist)));
  1143. X            curhist--;
  1144. X        }
  1145. X    }
  1146. X    hline = NULL;
  1147. X    return !(flag & HISTFLAG_NOEXEC || errflag);
  1148. X}
  1149. X
  1150. X/* remove the current line from the history List */
  1151. X
  1152. Xvoid remhist() /**/
  1153. X{
  1154. X    if (!histremmed)
  1155. X        {
  1156. X        histremmed = 1;
  1157. X        free(remnode(histlist,lastnode(histlist)));
  1158. X        free(remnode(lithistlist,lastnode(lithistlist)));
  1159. X        curhist--;
  1160. X        }
  1161. X}
  1162. X
  1163. X/* begin a word */
  1164. X
  1165. Xvoid hwbegin() /**/
  1166. X{
  1167. X    hlastw = hptr;
  1168. X}
  1169. X
  1170. X/* add a word to the history List */
  1171. X
  1172. Xchar *hwadd() /**/
  1173. X{
  1174. Xchar *ret = hlastw;
  1175. X
  1176. X    if (hlastw && hline)
  1177. X        {
  1178. X        hwaddc(HISTSPACE);
  1179. X        if (alstackind || strin)
  1180. X            if (!(alstackind == 1 && !alstack[0]))
  1181. X                hptr = hlastw;
  1182. X        }
  1183. X    if (alstat == ALSTAT_JUNK)
  1184. X        alstat = 0;
  1185. X    return ret;
  1186. X}
  1187. X
  1188. X/* get an argument specification */
  1189. X
  1190. Xint getargspec(argc,marg) /**/
  1191. Xint argc;int marg;
  1192. X{
  1193. Xint c,ret = -1;
  1194. X    if ((c = hgetch()) == '0')
  1195. X        return 0;
  1196. X    if (idigit(c))
  1197. X        {
  1198. X        ret = 0;
  1199. X        while (idigit(c))
  1200. X            {
  1201. X            ret = ret*10+c-'0';
  1202. X            c = hgetch();
  1203. X            }
  1204. X        hungetch(c);
  1205. X        }
  1206. X    else if (c == '^')
  1207. X        ret = 1;
  1208. X    else if (c == '$')
  1209. X        ret = argc;
  1210. X    else if (c == '%')
  1211. X        {
  1212. X        if (marg == -1)
  1213. X            {
  1214. X            herrflush();
  1215. X            zerr("%% with no previous word matched",NULL,0);
  1216. X            return -2;
  1217. X            }
  1218. X        ret = marg;
  1219. X        }
  1220. X    else
  1221. X        hungetch(c);
  1222. X    return ret;
  1223. X}
  1224. X
  1225. X/* do ?foo? search */
  1226. X
  1227. Xint hconsearch(str,marg) /**/
  1228. Xchar *str;int *marg;
  1229. X{
  1230. Xint t0,t1 = 0;
  1231. XLknode node;
  1232. Xchar *s;
  1233. X    if (curhist-firsthist < 1)
  1234. X        return -1;
  1235. X    for (t0 = curhist-1,node = prevnode(lastnode(histlist));
  1236. X            t0 >= firsthist; t0--,node = prevnode(node))
  1237. X        if (s = ztrstr(getdata(node),str))
  1238. X            {
  1239. X            while (s != (char *) getdata(node))
  1240. X                if (*s-- == HISTSPACE)
  1241. X                    t1++;
  1242. X            *marg = t1;
  1243. X            return t0;
  1244. X            }
  1245. X    return -1;
  1246. X}
  1247. X
  1248. X/* do !foo search */
  1249. X
  1250. Xint hcomsearch(str) /**/
  1251. Xchar *str;
  1252. X{
  1253. Xint t0;
  1254. XLknode node;
  1255. X
  1256. X    if (curhist-firsthist < 1)
  1257. X        return -1;
  1258. X    for (t0 = curhist-1,node = prevnode(lastnode(histlist)); t0 >= firsthist;
  1259. X            t0--,node = prevnode(node))
  1260. X        if (!strncmp(getdata(node),str,strlen(str)))
  1261. X            return t0;
  1262. X    return -1;
  1263. X}
  1264. X
  1265. X/* various utilities for : modifiers */
  1266. X
  1267. Xint remtpath(junkptr) /**/
  1268. Xchar **junkptr;
  1269. X{
  1270. Xchar *str = *junkptr,*cut;
  1271. X    if (cut = strrchr(str,'/')) {
  1272. X        if (str != cut) *cut = '\0';
  1273. X        else str[1] = '\0';
  1274. X        return 1;
  1275. X    }
  1276. X    return 0;
  1277. X}
  1278. Xint remtext(junkptr) /**/
  1279. Xchar **junkptr;
  1280. X{
  1281. Xchar *str = *junkptr,*cut;
  1282. X    if ((cut = strrchr(str,'.')) && cut != str)
  1283. X        {
  1284. X        *cut = '\0';
  1285. X        return 1;
  1286. X        }
  1287. X    return 0;
  1288. X}
  1289. Xint rembutext(junkptr) /**/
  1290. Xchar **junkptr;
  1291. X{
  1292. Xchar *str = *junkptr,*cut;
  1293. X    if ((cut = strrchr(str,'.')) && cut != str)
  1294. X        {
  1295. X        *junkptr = strdup(cut+1);  /* .xx or xx? */
  1296. X        return 1;
  1297. X        }
  1298. X    return 0;
  1299. X}
  1300. Xint remlpaths(junkptr) /**/
  1301. Xchar **junkptr;
  1302. X{
  1303. Xchar *str = *junkptr,*cut;
  1304. X    if (cut = strrchr(str,'/'))
  1305. X        {
  1306. X        *cut = '\0';
  1307. X        *junkptr = strdup(cut+1);
  1308. X        return 1;
  1309. X        }
  1310. X    return 0;
  1311. X}
  1312. X
  1313. Xint makeuppercase(junkptr) /**/
  1314. Xchar **junkptr;
  1315. X{
  1316. Xchar *str = *junkptr;
  1317. X
  1318. X    for (; *str; str++)
  1319. X        *str = tuupper(*str);
  1320. X    return 1;
  1321. X}
  1322. X
  1323. Xint makelowercase(junkptr) /**/
  1324. Xchar **junkptr;
  1325. X{
  1326. Xchar *str = *junkptr;
  1327. X
  1328. X    for (; *str; str++)
  1329. X        *str = tulower(*str);
  1330. X    return 1;
  1331. X}
  1332. X
  1333. Xvoid subst(strptr,in,out,gbal) /**/
  1334. Xchar **strptr;char *in;char *out;int gbal;
  1335. X{
  1336. Xchar *str = *strptr,*cut,*sptr;
  1337. Xint off;
  1338. X
  1339. X    while (cut = (char *) ztrstr(str,in)) {
  1340. X        *cut = '\0';
  1341. X        cut += strlen(in);
  1342. X        off = cut-*strptr;
  1343. X        *strptr = tricat(*strptr,sptr = convamps(out,in),cut);
  1344. X        if (gbal) {
  1345. X            str = (char *) *strptr+off+strlen(sptr);
  1346. X            continue;
  1347. X        }
  1348. X        break;
  1349. X    }
  1350. X}
  1351. Xchar *convamps(out,in) /**/
  1352. Xchar *out;char *in;
  1353. X{
  1354. Xchar *ptr,*ret,*pp;
  1355. Xint slen,inlen = strlen(in);
  1356. X    for (ptr = out, slen = 0; *ptr; ptr++,slen++)
  1357. X        if (*ptr == '\\')
  1358. X            ptr++;
  1359. X        else if (*ptr == '&')
  1360. X            slen += inlen-1;
  1361. X    ret = pp = alloc(slen+1);
  1362. X    for (ptr = out; *ptr; ptr++)
  1363. X        if (*ptr == '\\')
  1364. X            *pp++ = *++ptr;
  1365. X        else if (*ptr == '&')
  1366. X            {
  1367. X            strcpy(pp,in);
  1368. X            pp += inlen;
  1369. X            }
  1370. X        else
  1371. X            *pp++ = *ptr;
  1372. X    *pp = '\0';
  1373. X    return ret;
  1374. X}
  1375. X
  1376. Xchar *makehstr(s) /**/
  1377. Xchar *s;
  1378. X{
  1379. Xchar *t;
  1380. X
  1381. X    t = s = strdup(s);
  1382. X    for (; *t; t++)
  1383. X        if (*t == HISTSPACE)
  1384. X            *t = ' ';
  1385. X    return s;
  1386. X}
  1387. X
  1388. Xchar *quietgetevent(ev) /**/
  1389. Xint ev;
  1390. X{
  1391. XLknode node;
  1392. X    ev -= (lithist) ? firstlithist : firsthist;
  1393. X    if (ev < 0)
  1394. X        return NULL;
  1395. X    for (node = firstnode((lithist) ? lithistlist : histlist);
  1396. X            ev && node; incnode(node), ev--);
  1397. X    if (!node)
  1398. X        return NULL;
  1399. X    return getdata(node);
  1400. X}
  1401. X
  1402. Xchar *getevent(ev) /**/
  1403. Xint ev;
  1404. X{
  1405. XLknode node;
  1406. Xint oev = ev;
  1407. X    ev -= firsthist;
  1408. X    for (node = firstnode(histlist); ev && node; incnode(node), ev--);
  1409. X    if (!node)
  1410. X        {
  1411. X        herrflush();
  1412. X        zerr("no such event: %d",NULL,oev);
  1413. X        return NULL;
  1414. X        }
  1415. X    return getdata(node);
  1416. X}
  1417. Xint getargc(list) /**/
  1418. Xchar *list;
  1419. X{
  1420. Xint argc = 0;
  1421. X
  1422. X    for (; *list; list++)
  1423. X        if (*list == HISTSPACE)
  1424. X            argc++;
  1425. X    return argc;
  1426. X}
  1427. Xchar *getargs(elist,arg1,arg2) /**/
  1428. Xchar *elist;int arg1;int arg2;
  1429. X{
  1430. Xchar *ret = elist,*retn;
  1431. Xint acnt = arg2-arg1+1;
  1432. X
  1433. X    while (arg1--)
  1434. X        while (*ret && *ret++ != HISTSPACE);
  1435. X    if (!*ret)
  1436. X        {
  1437. X        herrflush();
  1438. X        zerr("no such word in event",NULL,0);
  1439. X        return NULL;
  1440. X        }
  1441. X    retn = ret = strdup(ret);
  1442. X    while (acnt > 0)
  1443. X        {
  1444. X        while (*ret && *ret != HISTSPACE)
  1445. X            ret++;
  1446. X        if (*ret == HISTSPACE)
  1447. X            *ret = ' ';
  1448. X        else
  1449. X            break;
  1450. X        acnt--;
  1451. X        }
  1452. X    if (acnt > 1 && !*ret)
  1453. X        {
  1454. X        herrflush();
  1455. X        zerr("no such word in event",NULL,0);
  1456. X        return NULL;
  1457. X        }
  1458. X    *ret = '\0';
  1459. X    return retn;
  1460. X}
  1461. X
  1462. Xvoid upcase(x) /**/
  1463. Xchar **x;
  1464. X{
  1465. Xchar *pp = *(char **) x;
  1466. X
  1467. X    for (; *pp; pp++)
  1468. X        *pp = tuupper(*pp);
  1469. X}
  1470. X
  1471. Xvoid downcase(x) /**/
  1472. Xchar **x;
  1473. X{
  1474. Xchar *pp = *(char **) x;
  1475. X
  1476. X    for (; *pp; pp++)
  1477. X        *pp = tulower(*pp);
  1478. X}
  1479. X
  1480. Xint quote(tr) /**/
  1481. Xchar **tr;
  1482. X{
  1483. Xchar *ptr,*rptr,**str = (char **) tr;
  1484. Xint len = 1;
  1485. X    for (ptr = *str; *ptr; ptr++,len++)
  1486. X        if (*ptr == '\'')
  1487. X            len += 3;
  1488. X    ptr = *str;
  1489. X    *str = rptr = zalloc(len);
  1490. X    for (ptr = *str; *ptr; )
  1491. X        if (*ptr == '\'')
  1492. X            {
  1493. X            *rptr++ = '\''; *rptr++ = '\\'; *rptr++ = '\''; *rptr++ = '\'';
  1494. X            ptr++;
  1495. X            }
  1496. X        else
  1497. X            *rptr++ = *ptr++;
  1498. X    return 0;
  1499. X}
  1500. Xint quotebreak(tr) /**/
  1501. Xchar **tr;
  1502. X{
  1503. Xchar *ptr,*rptr,**str = (char **) tr;
  1504. Xint len = 1;
  1505. X    for (ptr = *str; *ptr; ptr++,len++)
  1506. X        if (*ptr == '\'')
  1507. X            len += 3;
  1508. X        else if (inblank(*ptr))
  1509. X            len += 2;
  1510. X    ptr = *str;
  1511. X    *str = rptr = zalloc(len);
  1512. X    for (ptr = *str; *ptr; )
  1513. X        if (*ptr == '\'')
  1514. X            {
  1515. X            *rptr++ = '\''; *rptr++ = '\\'; *rptr++ = '\''; *rptr++ = '\'';
  1516. X            ptr++;
  1517. X            }
  1518. X        else if (inblank(*ptr))
  1519. X            {
  1520. X            *rptr++ = '\''; *rptr++ = *ptr++; *rptr++ = '\'';
  1521. X            }
  1522. X        else
  1523. X            *rptr++ = *ptr++;
  1524. X    return 0;
  1525. X}
  1526. X
  1527. Xstatic char *bp;
  1528. Xstatic int lensb,countp;
  1529. X
  1530. Xvoid stradd(d) /**/
  1531. Xchar *d;
  1532. X{
  1533. X    while (*bp++ = *d++);
  1534. X    bp--;
  1535. X}
  1536. X
  1537. Xint putstr(d) /**/
  1538. Xint d;
  1539. X{
  1540. X    *bp++ = d;
  1541. X    if (countp)
  1542. X        lensb++;
  1543. X    return 0;
  1544. X}
  1545. X
  1546. X#define tstradd(X) \
  1547. X    if (termok && unset(SINGLELINEZLE)) { \
  1548. X        char tbuf[2048],*tptr = tbuf; \
  1549. X        if (tgetstr(X,&tptr)) \
  1550. X            tputs(tbuf,1,putstr); \
  1551. X    } \
  1552. X    break
  1553. X
  1554. X/* get a prompt string */
  1555. X
  1556. Xchar *putprompt(fm,lenp) /**/
  1557. Xchar *fm;int *lenp;
  1558. X{
  1559. Xchar *ss,*ttyname DCLPROTO((int)),*bl0;
  1560. Xstatic char buf1[256],buf2[256],*buf;
  1561. Xchar buf3[MAXPATHLEN];
  1562. Xint t0,bracepos = 0;
  1563. Xstruct tm *tm = NULL;
  1564. Xtime_t timet;
  1565. X
  1566. X    lensb = 0; countp = 1;
  1567. X    if (!fm)
  1568. X        {
  1569. X        *lenp = 0;
  1570. X        return "";
  1571. X        }
  1572. X    /* kludge alert! */
  1573. X    buf = (buf == buf1) ? buf2 : buf1;
  1574. X    bp = bl0 = buf;
  1575. X    if (!columns)
  1576. X        columns = 80;
  1577. X    clearerr(stdin);
  1578. X    for(;*fm;fm++)
  1579. X        {
  1580. X        if (bp-buf >= 220)
  1581. X            break;
  1582. X        if (*fm == '%')
  1583. X            switch (*++fm)
  1584. X                {
  1585. X                case '~':
  1586. X                    t0 = finddir(cwd);
  1587. X                    if (t0 != -1) {
  1588. X                        *bp++ = '~';
  1589. X                        stradd(usernames[t0]);
  1590. X                        stradd(cwd+strlen(userdirs[t0]));
  1591. X                        break;
  1592. X                    }
  1593. X                    if (!strncmp(cwd,home,t0 = strlen(home)) && t0 > 1) {
  1594. X                        *bp++ = '~';
  1595. X                        stradd(cwd+t0);
  1596. X                        break;
  1597. X                    }
  1598. X                case 'd': case '/': stradd(cwd); break;
  1599. X                case 'c': case '.':
  1600. X                    t0 = finddir(cwd);
  1601. X                    if (t0 != -1) {
  1602. X                        sprintf(buf3,"~%s%s",usernames[t0],
  1603. X                            cwd+strlen(userdirs[t0]));
  1604. X                    } else if (!strncmp(cwd,home,t0 = strlen(home)) && t0 > 1) {
  1605. X                        sprintf(buf3,"~%s",cwd+t0);
  1606. X                    } else {
  1607. X                        strcpy(buf3,cwd);
  1608. X                    }
  1609. X                    t0 = 1;
  1610. X                    if (idigit(fm[1])) { t0 = fm[1]-'0'; fm++; }
  1611. X                    for (ss = buf3+strlen(buf3); ss > buf3; ss--)
  1612. X                        if (*ss == '/' && !--t0) {
  1613. X                            ss++;
  1614. X                            break;
  1615. X                        }
  1616. X                    if (*ss == '/' && ss[1]) ss++;
  1617. X                    stradd(ss);
  1618. X                    break;
  1619. X                case 'C':
  1620. X                    strcpy(buf3,cwd);
  1621. X                    t0 = 1;
  1622. X                    if (idigit(fm[1])) { t0 = fm[1]-'0'; fm++; }
  1623. X                    for (ss = buf3+strlen(buf3); ss > buf3; ss--)
  1624. X                        if (*ss == '/' && !--t0) {
  1625. X                            ss++;
  1626. X                            break;
  1627. X                        }
  1628. X                    if (*ss == '/' && ss[1]) ss++;
  1629. X                    stradd(ss);
  1630. X                    break;
  1631. X                case 'h': case '!':
  1632. X                    sprintf(bp,"%d",curhist);
  1633. X                    bp += strlen(bp);
  1634. X                    break;
  1635. X                case 'M': stradd(hostnam); break;
  1636. X                case 'm':
  1637. X                    if (idigit(fm[1]))
  1638. X                        t0 = (*++fm)-'0';
  1639. X                    else
  1640. X                        t0 = 1;
  1641. X                    for (ss = hostnam; *ss; ss++)
  1642. X                        if (*ss == '.' && !--t0)
  1643. X                            break;
  1644. X                    t0 = *ss;
  1645. X                    *ss = '\0';
  1646. X                    stradd(hostnam);
  1647. X                    *ss = t0;
  1648. X                    break;
  1649. X                case 'S': tstradd("so"); /* <- this is a macro */
  1650. X                case 's': tstradd("se");
  1651. X                case 'B': tstradd("md");
  1652. X                case 'b': tstradd("me");
  1653. X                case 'U': tstradd("us");
  1654. X                case 'u': tstradd("ue");
  1655. X                case '{': bracepos = bp-buf; countp = 0; break;
  1656. X                case '}': lensb += (bp-buf)-bracepos; countp = 1; break;
  1657. X                case 't': case '@':
  1658. X                    timet = time(NULL);
  1659. X                    tm = localtime(&timet);
  1660. X                    ztrftime(bp,16,"%l:%M%p",tm);
  1661. X                    if (*bp == ' ')
  1662. X                        chuck(bp);
  1663. X                    bp += strlen(bp);
  1664. X                    break;
  1665. X                case 'T':
  1666. X                    timet = time(NULL);
  1667. X                    tm = localtime(&timet);
  1668. X                    ztrftime(bp,16,"%k:%M",tm);
  1669. X                    bp += strlen(bp);
  1670. X                    break;
  1671. X                case '*':
  1672. X                    timet = time(NULL);
  1673. X                    tm = localtime(&timet);
  1674. X                    ztrftime(bp,16,"%k:%M:%S",tm);
  1675. X                    bp += strlen(bp);
  1676. X                    break;
  1677. X                case 'n': stradd(username); break;
  1678. X                case 'w':
  1679. X                    timet = time(NULL);
  1680. X                    tm = localtime(&timet);
  1681. X                    ztrftime(bp,16,"%a %e",tm);
  1682. X                    bp += strlen(bp);
  1683. X                    break;
  1684. X                case 'W':
  1685. X                    timet = time(NULL);
  1686. X                    tm = localtime(&timet);
  1687. X                    ztrftime(bp,16,"%m/%d/%y",tm);
  1688. X                    bp += strlen(bp);
  1689. X                    break;
  1690. X                case 'D':
  1691. X                    timet = time(NULL);
  1692. X                    tm = localtime(&timet);
  1693. X                    ztrftime(bp,16,"%y-%m-%d",tm);
  1694. X                    bp += strlen(bp);
  1695. X                    break;
  1696. X                case 'l':
  1697. X                    if (ss = ttyname(SHTTY))
  1698. X                        stradd((strncmp(ss,"/dev/tty",8) ? ss : ss+8));
  1699. X                    else
  1700. X                        stradd("()");
  1701. X                    break;
  1702. X                case '?':
  1703. X                    sprintf(bp,"%d",lastval);
  1704. X                    bp += strlen(bp);
  1705. X                    break;
  1706. X                case '%': *bp++ = '%'; break;
  1707. X                case '#': *bp++ = (geteuid()) ? '%' : '#'; break;
  1708. X                default: *bp++ = '%'; *bp++ = *fm; break;
  1709. X                }
  1710. X        else if (*fm == '!')
  1711. X            {
  1712. X            sprintf(bp,"%d",curhist);
  1713. X            bp += strlen(bp);
  1714. X            }
  1715. X        else
  1716. X            {
  1717. X            if (fm[0] == '\\' && fm[1])
  1718. X                fm++;
  1719. X            if ((*bp++ = *fm) == '\n')
  1720. X                bl0 = bp;
  1721. X            }
  1722. X        }
  1723. X    *lenp = (bp-bl0)-lensb;
  1724. X    *lenp %= columns;
  1725. X    if (*lenp == columns-1)
  1726. X        {
  1727. X        *lenp = 0;
  1728. X        *bp++ = ' ';
  1729. X        }
  1730. X    *bp = '\0';
  1731. X    return buf;
  1732. X}
  1733. X
  1734. Xvoid herrflush() /**/
  1735. X{
  1736. X    if (strin)
  1737. X        hflush();
  1738. X    else while (lastc != '\n' && !lexstop)
  1739. X        hgetch();
  1740. X}
  1741. X
  1742. X/* read an arbitrary amount of data into a buffer until stop is found */
  1743. X
  1744. Xchar *hdynread(stop) /**/
  1745. Xint stop;
  1746. X{
  1747. Xint bsiz = 256,ct = 0,c;
  1748. Xchar *buf = zalloc(bsiz),*ptr;
  1749. X    ptr = buf;
  1750. X    while ((c = hgetch()) != stop && c != '\n' && !lexstop)
  1751. X        {
  1752. X        if (c == '\\')
  1753. X            c = hgetch();
  1754. X        *ptr++ = c;
  1755. X        if (++ct == bsiz)
  1756. X            {
  1757. X            buf = realloc(buf,bsiz *= 2);
  1758. X            ptr = buf+ct;
  1759. X            }
  1760. X        }
  1761. X    *ptr = 0;
  1762. X    if (c == '\n')
  1763. X        {
  1764. X        hungetch('\n');
  1765. X        zerr("delimiter expected",NULL,0);
  1766. X        free(buf);
  1767. X        return NULL;
  1768. X        }
  1769. X    return buf;
  1770. X}
  1771. Xchar *hdynread2(stop) /**/
  1772. Xint stop;
  1773. X{
  1774. Xint bsiz = 256,ct = 0,c;
  1775. Xchar *buf = zalloc(bsiz),*ptr;
  1776. X    ptr = buf;
  1777. X    while ((c = hgetch()) != stop && c != '\n' && !lexstop)
  1778. X        {
  1779. X        if (c == '\n')
  1780. X            {
  1781. X            hungetch(c);
  1782. X            break;
  1783. X            }
  1784. X        if (c == '\\')
  1785. X            c = hgetch();
  1786. X        *ptr++ = c;
  1787. X        if (++ct == bsiz)
  1788. X            {
  1789. X            buf = realloc(buf,bsiz *= 2);
  1790. X            ptr = buf+ct;
  1791. X            }
  1792. X        }
  1793. X    *ptr = 0;
  1794. X    if (c == '\n')
  1795. X        hungetch('\n');
  1796. X    return buf;
  1797. X}
  1798. X
  1799. X/* set cbreak mode, or the equivalent */
  1800. X
  1801. Xvoid setcbreak() /**/
  1802. X{
  1803. Xstruct ttyinfo ti;
  1804. X
  1805. X    ti = shttyinfo;
  1806. X#ifdef TERMIOS
  1807. X    ti.termios.c_lflag &= ~ICANON;
  1808. X    ti.termios.c_cc[VMIN] = 1;
  1809. X    ti.termios.c_cc[VTIME] = 0;
  1810. X#else
  1811. X#ifdef TERMIO
  1812. X    ti.termio.c_lflag &= ~ICANON;
  1813. X    ti.termio.c_cc[VMIN] = 1;
  1814. X    ti.termio.c_cc[VTIME] = 0;
  1815. X#else
  1816. X    ti.sgttyb.sg_flags |= CBREAK;
  1817. X#endif
  1818. X#endif
  1819. X    settyinfo(&ti);
  1820. X}
  1821. X
  1822. Xint getlineleng() /**/
  1823. X{
  1824. Xint z;
  1825. X
  1826. X#ifdef TIOCSWINSZ
  1827. X    z = shttyinfo.winsize.ws_col;
  1828. X    return (z) ? z : 80;
  1829. X#else
  1830. X    return 80;
  1831. X#endif
  1832. X}
  1833. X
  1834. Xvoid unsetcbreak() /**/
  1835. X{
  1836. X    settyinfo(&shttyinfo);
  1837. X}
  1838. X
  1839. X/* give the tty to some process */
  1840. X
  1841. Xvoid attachtty(pgrp) /**/
  1842. Xlong pgrp;
  1843. X{
  1844. Xstatic int ep = 0;
  1845. Xint arg = pgrp;
  1846. X
  1847. X    if (jobbing)
  1848. X#ifndef TIOCSPGRP
  1849. X        if (SHTTY != -1 && tcsetpgrp(SHTTY,pgrp) == -1 && !ep)
  1850. X#else
  1851. X        if (SHTTY != -1 && ioctl(SHTTY,TIOCSPGRP,&arg) == -1 && !ep)
  1852. X#endif
  1853. X            {
  1854. X            zerr("can't set tty pgrp: %e",NULL,errno);
  1855. X            fflush(stderr);
  1856. X            opts[MONITOR] = OPT_UNSET;
  1857. X            ep =1;
  1858. X            errflag = 0;
  1859. X            }
  1860. X}
  1861. X
  1862. SHAR_EOF
  1863. chmod 0644 zsh2.1/src/hist.c ||
  1864. echo 'restore of zsh2.1/src/hist.c failed'
  1865. Wc_c="`wc -c < 'zsh2.1/src/hist.c'`"
  1866. test 24813 -eq "$Wc_c" ||
  1867.     echo 'zsh2.1/src/hist.c: original size 24813, current size' "$Wc_c"
  1868. rm -f _shar_wnt_.tmp
  1869. fi
  1870. # ============= zsh2.1/src/init.c ==============
  1871. if test -f 'zsh2.1/src/init.c' -a X"$1" != X"-c"; then
  1872.     echo 'x - skipping zsh2.1/src/init.c (File already exists)'
  1873.     rm -f _shar_wnt_.tmp
  1874. else
  1875. > _shar_wnt_.tmp
  1876. echo 'x - extracting zsh2.1/src/init.c (Text)'
  1877. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.1/src/init.c' &&
  1878. X/*
  1879. X
  1880. X    init.c - main loop and initialization routines
  1881. X
  1882. X    This file is part of zsh, the Z shell.
  1883. X
  1884. X    zsh is free software; no one can prevent you from reading the source
  1885. X   code, or giving it to someone else.
  1886. X
  1887. X   This file is copyrighted under the GNU General Public License, which
  1888. X   can be found in the file called COPYING.
  1889. X
  1890. X   Copyright (C) 1990, 1991 Paul Falstad
  1891. X
  1892. X   zsh is distributed in the hope that it will be useful, but
  1893. X   WITHOUT ANY WARRANTY.  No author or distributor accepts
  1894. X   responsibility to anyone for the consequences of using it or for
  1895. X   whether it serves any particular purpose or works at all, unless he
  1896. X   says so in writing.  Refer to the GNU General Public License
  1897. X   for full details.
  1898. X
  1899. X   Everyone is granted permission to copy, modify and redistribute
  1900. X   zsh, but only under the conditions described in the GNU General Public
  1901. X   License.   A copy of this license is supposed to have been given to you
  1902. X   along with zsh so you can know your rights and responsibilities.
  1903. X   It should be in a file named COPYING.
  1904. X
  1905. X   Among other things, the copyright notice and this notice must be
  1906. X   preserved on all copies.
  1907. X
  1908. X*/
  1909. X
  1910. X#define GLOBALS
  1911. X#include "zsh.h"
  1912. X#include <pwd.h>
  1913. X
  1914. Xextern int yydebug;
  1915. X
  1916. Xvoid main(argc,argv,envp) /**/
  1917. Xint argc; char **argv; char **envp;
  1918. X{
  1919. Xint notect = 0;
  1920. X
  1921. X    environ = envp;
  1922. X    pathsuppress = 1;
  1923. X    meminit();
  1924. X    setflags();
  1925. X    parseargs(argv);
  1926. X    setmoreflags();
  1927. X    setupvals();
  1928. X    initialize();
  1929. X    heapalloc();
  1930. X    runscripts();
  1931. X    if (interact)
  1932. X        {
  1933. X        pathsuppress = 0;
  1934. X        newcmdnamtab();
  1935. X        }
  1936. X    for(;;)
  1937. X        {
  1938. X        do
  1939. X            loop();
  1940. X        while (tok != ENDINPUT);
  1941. X        if (!(isset(IGNOREEOF) && interact))
  1942. X            {
  1943. X#if 0
  1944. X            if (interact)
  1945. X                fputs(islogin ? "logout\n" : "exit\n",stderr);
  1946. X#endif
  1947. X            zexit(NULL);
  1948. X            continue;
  1949. X            }
  1950. X        zerrnam("zsh",(!islogin) ? "use 'exit' to exit."
  1951. X            : "use 'logout' to logout.",NULL,0);
  1952. X        notect++;
  1953. X        if (notect == 10)
  1954. X            zexit(NULL);
  1955. X        }
  1956. X}
  1957. X
  1958. X/* keep executing lists until EOF found */
  1959. X
  1960. Xvoid loop() /**/
  1961. X{
  1962. XList list;
  1963. X
  1964. X    pushheap();
  1965. X    for(;;)
  1966. X        {
  1967. X        freeheap();
  1968. X        if (interact && isset(SHINSTDIN))
  1969. X            preprompt();
  1970. X        hbegin();        /* init history mech */
  1971. X        intr();            /* interrupts on */
  1972. X        ainit();            /* init alias mech */
  1973. X        lexinit();
  1974. X        errflag = 0;
  1975. X        if (!(list = parse_event()))
  1976. X            {                /* if we couldn't parse a list */
  1977. X            hend();
  1978. X            if (tok == ENDINPUT && !errflag)
  1979. X                break;
  1980. X            continue;
  1981. X            }
  1982. X        if (hend())
  1983. X            {
  1984. X            if (stopmsg)        /* unset 'you have stopped jobs' flag */
  1985. X                stopmsg--;
  1986. X            execlist(list);
  1987. X            }
  1988. X        if (ferror(stderr))
  1989. X            {
  1990. X            zerr("write error",NULL,0);
  1991. X            clearerr(stderr);
  1992. X            }
  1993. X        if (subsh)                /* how'd we get this far in a subshell? */
  1994. X            exit(lastval);
  1995. X        if ((!interact && errflag) || retflag)
  1996. X            break;
  1997. X        if ((opts['t'] == OPT_SET) || (lastval && opts[ERREXIT] == OPT_SET))
  1998. X            {
  1999. X            if (sigtrapped[SIGEXIT])
  2000. X                dotrap(SIGEXIT);
  2001. X            exit(lastval);
  2002. X            }
  2003. X        }
  2004. X    popheap();
  2005. X}
  2006. X
  2007. Xvoid setflags() /**/
  2008. X{
  2009. Xint c;
  2010. X
  2011. X    for (c = 0; c != 32; c++)
  2012. X        opts[c] = OPT_UNSET;
  2013. X    for (c = 32; c != 128; c++)
  2014. X        opts[c] = OPT_INVALID;
  2015. X    for (c = 'a'; c <= 'z'; c++)
  2016. X        opts[c] = opts[c-'a'+'A'] = OPT_UNSET;
  2017. X    for (c = '0'; c <= '9'; c++)
  2018. X        opts[c] = OPT_UNSET;
  2019. X    opts['A'] = OPT_INVALID;
  2020. X    opts['i'] = (isatty(0)) ? OPT_SET : OPT_UNSET;
  2021. X    opts[BGNICE] = opts[NOTIFY] = OPT_SET;
  2022. X    opts[USEZLE] = (interact && SHTTY != -1) ? OPT_SET : OPT_UNSET;
  2023. X}
  2024. X
  2025. Xstatic char *cmd;
  2026. X
  2027. Xvoid parseargs(argv) /**/
  2028. Xchar **argv;
  2029. X{
  2030. Xchar **x;
  2031. Xint bk = 0,action;
  2032. XLklist paramlist;
  2033. X
  2034. X    hackzero = argzero = *argv;
  2035. X    opts[LOGINSHELL] = (**(argv++) == '-') ? OPT_SET : OPT_UNSET;
  2036. X    SHIN = 0;
  2037. X    while (!bk && *argv && (**argv == '-' || **argv == '+'))
  2038. X        {
  2039. X        action = (**argv == '-') ? OPT_SET : OPT_UNSET;
  2040. X        while (*++*argv)
  2041. X            {
  2042. X            if (opts[**argv] == OPT_INVALID)
  2043. X                {
  2044. X                zerr("bad option: -%c",NULL,**argv);
  2045. X                exit(1);
  2046. X                }
  2047. X            opts[**argv] = action;
  2048. X            if (bk = **argv == 'b')
  2049. X                break;
  2050. X            if (**argv == 'c') /* -c command */
  2051. X                {
  2052. X                argv++;
  2053. X                if (!*argv)
  2054. X                    {
  2055. X                    zerr("string expected after -c",NULL,0);
  2056. X                    exit(1);
  2057. X                    }
  2058. X                cmd = *argv;
  2059. X                opts[INTERACTIVE] = OPT_UNSET;
  2060. X                break;
  2061. X                }
  2062. X            else if (**argv == 'o')
  2063. X                {
  2064. X                int c;
  2065. X
  2066. X                if (!*++*argv)
  2067. X                    argv++;
  2068. X                if (!*argv)
  2069. X                    {
  2070. X                    zerr("string expected after -o",NULL,0);
  2071. X                    exit(1);
  2072. X                    }
  2073. X                c = optlookup(*argv);
  2074. X                if (c == -1)
  2075. X                    zerr("no such option: %s",*argv,0);
  2076. X                else
  2077. X                    opts[c] = action;
  2078. X                break;
  2079. X                }
  2080. X            }
  2081. X        argv++;
  2082. X        }
  2083. X    paramlist = newlist();
  2084. X    if (*argv)
  2085. X        {
  2086. X        if (opts[SHINSTDIN] == OPT_UNSET)
  2087. X            {
  2088. X            SHIN = movefd(open(argzero = *argv,O_RDONLY));
  2089. X            if (SHIN == -1)
  2090. X                {
  2091. X                zerr("can't open input file: %s",*argv,0);
  2092. X                exit(1);
  2093. X                }
  2094. X            opts[INTERACTIVE] = OPT_UNSET;
  2095. X            argv++;
  2096. X            }
  2097. X        while (*argv)
  2098. X            addnode(paramlist,ztrdup(*argv++));
  2099. X        }
  2100. X    else
  2101. X        opts[SHINSTDIN] = OPT_SET;
  2102. X    pparams = x = zcalloc((countnodes(paramlist)+1)*sizeof(char *));
  2103. X    while (*x++ = getnode(paramlist));
  2104. X    free(paramlist);
  2105. X    argzero = ztrdup(argzero);
  2106. X}
  2107. X
  2108. Xvoid setmoreflags() /**/
  2109. X{
  2110. Xint t0;
  2111. X
  2112. X    /* stdout,stderr fully buffered */
  2113. X#ifdef _IOFBF
  2114. X    setvbuf(stdout,malloc(BUFSIZ),_IOFBF,BUFSIZ);
  2115. X    setvbuf(stderr,malloc(BUFSIZ),_IOFBF,BUFSIZ);
  2116. X#else
  2117. X    setbuffer(stdout,malloc(BUFSIZ),BUFSIZ);
  2118. X    setbuffer(stderr,malloc(BUFSIZ),BUFSIZ);
  2119. X#endif
  2120. X    subsh = 0;
  2121. X#ifndef NOCLOSEFUNNYFDS
  2122. X    /* this works around a bug in some versions of in.rshd */
  2123. X    for (t0 = 3; t0 != 10; t0++)
  2124. X        close(t0);
  2125. X#endif
  2126. X#ifdef JOB_CONTROL
  2127. X    opts[MONITOR] = (interact) ? OPT_SET : OPT_UNSET;
  2128. X    if (jobbing)
  2129. X        {
  2130. X        SHTTY = movefd((isatty(0)) ? dup(0) : open("/dev/tty",O_RDWR));
  2131. X        if (SHTTY == -1)
  2132. X            opts[MONITOR] = OPT_UNSET;
  2133. X        else
  2134. X            {
  2135. X#ifdef TIOCSETD
  2136. X            int ldisc = NTTYDISC;
  2137. X            ioctl(SHTTY, TIOCSETD, &ldisc);
  2138. X#endif
  2139. X            gettyinfo(&shttyinfo);    /* get tty state */
  2140. X            savedttyinfo = shttyinfo;
  2141. X            }
  2142. X#ifdef sgi
  2143. X        setpgrp(0,getpgrp(0));
  2144. X#endif
  2145. X        if ((mypgrp = getpgrp(0)) <= 0)
  2146. X            opts[MONITOR] = OPT_UNSET;
  2147. X        }
  2148. X    else
  2149. X        SHTTY = -1;
  2150. X#else
  2151. X    opts[MONITOR] = OPT_UNSET;
  2152. X    SHTTY = movefd((isatty(0)) ? dup(0) : open("/dev/tty",O_RDWR));
  2153. X    if (SHTTY != -1)
  2154. X        {
  2155. X        gettyinfo(&shttyinfo);
  2156. X        savedttyinfo = shttyinfo;
  2157. X        }
  2158. X#endif
  2159. X}
  2160. X
  2161. Xvoid setupvals() /**/
  2162. X{
  2163. Xstruct passwd *pwd;
  2164. Xchar *ptr;
  2165. Xstatic long bauds[] = {
  2166. X    0,50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400
  2167. X    };
  2168. X
  2169. X    curhist = 0;
  2170. X    histsiz = 20;
  2171. X    lithistsiz = 5;
  2172. X    logcheck = 60;
  2173. X    dirstacksize = -1;
  2174. X    listmax = 100;
  2175. X    bangchar = '!';
  2176. X    hashchar = '#';
  2177. X    hatchar = '^';
  2178. X    termok = 0;
  2179. X    curjob = prevjob = coprocin = coprocout = -1;
  2180. X    shtimer = time(NULL);    /* init $SECONDS */
  2181. X    srand((unsigned int) shtimer);
  2182. X    /* build various hash tables; argument to newhtable is table size */
  2183. X    aliastab = newhtable(37);
  2184. X    addreswords();
  2185. X    paramtab = newhtable(151);
  2186. X    cmdnamtab = newhtable(13);
  2187. X    initxbindtab();
  2188. X    nullcmd = ztrdup("cat");
  2189. X    prompt = ztrdup("%m%# ");
  2190. X    prompt2 = ztrdup("> ");
  2191. X    prompt3 = ztrdup("?# ");
  2192. X    prompt4 = ztrdup("+ ");
  2193. X    sprompt = ztrdup("zsh: correct `%s' to `%r' [nyae]? ");
  2194. X    ppid = getppid();
  2195. X#ifdef TERMIOS
  2196. X    baud = bauds[shttyinfo.termios.c_cflag & CBAUD];
  2197. X#else
  2198. X#ifdef TERMIO
  2199. X    baud = bauds[shttyinfo.termio.c_cflag & CBAUD];
  2200. X#else
  2201. X    baud = bauds[shttyinfo.sgttyb.sg_ospeed];
  2202. X#endif
  2203. X#endif
  2204. X#ifdef TIOCGWINSZ
  2205. X    if (!(columns = shttyinfo.winsize.ws_col))
  2206. X        columns = 80;
  2207. X    if (!(lines = shttyinfo.winsize.ws_row))
  2208. X        lines = 24;
  2209. X#else
  2210. X    columns = 80;
  2211. X    lines = 24;
  2212. X#endif
  2213. X    ifs = ztrdup(" \t\n");
  2214. X    if (pwd = getpwuid(getuid())) {
  2215. X        username = ztrdup(pwd->pw_name);
  2216. X        home = ztrdup(pwd->pw_dir);
  2217. X    } else {
  2218. X        username = ztrdup("");
  2219. X        home = ztrdup("/");
  2220. X    }
  2221. X    timefmt = ztrdup(DEFTIMEFMT);
  2222. X    watchfmt = ztrdup(DEFWATCHFMT);
  2223. X    if (!(ttystrname = ztrdup(ttyname(SHTTY))))
  2224. X        ttystrname = ztrdup("");
  2225. X    wordchars = ztrdup(DEFWORDCHARS);
  2226. X    fceditparam = ztrdup(DEFFCEDIT);
  2227. X    tmpprefix = ztrdup(DEFTMPPREFIX);
  2228. X    if (ispwd(home))
  2229. X        cwd = ztrdup(home);
  2230. X    else if ((ptr = zgetenv("PWD")) && ispwd(ptr))
  2231. X        cwd = ztrdup(ptr);
  2232. X    else
  2233. X        cwd = zgetwd();
  2234. X    oldpwd = ztrdup(cwd);
  2235. X    hostnam = zalloc(256);
  2236. X    underscore = ztrdup("");
  2237. X    gethostname(hostnam,256);
  2238. X    mypid = getpid();
  2239. X    cdpath = mkarray(NULL);
  2240. X    fignore = mkarray(NULL);
  2241. X    fpath = mkarray(NULL);
  2242. X    mailpath = mkarray(NULL);
  2243. X    watch = mkarray(NULL);
  2244. X    hosts = mkarray(NULL);
  2245. X    hostcmds = (char **) zcalloc(sizeof(char *)*7);
  2246. X    hostcmds[0] = ztrdup("telnet"); hostcmds[1] = ztrdup("rlogin");
  2247. X    hostcmds[2] = ztrdup("ftp"); hostcmds[3] = ztrdup("rup");
  2248. X    hostcmds[4] = ztrdup("rusers"); hostcmds[5] = ztrdup("rsh");
  2249. X    optcmds = (char **) zcalloc(sizeof(char *)*3);
  2250. X    optcmds[0] = ztrdup("setopt"); optcmds[1] = ztrdup("unsetopt");
  2251. X    bindcmds = (char **) zcalloc(sizeof(char *)*2);
  2252. X    bindcmds[0] = ztrdup("bindkey");
  2253. X    varcmds = (char **) zcalloc(sizeof(char *)*5);
  2254. X    varcmds[0] = ztrdup("export"); varcmds[1] = ztrdup("typeset");
  2255. X    varcmds[2] = ztrdup("vared"); varcmds[3] = ztrdup("unset");
  2256. X    userdirs = (char **) zcalloc(sizeof(char *)*2);
  2257. X    usernames = (char **) zcalloc(sizeof(char *)*2);
  2258. X    userdirsz = 2;
  2259. X    userdirct = 0;
  2260. X    optarg = ztrdup("");
  2261. X    optind = 0;
  2262. X    schedcmds = NULL;
  2263. X    path = (char **) zalloc(4*sizeof *path);
  2264. X    path[0] = ztrdup("/bin"); path[1] = ztrdup("/usr/bin");
  2265. X    path[2] = ztrdup("/usr/ucb"); path[3] = NULL;
  2266. X    inittyptab();
  2267. X    initlextabs();
  2268. X    setupparams();
  2269. X    setparams();
  2270. X    inittyptab();
  2271. X}
  2272. X
  2273. Xvoid initialize() /**/
  2274. X{
  2275. Xint t0;
  2276. X
  2277. X    breaks = loops = 0;
  2278. X    lastmailcheck = time(NULL);
  2279. X    firsthist = firstlithist = 1;
  2280. X    histsiz = DEFAULT_HISTSIZE;
  2281. X    histlist = newlist();
  2282. X    lithistlist = newlist();
  2283. X    locallist = NULL;
  2284. X    dirstack = newlist();
  2285. X    bufstack = newlist();
  2286. X    newcmdnamtab();
  2287. X    inbuf = zalloc(inbufsz = 256);
  2288. X    inbufptr = inbuf+inbufsz;
  2289. X    inbufct = 0;
  2290. X#ifdef QDEBUG
  2291. X    signal(SIGQUIT,SIG_IGN);
  2292. X#endif
  2293. X#ifdef RLIM_INFINITY
  2294. X    for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
  2295. X        getrlimit(t0,limits+t0);
  2296. X#endif
  2297. X    hsubl = hsubr = NULL;
  2298. X    lastpid = 0;
  2299. X    bshin = fdopen(SHIN,"r");
  2300. X    signal(SIGCHLD,handler);
  2301. X    if (jobbing)
  2302. X        {
  2303. X        signal(SIGTTOU,SIG_IGN);
  2304. X        signal(SIGTSTP,SIG_IGN);
  2305. X        signal(SIGTTIN,SIG_IGN);
  2306. X        signal(SIGPIPE,SIG_IGN);
  2307. X        attachtty(mypgrp);
  2308. X        }
  2309. X    if (interact)
  2310. X        {
  2311. X        signal(SIGTERM,SIG_IGN);
  2312. X#ifdef SIGWINCH
  2313. X        signal(SIGWINCH,handler);
  2314. X#endif
  2315. X        signal(SIGALRM,handler);
  2316. X        intr();
  2317. X        }
  2318. X}
  2319. X
  2320. Xvoid addreswords() /**/
  2321. X{
  2322. Xstatic char *reswds[] = {
  2323. X    "do", "done", "esac", "then", "elif", "else", "fi", "for", "case",
  2324. X    "if", "while", "function", "repeat", "time", "until", "exec", "command",
  2325. X    "select", "coproc", "noglob", "-", "nocorrect", "foreach", "end", NULL
  2326. X    };
  2327. Xint t0;
  2328. X
  2329. X    for (t0 = 0; reswds[t0]; t0++)
  2330. X        addhperm(reswds[t0],mkanode(NULL,-1-t0),aliastab,NULL);
  2331. X}
  2332. X
  2333. Xvoid runscripts() /**/
  2334. X{
  2335. X    if (opts[NORCS] == OPT_SET) {
  2336. X#ifdef GLOBALZPROFILE
  2337. X        source(GLOBALZPROFILE);
  2338. X#endif
  2339. X#ifdef GLOBALZSHRC
  2340. X        source(GLOBALZSHRC);
  2341. X#endif
  2342. X#ifdef GLOBALZLOGIN
  2343. X        if (islogin) source(GLOBALZLOGIN);
  2344. X#endif
  2345. X        return;
  2346. X    }
  2347. X    sourcehome(".zshenv");
  2348. X    if (opts[NORCS] == OPT_SET)
  2349. X        return;
  2350. X    if (interact) {
  2351. X        if (islogin) {
  2352. X            sourcehome(".zprofile");
  2353. X#ifdef GLOBALZPROFILE
  2354. X            source(GLOBALZPROFILE);
  2355. X#endif
  2356. X        }
  2357. X#ifdef GLOBALZSHRC
  2358. X        source(GLOBALZSHRC);
  2359. X#endif
  2360. X        sourcehome(".zshrc");
  2361. X        if (islogin) {
  2362. X#ifdef GLOBALZLOGIN
  2363. X            source(GLOBALZLOGIN);
  2364. X#endif
  2365. X            sourcehome(".zlogin");
  2366. X        }
  2367. X    }
  2368. X    if (interact)
  2369. X        readhistfile(getsparam("HISTFILE"),0);
  2370. X    if (opts['c'] == OPT_SET)
  2371. X        {
  2372. X        if (SHIN >= 10)
  2373. X            close(SHIN);
  2374. X        SHIN = movefd(open("/dev/null",O_RDONLY));
  2375. X        hungets(cmd);
  2376. X        strinbeg();
  2377. X        }
  2378. X#ifdef TIOCSWINSZ
  2379. X    if (!(columns = shttyinfo.winsize.ws_col))
  2380. X        columns = 80;
  2381. X    if (!(lines = shttyinfo.winsize.ws_row))
  2382. X        lines = 24;
  2383. X#endif
  2384. X}
  2385. X
  2386. Xvoid ainit() /**/
  2387. X{
  2388. X    alstackind = 0;        /* reset alias stack */
  2389. X    alstat = 0;
  2390. X    isfirstln = 1;
  2391. X}
  2392. X
  2393. Xvoid readhistfile(s,err) /**/
  2394. Xchar *s;int err;
  2395. X{
  2396. Xchar buf[1024];
  2397. XFILE *in;
  2398. X
  2399. X    if (!s)
  2400. X        return;
  2401. X    if (in = fopen(s,"r"))
  2402. X        {
  2403. X        permalloc();
  2404. X        while (fgets(buf,1024,in))
  2405. X            {
  2406. X            int l = strlen(buf);
  2407. X            char *pt = buf;
  2408. X
  2409. X            if (l && buf[l-1] == '\n')
  2410. X                buf[l-1] = '\0';
  2411. X            for (;*pt;pt++)
  2412. X                if (*pt == ' ')
  2413. X                *pt = HISTSPACE;
  2414. X            addnode(histlist,ztrdup(buf));
  2415. X            addnode(lithistlist,ztrdup(buf));
  2416. X            curhist++;
  2417. X            }
  2418. X        fclose(in);
  2419. X        lastalloc();
  2420. X        }
  2421. X    else if (err)
  2422. X        zerr("can't read history file",s,0);
  2423. X}
  2424. X
  2425. Xvoid savehistfile(s,err) /**/
  2426. Xchar *s;int err;
  2427. X{
  2428. Xchar *t;
  2429. XLknode n;
  2430. XLklist l;
  2431. XFILE *out;
  2432. X
  2433. X    if (!s || !interact)
  2434. X        return;
  2435. X    if (out = fdopen(open(s,O_CREAT|O_WRONLY|O_TRUNC,0600),"w"))
  2436. X        {
  2437. X        n = lastnode(l = (isset(HISTLIT) ? lithistlist : histlist));
  2438. X        if (n == (Lknode) l)
  2439. X            {
  2440. X            fclose(out);
  2441. X            return;
  2442. X            }
  2443. X        while (--savehist && prevnode(n) != (Lknode) l)
  2444. X            n = prevnode(n);
  2445. X        for (; n; incnode(n))
  2446. X            {
  2447. X            for (s = t = getdata(n); *s; s++)
  2448. X                if (*s == HISTSPACE)
  2449. X                    *s = ' ';
  2450. X            fputs(t,out);
  2451. X            fputc('\n',out);
  2452. X            }
  2453. X        fclose(out);
  2454. X        }
  2455. X    else if (err)
  2456. X        zerr("can't write history file: %s",s,0);
  2457. X}
  2458. X
  2459. SHAR_EOF
  2460. chmod 0644 zsh2.1/src/init.c ||
  2461. echo 'restore of zsh2.1/src/init.c failed'
  2462. Wc_c="`wc -c < 'zsh2.1/src/init.c'`"
  2463. test 12375 -eq "$Wc_c" ||
  2464.     echo 'zsh2.1/src/init.c: original size 12375, current size' "$Wc_c"
  2465. rm -f _shar_wnt_.tmp
  2466. fi
  2467. # ============= zsh2.1/src/jobs.c ==============
  2468. if test -f 'zsh2.1/src/jobs.c' -a X"$1" != X"-c"; then
  2469.     echo 'x - skipping zsh2.1/src/jobs.c (File already exists)'
  2470.     rm -f _shar_wnt_.tmp
  2471. else
  2472. > _shar_wnt_.tmp
  2473. echo 'x - extracting zsh2.1/src/jobs.c (Text)'
  2474. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.1/src/jobs.c' &&
  2475. X/*
  2476. X
  2477. X    jobs.c - job control
  2478. X
  2479. X    This file is part of zsh, the Z shell.
  2480. X
  2481. X    zsh is free software; no one can prevent you from reading the source
  2482. X   code, or giving it to someone else.
  2483. X
  2484. X   This file is copyrighted under the GNU General Public License, which
  2485. X   can be found in the file called COPYING.
  2486. X
  2487. X   Copyright (C) 1990, 1991 Paul Falstad
  2488. SHAR_EOF
  2489. true || echo 'restore of zsh2.1/src/jobs.c failed'
  2490. fi
  2491. echo 'End of zsh2.1.0 part 7'
  2492. echo 'File zsh2.1/src/jobs.c is continued in part 8'
  2493. echo 8 > _shar_seq_.tmp
  2494. exit 0
  2495.  
  2496. exit 0 # Just in case...
  2497. -- 
  2498. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2499. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2500. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2501. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2502.