home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume24 / zsh2.1 / part13 < prev    next >
Text File  |  1991-10-26  |  49KB  |  2,319 lines

  1. Newsgroups: comp.sources.misc
  2. From: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
  3. Subject:  v24i013:  zsh2.1 - The Z shell, Part13/19
  4. Message-ID: <1991Oct26.015004.19579@sparky.imd.sterling.com>
  5. X-Md4-Signature: 71a3711c5794b8728f05e980e2c4eec8
  6. Date: Sat, 26 Oct 1991 01:50:04 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
  10. Posting-number: Volume 24, Issue 13
  11. Archive-name: zsh2.1/part13
  12. Environment: BSD
  13. Supersedes: zsh2.00: Volume 18, Issue 84-98
  14.  
  15. #!/bin/sh
  16. # this is zshar.13 (part 13 of zsh2.1.0)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file zsh2.1/src/zsh.h 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" != 13; 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/zsh.h'
  34. else
  35. echo 'x - continuing file zsh2.1/src/zsh.h'
  36. sed 's/^X//' << 'SHAR_EOF' >> 'zsh2.1/src/zsh.h' &&
  37. X#define MENUCOMPLETE 'Y'
  38. X#define USEZLE 'Z'
  39. X#define ALLEXPORT 'a'
  40. X#define ERREXIT 'e'
  41. X#define NORCS 'f'
  42. X#define HISTIGNORESPACE 'g'
  43. X#define HISTIGNOREDUPS 'h'
  44. X#define INTERACTIVE 'i'
  45. X#define HISTLIT 'j'
  46. X#define INTERACTIVECOMMENTS 'k'
  47. X#define LOGINSHELL 'l'
  48. X#define MONITOR 'm'
  49. X#define NOEXEC 'n'
  50. X#define SHINSTDIN 's'
  51. X#define NOUNSET 'u'
  52. X#define VERBOSE 'v'
  53. X#define CHASELINKS 'w'
  54. X#define XTRACE 'x'
  55. X#define SHWORDSPLIT 'y'
  56. X#define MENUCOMPLETEBEEP '\2'
  57. X#define HISTNOSTORE '\3'
  58. X#define EXTENDEDGLOB '\5'
  59. X#define GLOBCOMPLETE '\6'
  60. X#define CSHJUNKIEQUOTES '\7'
  61. X#define PUSHDMINUS '\10'
  62. X#define CSHJUNKIELOOPS '\11'
  63. X#define RCQUOTES '\12'
  64. X#define KSHOPTIONPRINT '\13'
  65. X#define NOSHORTLOOPS '\14'
  66. X#define LASTMENU '\15'
  67. X#define AUTOMENU '\16'
  68. X#define HISTVERIFY '\17'
  69. X#define NOLISTBEEP '\20'
  70. X#define NOHUP '\21'
  71. X#define NOEQUALS '\22'
  72. X#define CSHNULLGLOB '\23'
  73. X
  74. X#ifndef GLOBALS
  75. Xextern struct option optns[];
  76. X#else
  77. Xstruct option optns[] = {
  78. X    "correct",CORRECT,
  79. X    "noclobber",NOCLOBBER,
  80. X    "nobadpattern",NOBADPATTERN,
  81. X    "nonomatch",NONOMATCH,
  82. X    "globdots",GLOBDOTS,
  83. X    "notify",NOTIFY,
  84. X    "bgnice",BGNICE,
  85. X    "ignoreeof",IGNOREEOF,
  86. X    "markdirs",MARKDIRS,
  87. X    "autolist",AUTOLIST,
  88. X    "nobeep",NOBEEP,
  89. X    "printexitvalue",PRINTEXITVALUE,
  90. X    "pushdtohome",PUSHDTOHOME,
  91. X    "pushdsilent",PUSHDSILENT,
  92. X    "noglob",NOGLOBOPT,
  93. X    "nullglob",NULLGLOB,
  94. X    "rmstarsilent",RMSTARSILENT,
  95. X    "ignorebraces",IGNOREBRACES,
  96. X    "autocd",AUTOCD,
  97. X    "nobanghist",NOBANGHIST,
  98. X    "sunkeyboardhack",SUNKEYBOARDHACK,
  99. X    "singlelinezle",SINGLELINEZLE,
  100. X    "autopushd",AUTOPUSHD,
  101. X    "correctall",CORRECTALL,
  102. X    "rcexpandparam",RCEXPANDPARAM,
  103. X    "pathdirs",PATHDIRS,
  104. X    "longlistjobs",LONGLISTJOBS,
  105. X    "recexact",RECEXACT,
  106. X    "cdablevars",CDABLEVARS,
  107. X    "mailwarning",MAILWARNING,
  108. X    "nopromptclobber",NOPROMPTCLOBBER,
  109. X    "autoresume",AUTORESUME,
  110. X    "listtypes",LISTTYPES,
  111. X    "menucomplete",MENUCOMPLETE,
  112. X    "zle",USEZLE,
  113. X    "allexport",ALLEXPORT,
  114. X    "errexit",ERREXIT,
  115. X    "norcs",NORCS,
  116. X    "histignorespace",HISTIGNORESPACE,
  117. X    "histignoredups",HISTIGNOREDUPS,
  118. X    "interactive",INTERACTIVE,
  119. X    "histlit",HISTLIT,
  120. X    "interactivecomments",INTERACTIVECOMMENTS,
  121. X    "login",LOGINSHELL,
  122. X    "monitor",MONITOR,
  123. X    "noexec",NOEXEC,
  124. X    "shinstdin",SHINSTDIN,
  125. X    "nounset",NOUNSET,
  126. X    "verbose",VERBOSE,
  127. X    "chaselinks",CHASELINKS,
  128. X    "xtrace",XTRACE,
  129. X    "shwordsplit",SHWORDSPLIT,
  130. X    "menucompletebeep",MENUCOMPLETEBEEP,
  131. X    "histnostore",HISTNOSTORE,
  132. X    "extendedglob",EXTENDEDGLOB,
  133. X    "globcomplete",GLOBCOMPLETE,
  134. X    "cshjunkiequotes",CSHJUNKIEQUOTES,
  135. X    "pushdminus",PUSHDMINUS,
  136. X    "cshjunkieloops",CSHJUNKIELOOPS,
  137. X    "rcquotes",RCQUOTES,
  138. X    "noshortloops",NOSHORTLOOPS,
  139. X    "lastmenu",LASTMENU,
  140. X    "automenu",AUTOMENU,
  141. X    "histverify",HISTVERIFY,
  142. X    "nolistbeep",NOLISTBEEP,
  143. X    "nohup",NOHUP,
  144. X    "noequals",NOEQUALS,
  145. X    "kshoptionprint",KSHOPTIONPRINT,
  146. X    "cshnullglob",CSHNULLGLOB,
  147. X    NULL,0
  148. X};
  149. X#endif
  150. X
  151. X#define ALSTAT_MORE 1    /* last alias ended with ' ' */
  152. X#define ALSTAT_JUNK 2    /* don't put word in history List */
  153. X
  154. X#undef isset
  155. X#define isset(X) (opts[X])
  156. X#define unset(X) (!opts[X])
  157. X#define interact (isset(INTERACTIVE))
  158. X#define jobbing (isset(MONITOR))
  159. X#define nointr() signal(SIGINT,SIG_IGN)
  160. X#define islogin (isset(LOGINSHELL))
  161. X
  162. X#undef WIFSTOPPED
  163. X#undef WIFSIGNALED
  164. X#undef WIFEXITED
  165. X#undef WEXITSTATUS
  166. X#undef WTERMSIG
  167. X#undef WSTOPSIG
  168. X#undef WCOREDUMPED
  169. X
  170. X#define SP(X) (X)
  171. X#define WIFSTOPPED(X) (((X)&0377)==0177)
  172. X#define WIFSIGNALED(X) (((X)&0377)!=0&&((X)&0377)!=0177)
  173. X#define WIFEXITED(X) (((X)&0377)==0)
  174. X#define WEXITSTATUS(X) (((X)>>8)&0377)
  175. X#define WTERMSIG(X) ((X)&0177)
  176. X#define WSTOPSIG(X) (((X)>>8)&0377)
  177. X#define WCOREDUMPED(X) ((X)&0200)
  178. X
  179. X#ifndef S_ISBLK
  180. X#define    _IFMT        0170000
  181. X#define    _IFDIR    0040000
  182. X#define    _IFCHR    0020000
  183. X#define    _IFBLK    0060000
  184. X#define    _IFREG    0100000
  185. X#define    _IFIFO    0010000
  186. X#define    S_ISBLK(m)    (((m)&_IFMT) == _IFBLK)
  187. X#define    S_ISCHR(m)    (((m)&_IFMT) == _IFCHR)
  188. X#define    S_ISDIR(m)    (((m)&_IFMT) == _IFDIR)
  189. X#define    S_ISFIFO(m)    (((m)&_IFMT) == _IFIFO)
  190. X#define    S_ISREG(m)    (((m)&_IFMT) == _IFREG)
  191. X#endif
  192. X
  193. X#ifndef S_ISSOCK
  194. X#ifndef _IFMT
  195. X#define _IFMT 0170000
  196. X#endif
  197. X#define    _IFLNK    0120000
  198. X#define    _IFSOCK    0140000
  199. X#define    S_ISLNK(m)    (((m)&_IFMT) == _IFLNK)
  200. X#define    S_ISSOCK(m)    (((m)&_IFMT) == _IFSOCK)
  201. X#endif
  202. X
  203. X#if S_IFIFO == S_IFSOCK
  204. X#undef S_IFIFO
  205. X#endif
  206. X
  207. X/* buffered shell input for non-interactive shells */
  208. X
  209. XEXTERN FILE *bshin;
  210. X
  211. X/* NULL-terminated arrays containing path, cdpath, etc. */
  212. X
  213. XEXTERN char **path,**cdpath,**fpath,**watch,**mailpath,**tildedirs,**fignore;
  214. XEXTERN char **hosts,**hostcmds,**optcmds,**bindcmds,**varcmds;
  215. X
  216. X/* named directories */
  217. X
  218. XEXTERN char **userdirs,**usernames;
  219. X
  220. X/* size of userdirs[], # of userdirs */
  221. X
  222. XEXTERN int userdirsz,userdirct;
  223. X
  224. XEXTERN char *mailfile;
  225. X
  226. XEXTERN char *yytext;
  227. X
  228. X/* error/break flag */
  229. X
  230. XEXTERN int errflag;
  231. X
  232. XEXTERN char *tokstr;
  233. XEXTERN int tok, tokfd;
  234. X
  235. X/* lexical analyzer error flag */
  236. X
  237. XEXTERN int lexstop;
  238. X
  239. X/* suppress error messages */
  240. X
  241. XEXTERN int noerrs;
  242. X
  243. X/* current history event number */
  244. X
  245. XEXTERN int curhist;
  246. X
  247. X/* if != 0, this is the first line of the command */
  248. X
  249. XEXTERN int isfirstln;
  250. X
  251. X/* if != 0, this is the first char of the command (not including
  252. X    white space */
  253. X
  254. XEXTERN int isfirstch;
  255. X
  256. X/* first event number in the history lists */
  257. X
  258. XEXTERN int firsthist,firstlithist;
  259. X
  260. X/* capacity of history lists */
  261. X
  262. XEXTERN int histsiz,lithistsiz;
  263. X
  264. X/* if = 1, we have performed history substitution on the current line
  265. X     if = 2, we have used the 'p' modifier */
  266. X
  267. XEXTERN int histdone;
  268. X
  269. X/* default event (usually curhist-1, that is, "!!") */
  270. X
  271. XEXTERN int defev;
  272. X
  273. X/* != 0 if we are about to read a command word */
  274. X
  275. XEXTERN int incmdpos;
  276. X
  277. X/* != 0 if we are in the middle of a [[ ... ]] */
  278. X
  279. XEXTERN int incond;
  280. X
  281. X/* != 0 if we are about to read a case pattern */
  282. X
  283. XEXTERN int incasepat;
  284. X
  285. X/* != 0 if we just read FUNCTION */
  286. X
  287. XEXTERN int infunc;
  288. X
  289. X/* != 0 if we just read a newline */
  290. X
  291. XEXTERN int isnewlin;
  292. X
  293. X/* the lists of history events */
  294. X
  295. XEXTERN Lklist histlist,lithistlist;
  296. X
  297. X/* the directory stack */
  298. X
  299. XEXTERN Lklist dirstack;
  300. X
  301. X/* the zle buffer stack */
  302. X
  303. XEXTERN Lklist bufstack;
  304. X
  305. X/* the input queue (stack?)
  306. X
  307. X    inbuf    = start of buffer
  308. X    inbufptr = location in buffer (= inbuf for a FULL buffer)
  309. X                                            (= inbuf+inbufsz for an EMPTY buffer)
  310. X    inbufct  = # of chars in buffer (inbufptr+inbufct == inbuf+inbufsz)
  311. X    inbufsz  = max size of buffer
  312. X*/
  313. X
  314. XEXTERN char *inbuf,*inbufptr;
  315. XEXTERN int inbufct,inbufsz;
  316. X
  317. XEXTERN char *ifs;        /* $IFS */
  318. X
  319. XEXTERN char *oldpwd;    /* $OLDPWD */
  320. X
  321. XEXTERN char *underscore; /* $_ */
  322. X
  323. X/* != 0 if this is a subshell */
  324. X
  325. XEXTERN int subsh;
  326. X
  327. X/* # of break levels */
  328. X
  329. XEXTERN int breaks;
  330. X
  331. X/* != 0 if we have a return pending */
  332. X
  333. XEXTERN int retflag;
  334. X
  335. X/* != 0 means don't hash the PATH */
  336. X
  337. XEXTERN int pathsuppress;
  338. X
  339. X/* # of nested loops we are in */
  340. X
  341. XEXTERN int loops;
  342. X
  343. X/* # of continue levels */
  344. X
  345. XEXTERN int contflag;
  346. X
  347. X/* the job we are working on */
  348. X
  349. XEXTERN int thisjob;
  350. X
  351. X/* the current job (+) */
  352. X
  353. XEXTERN int curjob;
  354. X
  355. X/* the previous job (-) */
  356. X
  357. XEXTERN int prevjob;
  358. X
  359. X/* hash table containing the aliases and reserved words */
  360. X
  361. XEXTERN Hashtab aliastab;
  362. X
  363. X/* hash table containing the parameters */
  364. X
  365. XEXTERN Hashtab paramtab;
  366. X
  367. X/* hash table containing the builtins/shfuncs/hashed commands */
  368. X
  369. XEXTERN Hashtab cmdnamtab;
  370. X
  371. X/* hash table containing the zle multi-character bindings */
  372. X
  373. XEXTERN Hashtab xbindtab;
  374. X
  375. X/* the job table */
  376. X
  377. XEXTERN struct job jobtab[MAXJOB];
  378. X
  379. X/* the list of sched jobs pending */
  380. X
  381. XEXTERN struct schedcmd *schedcmds;
  382. X
  383. X/* the last l for s/l/r/ history substitution */
  384. X
  385. XEXTERN char *hsubl;
  386. X
  387. X/* the last r for s/l/r/ history substitution */
  388. X
  389. XEXTERN char *hsubr;
  390. X
  391. XEXTERN char *username;    /* $USERNAME */
  392. XEXTERN long lastval;        /* $? */
  393. XEXTERN long baud;            /* $BAUD */
  394. XEXTERN long columns;        /* $COLUMNS */
  395. XEXTERN long lines;        /* $LINES */
  396. X
  397. X/* input fd from the coprocess */
  398. X
  399. XEXTERN int coprocin;
  400. X
  401. X/* output fd from the coprocess */
  402. X
  403. XEXTERN int coprocout;
  404. X
  405. XEXTERN long mailcheck;    /* $MAILCHECK */
  406. XEXTERN long logcheck;    /* $LOGCHECK */
  407. X
  408. X/* the last time we checked mail */
  409. X
  410. XEXTERN time_t lastmailcheck;
  411. X
  412. X/* the last time we checked the people in the WATCH variable */
  413. X
  414. XEXTERN time_t lastwatch;
  415. X
  416. X/* the last time we did the periodic() shell function */
  417. X
  418. XEXTERN time_t lastperiod;
  419. X
  420. X/* $SECONDS = time(NULL) - shtimer */
  421. X
  422. XEXTERN time_t shtimer;
  423. X
  424. XEXTERN long mypid;        /* $$ */
  425. XEXTERN long lastpid;        /* $! */
  426. XEXTERN long ppid;            /* $PPID */
  427. X
  428. X/* the process group of the shell */
  429. X
  430. XEXTERN long mypgrp;
  431. X
  432. XEXTERN char *cwd;            /* $PWD */
  433. XEXTERN char *optarg;        /* $OPTARG */
  434. XEXTERN long optind;        /* $OPTIND */
  435. XEXTERN char *prompt;        /* $PROMPT */
  436. XEXTERN char *rprompt;    /* $RPROMPT */
  437. XEXTERN char *prompt2;    /* etc. */
  438. XEXTERN char *prompt3;
  439. XEXTERN char *prompt4;
  440. XEXTERN char *sprompt;
  441. XEXTERN char *timefmt;
  442. XEXTERN char *watchfmt;
  443. XEXTERN char *wordchars;
  444. XEXTERN char *fceditparam;
  445. XEXTERN char *tmpprefix;
  446. X
  447. XEXTERN char *argzero;    /* $0 */
  448. X
  449. XEXTERN char *hackzero;
  450. X
  451. X/* the hostname */
  452. X
  453. XEXTERN char *hostnam;
  454. X
  455. XEXTERN char *home;        /* $HOME */
  456. XEXTERN char **pparams;    /* $argv */
  457. X
  458. X/* the default command for null commands */
  459. X
  460. XEXTERN char *nullcmd;
  461. X
  462. X/* the List of local variables we have to destroy */
  463. X
  464. XEXTERN Lklist locallist;
  465. X
  466. X/* the shell input fd */
  467. X
  468. XEXTERN int SHIN;
  469. X
  470. X/* the shell tty fd */
  471. X
  472. XEXTERN int SHTTY;
  473. X
  474. X/* the stack of aliases we are expanding */
  475. X
  476. XEXTERN struct alias *alstack[MAXAL];
  477. X
  478. X/* the alias stack pointer; also, the number of aliases currently
  479. X     being expanded */
  480. X
  481. XEXTERN int alstackind;
  482. X
  483. X/* != 0 means we are reading input from a string */
  484. X
  485. XEXTERN int strin;
  486. X
  487. X/* period between periodic() commands, in seconds */
  488. X
  489. XEXTERN long period;
  490. X
  491. X/* != 0 means history substitution is turned off */
  492. X
  493. XEXTERN int stophist;
  494. X
  495. XEXTERN int lithist;
  496. X
  497. X/* this line began with a space, so junk it if HISTIGNORESPACE is on */
  498. X
  499. XEXTERN int spaceflag;
  500. X
  501. X/* don't do spelling correction */
  502. X
  503. XEXTERN int nocorrect;
  504. X
  505. X/* != 0 means we have removed the current event from the history List */
  506. X
  507. XEXTERN int histremmed;
  508. X
  509. X/* the options; e.g. if opts['a'] == OPT_SET, -a is turned on */
  510. X
  511. XEXTERN int opts[128];
  512. X
  513. XEXTERN long lineno;        /* LINENO */
  514. XEXTERN long listmax;        /* LISTMAX */
  515. XEXTERN long savehist;    /* SAVEHIST */
  516. XEXTERN long shlvl;        /* SHLVL */
  517. XEXTERN long tmout;        /* TMOUT */
  518. XEXTERN long dirstacksize;    /* DIRSTACKSIZE */
  519. X
  520. X/* != 0 means we have called execlist() and then intend to exit(),
  521. X     so don't fork if not necessary */
  522. X
  523. XEXTERN int exiting;
  524. X
  525. XEXTERN int lastbase;        /* last input base we used */
  526. X
  527. X/* the limits for child processes */
  528. X
  529. X#ifdef RLIM_INFINITY
  530. XEXTERN struct rlimit limits[RLIM_NLIMITS];
  531. X#endif
  532. X
  533. X/* the current word in the history List */
  534. X
  535. XEXTERN char *hlastw;
  536. X
  537. X/* pointer into the history line */
  538. X
  539. XEXTERN char *hptr;
  540. X
  541. X/* the current history line */
  542. X
  543. XEXTERN char *hline;
  544. X
  545. X/* the termcap buffer */
  546. X
  547. XEXTERN char termbuf[1024];
  548. X
  549. X/* $TERM */
  550. X
  551. XEXTERN char *term;
  552. X
  553. X/* != 0 if this $TERM setup is usable */
  554. X
  555. XEXTERN int termok;
  556. X
  557. X/* flag for CSHNULLGLOB */
  558. X
  559. XEXTERN int badcshglob;
  560. X
  561. X/* max size of hline */
  562. X
  563. XEXTERN int hlinesz;
  564. X
  565. X/* the alias expansion status - if == ALSTAT_MORE, we just finished
  566. X    expanding an alias ending with a space */
  567. X
  568. XEXTERN int alstat;
  569. X
  570. X/* we have printed a 'you have stopped (running) jobs.' message */
  571. X
  572. XEXTERN int stopmsg;
  573. X
  574. X/* the default tty state */
  575. X
  576. XEXTERN struct ttyinfo shttyinfo;
  577. X
  578. X/* $TTY */
  579. X
  580. XEXTERN char *ttystrname;
  581. X
  582. X/* list of memory heaps */
  583. X
  584. XEXTERN Lklist heaplist;
  585. X
  586. X/* != 0 if we are allocating in the heaplist */
  587. X
  588. XEXTERN int useheap;
  589. X
  590. X#include "signals.h"
  591. X
  592. X#ifdef GLOBALS
  593. X
  594. X/* signal names */
  595. Xchar **sigptr = sigs;
  596. X
  597. X/* tokens */
  598. Xchar *ztokens = "#$^*()$=|{}[]`<>?~`,";
  599. X
  600. X#else
  601. Xextern char *ztokens,**sigptr;
  602. X#endif
  603. X
  604. X#define SIGERR (SIGCOUNT+1)
  605. X#define SIGDEBUG (SIGCOUNT+2)
  606. X#define VSIGCOUNT (SIGCOUNT+3)
  607. X#define SIGEXIT 0
  608. X
  609. X/* signals that are trapped = 1, signals ignored =2 */
  610. X
  611. XEXTERN int sigtrapped[VSIGCOUNT];
  612. X
  613. X/* trap functions for each signal */
  614. X
  615. XEXTERN List sigfuncs[VSIGCOUNT];
  616. X
  617. X/* $HISTCHARS */
  618. X
  619. XEXTERN char bangchar,hatchar,hashchar;
  620. X
  621. XEXTERN int eofseen;
  622. X
  623. X/* we are parsing a line sent to use by the editor */
  624. X
  625. XEXTERN int zleparse;
  626. X
  627. XEXTERN int wordbeg;
  628. X
  629. XEXTERN int parbegin;
  630. X
  631. X/* interesting termcap strings */
  632. X
  633. X#define TCCLEARSCREEN 0
  634. X#define TCLEFT 1
  635. X#define TCMULTLEFT 2
  636. X#define TCRIGHT 3
  637. X#define TCMULTRIGHT 4
  638. X#define TCUP 5
  639. X#define TCMULTUP 6
  640. X#define TCDOWN 7
  641. X#define TCMULTDOWN 8
  642. X#define TCDEL 9
  643. X#define TCMULTDEL 10
  644. X#define TCINS 11
  645. X#define TCMULTINS 12
  646. X#define TCCLEAREOD 13
  647. X#define TCCLEAREOL 14
  648. X#define TCINSLINE 15
  649. X#define TCDELLINE 16
  650. X#define TC_COUNT 17
  651. X
  652. X/* lengths of each string */
  653. X
  654. XEXTERN int tclen[TC_COUNT];
  655. X
  656. XEXTERN char *tcstr[TC_COUNT];
  657. X
  658. X#ifdef GLOBALS
  659. X
  660. X/* names of the strings we want */
  661. X
  662. Xchar *tccapnams[TC_COUNT] = {
  663. X    "cl","le","LE","nd","RI","up","UP","do",
  664. X    "DO","dc","DC","ic","IC","cd","ce","al","dl"
  665. X    };
  666. X
  667. X#else
  668. Xextern char *tccapnams[TC_COUNT];
  669. X#endif
  670. X
  671. X#define tccan(X) (!!tclen[X])
  672. X
  673. X#define HISTFLAG_DONE   1
  674. X#define HISTFLAG_NOEXEC 2
  675. X
  676. X#include "ztype.h"
  677. X#include "funcs.h"
  678. X
  679. X#ifdef __hpux
  680. X#define setpgrp setpgid
  681. X#endif
  682. X
  683. X#define _INCLUDE_POSIX_SOURCE
  684. X#define _INCLUDE_XOPEN_SOURCE
  685. X#define _INCLUDE_HPUX_SOURCE
  686. X
  687. X#ifdef SV_BSDSIG
  688. X#define SV_INTERRUPT SV_BSDSIG
  689. X#endif
  690. X
  691. X#ifdef SYSV
  692. X#define blockchld() sighold(SIGCHLD)
  693. X#define unblockchld() sigrelse(SIGCHLD)
  694. X#define chldsuspend() sigpause(SIGCHLD)
  695. X#else
  696. X#define blockchld() sigblock(sigmask(SIGCHLD))
  697. X#define unblockchld() sigsetmask(0)
  698. X#define chldsuspend() sigpause(0)
  699. X#endif
  700. SHAR_EOF
  701. echo 'File zsh2.1/src/zsh.h is complete' &&
  702. chmod 0644 zsh2.1/src/zsh.h ||
  703. echo 'restore of zsh2.1/src/zsh.h failed'
  704. Wc_c="`wc -c < 'zsh2.1/src/zsh.h'`"
  705. test 30146 -eq "$Wc_c" ||
  706.     echo 'zsh2.1/src/zsh.h: original size 30146, current size' "$Wc_c"
  707. rm -f _shar_wnt_.tmp
  708. fi
  709. # ============= zsh2.1/src/zle_vi.c ==============
  710. if test -f 'zsh2.1/src/zle_vi.c' -a X"$1" != X"-c"; then
  711.     echo 'x - skipping zsh2.1/src/zle_vi.c (File already exists)'
  712.     rm -f _shar_wnt_.tmp
  713. else
  714. > _shar_wnt_.tmp
  715. echo 'x - extracting zsh2.1/src/zle_vi.c (Text)'
  716. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.1/src/zle_vi.c' &&
  717. X/*
  718. X
  719. X    zle_vi.c - vi-specific functions
  720. X
  721. X    This file is part of zsh, the Z shell.
  722. X
  723. X    zsh is free software; no one can prevent you from reading the source
  724. X   code, or giving it to someone else.
  725. X
  726. X   This file is copyrighted under the GNU General Public License, which
  727. X   can be found in the file called COPYING.
  728. X
  729. X   Copyright (C) 1990, 1991 Paul Falstad
  730. X
  731. X   zsh is distributed in the hope that it will be useful, but
  732. X   WITHOUT ANY WARRANTY.  No author or distributor accepts
  733. X   responsibility to anyone for the consequences of using it or for
  734. X   whether it serves any particular purpose or works at all, unless he
  735. X   says so in writing.  Refer to the GNU General Public License
  736. X   for full details.
  737. X
  738. X   Everyone is granted permission to copy, modify and redistribute
  739. X   zsh, but only under the conditions described in the GNU General Public
  740. X   License.   A copy of this license is supposed to have been given to you
  741. X   along with zsh so you can know your rights and responsibilities.
  742. X   It should be in a file named COPYING.
  743. X
  744. X   Among other things, the copyright notice and this notice must be
  745. X   preserved on all copies.
  746. X
  747. X*/
  748. X
  749. X#define ZLE
  750. X#include "zsh.h"
  751. X
  752. X
  753. Xstatic void startvichange(im)
  754. Xint im;
  755. X{
  756. X    insmode = im;
  757. X    if (vichgbuf) free(vichgbuf);
  758. X    vichgbuf = zalloc(vichgbufsz = 16);
  759. X    vichgbuf[0] = c;
  760. X    vichgbufptr = 1;
  761. X    vichgflag = 1;
  762. X    viinsbegin = cs;
  763. X}
  764. X
  765. Xstatic void startvitext(im)
  766. X{
  767. X    startvichange(im);
  768. X    bindtab = mainbindtab;
  769. X    undoing = 0;
  770. X}
  771. X
  772. Xint vigetkey() /**/
  773. X{
  774. Xint ch;
  775. X
  776. X    if ((ch = getkey(0)) == -1)
  777. X        return 0;
  778. X    if (ch == 22)
  779. X        {
  780. X        if ((ch = getkey(0)) == -1)
  781. X            return 0;
  782. X        return ch;
  783. X        }
  784. X    else if (ch == 27)
  785. X        return 0;
  786. X    return ch;
  787. X}
  788. X
  789. Xint getvirange() /**/
  790. X{
  791. Xint k2,t0,startline;
  792. X
  793. X    startline = findbol();
  794. X    for (;;) {
  795. X        k2 = getkeycmd();
  796. X        if (k2 == -1) {
  797. X            feep();
  798. X            return -1;
  799. X        }
  800. X        if (zlecmds[k2].flags & ZLE_ARG)
  801. X            zlecmds[k2].func();
  802. X        else
  803. X            break;
  804. X    }
  805. X    if (k2 == bindk) {
  806. X        findline(&cs,&t0);
  807. X        return (t0 == ll) ? t0 : t0+1;
  808. X    }
  809. X    if (!(zlecmds[k2].flags & ZLE_MOVEMENT)) {
  810. X        feep();
  811. X        return -1;
  812. X    }
  813. X    t0 = cs;
  814. X
  815. X    virangeflag = 1;
  816. X    zlecmds[k2].func();
  817. X    virangeflag = 0;
  818. X    if (cs == t0) {
  819. X        feep();
  820. X        return -1;
  821. X    }
  822. X    if (startline != findbol()) {
  823. X        if (cs < t0) {
  824. X            cs = startline;
  825. X            t0 = findeol()+1;
  826. X        } else {
  827. X            t0 = startline;
  828. X            cs = findeol()+1;
  829. X        }
  830. X    }
  831. X    if (cs > t0) {
  832. X        k2 = cs;
  833. X        cs = t0;
  834. X        t0 = k2;
  835. X    }
  836. X    return t0;
  837. X}
  838. X
  839. Xvoid viaddnext() /**/
  840. X{
  841. X    if (cs != ll)
  842. X        cs++;
  843. X    startvitext(1);
  844. X}
  845. X
  846. Xvoid viaddeol() /**/
  847. X{
  848. X    cs = findeol();
  849. X    startvitext(1);
  850. X}
  851. X
  852. Xvoid viinsert() /**/
  853. X{
  854. X    startvitext(1);
  855. X}
  856. X
  857. Xvoid viinsertbol() /**/
  858. X{
  859. X    cs = findbol();
  860. X    startvitext(1);
  861. X}
  862. X
  863. Xvoid videlete() /**/
  864. X{
  865. Xint c2;
  866. X
  867. X    startvichange(1);
  868. X    if ((c2 = getvirange()) == -1)
  869. X        { vichgflag = 0; return; }
  870. X    forekill(c2-cs,0);
  871. X    vichgflag = 0;
  872. X}
  873. X
  874. Xvoid vichange() /**/
  875. X{
  876. Xint c2;
  877. X
  878. X    startvichange(1);
  879. X    if ((c2 = getvirange()) == -1)
  880. X        { vichgflag = 0; return; }
  881. X    forekill(c2-cs,0);
  882. X    bindtab = mainbindtab;
  883. X    undoing = 0;
  884. X}
  885. X
  886. Xvoid visubstitute() /**/
  887. X{
  888. X    if (mult < 0) return;
  889. X    if (findeol()-cs < mult) mult = findeol()-cs;
  890. X    if (mult) {
  891. X        foredel(mult);
  892. X        startvitext(1);
  893. X    }
  894. X}
  895. X
  896. Xvoid vichangeeol() /**/
  897. X{
  898. X    killline();
  899. X    startvitext(1);
  900. X}
  901. X
  902. Xvoid vichangewholeline() /**/
  903. X{
  904. Xint cq;
  905. X
  906. X    findline(&cs,&cq);
  907. X    foredel(cq-cs);
  908. X    startvitext(1);
  909. X}
  910. X
  911. Xvoid viyank() /**/
  912. X{
  913. Xint c2;
  914. X
  915. X    if ((c2 = getvirange()) == -1)
  916. X        return;
  917. X    cut(cs,c2-cs,0);
  918. X}
  919. X
  920. Xvoid viyankeol() /**/
  921. X{
  922. Xint x = findeol();
  923. X
  924. X    if (x == cs)
  925. X        feep();
  926. X    else
  927. X        cut(cs,x-cs,0);
  928. X}
  929. X
  930. Xvoid vireplace() /**/
  931. X{
  932. X    startvitext(0);
  933. X}
  934. X
  935. Xvoid vireplacechars() /**/
  936. X{
  937. Xint ch;
  938. X
  939. X    if (mult < 0) return;
  940. X    if (mult+cs > ll) {
  941. X        feep();
  942. X        return;
  943. X    }
  944. X    startvichange(1);
  945. X    if (ch = vigetkey())
  946. X        while (mult--)
  947. X            line[cs++] = ch;
  948. X    vichgflag = 0;
  949. X}
  950. X
  951. Xvoid vicmdmode() /**/
  952. X{
  953. X    bindtab = altbindtab;
  954. X    if (cs) cs--;
  955. X    undoing = 1;
  956. X    if (vichgflag) vichgflag = 0;
  957. X}
  958. X
  959. Xvoid viopenlinebelow() /**/
  960. X{
  961. X    cs = findeol();
  962. X    spaceinline(1);
  963. X    line[cs++] = '\n';
  964. X    startvitext(1);
  965. X}
  966. X
  967. Xvoid viopenlineabove() /**/
  968. X{
  969. X    cs = findbol();
  970. X    spaceinline(1);
  971. X    line[cs] = '\n';
  972. X    startvitext(1);
  973. X}
  974. X
  975. Xvoid vioperswapcase() /**/
  976. X{
  977. Xint c2;
  978. X
  979. X    if ((c2 = getvirange()) == -1)
  980. X        return;
  981. X    while (cs < c2)
  982. X        {
  983. X        int ch = line[cs];
  984. X
  985. X        if (ch >= 'a' && ch <= 'z')
  986. X            ch = tuupper(ch);
  987. X        else if (ch >= 'A' && ch <= 'Z')
  988. X            ch = tulower(ch);
  989. X        line[cs++] = ch;
  990. X        }
  991. X}
  992. X
  993. Xvoid virepeatchange() /**/
  994. X{
  995. X    if (!vichgbuf || bindtab == mainbindtab || vichgflag) feep();
  996. X    else ungetkeys(vichgbuf,vichgbufptr);
  997. X}
  998. X
  999. Xvoid viindent() /**/
  1000. X{
  1001. Xint c2,endcs,t0,rmult;
  1002. X
  1003. X    if (mult < 0) { mult = -mult; viunindent(); return; }
  1004. X    rmult = mult;
  1005. X    if ((c2 = getvirange()) == -1)
  1006. X        return;
  1007. X    if (cs != findbol()) { feep(); return; }
  1008. X    endcs = cs+rmult;
  1009. X    while (cs < c2) {
  1010. X        spaceinline(rmult);
  1011. X        for (t0 = 0; t0 != rmult; t0++) line[cs++] = '\t';
  1012. X        cs = findeol()+1;
  1013. X    }
  1014. X    cs = endcs;
  1015. X}
  1016. X
  1017. Xvoid viunindent() /**/
  1018. X{
  1019. Xint c2,endcs,t0,rmult;
  1020. X
  1021. X    rmult = mult;
  1022. X    if (mult < 0) { mult = -mult; viindent(); return; }
  1023. X    if ((c2 = getvirange()) == -1)
  1024. X        return;
  1025. X    if (cs != findbol()) { feep(); return; }
  1026. X    endcs = cs;
  1027. X    while (cs < c2) {
  1028. X        for (t0 = 0; t0 != rmult && line[cs] == '\t'; t0++) foredel(1);
  1029. X        cs = findeol()+1;
  1030. X    }
  1031. X    cs = endcs;
  1032. X}
  1033. SHAR_EOF
  1034. chmod 0644 zsh2.1/src/zle_vi.c ||
  1035. echo 'restore of zsh2.1/src/zle_vi.c failed'
  1036. Wc_c="`wc -c < 'zsh2.1/src/zle_vi.c'`"
  1037. test 5031 -eq "$Wc_c" ||
  1038.     echo 'zsh2.1/src/zle_vi.c: original size 5031, current size' "$Wc_c"
  1039. rm -f _shar_wnt_.tmp
  1040. fi
  1041. # ============= zsh2.1/src/ztype.h ==============
  1042. if test -f 'zsh2.1/src/ztype.h' -a X"$1" != X"-c"; then
  1043.     echo 'x - skipping zsh2.1/src/ztype.h (File already exists)'
  1044.     rm -f _shar_wnt_.tmp
  1045. else
  1046. > _shar_wnt_.tmp
  1047. echo 'x - extracting zsh2.1/src/ztype.h (Text)'
  1048. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.1/src/ztype.h' &&
  1049. X/*
  1050. X
  1051. X    ztype.h - character classification macros
  1052. X
  1053. X    This file is part of zsh, the Z shell.
  1054. X
  1055. X    zsh is free software; no one can prevent you from reading the source
  1056. X   code, or giving it to someone else.
  1057. X
  1058. X   This file is copyrighted under the GNU General Public License, which
  1059. X   can be found in the file called COPYING.
  1060. X
  1061. X   Copyright (C) 1990, 1991 Paul Falstad
  1062. X
  1063. X   zsh is distributed in the hope that it will be useful, but
  1064. X   WITHOUT ANY WARRANTY.  No author or distributor accepts
  1065. X   responsibility to anyone for the consequences of using it or for
  1066. X   whether it serves any particular purpose or works at all, unless he
  1067. X   says so in writing.  Refer to the GNU General Public License
  1068. X   for full details.
  1069. X
  1070. X   Everyone is granted permission to copy, modify and redistribute
  1071. X   zsh, but only under the conditions described in the GNU General Public
  1072. X   License.   A copy of this license is supposed to have been given to you
  1073. X   along with zsh so you can know your rights and responsibilities.
  1074. X   It should be in a file named COPYING.
  1075. X
  1076. X   Among other things, the copyright notice and this notice must be
  1077. X   preserved on all copies.
  1078. X
  1079. X*/
  1080. X
  1081. X#define IDIGIT  1
  1082. X#define IALNUM  2
  1083. X#define IBLANK  4
  1084. X#define INBLANK 8
  1085. X#define ITOK    16
  1086. X#define ISEP    32
  1087. X#define IALPHA  64
  1088. X#define IIDENT  128
  1089. X#define IUSER   256
  1090. X#define ICNTRL  512
  1091. X#define IWORD     1024
  1092. X#define ISPECIAL 2048
  1093. X#define _icom(X,Y) (typtab[(int) (unsigned char) (X)] & Y)
  1094. X#define idigit(X) _icom(X,IDIGIT)
  1095. X#define ialnum(X) _icom(X,IALNUM)
  1096. X#define iblank(X) _icom(X,IBLANK)        /* blank, not including \n */
  1097. X#define inblank(X) _icom(X,INBLANK)        /* blank or \n */
  1098. X#define itok(X) _icom(X,ITOK)
  1099. X#define isep(X) _icom(X,ISEP)
  1100. X#define ialpha(X) _icom(X,IALPHA)
  1101. X#define iident(X) _icom(X,IIDENT)
  1102. X#define iuser(X) _icom(X,IUSER)            /* username char */
  1103. X#define icntrl(X) _icom(X,ICNTRL)
  1104. X#define iword(X) _icom(X,IWORD)
  1105. X#define ispecial(X) _icom(X,ISPECIAL)
  1106. X
  1107. XEXTERN short int typtab[256];
  1108. X
  1109. SHAR_EOF
  1110. chmod 0644 zsh2.1/src/ztype.h ||
  1111. echo 'restore of zsh2.1/src/ztype.h failed'
  1112. Wc_c="`wc -c < 'zsh2.1/src/ztype.h'`"
  1113. test 1927 -eq "$Wc_c" ||
  1114.     echo 'zsh2.1/src/ztype.h: original size 1927, current size' "$Wc_c"
  1115. rm -f _shar_wnt_.tmp
  1116. fi
  1117. # ============= zsh2.1/src/lex.pro ==============
  1118. if test -f 'zsh2.1/src/lex.pro' -a X"$1" != X"-c"; then
  1119.     echo 'x - skipping zsh2.1/src/lex.pro (File already exists)'
  1120.     rm -f _shar_wnt_.tmp
  1121. else
  1122. > _shar_wnt_.tmp
  1123. echo 'x - extracting zsh2.1/src/lex.pro (Text)'
  1124. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.1/src/lex.pro' &&
  1125. Xvoid lexsave DCLPROTO((void));
  1126. Xvoid lexrestore DCLPROTO((void));
  1127. Xvoid yylex DCLPROTO((void));
  1128. Xvoid ctxtlex DCLPROTO((void));
  1129. Xvoid initlextabs DCLPROTO((void));
  1130. Xvoid lexinit DCLPROTO((void));
  1131. Xvoid add DCLPROTO((int c));
  1132. Xint gettok DCLPROTO((void));
  1133. Xint exalias DCLPROTO((void));
  1134. Xint skipcomm DCLPROTO((void));
  1135. SHAR_EOF
  1136. chmod 0644 zsh2.1/src/lex.pro ||
  1137. echo 'restore of zsh2.1/src/lex.pro failed'
  1138. Wc_c="`wc -c < 'zsh2.1/src/lex.pro'`"
  1139. test 309 -eq "$Wc_c" ||
  1140.     echo 'zsh2.1/src/lex.pro: original size 309, current size' "$Wc_c"
  1141. rm -f _shar_wnt_.tmp
  1142. fi
  1143. # ============= zsh2.1/src/zle_tricky.c ==============
  1144. if test -f 'zsh2.1/src/zle_tricky.c' -a X"$1" != X"-c"; then
  1145.     echo 'x - skipping zsh2.1/src/zle_tricky.c (File already exists)'
  1146.     rm -f _shar_wnt_.tmp
  1147. else
  1148. > _shar_wnt_.tmp
  1149. echo 'x - extracting zsh2.1/src/zle_tricky.c (Text)'
  1150. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.1/src/zle_tricky.c' &&
  1151. X/*
  1152. X
  1153. X    zle_tricky.c - expansion and completion
  1154. X
  1155. X    This file is part of zsh, the Z shell.
  1156. X
  1157. X    zsh is free software; no one can prevent you from reading the source
  1158. X   code, or giving it to someone else.
  1159. X
  1160. X   This file is copyrighted under the GNU General Public License, which
  1161. X   can be found in the file called COPYING.
  1162. X
  1163. X   Copyright (C) 1990, 1991 Paul Falstad
  1164. X
  1165. X   zsh is distributed in the hope that it will be useful, but
  1166. X   WITHOUT ANY WARRANTY.  No author or distributor accepts
  1167. X   responsibility to anyone for the consequences of using it or for
  1168. X   whether it serves any particular purpose or works at all, unless he
  1169. X   says so in writing.  Refer to the GNU General Public License
  1170. X   for full details.
  1171. X
  1172. X   Everyone is granted permission to copy, modify and redistribute
  1173. X   zsh, but only under the conditions described in the GNU General Public
  1174. X   License.   A copy of this license is supposed to have been given to you
  1175. X   along with zsh so you can know your rights and responsibilities.
  1176. X   It should be in a file named COPYING.
  1177. X
  1178. X   Among other things, the copyright notice and this notice must be
  1179. X   preserved on all copies.
  1180. X
  1181. X*/
  1182. X
  1183. X#define ZLE
  1184. X#include "zsh.h"
  1185. X#ifdef __hpux
  1186. X#include <ndir.h>
  1187. X#else
  1188. X#ifdef SYSV
  1189. X#define direct dirent
  1190. X#else
  1191. X#include <sys/dir.h>
  1192. X#endif
  1193. X#endif
  1194. X#include    <pwd.h>
  1195. X
  1196. Xstatic int we,wb,usemenu,useglob;
  1197. X
  1198. Xstatic int menub,menue,menuw;
  1199. Xstatic Lklist menulist;
  1200. Xstatic Lknode menunode;
  1201. X
  1202. X#define inststr(X) inststrlen((X),-1)
  1203. X
  1204. Xint usetab() /**/
  1205. X{
  1206. Xchar *s = line+cs-1;
  1207. X
  1208. X    for (; s >= line && *s != '\n'; s--)
  1209. X        if (*s != '\t' && *s != ' ')
  1210. X            return 0;
  1211. X    return 1;
  1212. X}
  1213. X
  1214. X#define COMP_COMPLETE 0
  1215. X#define COMP_LIST_COMPLETE 1
  1216. X#define COMP_SPELL 2
  1217. X#define COMP_EXPAND 3
  1218. X#define COMP_EXPAND_COMPLETE 4
  1219. X#define COMP_LIST_EXPAND 5
  1220. X#define COMP_ISEXPAND(X) ((X) >= COMP_EXPAND)
  1221. X
  1222. Xvoid completeword() /**/
  1223. X{
  1224. X    usemenu = isset(MENUCOMPLETE) || (useglob = isset(GLOBCOMPLETE));
  1225. X    if (c == '\t' && usetab())
  1226. X        selfinsert();
  1227. X    else
  1228. X        docomplete(COMP_COMPLETE);
  1229. X}
  1230. X
  1231. Xvoid menucompleteword() /**/
  1232. X{
  1233. X    usemenu = 1; useglob = isset(GLOBCOMPLETE);
  1234. X    if (c == '\t' && usetab())
  1235. X        selfinsert();
  1236. X    else
  1237. X        docomplete(COMP_COMPLETE);
  1238. X}
  1239. X
  1240. Xvoid listchoices() /**/
  1241. X{
  1242. X    usemenu = isset(MENUCOMPLETE) || (useglob = isset(GLOBCOMPLETE));
  1243. X    docomplete(COMP_LIST_COMPLETE);
  1244. X}
  1245. X
  1246. Xvoid spellword() /**/
  1247. X{
  1248. X    usemenu = useglob = 0;
  1249. X    docomplete(COMP_SPELL);
  1250. X}
  1251. X
  1252. Xvoid deletecharorlist() /**/
  1253. X{
  1254. X    usemenu = isset(MENUCOMPLETE) || (useglob = isset(GLOBCOMPLETE));
  1255. X    if (cs != ll)
  1256. X        deletechar();
  1257. X    else
  1258. X        docomplete(COMP_LIST_COMPLETE);
  1259. X}
  1260. X
  1261. Xvoid expandword() /**/
  1262. X{
  1263. X    usemenu = useglob = 0;
  1264. X    if (c == '\t' && usetab())
  1265. X        selfinsert();
  1266. X    else
  1267. X        docomplete(COMP_EXPAND);
  1268. X}
  1269. X
  1270. Xvoid expandorcomplete() /**/
  1271. X{
  1272. X    usemenu = isset(MENUCOMPLETE) || (useglob = isset(GLOBCOMPLETE));
  1273. X    if (c == '\t' && usetab())
  1274. X        selfinsert();
  1275. X    else
  1276. X        docomplete(COMP_EXPAND_COMPLETE);
  1277. X}
  1278. X
  1279. Xvoid menuexpandorcomplete() /**/
  1280. X{
  1281. X    usemenu = 1; useglob = isset(GLOBCOMPLETE);
  1282. X    if (c == '\t' && usetab())
  1283. X        selfinsert();
  1284. X    else
  1285. X        docomplete(COMP_EXPAND_COMPLETE);
  1286. X}
  1287. X
  1288. Xvoid listexpand() /**/
  1289. X{
  1290. X    usemenu = isset(MENUCOMPLETE); useglob = isset(GLOBCOMPLETE);
  1291. X    docomplete(COMP_LIST_EXPAND);
  1292. X}
  1293. X
  1294. Xvoid reversemenucomplete() /**/
  1295. X{
  1296. Xchar *s;
  1297. X
  1298. X    if (!menucmp)
  1299. X        menucompleteword();    /* better than just feep'ing, pem */
  1300. X    if (!menucmp) return;
  1301. X    cs = menub;
  1302. X    foredel(menue-menub);
  1303. X    if (menunode == firstnode(menulist))
  1304. X        menunode = lastnode(menulist);
  1305. X    else
  1306. X        menunode = prevnode(menunode);
  1307. X    inststr(s = menunode->dat);
  1308. X    menue = cs;
  1309. X}
  1310. X
  1311. X/*
  1312. X * Accepts the current completion and starts a new arg,
  1313. X * with the next completions. This gives you a way to accept
  1314. X * several selections from the list of matches.
  1315. X */
  1316. Xvoid acceptandmenucomplete() /**/
  1317. X{
  1318. Xint t0,t1;
  1319. X
  1320. X    if (!menucmp) {
  1321. X        feep();
  1322. X        return;
  1323. X    }
  1324. X    spaceinline(1);
  1325. X    line[cs++] = ' ';
  1326. X    spaceinline(menub-menuw);
  1327. X    t1 = cs;
  1328. X    for (t0 = menuw; t0 != menub; t0++)
  1329. X        line[cs++] = line[t0];
  1330. X    menue = menub = cs;
  1331. X    menuw = t1;
  1332. X    menucompleteword();
  1333. X}
  1334. X
  1335. Xstatic char *lastmenu = NULL;
  1336. Xstatic int lastmenupos = -1;
  1337. Xstatic int lincmd,lastambig;
  1338. Xstatic char *cmdstr;
  1339. X
  1340. Xvoid docomplete(lst) /**/
  1341. Xint lst;
  1342. X{
  1343. Xchar *s;
  1344. X
  1345. X    if (isset(AUTOMENU) && !menucmp && c == '\t' &&
  1346. X        (lastcmd & ZLE_MENUCMP) && lastambig) usemenu = 1;
  1347. X    if (menucmp) { do_menucmp(lst); return; }
  1348. X    if (doexpandhist()) return;
  1349. X    s = get_comp_string();
  1350. X    if (s) {
  1351. X        if (lst == COMP_EXPAND_COMPLETE) {
  1352. X            char *q = s;
  1353. X
  1354. X            if (*q == Tilde) q++;
  1355. X            else if (*q == Equals) {
  1356. X                for (q++; *q; q++)
  1357. X                    if (*q == '/')
  1358. X                        break;
  1359. X                if (!*q)
  1360. X                    lst = COMP_EXPAND;
  1361. X                q = s+1;
  1362. X            } else {
  1363. X                for (; *q && *q != String; q++);
  1364. X                if (*q == String) {
  1365. X                    if (getsparam(q+1)) lst = COMP_EXPAND;
  1366. X                    else lst = COMP_COMPLETE;
  1367. X                }
  1368. X                q = s;
  1369. X            }
  1370. X            if (lst == COMP_EXPAND_COMPLETE) {
  1371. X                for (; *q; q++)
  1372. X                    if (itok(*q))
  1373. X                        break;
  1374. X                if (!*q)
  1375. X                    lst = COMP_COMPLETE;
  1376. X            }
  1377. X        }
  1378. X        if (lst == COMP_SPELL) {
  1379. X            char    **x = &s;
  1380. X            untokenize(s);
  1381. X            cs = wb;
  1382. X            foredel(we-wb);
  1383. X            /* call the real spell checker, ash@aaii.oz.zu */
  1384. X            spckword(x, NULL, NULL, lincmd, 0);
  1385. X            inststr(*x);
  1386. X        } else if (COMP_ISEXPAND(lst))
  1387. X            doexpansion(s,lst,lincmd);
  1388. X        else {
  1389. X            docompletion(s,lst,lincmd);
  1390. X        }
  1391. X        free(s);
  1392. X    }
  1393. X    popheap();
  1394. X    lexrestore();
  1395. X}
  1396. X
  1397. Xvoid do_menucmp(lst) /**/
  1398. Xint lst;
  1399. X{
  1400. Xchar *s;
  1401. X
  1402. X    if (isset(LASTMENU) && lastmenu) {
  1403. X        if (COMP_ISEXPAND(lst) || cs != lastmenupos ||
  1404. X                strcmp(line, lastmenu) != 0) {
  1405. X            free(lastmenu);
  1406. X            lastmenu = NULL;
  1407. X            lastmenupos = -1;
  1408. X            freemenu();
  1409. X        }
  1410. X    }
  1411. X    if (lst == COMP_LIST_COMPLETE) {
  1412. X        listmatches(menulist, NULL);
  1413. X        return;
  1414. X    }
  1415. X    cs = menub;
  1416. X    foredel(menue-menub);
  1417. X    incnode(menunode);
  1418. X    if (!menunode)
  1419. X        menunode = firstnode(menulist);
  1420. X    s = menunode->dat;
  1421. X    if (*s == '~' || *s == '=' || *s == '$') {
  1422. X        spaceinline(1);
  1423. X        line[cs++] = *s++;
  1424. X    }
  1425. X    inststr(s = menunode->dat);
  1426. X    if (isset(LASTMENU)) {
  1427. X        if (lastmenu) free(lastmenu);
  1428. X        lastmenu = ztrdup(line);
  1429. X        lastmenupos = cs;
  1430. X    }
  1431. X    menue = cs;
  1432. X}
  1433. X
  1434. Xchar *get_comp_string() /**/
  1435. X{
  1436. Xint t0;
  1437. Xchar *s,*linptr;
  1438. X
  1439. X    linptr = line;
  1440. Xstart:
  1441. X    lincmd = incmdpos;
  1442. X    cmdstr = NULL;
  1443. X    zleparse = 1;
  1444. X    lexsave();
  1445. X    hungets(" "); /* KLUDGE! */
  1446. X    hungets(linptr);
  1447. X    strinbeg();
  1448. X    pushheap();
  1449. X    do {
  1450. X        lincmd = incmdpos;
  1451. X        ctxtlex();
  1452. X        if (tok == ENDINPUT) break;
  1453. X        if (lincmd) cmdstr = strdup(tokstr);
  1454. X    } while (tok != ENDINPUT && zleparse);
  1455. X    t0 = tok;
  1456. X    if (t0 == ENDINPUT) {
  1457. X        s = ztrdup("");
  1458. X        we = wb = cs;
  1459. X        t0 = STRING;
  1460. X    } else if (t0 == STRING) {
  1461. X        s = ztrdup(tokstr);
  1462. X    } else if (t0 == ENVSTRING) {
  1463. X        for (s = tokstr; *s && *s != '='; s++, wb++);
  1464. X        if (*s) { s++; wb++; t0 = STRING; s = ztrdup(s); }
  1465. X        lincmd = 1;
  1466. X    }
  1467. X    hflush();
  1468. X    strinend();
  1469. X    errflag = zleparse = 0;
  1470. X    if (we > ll) we = ll;
  1471. X    if (t0 == LEXERR && parbegin != -1) {
  1472. X        linptr += ll+1-parbegin;
  1473. X        popheap();
  1474. X        lexrestore();
  1475. X        goto start;
  1476. X    }
  1477. X    if (t0 != STRING) { feep(); return NULL; }
  1478. X    return s;
  1479. X}
  1480. X
  1481. Xvoid doexpansion(s,lst,lincmd) /**/
  1482. Xchar *s;int lst;int lincmd;
  1483. X{
  1484. XLklist vl = newlist();
  1485. Xchar *ss;
  1486. X
  1487. X    pushheap();
  1488. X    addnode(vl,s);
  1489. X    prefork(vl);
  1490. X    if (errflag)
  1491. X        goto end;
  1492. X    postfork(vl,1);
  1493. X    if (errflag)
  1494. X        goto end;
  1495. X    if (!full(vl) || !*(char *) peekfirst(vl)) {
  1496. X        feep();
  1497. X        goto end;
  1498. X    }
  1499. X    if (lst == COMP_LIST_EXPAND) {
  1500. X        listmatches(vl,NULL);
  1501. X        goto end;
  1502. X    } else if (peekfirst(vl) == s) {
  1503. X        if (lst == COMP_EXPAND_COMPLETE) {
  1504. X            docompletion(s,COMP_COMPLETE,lincmd);
  1505. X        } else
  1506. X            feep();
  1507. X        goto end;
  1508. X    }
  1509. X    cs = wb;
  1510. X    foredel(we-wb);
  1511. X    while (ss = ugetnode(vl)) {
  1512. X        untokenize(ss);
  1513. X        inststr(ss);
  1514. X        if (full(vl)) {
  1515. X            spaceinline(1);
  1516. X            line[cs++] = ' ';
  1517. X        }
  1518. X    }
  1519. Xend:
  1520. X    popheap();
  1521. X    setterm();
  1522. X}
  1523. X
  1524. Xvoid gotword(s) /**/
  1525. Xchar *s;
  1526. X{
  1527. X    we = ll+1-inbufct;
  1528. X    if (cs <= we)
  1529. X        {
  1530. X        wb = ll-wordbeg;
  1531. X        zleparse = 0;
  1532. X        /* major hack ahead */
  1533. X        if (wb && line[wb] == '!' && line[wb-1] == '\\')
  1534. X            wb--;
  1535. X        }
  1536. X}
  1537. X
  1538. Xvoid inststrlen(s,l) /**/
  1539. Xchar *s;int l;
  1540. X{
  1541. Xchar *t,*u,*v;
  1542. X
  1543. X    t = halloc(strlen(s)*2+2);
  1544. X    u = s;
  1545. X    v = t;
  1546. X    for (; *u; u++)
  1547. X        {
  1548. X        if (l != -1 && !l--)
  1549. X            break;
  1550. X        if (ispecial(*u))
  1551. X            if (*u == '\n')
  1552. X                {
  1553. X                *v++ = '\'';
  1554. X                *v++ = '\n';
  1555. X                *v++ = '\'';
  1556. X                continue;
  1557. X                }
  1558. X            else
  1559. X                *v++ = '\\';
  1560. X        *v++ = *u;
  1561. X        }
  1562. X    *v = '\0';
  1563. X    spaceinline(strlen(t));
  1564. X    strncpy(line+cs,t,strlen(t));
  1565. X    cs += strlen(t);
  1566. X}
  1567. X
  1568. Xstatic int ambig,haspath,exact;
  1569. Xstatic Lklist matches;
  1570. Xstatic char *pat;
  1571. Xstatic int typechar;
  1572. X
  1573. Xvoid addmatch(s) /**/
  1574. Xchar *s;
  1575. X{
  1576. X    if (full(matches))
  1577. X        {
  1578. X        int y = pfxlen(peekfirst(matches),s);
  1579. X
  1580. X        if (y < ambig)
  1581. X            ambig = y;
  1582. X        }
  1583. X    else
  1584. X        ambig = strlen(s);
  1585. X    if (!strcmp(pat,s))
  1586. X        exact = 1;
  1587. X    addnodeinorder(matches,strdup(s));
  1588. X}
  1589. X
  1590. X
  1591. Xvoid addcmdmatch(s,t) /**/
  1592. Xchar *s;char *t;
  1593. X{
  1594. X    if (strpfx(pat,s))
  1595. X        addmatch(s);
  1596. X}
  1597. X
  1598. Xvoid addcmdnodis(s,t) /**/
  1599. Xchar *s;char *t;
  1600. X{
  1601. X    if (strpfx(pat,s) && ((Cmdnam) t)->type != DISABLED)
  1602. X        addmatch(s);
  1603. X}
  1604. X
  1605. Xvoid maketildelist(s) /**/
  1606. Xchar    *s;
  1607. X{
  1608. X    struct passwd    *pwd;
  1609. X    int        len;
  1610. X
  1611. X    s++;
  1612. X    len = strlen(s);
  1613. X    if (len < 1) {
  1614. X        addmatch(s);
  1615. X        *s = 0;
  1616. X        return;
  1617. X    }
  1618. X    while ((pwd = getpwent()) != NULL && !errflag)
  1619. X        if (strncmp(pwd->pw_name, s, len) == 0)
  1620. X            addmatch(pwd->pw_name);
  1621. X    endpwent();
  1622. X    *s = 0;
  1623. X}
  1624. X
  1625. X/*
  1626. X * opendir that handles '~' and '=' and '$'.
  1627. X * orig. by ash@aaii.oz.au, mod. by pf
  1628. X */
  1629. XDIR *OPENDIR(s)
  1630. Xchar    *s;
  1631. X{
  1632. X    if (*s != '~' && *s != '=' && *s != '$')
  1633. X        return(opendir(s));
  1634. X    s = strdup(s);
  1635. X    *s = (*s == '=') ? Equals : (*s == '~') ? Tilde : String;
  1636. X    singsub(&s);
  1637. X    return(opendir(s));
  1638. X}
  1639. Xchar *dirname(s)
  1640. Xchar    *s;
  1641. X{
  1642. X    if (*s == '~' || *s == '=' || *s == '$') {
  1643. X      s = strdup(s);
  1644. X      *s = (*s == '=') ? Equals : (*s == '~') ? Tilde : String;
  1645. X      singsub(&s);
  1646. X    }
  1647. X    return(s);
  1648. X}
  1649. X
  1650. Xint Isdir(s) /**/
  1651. Xchar *s;
  1652. X{
  1653. Xstruct stat sbuf;
  1654. X
  1655. X   if (stat(s,&sbuf) == -1)
  1656. X      return 0;
  1657. X   return S_ISDIR(sbuf.st_mode);
  1658. X}
  1659. X
  1660. X/* this will work whether s is tokenized or not */
  1661. Xint isdir(t,s) /**/
  1662. Xchar *t;char *s;
  1663. X{
  1664. Xchar buf[MAXPATHLEN];
  1665. X
  1666. X    if (typechar != '$')
  1667. X        sprintf(buf,"%s/%s",(s) ? s : ".",t);
  1668. X    else
  1669. X        sprintf(buf,"$%s",t);
  1670. X    s = buf;
  1671. X    if (*s != '~' && *s != '=' && *s != Tilde && *s != Equals &&
  1672. X         *s != '$' && *s != String)
  1673. X        return(Isdir(s));
  1674. X    s = strdup(s);
  1675. X    if (*s == '~' || *s == '=' || *s == '$')
  1676. X        *s = (*s == '=') ? Equals : (*s == '~') ? Tilde : String;
  1677. X    singsub(&s);
  1678. X    return(Isdir(s));
  1679. X}
  1680. X
  1681. X#define SLASH_YES   0
  1682. X#define SLASH_NO    1
  1683. X#define SLASH_MAYBE 2
  1684. X
  1685. Xint slashflag;
  1686. Xint addedstar;
  1687. Xchar *pathprefix;
  1688. X
  1689. Xvoid docompletion(s,lst,incmd) /**/
  1690. Xchar *s;int lst;int incmd;
  1691. X{
  1692. Xchar *tokorigs;
  1693. Xchar *origs;
  1694. X
  1695. X    slashflag = SLASH_MAYBE;
  1696. X    addedstar = 0;
  1697. X    lastambig = 0;
  1698. X
  1699. X    heapalloc();
  1700. X    pushheap();
  1701. X    if (useglob)
  1702. X        tokorigs = strdup(s);
  1703. X    untokenize(s);
  1704. X    origs = strdup(s);
  1705. X    matches = newlist();
  1706. X    if (cmdstr && inarray(cmdstr,hostcmds)) {
  1707. X        char **x;
  1708. X        haspath = exact = 0;
  1709. X        slashflag = SLASH_NO;
  1710. X        pat = s;
  1711. X        for (x = hosts; *x; x++) addcmdmatch(*x,NULL);
  1712. X    } else if (cmdstr && inarray(cmdstr,optcmds)) {
  1713. X        struct option *o;
  1714. X        haspath = exact = 0;
  1715. X        slashflag = SLASH_NO;
  1716. X        pat = s;
  1717. X        for (o = optns; o->name; o++) addcmdmatch(o->name,NULL);
  1718. X    } else if (cmdstr && inarray(cmdstr,varcmds)) {
  1719. X        haspath = exact = 0;
  1720. X        slashflag = SLASH_NO;
  1721. X        pat = s;
  1722. X        listhtable(paramtab,addcmdmatch);
  1723. X    } else if (cmdstr && inarray(cmdstr,bindcmds)) {
  1724. X        int t0;
  1725. X        haspath = exact = 0;
  1726. X        slashflag = SLASH_NO;
  1727. X        pat = s;
  1728. X        for (t0 = 0; t0 != ZLECMDCOUNT; t0++)
  1729. X            if (*zlecmds[t0].name) addcmdmatch(zlecmds[t0].name,NULL);
  1730. X    } else {
  1731. X        gen_matches_reg(s,incmd);
  1732. X        /* only do "globbed" completion if regular completion fails.
  1733. X           pem, 7Oct91 */
  1734. X        if ((!full(matches) || errflag) && useglob) {
  1735. X            gen_matches_glob(tokorigs,incmd);
  1736. X            /*
  1737. X             * gen_matches_glob changes the insert line to be correct up
  1738. X             * to the match, so the prefix string must be "". ash, 7Oct91
  1739. X             */
  1740. X            *s = 0;
  1741. X        }
  1742. X    }
  1743. X    if (lst != COMP_LIST_COMPLETE) do_fignore(origs);
  1744. X    if (!full(matches) || errflag) {
  1745. X        feep();
  1746. X    } else if (lst == COMP_LIST_COMPLETE) {
  1747. X        listmatches(matches,
  1748. X            unset(LISTTYPES) ? NULL :
  1749. X                (haspath) ? pathprefix : "./");
  1750. X    } else if (nextnode(firstnode(matches))) {
  1751. X        do_ambiguous(s);
  1752. X    } else {
  1753. X        do_single(s);
  1754. X    }
  1755. X    ll = strlen(line);
  1756. X    setterm();
  1757. X    popheap();
  1758. X    permalloc();
  1759. X}
  1760. X
  1761. Xvoid gen_matches_glob(s,incmd) /**/
  1762. Xchar *s;int incmd;
  1763. X{
  1764. Xchar *pt,*u;
  1765. Xint hasp = 0;
  1766. XDIR *d;
  1767. Xstruct direct *de;
  1768. X
  1769. X    /*
  1770. X     * Find the longest prefix string without any
  1771. X     * chars special to glob - ash.
  1772. X     */
  1773. X    for (pt = s; *pt; pt++) {
  1774. X        if (pt == s && (*pt == Tilde || *pt == Equals)) continue;
  1775. X        if (ispecial(*pt) || itok(*pt)) break;
  1776. X    }
  1777. X    for (; pt > s && *pt != '/'; pt--) ;
  1778. X    if (*pt == '/') {
  1779. X        *pt = 0;
  1780. X        u = pt + 1;
  1781. X        wb += strlen(s);
  1782. X        hasp = 1;
  1783. X    } else u = s;
  1784. X    if (!hasp && (*s == Tilde || *s == Equals)) {
  1785. X        /* string contains only ~xx, so do tilde expansion */
  1786. X        maketildelist(s);
  1787. X        wb++;
  1788. X        pathprefix = s;
  1789. X        slashflag = SLASH_YES;
  1790. X    } else if (incmd && !hasp) {
  1791. X        slashflag = SLASH_NO;
  1792. X        pat = s;
  1793. X        listhtable(aliastab ,addcmdmatch);
  1794. X        listhtable(cmdnamtab,addcmdnodis);
  1795. X        if (d = opendir(".")) {
  1796. X            char *q;
  1797. X
  1798. X            readdir(d); readdir(d);
  1799. X            while ((de = readdir(d)) && !errflag)
  1800. X                if (strpfx(pat,q = de->d_name) &&
  1801. X                            (*q != '.' || *u == '.' || isset(GLOBDOTS)))
  1802. X                    addmatch(q);
  1803. X            closedir(d);
  1804. X        }
  1805. X    } else {
  1806. X         int     commonprefix = 0;
  1807. X         char    *prefix;
  1808. X         Lknode    n;
  1809. X         int        nonomatch = isset(NONOMATCH);
  1810. X
  1811. X         opts[NONOMATCH] = 1;
  1812. X         if (hasp) {
  1813. X            /* Find the longest common prefix string
  1814. X             * after globbing the input. All expansions
  1815. X             * ~foo/bar/* will turn into something like
  1816. X             * /tmp_mnt/hosts/somehost/home/foo/...
  1817. X             * We will remove this common prefix from the matches.
  1818. X             * ash, 7 May '91
  1819. X             */
  1820. X            pathprefix = s;
  1821. X            addnode(matches,s);
  1822. X            prefork(matches);
  1823. X            if (!errflag) postfork(matches,1);
  1824. X            if (!errflag) {
  1825. X                prefix = peekfirst(matches);
  1826. X                if (prefix) commonprefix = strlen(prefix) + 1;
  1827. X                *pt = '/';
  1828. X            }
  1829. X        }
  1830. X        if (s[strlen(s) - 1] == '/') {
  1831. X            /* if strings ends in a '/' always add a '*' */
  1832. X            s = dyncat(s,"x");
  1833. X            s[strlen(s)-1] = Star;
  1834. X            addedstar = 1;
  1835. X        }
  1836. X        matches = newlist();
  1837. X        addnode(matches,s);
  1838. X        prefork(matches);
  1839. X        if (!errflag) postfork(matches,1);
  1840. X        opts[NONOMATCH] = nonomatch;
  1841. X        if (errflag || !full(matches) || !nextnode(firstnode(matches))) {
  1842. X            /* if there were no matches (or only one)
  1843. X                add a trailing * and try again */
  1844. X            s = dyncat(s,"x");
  1845. X            s[strlen(s)-1] = Star;
  1846. X            addedstar = 1;
  1847. X            matches = newlist();
  1848. X            addnode(matches,s);
  1849. X            prefork(matches);
  1850. X            if (errflag) return;
  1851. X            postfork(matches,1);
  1852. X            if (errflag) return;
  1853. X        }
  1854. X        /* remove the common prefix from all the matches */
  1855. X        if (commonprefix)
  1856. X            for (n = firstnode(matches); n; incnode(n))
  1857. X                n->dat = (char *) n->dat+commonprefix;
  1858. X        s = pt;
  1859. X        *s = 0;
  1860. X    }
  1861. X}
  1862. X
  1863. Xvoid gen_matches_reg(s,incmd) /**/
  1864. Xchar *s;int incmd;
  1865. X{
  1866. Xchar *u;
  1867. XDIR *d;
  1868. Xstruct direct *de;
  1869. X
  1870. X    haspath = exact = 0;
  1871. X    for (u = s+strlen(s); u >= s; u--)
  1872. X        if (*u == '/' || *u == '@' || *u == '$') break;
  1873. X    typechar = *u;
  1874. X    if (u >= s) {
  1875. X        *u++ = '\0';
  1876. X        haspath = 1;
  1877. X    } else u = s;
  1878. X    pat = u;
  1879. X    if (typechar == '$' && haspath) {
  1880. X        /* slashflag = SLASH_NO; */
  1881. X        listhtable(paramtab,addcmdmatch);
  1882. X    } else if (typechar == '@' && haspath) {
  1883. X        char **x;
  1884. X        slashflag = SLASH_NO;
  1885. X        for (x = hosts; *x; x++) addcmdmatch(*x,NULL);
  1886. X    } else if (*s == '~' && !haspath) {
  1887. X        maketildelist(s);
  1888. X        pathprefix = s;
  1889. X        slashflag = SLASH_YES;
  1890. X    } else if (incmd && !haspath) {
  1891. X        slashflag = SLASH_NO;
  1892. X        listhtable(aliastab ,addcmdmatch);
  1893. X        listhtable(cmdnamtab,addcmdnodis);
  1894. X        if (d = opendir(".")) {
  1895. X            char *q;
  1896. X            struct stat buf;
  1897. X
  1898. X            readdir(d); readdir(d);
  1899. X            while ((de = readdir(d)) && !errflag)
  1900. X                if (strpfx(pat,q = de->d_name) &&
  1901. X                        (*q != '.' || *u == '.' || isset(GLOBDOTS)) &&
  1902. X                        stat(q,&buf) >= 0 &&
  1903. X                        (buf.st_mode & (S_IFMT|S_IEXEC)) == (S_IFREG|S_IEXEC))
  1904. X                    addmatch(q);
  1905. X            closedir(d);
  1906. X        }
  1907. X    } else if (d = OPENDIR(pathprefix =
  1908. X            ((haspath || *s == '~') ? ((*s) ? s : "/") : "."))) {
  1909. X        char *q,buf2[MAXPATHLEN];
  1910. X        struct stat buf;
  1911. X        char dn[MAXPATHLEN];
  1912. X        
  1913. X        strcpy(dn,dirname(pathprefix));
  1914. X        readdir(d); readdir(d);
  1915. X        while ((de = readdir(d)) && !errflag)
  1916. X          if (strpfx(pat,q = de->d_name) &&
  1917. X                (*q != '.' || *u == '.' || isset(GLOBDOTS))) {
  1918. X             if (incmd) {
  1919. X                sprintf(buf2,"%s/%s",dn,q);
  1920. X                if (stat(buf2,&buf) < 0 ||
  1921. X                     (buf.st_mode & S_IEXEC) == S_IEXEC) {
  1922. X                  addmatch(q);
  1923. X                }
  1924. X             } else {
  1925. X                addmatch(q);
  1926. X             }
  1927. X          }
  1928. X        closedir(d);
  1929. X    }
  1930. X}
  1931. X
  1932. Xvoid do_fignore(origstr) /**/
  1933. Xchar *origstr;
  1934. X{
  1935. X    if (full(matches) && nextnode(firstnode(matches))) {
  1936. X        Lknode z,zn;
  1937. X
  1938. X        for (z = firstnode(matches); z; z = zn) {
  1939. X            char *q = getdata(z);
  1940. X            int namlen = strlen(q);
  1941. X            int    slen = strlen(origstr);
  1942. X            char **pt = fignore;
  1943. X    
  1944. X            zn = nextnode(z);
  1945. X            for (; *pt; pt++) {
  1946. X                /* We try to be smart here and override the
  1947. X                   fignore variable if the user has explicity
  1948. X                   used the ignored prefix, pem, 7 May 1991 */
  1949. X                if (!addedstar && strcmp(origstr+slen-strlen(*pt), *pt) == 0)
  1950. X                    continue;
  1951. X                if (strlen(*pt) < namlen && !strcmp(q+namlen-strlen(*pt),*pt)) {
  1952. X                    uremnode(matches,z);
  1953. X                    break;
  1954. X                }
  1955. X            }
  1956. X        }
  1957. X    }
  1958. X}
  1959. X
  1960. Xvoid do_ambiguous(s) /**/
  1961. Xchar *s;
  1962. X{
  1963. X    lastambig = 1;
  1964. X    if (usemenu) { do_ambig_menu(s); return; }
  1965. X    if (useglob) {
  1966. X        feep();
  1967. X        if (isset(AUTOLIST))
  1968. X            listmatches(matches,
  1969. X                unset(LISTTYPES) ? NULL : (haspath) ? pathprefix : "./");
  1970. X        return;
  1971. X    }
  1972. X    cs = wb;
  1973. X    foredel(we-wb);
  1974. X    if (*s == '~' || *s == '=' || *s == '$') {
  1975. X        spaceinline(1);
  1976. X        line[cs++] = *s++;
  1977. X    }
  1978. X    if (haspath) {
  1979. X        inststr(s);
  1980. X        spaceinline(1);
  1981. X        line[cs++] = typechar;
  1982. X    }
  1983. X    if (isset(RECEXACT) && exact) {
  1984. X        lastambig = 0;
  1985. X        if ((*pat == '~' || *pat == '=' || *pat == '$') && !haspath) {
  1986. X            spaceinline(1);
  1987. X            line[cs++] = *s++;
  1988. X        }
  1989. X        inststr(pat);
  1990. X        spaceinline(1);
  1991. X        switch (slashflag) {
  1992. X            case SLASH_YES: line[cs++] = '/'; break;
  1993. X            case SLASH_NO : line[cs++] = ' '; break;
  1994. X            case SLASH_MAYBE: line[cs++] = isdir(pat,pathprefix)?'/':' '; break;
  1995. X        }
  1996. X        return;
  1997. X    }
  1998. X    s = peekfirst(matches);
  1999. X    if ((*s == '~' || *s == '=' || *s == '$') && !haspath) {
  2000. X        spaceinline(1);
  2001. X        line[cs++] = *s++;
  2002. X        ambig--;
  2003. X    }
  2004. X    inststrlen(s,ambig);
  2005. X    refresh();
  2006. X    if (isset(AUTOLIST)) {
  2007. X        if (unset(NOLISTBEEP)) feep();
  2008. X        listmatches(matches,
  2009. X            unset(LISTTYPES) ? NULL : (haspath) ? pathprefix : "./");
  2010. X    } else feep();
  2011. X}
  2012. X
  2013. Xvoid do_single(s) /**/
  2014. Xchar *s;
  2015. X{
  2016. X    cs = wb;
  2017. X    foredel(we-wb);
  2018. X    if (*s == '~' || *s == '=' || *s == '$') {
  2019. X        spaceinline(1);
  2020. X        line[cs++] = *s++;
  2021. X    }
  2022. X    if (haspath) {
  2023. X        inststr(s);
  2024. X        spaceinline(1);
  2025. X        line[cs++] = typechar;
  2026. X    }
  2027. X    s = peekfirst(matches);
  2028. X    if ((*s == '~' || *s == '=' || *s == '$') && !haspath) {
  2029. X        spaceinline(1);
  2030. X        line[cs++] = *s++;
  2031. X    }
  2032. X    inststr(s);
  2033. X    spaceinline(1);
  2034. X    switch (slashflag) {
  2035. X        case SLASH_YES: line[cs++] = '/'; break;
  2036. X        case SLASH_NO : line[cs++] = ' '; break;
  2037. X        case SLASH_MAYBE: line[cs++] = isdir(s,pathprefix) ? '/' : ' '; break;
  2038. X    }
  2039. X}
  2040. X
  2041. Xvoid do_ambig_menu(s) /**/
  2042. Xchar *s;
  2043. X{
  2044. X    menucmp = 1;
  2045. X    if (isset(MENUCOMPLETEBEEP)) feep();
  2046. X    cs = wb;
  2047. X    menuw = cs;
  2048. X    foredel(we-wb);
  2049. X    if (*s == '~' || *s == '=' || *s == '$') {
  2050. X        spaceinline(1);
  2051. X        line[cs++] = *s++;
  2052. X    }
  2053. X    if (haspath) {
  2054. X        inststr(s);
  2055. X        spaceinline(1);
  2056. X        line[cs++] = typechar;
  2057. X    }
  2058. X    menub = cs;
  2059. X    s = peekfirst(matches);
  2060. X    if ((*s == '~' || *s == '=' || *s == '$') && !haspath) {
  2061. X        spaceinline(1);
  2062. X        line[cs++] = *s++;
  2063. X    }
  2064. X    inststr(s);
  2065. X    menue = cs;
  2066. X    permalloc();
  2067. X    menulist = duplist(matches,(VFunc)ztrdup);
  2068. X    heapalloc();
  2069. X    menunode = firstnode(menulist);
  2070. X    permalloc();
  2071. X    if (isset(LASTMENU)) {
  2072. X        if (lastmenu)
  2073. X            free(lastmenu);
  2074. X        lastmenu = ztrdup(line);
  2075. X        lastmenupos = cs;
  2076. X    }
  2077. X}
  2078. X
  2079. Xint strpfx(s,t) /**/
  2080. Xchar *s;char *t;
  2081. X{
  2082. X    while (*s && *s == *t) s++,t++;
  2083. X    return !*s;
  2084. X}
  2085. X
  2086. Xint pfxlen(s,t) /**/
  2087. Xchar *s;char *t;
  2088. X{
  2089. Xint i = 0;
  2090. X
  2091. X    while (*s && *s == *t) s++,t++,i++;
  2092. X    return i;
  2093. X}
  2094. X
  2095. Xvoid listmatches(l,apps) /**/
  2096. XLklist l;char *apps;
  2097. X{
  2098. Xint longest = 1,fct,fw = 0,colsz,t0,t1,ct;
  2099. XLknode n;
  2100. Xchar **arr,**ap;
  2101. X
  2102. X    trashzle();
  2103. X    ct = countnodes(l);
  2104. X    if (listmax && ct > listmax)
  2105. X        {
  2106. X        fprintf(stdout,"zsh: do you wish to see all %d possibilities? ",ct);
  2107. X        fflush(stdout);
  2108. X        if (getquery() != 'y')
  2109. X            return;
  2110. X        }
  2111. X    ap = arr = alloc((countnodes(l)+1)*sizeof(char **));
  2112. X    for (n = firstnode(l); n; incnode(n))
  2113. X        *ap++ = getdata(n);
  2114. X    *ap = NULL;
  2115. X    for (ap = arr; *ap; ap++)
  2116. X        if (strlen(*ap) > longest)
  2117. X            longest = strlen(*ap);
  2118. X    if (apps)
  2119. X        {
  2120. X        apps = strdup(apps);
  2121. X        if (*apps == '~')
  2122. X            *apps = Tilde;
  2123. X        else if (*apps == '=')
  2124. X            *apps = Equals;
  2125. X        else if (*apps == '$')
  2126. X            *apps = String;
  2127. X        singsub(&apps);
  2128. X        longest++;
  2129. X        }
  2130. X    qsort(arr,ct,sizeof(char *),forstrcmp);
  2131. X    fct = (columns-1)/(longest+2);
  2132. X    if (fct == 0)
  2133. X        fct = 1;
  2134. X    else
  2135. X        fw = (columns-1)/fct;
  2136. X    colsz = (ct+fct-1)/fct;
  2137. X    for (t1 = 0; t1 != colsz; t1++)
  2138. X        {
  2139. X        ap = arr+t1;
  2140. X        if (apps)
  2141. X            {
  2142. X            do
  2143. X                {
  2144. X                int t2 = strlen(*ap)+1;
  2145. X                char pbuf[MAXPATHLEN];
  2146. X                struct stat buf;
  2147. X
  2148. X                printf("%s",*ap);
  2149. X                sprintf(pbuf,"%s/%s",apps,*ap);
  2150. X                if (lstat(pbuf,&buf))
  2151. X                    putchar(' ');
  2152. X                else switch (buf.st_mode & S_IFMT) /* screw POSIX */
  2153. X                    {
  2154. X                    case S_IFDIR: putchar('/'); break;
  2155. X#ifdef S_IFIFO
  2156. X                    case S_IFIFO: putchar('|'); break;
  2157. X#endif
  2158. X                    case S_IFCHR: putchar('%'); break;
  2159. X                    case S_IFBLK: putchar('#'); break;
  2160. X#ifdef S_IFLNK
  2161. X                    case S_IFLNK: putchar(
  2162. X                        (access(pbuf,F_OK) == -1) ? '&' : '@'); break;
  2163. X#endif
  2164. X#ifdef S_IFSOCK
  2165. X                    case S_IFSOCK: putchar('='); break;
  2166. X#endif
  2167. X                    default:
  2168. X                        if (buf.st_mode & 0111)
  2169. X                            putchar('*');
  2170. X                        else
  2171. X                            putchar(' ');
  2172. X                        break;
  2173. X                    }
  2174. X                for (; t2 < fw; t2++) putchar(' ');
  2175. X                for (t0 = colsz; t0 && *ap; t0--,ap++);
  2176. X                }
  2177. X            while (*ap);
  2178. X            }
  2179. X        else
  2180. X            do
  2181. X                {
  2182. X                int t2 = strlen(*ap);
  2183. X
  2184. X                printf("%s",*ap);
  2185. X                for (; t2 < fw; t2++) putchar(' ');
  2186. X                for (t0 = colsz; t0 && *ap; t0--,ap++);
  2187. X                }
  2188. X            while (*ap);
  2189. X        putchar('\n');
  2190. X        }
  2191. X    resetneeded = 1;
  2192. X    fflush(stdout);
  2193. X}
  2194. X
  2195. Xvoid selectlist(l) /**/
  2196. XLklist l;
  2197. X{
  2198. Xint longest = 1,fct,fw = 0,colsz,t0,t1,ct;
  2199. XLknode n;
  2200. Xchar **arr,**ap;
  2201. X
  2202. X    trashzle();
  2203. X    ct = countnodes(l);
  2204. X    ap = arr = alloc((countnodes(l)+1)*sizeof(char **));
  2205. X    for (n = firstnode(l); n; incnode(n))
  2206. X        *ap++ = getdata(n);
  2207. X    *ap = NULL;
  2208. X    for (ap = arr; *ap; ap++)
  2209. X        if (strlen(*ap) > longest)
  2210. X            longest = strlen(*ap);
  2211. X    t0 = ct;
  2212. X    longest++;
  2213. X    while (t0)
  2214. X        t0 /= 10, longest++;
  2215. X    fct = (columns-1)/(longest+2);
  2216. X    if (fct == 0)
  2217. X        fct = 1;
  2218. X    else
  2219. X        fw = (columns-1)/fct;
  2220. X    colsz = (ct+fct-1)/fct;
  2221. X    for (t1 = 0; t1 != colsz; t1++)
  2222. X        {
  2223. X        ap = arr+t1;
  2224. X        do
  2225. X            {
  2226. X            int t2 = strlen(*ap)+1,t3;
  2227. X
  2228. X            fprintf(stderr,"%d %s",t3 = ap-arr+1,*ap);
  2229. X            while (t3)
  2230. X                t2++,t3 /= 10;
  2231. X            for (; t2 < fw; t2++) fputc(' ',stderr);
  2232. X            for (t0 = colsz; t0 && *ap; t0--,ap++);
  2233. X            }
  2234. X        while (*ap);
  2235. X        fputc('\n',stderr);
  2236. X        }
  2237. X    resetneeded = 1;
  2238. X    fflush(stderr);
  2239. X}
  2240. X
  2241. Xint doexpandhist() /**/
  2242. X{
  2243. Xchar *cc,*ce;
  2244. Xint t0,oldcs,oldll;
  2245. X
  2246. X    for (cc = line, ce = line+ll; cc < ce; cc++)
  2247. X        if (*cc == '\\' && cc[1])
  2248. X            cc++;
  2249. X        else if (*cc == bangchar)
  2250. X            break;
  2251. X    if (*cc == bangchar && cc[1] == '"') return 0;
  2252. X    if (cc == ce && *line != hatchar)
  2253. X        return 0;
  2254. X    oldcs = cs;
  2255. X    oldll = ll;
  2256. X    zleparse = 1;
  2257. X    lexsave();
  2258. X    hungets(line);
  2259. X    strinbeg();
  2260. X    pushheap();
  2261. X    ll = cs = 0;
  2262. X    for(;;)
  2263. X        {
  2264. X        t0 = hgetc();
  2265. X        if (lexstop)
  2266. X            break;
  2267. X        spaceinline(1);
  2268. X        line[cs++] = t0;
  2269. X        }
  2270. X    hflush();
  2271. X    popheap();
  2272. X    strinend();
  2273. X    errflag = zleparse = 0;
  2274. X    t0 = histdone;
  2275. X    lexrestore();
  2276. X    line[ll = cs] = '\0';
  2277. X    if (ll == oldll) cs = oldcs;
  2278. X    return t0;
  2279. X}
  2280. X
  2281. Xvoid magicspace() /**/
  2282. X{
  2283. X    doexpandhist();
  2284. X    c = ' ';
  2285. X    selfinsert();
  2286. X}
  2287. X
  2288. Xvoid expandhistory() /**/
  2289. X{
  2290. X    if (!doexpandhist())
  2291. X        feep();
  2292. X}
  2293. X
  2294. Xstatic int cmdwb,cmdwe;
  2295. X
  2296. Xchar *getcurcmd() /**/
  2297. X{
  2298. Xint lincmd = incmdpos;
  2299. Xchar *s = NULL;
  2300. X
  2301. X    zleparse = 1;
  2302. X    lexsave();
  2303. X    hungets(" "); /* KLUDGE! */
  2304. X    hungets(line);
  2305. SHAR_EOF
  2306. true || echo 'restore of zsh2.1/src/zle_tricky.c failed'
  2307. fi
  2308. echo 'End of zsh2.1.0 part 13'
  2309. echo 'File zsh2.1/src/zle_tricky.c is continued in part 14'
  2310. echo 14 > _shar_seq_.tmp
  2311. exit 0
  2312.  
  2313. exit 0 # Just in case...
  2314. -- 
  2315. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2316. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2317. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2318. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2319.