home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume43 / zsh / part14 < prev    next >
Encoding:
Internet Message Format  |  1994-07-14  |  85.6 KB

  1. From: zsh-list@sterling.com (Bas de Bakker)
  2. Newsgroups: comp.sources.misc
  3. Subject: v43i103:  zsh - The Z shell, version 2.5.0, Part14/18
  4. Date: 13 Jul 1994 23:07:08 -0500
  5. Organization: Sterling Software
  6. Sender: kent@sparky.sterling.com
  7. Approved: kent@sparky.sterling.com
  8. Message-ID: <302dlc$63@sparky.sterling.com>
  9. X-Md4-Signature: 4b3464b17b6e50ee6a859e2fea66d895
  10.  
  11. Submitted-by: zsh-list@sterling.com (Bas de Bakker)
  12. Posting-number: Volume 43, Issue 103
  13. Archive-name: zsh/part14
  14. Environment: UNIX
  15. Supersedes: zsh: Volume 35, Issue 51-72
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # Contents:  zsh-2.5.0/dots/zcomp zsh-2.5.0/help/autoload
  22. #   zsh-2.5.0/src/hist.c zsh-2.5.0/src/jobs.c
  23. #   zsh-2.5.0/src/zle_bindings.c
  24. # Wrapped by kent@sparky on Tue Jul 12 16:47:25 1994
  25. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
  26. echo If this archive is complete, you will see the following message:
  27. echo '          "shar: End of archive 14 (of 18)."'
  28. if test -f 'zsh-2.5.0/dots/zcomp' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'zsh-2.5.0/dots/zcomp'\"
  30. else
  31.   echo shar: Extracting \"'zsh-2.5.0/dots/zcomp'\" \(10755 characters\)
  32.   sed "s/^X//" >'zsh-2.5.0/dots/zcomp' <<'END_OF_FILE'
  33. X# This file gives some examples of compctl commands. The name zcomp
  34. X# does not mean anything to zsh, you can either put the compctl commands
  35. X# in your .zshrc or include a separate file from your .zshrc with the
  36. X# source command.
  37. X
  38. X# These are just examples, use and modify to personal taste.  Copying this
  39. X# file without thought will needlessly increase zsh's memory usage and
  40. X# startup time.
  41. X
  42. X# For an explanation of what all this means, read either the
  43. X# introduction for some explanation or the manual for a detailed
  44. X# description.
  45. X
  46. X# Rmdir only real directories
  47. Xcompctl -g '*(/)' rmdir dircmp
  48. X
  49. X# Strip, profile, and debug only executables.  The compctls for the
  50. X# debuggers could be better, of course.
  51. Xcompctl -g '*(*)' strip gprof adb dbx xdbx ups
  52. X
  53. X# See the func/cdmatch function in the distribution
  54. Xcompctl -K cdmatch -S '/' -x 'S[/][~]' -g '*(-/)' -- cd pushd
  55. X
  56. X# For rcs users, co and rlog from the RCS directory.  We don't want to see
  57. X# the RCS and ,v though.
  58. Xcompctl -g 'RCS/*(:t:s/\,v//)' co rlog rcs
  59. X
  60. X# Run ghostscript on postscript files, but if no postscript file matches what
  61. X# we already typed, complete directories as the postscript file may not be in
  62. X# the current directory.
  63. Xcompctl -g '*.ps' + -g '*(-/)' gs ghostview psps pstops psmulti psselect
  64. X
  65. X# Similar things for tex, texinfo and dvi files.
  66. Xcompctl -g '*.tex*' + -g '*(-/)' tex latex texi2dvi glatex slitex gslitex
  67. Xcompctl -g '*.dvi' + -g '*(-/)' xdvi dvips
  68. X
  69. X# Anything after nohup is a command by itself with its own completion
  70. X# (the one for the trap builtin isn't perfect -- it does not complete
  71. X# signal names)
  72. Xcompctl -l '' nohup exec nice eval trap
  73. Xcompctl -l '' -x 'p[1]' -B -- builtin
  74. X
  75. X# If the command is rsh, make the first argument complete to hosts and treat the
  76. X# rest of the line as a command on its own.
  77. Xcompctl -k hosts -x 'p[2,-1]' -l '' -- rsh
  78. X
  79. X# kill takes signal names as the first argument after -, but job names after %
  80. Xcompctl -j -P % -x 's[-] p[1]' -k signals -- kill
  81. X
  82. X# gzip files, but gzip -d only gzipped or compressed files
  83. Xcompctl -f -x 'R[-*d,^*]' -g '*.gz *.z *.Z' + -g '*(-/)' -- gzip
  84. Xcompctl -g '*.gz *.z *.Z' + -g '*(-/)' gunzip   # zcat if you use GNU
  85. Xcompctl -g '*.Z' + -g '*(-/)' uncompress zmore  # zcat if you don't use GNU
  86. Xcompctl -g '*.F' + -g '*(-/)' melt fcat
  87. X
  88. X# find is very system dependend, this one is for GNU find.
  89. Xcompctl -x 's[-]' -k "(daystart depth follow maxdepth mindepth noleaf version xdev \
  90. Xamin anewer cmin cnewer ctime empty false fstype gid group inum links lname mmin \
  91. Xmtime name newer nouser nogroup path perm regex size true type uid used user xtype \
  92. Xexec fprint fprint0 fprintf ok print print0 printf prune ls)" - \
  93. X'p[1]' -g '. .. *(-/)' - \
  94. X'c[-1,-anewer][-1,-cnewer][-1,-newer][-1,-fprint][-1,fprint0][-1,fprintf]' -f - \
  95. X'c[-1,-fstype]' -k '(ufs 4.2 4.3 nfs tmp mfs S51K S52K)' - \
  96. X'c[-1,-group]' -s '$(groups)' - \
  97. X'c[-1,-user]' -u - \
  98. X'r[-exec,;][-ok,;]' -l '' -- find
  99. X
  100. X# xsetroot: gets possible colours, cursors and bitmaps from wherever.
  101. X# Uses two auxiliary functions.  You might need to change the path names.
  102. XXcolours() { reply=($(awk '{ print $4 }' < /usr/lib/X11/X11/rgb.txt)) }
  103. XXcursor() { reply=($(awk '/^#define/ {print $2}' \
  104. X</usr/include/X11/cursorfont.h | sed 's/^XC_//')) }
  105. Xcompctl -k '(-help -def -display -cursor -cursor_name -bitmap -mod -fg -bg
  106. X  -grey -rv -solid -name)' -x 'c[-1,-display]' -k hosts -S ':0.0' - \
  107. X  'c[-1,-cursor]' -f -  'c[-2,-cursor]' -f - \
  108. X  'c[-1,-bitmap]' -g '/usr/include/X11/bitmaps/*' - \
  109. X  'c[-1,-cursor_name]' -K Xcursor - \
  110. X  'C[-1,-(solid|fg|bg)]' -K Xcolours -- xsetroot
  111. X
  112. X# Default completion.  See func/multicomp
  113. Xcompctl -D -f + -U -K multicomp
  114. X# If completion of usernames is slow for you, you may want to add something
  115. X# like
  116. X#    -x 'C[0,*/*]' -f - 's[~]' -S/ -k users + -u
  117. X# where `users' contains the names of the users you want to complete often.
  118. X# If you want to use this and to be able to complete named directories after
  119. X# the `~' you should add `+ -n' at the end
  120. X
  121. X
  122. X# rlogin takes hosts and users after `-l'
  123. Xcompctl -k hosts -x 'c[-1,-l]' -u -- rlogin
  124. X
  125. X# su takes an username and args for the shell, the `-c' case is
  126. X# handled specially here
  127. Xcompctl -u -x 'w[2,-c] p[3,-1]' -l '' -- su
  128. X
  129. X# Some systems have directories containing indices of ftp servers.
  130. X# For example: we have the directory /home/ftp/index/INDEX containing
  131. X# files of the form `<name>-INDEX.Z', this leads to:
  132. Xcompctl -g '/home/ftp/index/INDEX/*-INDEX.Z(:t:r:s/-INDEX//)' ftp tftp
  133. X
  134. X# There are (at least) two ways to complete manual pages.  This one is
  135. X# extremely memory expensive if you have lots of man pages
  136. Xman_var() {
  137. X  man_pages=( $^manpath/man*/*(N:t:r) )   # Check your setting of SH_WORD_SPLIT
  138. X  compctl -k man_pages man
  139. X  reply=( $man_pages )
  140. X}
  141. Xcompctl -K man_var man
  142. X# This one isn't that expensive but somewhat slower
  143. Xman_glob () {
  144. X  local a
  145. X  read -cA a
  146. X  if [[ $a[2] = -s ]] then         # Or [[ $a[2] = [0-9]* ]] for BSD
  147. X    reply=( $^manpath/man$a[3]/$1*$2(N:t:r) )    # See above
  148. X  else
  149. X    reply=( $^manpath/man*/$1*$2(N:t:r) )    # See above
  150. X  fi
  151. X}
  152. Xcompctl -K man_glob man
  153. X
  154. X# Misc.
  155. Xcompctl -s '$(groups)' newgrp
  156. Xcompctl -f -x 'p[1]' -s '$(groups)' -- chgrp
  157. Xcompctl -f -x 'p[1]' -u -- chown
  158. Xcompctl -g '*.x' + -g '*(-/)' rpcgen
  159. Xcompctl -g "*.[cCoa]" -x 's[-I]' -g "*(/)" - \
  160. X  's[-l]' -s '${(s.:.)LD_LIBRARY_PATH}/lib*.a(:t:r:s/lib//)' -- cc gcc
  161. Xcompctl -f -x 'C[-1,*f*] p[2]' -g "*.tar" -- tar
  162. Xcompctl -u -x 's[+] c[-1,-f],s[-f+]' -g '~/Mail/*(:t)' - \
  163. X  's[-f],c[-1,-f]' -f -- mail elm
  164. X
  165. X# Some builtins.
  166. Xcompctl -j -P % fg bg wait jobs disown
  167. Xcompctl -A shift
  168. Xcompctl -caF type whence which
  169. Xcompctl -F unfunction
  170. Xcompctl -a unalias
  171. Xcompctl -v unset typeset declare vared readonly export integer
  172. Xcompctl -e disable
  173. Xcompctl -d enable
  174. Xcompctl -k '(cputime filesize datasize stacksize coredumpsize resident \
  175. X  memoryuse memorylocked descriptors openfiles vmemorysize)' limit ulimit
  176. Xcompctl -l '' -x 'p[1]' -f -- . source
  177. X
  178. X# Various MH completions by Peter Stephenson
  179. X# Still to do:
  180. X# Support for searching for files in standard MH locations.
  181. X
  182. X# mhcomp is best autoloaded.  Edit path where indicated.
  183. Xfunction mhcomp {
  184. X  # Completion function for MH folders.
  185. X  # Works with both + (rel. to top) and @ (rel. to current).
  186. X  local nword args pref char mhpath
  187. X  integer ngtrue
  188. X  read -nc nword
  189. X  read -cA args
  190. X
  191. X  [[ -o nullglob ]] && ngtrue=1 || setopt nullglob
  192. X
  193. X  pref=$args[$nword]
  194. X  char=$pref[1]
  195. X  pref=$pref[2,-1]
  196. X
  197. X# The `...`'s here account for most of the time spent in this function.
  198. X  if [[ $char = + ]]; then
  199. X#    mhpath=`mhpath +`
  200. X# EDIT ME:  Use a hard wired value here: it's faster.
  201. X    mhpath=~/Mail
  202. X  elif [[ $char = @ ]]; then
  203. X    mhpath=`mhpath`
  204. X  fi
  205. X
  206. X  reply="reply=($mhpath/$pref*(-/))"
  207. X  eval $reply
  208. X
  209. X  # I'm frankly amazed that this next step works, but it does.
  210. X  reply=(${reply#$mhpath/})
  211. X
  212. X  (( ngtrue )) || unsetopt nullglob
  213. X}
  214. X
  215. Xmhfseq() { set -A reply $(mark | awk -F: '{print $1}') \
  216. Xnext cur prev first last all unseen }
  217. X
  218. Xcompctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - \
  219. X  's[-]' -k '(all fast nofast header noheader help list nolist \
  220. X  pack nopack pop push recurse norecurse total nototal)' -- folder
  221. Xcompctl -K mhfseq -x 's[+][@],c[-1,-draftfolder] s[+][@]' \
  222. X  -K mhcomp -S / -q - 'c[-1,-draftmessage]' -K mhfseq - \
  223. X  'C[-1,-(editor|whatnowproc)]' -c - \
  224. X  's[-]' -k '(draftfolder draftmessage nodraftfolder editor noedit \
  225. X  file form use nouse whatnowproc nowhatnowproc help)' -- comp
  226. Xcompctl -K mhfseq + -x 's[+][@]' -K mhcomp -S / -q - \
  227. X  's[-]' -k '(audit noaudit changecur nochangecur form format \
  228. X  file silent nosilent truncate notruncate width help)' - \
  229. X  'C[-1,-(audit|form|file)]' -f -- inc
  230. Xcompctl -K mhfseq -x 's[+][@],C[-1,-src] s[+][@]' \
  231. X  -K mhcomp -S / -q - 'c[-1,-file]' -f - 'c[-1,-rmmprov]' -c - \
  232. X  's[-]' -k '(draft link nolink preserve nopreserve src file \
  233. X  rmmproc normmproc help)' -- refile
  234. Xcompctl -K mhfseq -x 's[+][@],C[-1,-(draftfolder|fcc)] s[+][@]' \
  235. X  -K mhcomp -S / -q - 'c[-1,-draftmessage]' -K mhfseq -\
  236. X  's[-]' -k '(annotate noannotate cc nocc draftfolder nodraftfolder \
  237. X  draftmessage editor noedit fcc filter form inplace noinplace query \
  238. X  noquery width whatnowproc nowhatnowproc help)' - 'c[-1,(cc|nocc)]' \
  239. X  -k '(all to cc me)' - 'C[-1,-(filter|form)]' -f - \
  240. X  'C[-1,-(editor|whatnowproc)]' -c -- repl
  241. Xcompctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - \
  242. X  's[-]' -k '(clear noclear form format header noheader reverse noreverse \
  243. X  file help width)' - 'C[-1,-(file|form)]' -f -- scan
  244. Xcompctl -K mhfseq -x 's[+][@]'  -K mhcomp -S / -q - \
  245. X  's[-]' -k '(draft header noheader showproc noshowproc)' - \
  246. X  'c[-1,showproc]' -c -- show
  247. Xcompctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - 's[-]' \
  248. X  -k '(help)' -- rmm
  249. X
  250. X# End of MH completions
  251. X
  252. X# By Bart Schaefer
  253. X# CVS -- there's almost no way to make this all-inclusive, but ...
  254. X#
  255. Xcvsflags=(-H -Q -q -r -w -l -n -t -v -b -e -d)
  256. Xcvscmds=(add admin checkout commit diff history import export log rdiff
  257. X        release remove status tag rtag update)
  258. X
  259. X# diff assumes gnu rcs using gnu diff
  260. X# log assumes gnu rcs
  261. X
  262. Xcompctl -k "($cvscmds $cvsflags)" \
  263. X    -x "c[-1,-D]" -k '(today yesterday 1\\\ week\\\ ago)' \
  264. X    - "r[add,;]" -k "(-k -m)" -f \
  265. X    - "r[admin,;]" -K cvstargets \
  266. X    - "r[checkout,;]" -k "(-A -N -P -Q -c -f -l -n -p -q -s -r -D -d -k -j)" \
  267. X    - "r[commit,;]" -k "(-n -R -l -f -m -r)"  -K cvstargets \
  268. X    - "r[diff,;]" -k "(-l -D -r -c -u -b -w)" -K cvstargets \
  269. X    - "r[history,;]" \
  270. X    -k "(-T -c -o -m -x -a -e -l -w -D -b -f -n -p -r -t -u)" \
  271. X    -K cvstargets \
  272. X    - "r[history,;] c[-1,-u]" -u \
  273. X    - "r[import,;]" -k "(-Q -q -I -b -m)" -f \
  274. X    - "r[export,;]" -k "(-N -Q -f -l -n -q -r -D -d)" -f \
  275. X    - "R[(r|)log,;]" -k "(-l -R -h -b -t -r -w)" -K cvstargets \
  276. X    - 'R[(r|)log,;] s[-w] n[-1,,],s[-w]' -u -S , -q \
  277. X    - "r[rdiff,;]" -k "(-Q -f -l -c -u -s -t -D -r -V)" -K cvstargets \
  278. X    - "r[release,;]" -k "(-Q -d -q)" -f \
  279. X    - "r[remove,;]" -k "(-l -R)" -K cvstargets \
  280. X    - "r[status,;]" -k "(-v -l -R)" -K cvstargets \
  281. X    - "r[tag,;]" -k "(-Q -l -R -q -d -b)" -K cvstargets \
  282. X    - "r[rtag,;]" -k "(-Q -a -f -l -R -n -q -d -b -r -D)" -f \
  283. X    - "r[update,;]" -k "(-A -P -Q -d -f -l -R -p -q -k -r -D -j -I)" \
  284. X    -K cvstargets \
  285. X    -- cvs
  286. Xunset cvsflags cvscmds
  287. X
  288. Xcvstargets() {
  289. X    local nword args pref ngtrue f
  290. X    [[ -o nullglob ]] && ngtrue=1
  291. X    setopt nullglob
  292. X    read -nc nword; read -Ac args
  293. X    pref=$args[$nword]
  294. X    if [[ -d $pref:h && ! -d $pref ]]
  295. X    then
  296. X    pref=$pref:h
  297. X    elif [[ $pref != */* ]]
  298. X    then
  299. X    pref=
  300. X    fi
  301. X    [[ -n "$pref" && "$pref" != */ ]] && pref=$pref/
  302. X    reply=($(for f in $(cat ${pref}CVS/Entries 2>/dev/null | \
  303. X            sed 's/^\/\([^\/]*\).*/\1/'); do echo $pref$f; done)
  304. X       $(echo ${pref}**/CVS(:h) | sed 's/CVS//'))
  305. X    [[ $ngtrue = 1 ]] || unsetopt nullglob
  306. X}
  307. END_OF_FILE
  308.   if test 10755 -ne `wc -c <'zsh-2.5.0/dots/zcomp'`; then
  309.     echo shar: \"'zsh-2.5.0/dots/zcomp'\" unpacked with wrong size!
  310.   fi
  311.   # end of 'zsh-2.5.0/dots/zcomp'
  312. fi
  313. if test -f 'zsh-2.5.0/help/autoload' -a "${1}" != "-c" ; then 
  314.   echo shar: Will not clobber existing file \"'zsh-2.5.0/help/autoload'\"
  315. else
  316.   echo shar: Extracting \"'zsh-2.5.0/help/autoload'\" \(316 characters\)
  317.   sed "s/^X//" >'zsh-2.5.0/help/autoload' <<'END_OF_FILE'
  318. X       autoload [ name ... ]
  319. X              For  each  of  the  names (which are names of func-
  320. X              tions), create a function  marked  undefined.   The
  321. X              fpath  variable will be searched to find the actual
  322. X              function definition when the function is first ref-
  323. X              erenced.
  324. END_OF_FILE
  325.   if test 316 -ne `wc -c <'zsh-2.5.0/help/autoload'`; then
  326.     echo shar: \"'zsh-2.5.0/help/autoload'\" unpacked with wrong size!
  327.   fi
  328.   # end of 'zsh-2.5.0/help/autoload'
  329. fi
  330. if test -f 'zsh-2.5.0/src/hist.c' -a "${1}" != "-c" ; then 
  331.   echo shar: Will not clobber existing file \"'zsh-2.5.0/src/hist.c'\"
  332. else
  333.   echo shar: Extracting \"'zsh-2.5.0/src/hist.c'\" \(27109 characters\)
  334.   sed "s/^X//" >'zsh-2.5.0/src/hist.c' <<'END_OF_FILE'
  335. X/*
  336. X *
  337. X * hist.c - history expansion
  338. X *
  339. X * This file is part of zsh, the Z shell.
  340. X *
  341. X * This software is Copyright 1992 by Paul Falstad
  342. X *
  343. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  344. X * use this software as long as: there is no monetary profit gained
  345. X * specifically from the use or reproduction of this software, it is not
  346. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  347. X * included prominently in any copy made.
  348. X *
  349. X * The author make no claims as to the fitness or correctness of this software
  350. X * for any use whatsoever, and it is provided as is. Any use of this software
  351. X * is at the user's own risk.
  352. X *
  353. X */
  354. X
  355. X#include "zsh.h"
  356. X
  357. Xstatic Histent curhistent;
  358. X
  359. Xstatic int lastc;
  360. X
  361. X/* add a character to the current history word */
  362. X
  363. Xvoid hwaddc(c)            /**/
  364. Xint c;
  365. X{
  366. X    if (hlastw && chline && (!(errflag || lexstop) || c == HISTSPACE)) {
  367. X    if (c == '!' && unset(NOBANGHIST))
  368. X        hwaddc('\\');
  369. X    *hptr++ = c;
  370. X    if (hptr - chline >= hlinesz) {
  371. X        int ll, flag = 0, oldsiz = hlinesz;
  372. X
  373. X        ll = hptr - hlastw;
  374. X        if (curhistent->lex == chline)
  375. X        flag = 1;
  376. X        chline = realloc(chline, hlinesz = oldsiz + 16);
  377. X        if (flag)
  378. X        curhistent->lex = chline;
  379. X        hptr = chline + oldsiz;
  380. X        hlastw = hptr - ll;
  381. X    }
  382. X    }
  383. X}
  384. X
  385. X#define habort() { errflag = lexstop = 1; return ' '; }
  386. X
  387. X/* get a character after performing history substitution */
  388. X
  389. Xint hgetc()
  390. X{                /**/
  391. X    int c, ev, farg, evset = -1, larg, argc, cflag = 0, bflag = 0;
  392. X    static int mev = -1, marg = -1;
  393. X    char buf[256], *ptr;
  394. X    char *sline, *eline;
  395. X
  396. X  tailrec:
  397. X    c = hgetch();
  398. X    if (stophist || alstackind) {
  399. X    hwaddc(c);
  400. X    return c;
  401. X    }
  402. X    if (isfirstch && c == hatchar) {
  403. X    isfirstch = 0;
  404. X    hungetch(hatchar);
  405. X    hungets(":s");
  406. X    goto hatskip;
  407. X    }
  408. X    if (c != ' ')
  409. X    isfirstch = 0;
  410. X    if (c == '\\') {
  411. X    int g = hgetch();
  412. X
  413. X    if (g != bangchar)
  414. X        hungetch(g);
  415. X    else {
  416. X        hwaddc(bangchar);
  417. X        return bangchar;
  418. X    }
  419. X    }
  420. X    if (c != bangchar) {
  421. X    hwaddc(c);
  422. X    return c;
  423. X    }
  424. X  hatskip:
  425. X    *hptr = '\0';
  426. X    if ((c = hgetch()) == '{') {
  427. X    bflag = cflag = 1;
  428. X    c = hgetch();
  429. X    }
  430. X    if (c == '\"') {
  431. X    stophist = 1;
  432. X    goto tailrec;
  433. X    }
  434. X    if ((!cflag && inblank(c)) || c == '=' || c == '(' || lexstop) {
  435. X    if (lexstop)
  436. X        lexstop = 0;
  437. X    else
  438. X        hungetch(c);
  439. X    hwaddc(bangchar);
  440. X    return bangchar;
  441. X    }
  442. X    cflag = 0;
  443. X    ptr = buf;
  444. X
  445. X/* get event number */
  446. X
  447. X    if (c == '?') {
  448. X    for (;;) {
  449. X        c = hgetch();
  450. X        if (c == '?' || c == '\n' || lexstop)
  451. X        break;
  452. X        else
  453. X        *ptr++ = c;
  454. X    }
  455. X    if (c != '\n' && !lexstop)
  456. X        c = hgetch();
  457. X    *ptr = '\0';
  458. X    mev = ev = hconsearch(hsubl = ztrdup(buf), &marg);
  459. X    evset = 0;
  460. X    if (ev == -1) {
  461. X        herrflush();
  462. X        zerr("no such event: %s", buf, 0);
  463. X        habort();
  464. X    }
  465. X    } else {
  466. X    int t0;
  467. X
  468. X    for (;;) {
  469. X        if (inblank(c) || c == ';' || c == ':' || c == '^' || c == '$' ||
  470. X        c == '*' || c == '%' || c == '}' ||
  471. X        c == '\'' || c == '"' || c == '`' || lexstop)
  472. X        break;
  473. X        if (ptr != buf) {
  474. X        if (c == '-')
  475. X            break;
  476. X        if ((idigit(buf[0]) || buf[0] == '-') && !idigit(c))
  477. X            break;
  478. X        }
  479. X        *ptr++ = c;
  480. X        if (c == '#' || c == bangchar) {
  481. X        c = hgetch();
  482. X        break;
  483. X        }
  484. X        c = hgetch();
  485. X    }
  486. X    *ptr = 0;
  487. X    if (!*buf)
  488. X        if (c != '%') {
  489. X        if (isset(CSHJUNKIEHISTORY))
  490. X            ev = curhist - 1;
  491. X        else
  492. X            ev = defev;
  493. X        if (c == ':' && evset == -1)
  494. X            evset = 0;
  495. X        else
  496. X            evset = 1;
  497. X        } else {
  498. X        if (marg != -1)
  499. X            ev = mev;
  500. X        else
  501. X            ev = defev;
  502. X        evset = 0;
  503. X    } else if ((t0 = atoi(buf))) {
  504. X        ev = (t0 < 0) ? curhist + t0 : t0;
  505. X        evset = 1;
  506. X    } else if ((unsigned)*buf == bangchar) {
  507. X        ev = curhist - 1;
  508. X        evset = 1;
  509. X    } else if (*buf == '#') {
  510. X        ev = curhist;
  511. X        evset = 1;
  512. X    } else if ((ev = hcomsearch(buf)) == -1) {
  513. X        zerr("event not found: %s", buf, 0);
  514. X        while (c != '\n' && !lexstop)
  515. X        c = hgetch();
  516. X        habort();
  517. X    } else
  518. X        evset = 1;
  519. X    }
  520. X
  521. X/* get the event */
  522. X
  523. X    if (!(eline = getevent(defev = ev)))
  524. X    habort();
  525. X
  526. X/* extract the relevant arguments */
  527. X
  528. X    argc = getargc(eline);
  529. X    if (c == ':') {
  530. X    cflag = 1;
  531. X    c = hgetch();
  532. X    if (c == '%' && marg != -1) {
  533. X        if (!evset) {
  534. X        eline = getevent(defev = mev);
  535. X        argc = getargc(eline);
  536. X        } else {
  537. X        zerr("Ambiguous history reference", NULL, 0);
  538. X        while (c != '\n' && !lexstop)
  539. X            c = hgetch();
  540. X        habort();
  541. X        }
  542. X
  543. X    }
  544. X    }
  545. X    if (c == '*') {
  546. X    farg = 1;
  547. X    larg = argc;
  548. X    cflag = 0;
  549. X    } else {
  550. X    hungetch(c);
  551. X    larg = farg = getargspec(argc, marg, evset);
  552. X    if (larg == -2)
  553. X        habort();
  554. X    if (farg != -1)
  555. X        cflag = 0;
  556. X    c = hgetch();
  557. X    if (c == '*') {
  558. X        cflag = 0;
  559. X        larg = argc;
  560. X    } else if (c == '-') {
  561. X        cflag = 0;
  562. X        larg = getargspec(argc, marg, evset);
  563. X        if (larg == -2)
  564. X        habort();
  565. X        if (larg == -1)
  566. X        larg = argc - 1;
  567. X    } else
  568. X        hungetch(c);
  569. X    }
  570. X    if (farg == -1)
  571. X    farg = 0;
  572. X    if (larg == -1)
  573. X    larg = argc;
  574. X    if (!(sline = getargs(eline, farg, larg)))
  575. X    habort();
  576. X
  577. X/* do the modifiers */
  578. X
  579. X    for (;;) {
  580. X    c = (cflag) ? ':' : hgetch();
  581. X    cflag = 0;
  582. X    if (c == ':') {
  583. X        int gbal = 0;
  584. X
  585. X        if ((c = hgetch()) == 'g') {
  586. X        gbal = 1;
  587. X        c = hgetch();
  588. X        }
  589. X        switch (c) {
  590. X        case 'p':
  591. X        histdone = HISTFLAG_DONE | HISTFLAG_NOEXEC;
  592. X        break;
  593. X        case 'h':
  594. X        if (!remtpath(&sline)) {
  595. X            herrflush();
  596. X            zerr("modifier failed: h", NULL, 0);
  597. X            habort();
  598. X        }
  599. X        break;
  600. X        case 'e':
  601. X        if (!rembutext(&sline)) {
  602. X            herrflush();
  603. X            zerr("modifier failed: e", NULL, 0);
  604. X            habort();
  605. X        }
  606. X        break;
  607. X        case 'r':
  608. X        if (!remtext(&sline)) {
  609. X            herrflush();
  610. X            zerr("modifier failed: r", NULL, 0);
  611. X            habort();
  612. X        }
  613. X        break;
  614. X        case 't':
  615. X        if (!remlpaths(&sline)) {
  616. X            herrflush();
  617. X            zerr("modifier failed: t", NULL, 0);
  618. X            habort();
  619. X        }
  620. X        break;
  621. X        case 's':
  622. X        {
  623. X            int del;
  624. X            char *ptr1, *ptr2;
  625. X
  626. X            del = hgetch();
  627. X            ptr1 = hdynread2(del);
  628. X            if (!ptr1)
  629. X            habort();
  630. X            ptr2 = hdynread2(del);
  631. X            if (strlen(ptr1)) {
  632. X            zsfree(hsubl);
  633. X            hsubl = ptr1;
  634. X            }
  635. X            zsfree(hsubr);
  636. X            hsubr = ptr2;
  637. X            if (hsubl && !ztrstr(sline, hsubl)) {
  638. X            herrflush();
  639. X            zerr("substitution failed", NULL, 0);
  640. X            habort();
  641. X            }
  642. X        }
  643. X        case '&':
  644. X        if (hsubl && hsubr)
  645. X            subst(&sline, hsubl, hsubr, gbal);
  646. X        else {
  647. X            herrflush();
  648. X            zerr("no previous substitution with &", NULL, 0);
  649. X            habort();
  650. X        }
  651. X        break;
  652. X        case 'q':
  653. X        quote(&sline);
  654. X        break;
  655. X        case 'x':
  656. X        quotebreak(&sline);
  657. X        break;
  658. X        case 'l':
  659. X        downcase(&sline);
  660. X        break;
  661. X        case 'u':
  662. X        upcase(&sline);
  663. X        break;
  664. X        default:
  665. X        herrflush();
  666. X        zerr("illegal modifier: %c", NULL, c);
  667. X        habort();
  668. X        }
  669. X    } else {
  670. X        if (c != '}' || !bflag)
  671. X        hungetch(c);
  672. X        if (c != '}' && bflag) {
  673. X        zerr("'}' expected", NULL, 0);
  674. X        habort();
  675. X        }
  676. X        break;
  677. X    }
  678. X    }
  679. X
  680. X/* stuff the resulting string in the input queue and start over */
  681. X
  682. X    lexstop = 0;
  683. X    if (alstackind != MAXAL) {
  684. X    hungets(HISTMARK);
  685. X    alstack[alstackind++] = NULL;
  686. X    }
  687. X    for (ptr = sline; *ptr; ptr++) {
  688. X    if (ptr[0] == '\\' && ptr[1] == '!')
  689. X        chuck(ptr);
  690. X    }
  691. X    hungets(sline);
  692. X    histdone |= HISTFLAG_DONE;
  693. X    if (isset(HISTVERIFY))
  694. X    histdone |= HISTFLAG_NOEXEC | HISTFLAG_RECALL;
  695. X    goto tailrec;
  696. X}
  697. X
  698. X/* reset the alias stack for lexrestore () */
  699. X
  700. Xvoid clearalstack()
  701. X{                /**/
  702. X    Alias ix;
  703. X
  704. X    while (alstackind) {
  705. X    ix = alstack[--alstackind];
  706. X    ix->inuse = 0;
  707. X    }
  708. X}
  709. X
  710. X/* get a character without history expansion */
  711. X
  712. Xint hgetch()
  713. X{                /**/
  714. X    unsigned char *hgetchline, *hgetchpmpt = NULL, *hgetchpmpt2 = NULL;
  715. X    int plen, p2len = 0;
  716. X
  717. X  start:
  718. X    if (inbufct) {
  719. X    inbufct--;
  720. X    if ((lastc = *inbufptr++) == ALPOP && alstackind > 0) {
  721. X        Alias ix;
  722. X        char *t;
  723. X
  724. X        ix = alstack[--alstackind];
  725. X        if (ix) {
  726. X        ix->inuse = 0;
  727. X        t = ix->text;
  728. X        if (*t && t[strlen(t) - 1] == ' ')
  729. X            alstat = ALSTAT_MORE;
  730. X        else
  731. X            alstat = ALSTAT_JUNK;
  732. X        }
  733. X        goto start;
  734. X    }
  735. X    if (itok(lastc))
  736. X        goto start;
  737. X    return lastc;
  738. X    }
  739. X    if (strin || errflag) {
  740. X    lexstop = 1;
  741. X    return lastc = ' ';
  742. X    }
  743. X    if (interact && isset(SHINSTDIN))
  744. X    if (!isfirstln)
  745. X        hgetchpmpt = (unsigned char *)putprompt(prompt2, &plen, 0);
  746. X    else {
  747. X        hgetchpmpt = (unsigned char *)putprompt(prompt, &plen, 0);
  748. X        if (rprompt)
  749. X        hgetchpmpt2 = (unsigned char *)putprompt(rprompt, &p2len, 0);
  750. X        else
  751. X        hgetchpmpt2 = NULL, p2len = 0;
  752. X    }
  753. X    if (!(interact && isset(SHINSTDIN) && SHTTY != -1 && isset(USEZLE))) {
  754. X    char *lbuf;
  755. X
  756. X    if (interact && isset(SHINSTDIN))
  757. X        write(2, (WRITE_ARG_2_T) hgetchpmpt, strlen((char *)hgetchpmpt));
  758. X    hgetchline = (unsigned char *)fgets(lbuf = (char *)zalloc(256), 256, bshin);
  759. X    if (!hgetchline)
  760. X        zfree(lbuf, 256);
  761. X    } else
  762. X    hgetchline = zleread(hgetchpmpt, hgetchpmpt2, plen, p2len);
  763. X    if (!hgetchline) {
  764. X    lexstop = 1;
  765. X    return lastc = ' ';
  766. X    }
  767. X    if (errflag) {
  768. X    free(hgetchline);
  769. X    lexstop = errflag = 1;
  770. X    return lastc = ' ';
  771. X    }
  772. X    if (interact && isset(SHINSTDIN)) {
  773. X    char *s = curhistent->lit;
  774. X
  775. X    curhistent->lit = tricat("", s, (char *)hgetchline);
  776. X    zsfree(s);
  777. X    }
  778. X    if (isfirstln)
  779. X    spaceflag = *hgetchline == ' ';
  780. X    if (isset(VERBOSE)) {
  781. X    fputs((char *)hgetchline, stderr);
  782. X    fflush(stderr);
  783. X    }
  784. X    if (*hgetchline && hgetchline[strlen((char *)hgetchline) - 1] == '\n') {
  785. X    lineno++;
  786. X    if (interact && isset(SUNKEYBOARDHACK) && isset(SHINSTDIN) &&
  787. X        SHTTY != -1 && *hgetchline && hgetchline[1] &&
  788. X        hgetchline[strlen((char *)hgetchline) - 2] == '`') {
  789. X        int ct;
  790. X        unsigned char *ptr;
  791. X
  792. X        for (ct = 0, ptr = hgetchline; *ptr; ptr++)
  793. X        if (*ptr == '`')
  794. X            ct++;
  795. X        if (ct & 1) {
  796. X        ptr[-2] = '\n';
  797. X        ptr[-1] = '\0';
  798. X        }
  799. X    }
  800. X    }
  801. X    isfirstch = 1;
  802. X    hungets((char *)hgetchline);
  803. X    free(hgetchline);
  804. X    goto start;
  805. X}
  806. X
  807. X/* Read one line of at most n-1 chars from the input queue */
  808. X
  809. Xchar *hgets(buf, n)        /**/
  810. Xchar *buf;
  811. Xint n;
  812. X{
  813. X    int l;
  814. X
  815. X    for (l = 0; l < n - 1; l++)
  816. X    if ((buf[l] = hgetch()) == '\n' || lexstop)
  817. X        break;
  818. X    buf[l + (lexstop ? 0 : 1)] = 0;
  819. X
  820. X    return (!lexstop || l) ? buf : NULL;
  821. X}
  822. X
  823. X/* put a string in the input queue */
  824. X
  825. Xvoid hungets(str)        /**/
  826. Xchar *str;
  827. X{
  828. X    int slen = strlen(str);
  829. X
  830. X/* shrink inbuf if it gets too big */
  831. X
  832. X    if (!inbufct && inbufsz > 65536) {
  833. X    free(inbuf);
  834. X    inbuf = (char *)zalloc(inbufsz = 256);
  835. X    inbufptr = inbuf + inbufsz;
  836. X    inbufct = 0;
  837. X    }
  838. X    if (slen + inbufct > inbufsz) {
  839. X    char *x;
  840. X
  841. X    while (slen + inbufct > inbufsz)
  842. X        inbufsz *= 4;
  843. X    x = (char *)zalloc(inbufsz);
  844. X    memcpy(x + inbufsz - inbufct, inbufptr, inbufct);
  845. X    inbufptr = x + inbufsz - inbufct;
  846. X    free(inbuf);
  847. X    inbuf = x;
  848. X    }
  849. X    memcpy(inbufptr -= slen, str, slen);
  850. X    inbufct += slen;
  851. X}
  852. X
  853. X/* unget a char and remove it from chline */
  854. X
  855. Xvoid hungetc(c)            /**/
  856. Xint c;
  857. X{
  858. X    if (lexstop)
  859. X    return;
  860. X    if (hlastw) {
  861. X    if (hlastw == hptr)
  862. X        zerr("hungetc attempted at buffer start", NULL, 0);
  863. X    else {
  864. X        hptr--;
  865. X        if (*hptr == '!' && unset(NOBANGHIST))
  866. X        hptr--;
  867. X    }
  868. X    }
  869. X    hungetch(c);
  870. X}
  871. X
  872. Xvoid hungetch(c)        /**/
  873. Xint c;
  874. X{
  875. X    if (lexstop)
  876. X    return;
  877. X    if (inbufct == inbufsz) {
  878. X    hungets(" ");
  879. X    *inbufptr = c;
  880. X    } else {
  881. X    *--inbufptr = c;
  882. X    inbufct++;
  883. X    }
  884. X}
  885. X
  886. X/* begin reading a string */
  887. X
  888. Xvoid strinbeg()
  889. X{                /**/
  890. X    strin = 1;
  891. X    hbegin();
  892. X    lexinit();
  893. X}
  894. X
  895. X/* done reading a string */
  896. X
  897. Xvoid strinend()
  898. X{                /**/
  899. X    hend();
  900. X    strin = 0;
  901. X    isfirstch = 1;
  902. X    histdone = 0;
  903. X}
  904. X
  905. X/* stuff a whole file into the input queue and print it */
  906. X
  907. Xint stuff(fn)            /**/
  908. Xchar *fn;
  909. X{
  910. X    FILE *in;
  911. X    char *buf;
  912. X    int len;
  913. X
  914. X    if (!(in = fopen(fn, "r"))) {
  915. X    zerr("can't open %s", fn, 0);
  916. X    return 1;
  917. X    }
  918. X    fseek(in, 0, 2);
  919. X    len = ftell(in);
  920. X    fseek(in, 0, 0);
  921. X    buf = (char *)alloc(len + 1);
  922. X    if (!(fread(buf, len, 1, in))) {
  923. X    zerr("read error on %s", fn, 0);
  924. X    fclose(in);
  925. X    zfree(buf, len + 1);
  926. X    return 1;
  927. X    }
  928. X    fclose(in);
  929. X    buf[len] = '\0';
  930. X    fwrite(buf, len, 1, stdout);
  931. X    hungets(buf);
  932. X    return 0;
  933. X}
  934. X
  935. X/* flush input queue */
  936. X
  937. Xvoid hflush()
  938. X{                /**/
  939. X    inbufptr += inbufct;
  940. X    inbufct = 0;
  941. X}
  942. X
  943. X/* initialize the history mechanism */
  944. X
  945. Xvoid hbegin()
  946. X{                /**/
  947. X    isfirstln = isfirstch = 1;
  948. X    histremmed = errflag = histdone = spaceflag = 0;
  949. X    stophist = !interact || isset(NOBANGHIST) || unset(SHINSTDIN);
  950. X    lithist = isset(HISTLIT);
  951. X    chline = hptr = zcalloc(hlinesz = 16);
  952. X    curhistent = gethistent(curhist);
  953. X    if (!curhistent->ftim)
  954. X    curhistent->ftim = time(NULL);
  955. X    if (interact && isset(SHINSTDIN) && !strin) {
  956. X    attachtty(mypgrp);
  957. X    defev = curhist++;
  958. X    if (curhist - histsiz >= 0)
  959. X        if (gethistent(curhist - histsiz)->lex) {
  960. X        zsfree(gethistent(curhist - histsiz)->lex);
  961. X        gethistent(curhist - histsiz)->lex = NULL;
  962. X        }
  963. X    if (curhist - lithistsiz >= 0)
  964. X        if (gethistent(curhist - lithistsiz)->lit) {
  965. X        zsfree(gethistent(curhist - lithistsiz)->lit);
  966. X        gethistent(curhist - lithistsiz)->lit = NULL;
  967. X        }
  968. X    curhistent = gethistent(curhist);
  969. X    curhistent->lex = chline;
  970. X    *(curhistent->lit = zalloc(1)) = '\0';
  971. X    } else
  972. X    histremmed = 1;
  973. X}
  974. X
  975. X/* say we're done using the history mechanism */
  976. X
  977. Xint hend()
  978. X{                /**/
  979. X    int flag, save = 1;
  980. X    Histent he;
  981. X
  982. X    if (!chline)
  983. X    return 1;
  984. X    if (!interact || strin || unset(SHINSTDIN)) {
  985. X    zfree(chline, hlinesz);
  986. X    return 1;
  987. X    }
  988. X    flag = histdone;
  989. X    histdone = 0;
  990. X    if (hptr < chline + 2)
  991. X    save = 0;
  992. X    else {
  993. X    char *s, *t;
  994. X
  995. X    s = curhistent->lit;
  996. X    if (*s && (*(t = s + strlen(s) - 1) == HISTSPACE || *t == '\n'))
  997. X        *t = '\0';
  998. X    hptr[-1] = '\0';
  999. X    if (hptr[-2] == '\n')
  1000. X        if (chline[1]) {
  1001. X        if (hptr[-3] == HISTSPACE)
  1002. X            hptr[-3] = '\0';
  1003. X        else
  1004. X            hptr[-2] = '\0';
  1005. X        } else
  1006. X        save = 0;
  1007. X    he = gethistent(curhist - 1);
  1008. X    if (!*chline || !strcmp(chline, "\n") ||
  1009. X        (isset(HISTIGNOREDUPS) && he->lex && !strcmp(he->lex, chline)) ||
  1010. X        (isset(HISTIGNORESPACE) && spaceflag))
  1011. X        save = 0;
  1012. X    }
  1013. X    if (flag & (HISTFLAG_DONE | HISTFLAG_RECALL)) {
  1014. X    char *ptr, *p;
  1015. X
  1016. X    p = ptr = ztrdup(chline);
  1017. X    for (; *p; p++)
  1018. X        if (*p == HISTSPACE)
  1019. X        *p = ' ';
  1020. X    if ((flag & (HISTFLAG_DONE | HISTFLAG_RECALL)) == HISTFLAG_DONE) {
  1021. X        fprintf(stderr, "%s\n", ptr);
  1022. X        fflush(stderr);
  1023. X    }
  1024. X    if (flag & HISTFLAG_RECALL) {
  1025. X        permalloc();
  1026. X        pushnode(bufstack, ptr);
  1027. X        lastalloc();
  1028. X        save = 0;
  1029. X    } else
  1030. X        zsfree(ptr);
  1031. X    }
  1032. X    curhistent->stim = time(NULL);
  1033. X    curhistent->ftim = 0L;
  1034. X    curhistent->flags = 0;
  1035. X    if (!save)
  1036. X    remhist();
  1037. X    if (chline && !curhistent->lex)
  1038. X    zfree(chline, hlinesz);
  1039. X    if (curhistent->lex) {
  1040. X    char *s = ztrdup(curhistent->lex);
  1041. X
  1042. X    zfree(curhistent->lex, hlinesz);
  1043. X    curhistent->lex = s;
  1044. X    }
  1045. X    chline = NULL;
  1046. X    return !(flag & HISTFLAG_NOEXEC || errflag);
  1047. X}
  1048. X
  1049. X/* remove the current line from the history List */
  1050. X
  1051. Xvoid remhist()
  1052. X{                /**/
  1053. X    if (!histremmed) {
  1054. X    histremmed = 1;
  1055. X    curhist--;
  1056. X    }
  1057. X}
  1058. X
  1059. X/* begin a word */
  1060. X
  1061. Xvoid hwbegin()
  1062. X{                /**/
  1063. X    hlastw = hptr;
  1064. X}
  1065. X
  1066. X/* add a word to the history List */
  1067. X
  1068. Xchar *hwadd()
  1069. X{                /**/
  1070. X    if (hlastw && chline) {
  1071. X    hwaddc(HISTSPACE);
  1072. X    if (alstackind || strin)
  1073. X        if (!(alstackind == 1 && !alstack[0]))
  1074. X        hptr = hlastw;
  1075. X    }
  1076. X    if (alstat == ALSTAT_JUNK)
  1077. X    alstat = 0;
  1078. X    return hlastw;
  1079. X}
  1080. X
  1081. X/* get an argument specification */
  1082. X
  1083. Xint getargspec(argc, marg, evset)    /**/
  1084. Xint argc;
  1085. Xint marg;
  1086. Xint evset;
  1087. X{
  1088. X    int c, ret = -1;
  1089. X
  1090. X    if ((c = hgetch()) == '0')
  1091. X    return 0;
  1092. X    if (idigit(c)) {
  1093. X    ret = 0;
  1094. X    while (idigit(c)) {
  1095. X        ret = ret * 10 + c - '0';
  1096. X        c = hgetch();
  1097. X    }
  1098. X    hungetch(c);
  1099. X    } else if (c == '^')
  1100. X    ret = 1;
  1101. X    else if (c == '$')
  1102. X    ret = argc;
  1103. X    else if (c == '%') {
  1104. X    if (evset) {
  1105. X        herrflush();
  1106. X        zerr("Ambiguous history reference", NULL, 0);
  1107. X        return -2;
  1108. X    }
  1109. X    if (marg == -1) {
  1110. X        herrflush();
  1111. X        zerr("%% with no previous word matched", NULL, 0);
  1112. X        return -2;
  1113. X    }
  1114. X    ret = marg;
  1115. X    } else
  1116. X    hungetch(c);
  1117. X    return ret;
  1118. X}
  1119. X
  1120. X/* do ?foo? search */
  1121. X
  1122. Xint hconsearch(str, marg)    /**/
  1123. Xchar *str;
  1124. Xint *marg;
  1125. X{
  1126. X    int t0, t1 = 0;
  1127. X    char *s, *hs;
  1128. X
  1129. X    for (t0 = curhist - 1; (hs = quietgetevent(t0)); t0--)
  1130. X    if ((s = ztrstr(hs, str))) {
  1131. X        while (s != hs)
  1132. X        if (*s-- == HISTSPACE)
  1133. X            t1++;
  1134. X        *marg = t1;
  1135. X        return t0;
  1136. X    }
  1137. X    return -1;
  1138. X}
  1139. X
  1140. X/* do !foo search */
  1141. X
  1142. Xint hcomsearch(str)        /**/
  1143. Xchar *str;
  1144. X{
  1145. X    int t0;
  1146. X    char *hs;
  1147. X
  1148. X    for (t0 = curhist - 1; (hs = quietgetevent(t0)); t0--)
  1149. X    if (!strncmp(hs, str, strlen(str)))
  1150. X        return t0;
  1151. X    return -1;
  1152. X}
  1153. X
  1154. X/* various utilities for : modifiers */
  1155. X
  1156. Xint remtpath(junkptr)        /**/
  1157. Xchar **junkptr;
  1158. X{
  1159. X    char *str = *junkptr, *remcut;
  1160. X
  1161. X    if ((remcut = strrchr(str, '/'))) {
  1162. X    if (str != remcut)
  1163. X        *remcut = '\0';
  1164. X    else
  1165. X        str[1] = '\0';
  1166. X    return 1;
  1167. X    }
  1168. X    return 0;
  1169. X}
  1170. X
  1171. Xint remtext(junkptr)        /**/
  1172. Xchar **junkptr;
  1173. X{
  1174. X    char *str = *junkptr, *remcut;
  1175. X
  1176. X    if ((remcut = strrchr(str, '.')) && remcut != str) {
  1177. X    *remcut = '\0';
  1178. X    return 1;
  1179. X    }
  1180. X    return 0;
  1181. X}
  1182. X
  1183. Xint rembutext(junkptr)        /**/
  1184. Xchar **junkptr;
  1185. X{
  1186. X    char *str = *junkptr, *remcut;
  1187. X
  1188. X    if ((remcut = strrchr(str, '.')) && remcut != str) {
  1189. X    *junkptr = dupstring(remcut + 1);    /* .xx or xx? */
  1190. X    return 1;
  1191. X    }
  1192. X    return 0;
  1193. X}
  1194. X
  1195. Xint remlpaths(junkptr)        /**/
  1196. Xchar **junkptr;
  1197. X{
  1198. X    char *str = *junkptr, *remcut;
  1199. X
  1200. X    if ((remcut = strrchr(str, '/'))) {
  1201. X    *remcut = '\0';
  1202. X    *junkptr = dupstring(remcut + 1);
  1203. X    return 1;
  1204. X    }
  1205. X    return 0;
  1206. X}
  1207. X
  1208. Xint makeuppercase(junkptr)    /**/
  1209. Xchar **junkptr;
  1210. X{
  1211. X    char *str = *junkptr;
  1212. X
  1213. X    for (; *str; str++)
  1214. X    *str = tuupper(*str);
  1215. X    return 1;
  1216. X}
  1217. X
  1218. Xint makelowercase(junkptr)    /**/
  1219. Xchar **junkptr;
  1220. X{
  1221. X    char *str = *junkptr;
  1222. X
  1223. X    for (; *str; str++)
  1224. X    *str = tulower(*str);
  1225. X    return 1;
  1226. X}
  1227. X
  1228. Xint makecapitals(junkptr)    /**/
  1229. Xchar **junkptr;
  1230. X{
  1231. X    char *str = *junkptr;
  1232. X
  1233. X    for (; *str;) {
  1234. X    for (; *str && !ialnum(*str); str++);
  1235. X    if (*str)
  1236. X        *str = tuupper(*str), str++;
  1237. X    for (; *str && ialnum(*str); str++)
  1238. X        *str = tulower(*str);
  1239. X    }
  1240. X    return 1;
  1241. X}
  1242. X
  1243. Xvoid subst(strptr, in, out, gbal)    /**/
  1244. Xchar **strptr;
  1245. Xchar *in;
  1246. Xchar *out;
  1247. Xint gbal;
  1248. X{
  1249. X    char *str = *strptr, *instr = *strptr, *substcut, *sptr, *oldstr;
  1250. X    int off, inlen, outlen;
  1251. X
  1252. X    if (!(substcut = (char *)ztrstr(str, in)))
  1253. X    return;
  1254. X    inlen = strlen(in);
  1255. X    sptr = convamps(out, in, inlen);
  1256. X    outlen = strlen(sptr);
  1257. X
  1258. X    do {
  1259. X    *substcut = '\0';
  1260. X    off = substcut - *strptr + outlen;
  1261. X    substcut += inlen;
  1262. X    *strptr = tricat(oldstr = *strptr, sptr, substcut);
  1263. X    if (oldstr != instr)
  1264. X        zsfree(oldstr);
  1265. X    str = (char *)*strptr + off;
  1266. X    } while (gbal && (substcut = (char *)ztrstr(str, in)));
  1267. X}
  1268. X
  1269. Xchar *convamps(out, in, inlen)    /**/
  1270. Xchar *out;
  1271. Xchar *in;
  1272. Xint inlen;
  1273. X{
  1274. X    char *ptr, *ret, *pp;
  1275. X    int slen, sdup = 0;
  1276. X
  1277. X    for (ptr = out, slen = 0; *ptr; ptr++, slen++)
  1278. X    if (*ptr == '\\')
  1279. X        ptr++, sdup = 1;
  1280. X    else if (*ptr == '&')
  1281. X        slen += inlen - 1, sdup = 1;
  1282. X    if (!sdup)
  1283. X    return out;
  1284. X    ret = pp = (char *)alloc(slen + 1);
  1285. X    for (ptr = out; *ptr; ptr++)
  1286. X    if (*ptr == '\\')
  1287. X        *pp++ = *++ptr;
  1288. X    else if (*ptr == '&') {
  1289. X        strcpy(pp, in);
  1290. X        pp += inlen;
  1291. X    } else
  1292. X        *pp++ = *ptr;
  1293. X    *pp = '\0';
  1294. X    return ret;
  1295. X}
  1296. X
  1297. Xchar *makehstr(s)        /**/
  1298. Xchar *s;
  1299. X{
  1300. X    char *t;
  1301. X
  1302. X    t = s = dupstring(s);
  1303. X    for (; *t; t++)
  1304. X    if (*t == HISTSPACE)
  1305. X        *t = ' ';
  1306. X    return s;
  1307. X}
  1308. X
  1309. Xchar *quietgetevent(ev)        /**/
  1310. Xint ev;
  1311. X{
  1312. X    Histent ent;
  1313. X
  1314. X    if (ev < firsthist() || ev > curhist)
  1315. X    return NULL;
  1316. X    ent = gethistent(ev);
  1317. X    return (lithist) ? ent->lit : ent->lex;
  1318. X}
  1319. X
  1320. Xchar *getevent(ev)        /**/
  1321. Xint ev;
  1322. X{
  1323. X    char *ret;
  1324. X
  1325. X    ret = quietgetevent(ev);
  1326. X    if (!ret) {
  1327. X    herrflush();
  1328. X    zerr("no such event: %d", NULL, ev);
  1329. X    }
  1330. X    return ret;
  1331. X}
  1332. X
  1333. Xint getargc(list)        /**/
  1334. Xchar *list;
  1335. X{
  1336. X    int argc = 0;
  1337. X
  1338. X    for (; *list; list++)
  1339. X    if (*list == HISTSPACE)
  1340. X        argc++;
  1341. X    return argc;
  1342. X}
  1343. X
  1344. Xchar *getargs(elist, arg1, arg2)/**/
  1345. Xchar *elist;
  1346. Xint arg1;
  1347. Xint arg2;
  1348. X{
  1349. X    char *ret = elist, *retn;
  1350. X    int acnt = arg2 - arg1 + 1;
  1351. X
  1352. X    while (arg1--)
  1353. X    while (*ret && *ret++ != HISTSPACE);
  1354. X    if (!*ret)
  1355. X    if (arg1 == -1 && arg2 == 0) {
  1356. X        herrflush();
  1357. X        zerr("no words available from current command", NULL, 0);
  1358. X        return NULL;
  1359. X    } else {
  1360. X        herrflush();
  1361. X        zerr("no such word in event", NULL, 0);
  1362. X        return NULL;
  1363. X    }
  1364. X    retn = ret = dupstring(ret);
  1365. X    while (acnt > 0) {
  1366. X    while (*ret && *ret != HISTSPACE)
  1367. X        ret++;
  1368. X    if (*ret == HISTSPACE)
  1369. X        *ret = ' ';
  1370. X    else
  1371. X        break;
  1372. X    acnt--;
  1373. X    }
  1374. X    if (acnt > 1 && !*ret) {
  1375. X    herrflush();
  1376. X    zerr("no such word in event", NULL, 0);
  1377. X    return NULL;
  1378. X    }
  1379. X    *ret = '\0';
  1380. X    return retn;
  1381. X}
  1382. X
  1383. Xvoid upcase(x)            /**/
  1384. Xchar **x;
  1385. X{
  1386. X    char *pp = *(char **)x;
  1387. X
  1388. X    for (; *pp; pp++)
  1389. X    *pp = tuupper(*pp);
  1390. X}
  1391. X
  1392. Xvoid downcase(x)        /**/
  1393. Xchar **x;
  1394. X{
  1395. X    char *pp = *(char **)x;
  1396. X
  1397. X    for (; *pp; pp++)
  1398. X    *pp = tulower(*pp);
  1399. X}
  1400. X
  1401. Xint quote(tr)            /**/
  1402. Xchar **tr;
  1403. X{
  1404. X    char *ptr, *rptr, **str = (char **)tr;
  1405. X    int len = 3;
  1406. X    int inquotes = 0;
  1407. X
  1408. X    for (ptr = *str; *ptr; ptr++, len++)
  1409. X    if (*ptr == '\'') {
  1410. X        len += 3;
  1411. X        if (!inquotes)
  1412. X        inquotes = 1;
  1413. X        else
  1414. X        inquotes = 0;
  1415. X    } else if (inblank(*ptr) && !inquotes && ptr[-1] != '\\')
  1416. X        len += 2;
  1417. X    ptr = *str;
  1418. X    *str = rptr = (char *)alloc(len);
  1419. X    *rptr++ = '\'';
  1420. X    for (; *ptr; ptr++)
  1421. X    if (*ptr == '\'') {
  1422. X        if (!inquotes)
  1423. X        inquotes = 1;
  1424. X        else
  1425. X        inquotes = 0;
  1426. X        *rptr++ = '\'';
  1427. X        *rptr++ = '\\';
  1428. X        *rptr++ = '\'';
  1429. X        *rptr++ = '\'';
  1430. X    } else if (inblank(*ptr) && !inquotes && ptr[-1] != '\\') {
  1431. X        *rptr++ = '\'';
  1432. X        *rptr++ = *ptr;
  1433. X        *rptr++ = '\'';
  1434. X    } else
  1435. X        *rptr++ = *ptr;
  1436. X    *rptr++ = '\'';
  1437. X    *rptr++ = 0;
  1438. X    str[1] = NULL;
  1439. X    return 0;
  1440. X}
  1441. X
  1442. Xint quotebreak(tr)        /**/
  1443. Xchar **tr;
  1444. X{
  1445. X    char *ptr, *rptr, **str = (char **)tr;
  1446. X    int len = 3;
  1447. X
  1448. X    for (ptr = *str; *ptr; ptr++, len++)
  1449. X    if (*ptr == '\'')
  1450. X        len += 3;
  1451. X    else if (inblank(*ptr))
  1452. X        len += 2;
  1453. X    ptr = *str;
  1454. X    *str = rptr = (char *)alloc(len);
  1455. X    *rptr++ = '\'';
  1456. X    for (; *ptr;)
  1457. X    if (*ptr == '\'') {
  1458. X        *rptr++ = '\'';
  1459. X        *rptr++ = '\\';
  1460. X        *rptr++ = '\'';
  1461. X        *rptr++ = '\'';
  1462. X        ptr++;
  1463. X    } else if (inblank(*ptr)) {
  1464. X        *rptr++ = '\'';
  1465. X        *rptr++ = *ptr++;
  1466. X        *rptr++ = '\'';
  1467. X    } else
  1468. X        *rptr++ = *ptr++;
  1469. X    *rptr++ = '\'';
  1470. X    *rptr++ = '\0';
  1471. X    return 0;
  1472. X}
  1473. X
  1474. Xvoid herrflush()
  1475. X{                /**/
  1476. X    if (strin)
  1477. X    hflush();
  1478. X    else
  1479. X    while (lastc != '\n' && !lexstop)
  1480. X        hgetch();
  1481. X}
  1482. X
  1483. X/* read an arbitrary amount of data into a buffer until stop is found */
  1484. X
  1485. Xchar *hdynread(stop)        /**/
  1486. Xint stop;
  1487. X{
  1488. X    int bsiz = 256, ct = 0, c;
  1489. X    char *buf = (char *)zalloc(bsiz), *ptr;
  1490. X
  1491. X    ptr = buf;
  1492. X    while ((c = hgetch()) != stop && c != '\n' && !lexstop) {
  1493. X    if (c == '\\')
  1494. X        c = hgetch();
  1495. X    *ptr++ = c;
  1496. X    if (++ct == bsiz) {
  1497. X        buf = realloc(buf, bsiz *= 2);
  1498. X        ptr = buf + ct;
  1499. X    }
  1500. X    }
  1501. X    *ptr = 0;
  1502. X    if (c == '\n') {
  1503. X    hungetch('\n');
  1504. X    zerr("delimiter expected", NULL, 0);
  1505. X    zfree(buf, bsiz);
  1506. X    return NULL;
  1507. X    }
  1508. X    return buf;
  1509. X}
  1510. X
  1511. Xchar *hdynread2(stop)        /**/
  1512. Xint stop;
  1513. X{
  1514. X    int bsiz = 256, ct = 0, c;
  1515. X    char *buf = (char *)zalloc(bsiz), *ptr;
  1516. X
  1517. X    ptr = buf;
  1518. X    while ((c = hgetch()) != stop && c != '\n' && !lexstop) {
  1519. X    if (c == '\n') {
  1520. X        hungetch(c);
  1521. X        break;
  1522. X    }
  1523. X    if (c == '\\')
  1524. X        c = hgetch();
  1525. X    *ptr++ = c;
  1526. X    if (++ct == bsiz) {
  1527. X        buf = realloc(buf, bsiz *= 2);
  1528. X        ptr = buf + ct;
  1529. X    }
  1530. X    }
  1531. X    *ptr = 0;
  1532. X    if (c == '\n')
  1533. X    hungetch('\n');
  1534. X    return buf;
  1535. X}
  1536. X
  1537. Xvoid inithist()
  1538. X{                /**/
  1539. X    histentct = (lithistsiz > histsiz) ? lithistsiz : histsiz;
  1540. X    histentarr = (Histent) zcalloc(histentct * sizeof *histentarr);
  1541. X}
  1542. X
  1543. Xvoid resizehistents()
  1544. X{                /**/
  1545. X    int newentct, t0, t1, firstlit, firstlex;
  1546. X    Histent newarr;
  1547. X
  1548. X    newentct = (lithistsiz > histsiz) ? lithistsiz : histsiz;
  1549. X    newarr = (Histent) zcalloc(newentct * sizeof *newarr);
  1550. X    firstlex = curhist - histsiz + 1;
  1551. X    firstlit = curhist - lithistsiz + 1;
  1552. X    t0 = firsthist();
  1553. X    if (t0 < curhist - newentct)
  1554. X    t0 = curhist - newentct;
  1555. X    t1 = t0 % newentct;
  1556. X    for (; t0 <= curhist; t0++) {
  1557. X    newarr[t1] = *gethistent(t0);
  1558. X    if (t0 < firstlex) {
  1559. X        zsfree(newarr[t1].lex);
  1560. X        newarr[t1].lex = NULL;
  1561. X    }
  1562. X    if (t0 < firstlit) {
  1563. X        zsfree(newarr[t1].lit);
  1564. X        newarr[t1].lit = NULL;
  1565. X    }
  1566. X    t1++;
  1567. X    if (t1 == newentct)
  1568. X        t1 = 0;
  1569. X    }
  1570. X    free(histentarr);
  1571. X    histentarr = newarr;
  1572. X    histentct = newentct;
  1573. X}
  1574. X
  1575. Xvoid readhistfile(s, err)    /**/
  1576. Xchar *s;
  1577. Xint err;
  1578. X{
  1579. X    char buf[1024];
  1580. X    FILE *in;
  1581. X    Histent ent;
  1582. X    time_t tim = time(NULL);
  1583. X
  1584. X    if (!s)
  1585. X    return;
  1586. X    if ((in = fopen(s, "r"))) {
  1587. X    while (fgets(buf, sizeof(buf), in)) {
  1588. X        int l = strlen(buf);
  1589. X        char *pt = buf;
  1590. X
  1591. X        while (l && buf[l - 1] == '\n') {
  1592. X        buf[l - 1] = '\0';
  1593. X        if (l > 1 && buf[l - 2] == '\\') {
  1594. X            buf[l - 2] = '\n';
  1595. X            fgets(buf + l - 1, sizeof(buf) - (l - 1), in);
  1596. X            l = strlen(buf);
  1597. X        } else
  1598. X            break;
  1599. X        }
  1600. X        for (; *pt; pt++)
  1601. X        if (*pt == ' ')
  1602. X            *pt = HISTSPACE;
  1603. X
  1604. X        ent = gethistent(++curhist);
  1605. X        pt = buf;
  1606. X        if (*pt == ':') {
  1607. X        pt++;
  1608. X        ent->stim = atol(pt);
  1609. X        for (; *pt != ':' && *pt; pt++);
  1610. X        if (*pt) {
  1611. X            pt++;
  1612. X            ent->ftim = atol(pt);
  1613. X            for (; *pt != ';' && *pt; pt++);
  1614. X            if (*pt)
  1615. X            pt++;
  1616. X        } else {
  1617. X            ent->ftim = tim;
  1618. X        }
  1619. X        if (ent->stim == 0)
  1620. X            ent->stim = tim;
  1621. X        if (ent->ftim == 0)
  1622. X            ent->ftim = tim;
  1623. X        } else {
  1624. X        ent->ftim = ent->stim = tim;
  1625. X        }
  1626. X        zsfree(ent->lex);
  1627. X        zsfree(ent->lit);
  1628. X        ent->lex = ztrdup(pt);
  1629. X        ent->lit = ztrdup(pt);
  1630. X        ent->flags = HIST_OLD;
  1631. X    }
  1632. X    fclose(in);
  1633. X    } else if (err)
  1634. X    zerr("can't read history file", s, 0);
  1635. X}
  1636. X
  1637. Xvoid savehistfile(s, err, app)    /**/
  1638. Xchar *s;
  1639. Xint err;
  1640. Xint app;
  1641. X{
  1642. X    char *t;
  1643. X    FILE *out;
  1644. X    int ev;
  1645. X    Histent ent;
  1646. X
  1647. X    if (!s || !interact || savehist == 0)
  1648. X    return;
  1649. X    ev = curhist - savehist + 1;
  1650. X    if (ev < firsthist())
  1651. X    ev = firsthist();
  1652. X    if (app & 1)
  1653. X    out = fdopen(open(s, O_CREAT | O_WRONLY | O_APPEND, 0600), "a");
  1654. X    else
  1655. X    out = fdopen(open(s, O_CREAT | O_WRONLY | O_TRUNC, 0600), "w");
  1656. X    if (out) {
  1657. X    for (; ev <= curhist; ev++) {
  1658. X        ent = gethistent(ev);
  1659. X        if (app & 2) {
  1660. X        if (ent->flags & HIST_OLD)
  1661. X            continue;
  1662. X        ent->flags |= HIST_OLD;
  1663. X        }
  1664. X        t = ((lithist) ? ent->lit : ent->lex);
  1665. X        if (isset(EXTENDEDHISTORY)) {
  1666. X        fprintf(out, ": %ld:%ld;",
  1667. X            (long)ent->stim,
  1668. X            (long)ent->ftim);
  1669. X        } else if (*t == ':')
  1670. X        fputc('\\', out);
  1671. X
  1672. X        for (; *t; t++)
  1673. X        if (*t == HISTSPACE)
  1674. X            fputc(' ', out);
  1675. X        else {
  1676. X            if (*t == '\n')
  1677. X            fputc('\\', out);
  1678. X            fputc(*t, out);
  1679. X        }
  1680. X        fputc('\n', out);
  1681. X    }
  1682. X    fclose(out);
  1683. X
  1684. X    if (app & 2 && (out = fopen(s, "r"))) {
  1685. X        char **store, buf[1024], **ptr;
  1686. X        int i, l, histnum = 0;
  1687. X
  1688. X        store = (char **)zcalloc((savehist + 1) * sizeof *store);
  1689. X        while (fgets(buf, sizeof(buf), out)) {
  1690. X        l = strlen(buf);
  1691. X        if (l > 1)
  1692. X            while (l < sizeof(buf) - 1 && buf[l - 2] == '\\') {
  1693. X            fgets(buf + l, sizeof buf - l, out);
  1694. X            l = strlen(buf);
  1695. X            }
  1696. X        if (store[i = histnum % savehist])
  1697. X            free(store[i]);
  1698. X        store[i] = (char *)zalloc(l + 1);
  1699. X        strcpy(store[i], buf);
  1700. X        histnum++;
  1701. X        }
  1702. X        fclose(out);
  1703. X        if ((out = fdopen(open(s, O_WRONLY | O_TRUNC, 0600), "w"))) {
  1704. X        if (histnum < savehist)
  1705. X            for (i = 0; i < histnum; i++)
  1706. X            fprintf(out, "%s", store[i]);
  1707. X        else
  1708. X            for (i = histnum; i < histnum + savehist; i++)
  1709. X            fprintf(out, "%s", store[i % savehist]);
  1710. X        fclose(out);
  1711. X        }
  1712. X        for (ptr = store; *ptr; ptr++)
  1713. X        zsfree(*ptr);
  1714. X        free(store);
  1715. X    }
  1716. X    } else if (err)
  1717. X    zerr("can't write history file %s", s, 0);
  1718. X}
  1719. X
  1720. Xint firsthist()
  1721. X{                /**/
  1722. X    int ev;
  1723. X    Histent ent;
  1724. X
  1725. X    ev = curhist - histentct + 1;
  1726. X    if (ev < 1)
  1727. X    ev = 1;
  1728. X    do {
  1729. X    ent = gethistent(ev);
  1730. X    if ((lithist) ? ent->lit : ent->lex)
  1731. X        break;
  1732. X    ev++;
  1733. X    }
  1734. X    while (ev < curhist);
  1735. X    return ev;
  1736. X}
  1737. END_OF_FILE
  1738.   if test 27109 -ne `wc -c <'zsh-2.5.0/src/hist.c'`; then
  1739.     echo shar: \"'zsh-2.5.0/src/hist.c'\" unpacked with wrong size!
  1740.   fi
  1741.   # end of 'zsh-2.5.0/src/hist.c'
  1742. fi
  1743. if test -f 'zsh-2.5.0/src/jobs.c' -a "${1}" != "-c" ; then 
  1744.   echo shar: Will not clobber existing file \"'zsh-2.5.0/src/jobs.c'\"
  1745. else
  1746.   echo shar: Extracting \"'zsh-2.5.0/src/jobs.c'\" \(21649 characters\)
  1747.   sed "s/^X//" >'zsh-2.5.0/src/jobs.c' <<'END_OF_FILE'
  1748. X/*
  1749. X * jobs.c - job control
  1750. X *
  1751. X * This file is part of zsh, the Z shell.
  1752. X *
  1753. X * This software is Copyright 1992 by Paul Falstad
  1754. X *
  1755. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  1756. X * use this software as long as: there is no monetary profit gained
  1757. X * specifically from the use or reproduction of this software, it is not
  1758. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  1759. X * included prominently in any copy made.
  1760. X *
  1761. X * The author make no claims as to the fitness or correctness of this software
  1762. X * for any use whatsoever, and it is provided as is. Any use of this software
  1763. X * is at the user's own risk.
  1764. X *
  1765. X */
  1766. X
  1767. X#include "zsh.h"
  1768. X#include <errno.h>
  1769. X#include <setjmp.h>
  1770. X
  1771. X#if defined(POSIX) && !defined(__386BSD__) && !defined(__NetBSD__) && !defined(__FreeBSD__)
  1772. X#define JMP_BUF       sigjmp_buf
  1773. X#define SETJMP(b)     sigsetjmp((b), 1)
  1774. X#define LONGJMP(b,n)  siglongjmp((b), (n))
  1775. X#else
  1776. X#define JMP_BUF       jmp_buf
  1777. X#define SETJMP(b)     setjmp(b)
  1778. X#define LONGJMP(b,n)  longjmp((b), (n))
  1779. X#endif
  1780. X
  1781. X#if defined(RESETHANDNEEDED) && !defined(POSIX)
  1782. X#define SIGPROCESS(sig)  sig_ignore(sig)
  1783. X#define SIGRESET(sig)    sig_handle(sig)
  1784. X#else
  1785. X#define SIGPROCESS(sig)  ;
  1786. X#define SIGRESET(sig)    ;
  1787. X#endif
  1788. X
  1789. X/* empty job structure for quick clearing of jobtab entries */
  1790. X
  1791. Xstatic struct job zero;        /* static variables are initialized to zero */
  1792. X
  1793. Xstruct timeval dtimeval, now;
  1794. Xstruct timezone dummy_tz;
  1795. X
  1796. X/* Diff two timevals for elapsed-time computations */
  1797. X
  1798. Xstruct timeval *dtime(dt, t1, t2)    /**/
  1799. Xstruct timeval *dt;
  1800. Xstruct timeval *t1;
  1801. Xstruct timeval *t2;
  1802. X{
  1803. X    dt->tv_sec = t2->tv_sec - t1->tv_sec;
  1804. X    dt->tv_usec = t2->tv_usec - t1->tv_usec;
  1805. X    if (dt->tv_usec < 0) {
  1806. X    dt->tv_usec += 1000000;
  1807. X    dt->tv_sec -= 1;
  1808. X    }
  1809. X    return dt;
  1810. X}
  1811. X
  1812. X/* do a safe, race-free sigpause() to wait for SIGCHLD */
  1813. X
  1814. Xstatic int chld_longjmp = 0;
  1815. Xstatic struct z_jmp_buf {
  1816. X    JMP_BUF jbuf;
  1817. X} foil_race;
  1818. X
  1819. Xvoid chldhandler DCLPROTO((struct z_jmp_buf * jump));
  1820. X
  1821. Xvoid chldsuspend(sig)        /**/
  1822. Xint sig;
  1823. X{
  1824. X/* assumes blockchld() is in effect */
  1825. X    if (SETJMP(foil_race.jbuf) == 0) {
  1826. X    chld_longjmp = 1;
  1827. X    unblockchld();
  1828. X    chldpause(sig);
  1829. X    }
  1830. X    chld_longjmp = 0;
  1831. X}
  1832. X
  1833. X#ifdef INTHANDTYPE
  1834. X#define RETURN   { SIGRESET(sig); return 0; }
  1835. X#else
  1836. X#define RETURN   { SIGRESET(sig); return; }
  1837. X#endif
  1838. X
  1839. Xstatic int from_sig = 0;
  1840. X
  1841. X/* the signal handler */
  1842. X
  1843. XHANDTYPE handler(sig)        /**/
  1844. Xint sig;
  1845. X{
  1846. X    sigset_t heldsigs;
  1847. X    int do_jump;
  1848. X    struct z_jmp_buf jump_to;
  1849. X
  1850. X    SIGPROCESS(sig);
  1851. X
  1852. X    fast_block(&heldsigs);    /* Prevent signal traps temporarily */
  1853. X
  1854. X    do_jump = chld_longjmp;
  1855. X    chld_longjmp = 0;        /* In case a SIGCHLD somehow arrives */
  1856. X
  1857. X    if (zigheld) {
  1858. X    zighold(sig, heldsigs);    /* zigsafe() will fast_unblock(&heldsigs) */
  1859. X    RETURN;
  1860. X    }
  1861. X    if (sig == SIGCHLD) {    /* Traps can cause nested chldsuspend() */
  1862. X    if (do_jump)
  1863. X        jump_to = foil_race;/* copy foil_race */
  1864. X    }
  1865. X    fast_unblock(&heldsigs);    /* Signal traps OK again (foil_race copied) */
  1866. X
  1867. X    switch (sig) {
  1868. X    case SIGHUP:
  1869. X    if (sigtrapped[SIGHUP])
  1870. X        dotrap(SIGHUP);
  1871. X    else {
  1872. X        stopmsg = 1;
  1873. X        from_sig = 1;
  1874. X        zexit(SIGHUP);
  1875. X    }
  1876. X    break;
  1877. X
  1878. X    case SIGINT:
  1879. X    if (sigtrapped[SIGINT])
  1880. X        dotrap(SIGINT);
  1881. X    else {
  1882. X        breaks = loops;
  1883. X        errflag = 1;
  1884. X    }
  1885. X    break;
  1886. X
  1887. X#if defined(SIGWINCH) && defined(TIOCGWINSZ)
  1888. X    case SIGWINCH:
  1889. X    adjustwinsize();
  1890. X    break;
  1891. X#endif
  1892. X
  1893. X    case SIGCHLD:
  1894. X    chldhandler(do_jump ? &jump_to : (struct z_jmp_buf *)0);
  1895. X    RETURN;
  1896. X
  1897. X    default:
  1898. X    dotrap(sig);
  1899. X    if (sig == SIGALRM) {
  1900. X        if (!sigtrapped[SIGALRM]) {
  1901. X        zerr("timeout", NULL, 0);
  1902. X        exit(1);
  1903. X        } else if (tmout) {
  1904. X        alarm(tmout);
  1905. X        }
  1906. X    }
  1907. X    break;
  1908. X    }
  1909. X
  1910. X    RETURN;
  1911. X}
  1912. X
  1913. X#undef RETURN
  1914. X
  1915. X#define RETURN \
  1916. X    if (jump) { SIGRESET(SIGCHLD); LONGJMP(jump->jbuf, 1); } else return
  1917. X
  1918. Xvoid chldhandler(jump)
  1919. Xstruct z_jmp_buf *jump;
  1920. X{
  1921. X    long pid;
  1922. X    int statusp;
  1923. X    Job jn;
  1924. X    struct process *pn;
  1925. X
  1926. X#ifdef HAS_RUSAGE
  1927. X    struct rusage ru;
  1928. X
  1929. X#else
  1930. X    long chlds, chldu;
  1931. X
  1932. X#endif
  1933. X
  1934. X    for (;;) {
  1935. X    int old_errno = errno;
  1936. X
  1937. X#ifdef HAS_RUSAGE
  1938. X    pid = wait3((vptr) & statusp, WNOHANG | WUNTRACED, &ru);
  1939. X#else
  1940. X#ifndef WNOHANG
  1941. X    pid = wait(&statusp);
  1942. X#else
  1943. X#ifdef HAS_WAITPID
  1944. X    pid = waitpid(-1, (vptr) & statusp, WNOHANG | WUNTRACED);
  1945. X#else
  1946. X    pid = wait3((vptr) & statusp, WNOHANG | WUNTRACED, NULL);
  1947. X#endif
  1948. X#endif
  1949. X    chlds = shtms.tms_cstime;
  1950. X    chldu = shtms.tms_cutime;
  1951. X    times(&shtms);
  1952. X#endif
  1953. X    if (pid == -1) {
  1954. X        if (errno != ECHILD)
  1955. X        zerr("wait failed: %e", NULL, errno);
  1956. X        errno = old_errno;
  1957. X        RETURN;
  1958. X    }
  1959. X    errno = old_errno;
  1960. X    if (!pid)
  1961. X        RETURN;
  1962. X    if (pid == cmdoutpid) {
  1963. X        cmdoutdone(statusp);
  1964. X        continue;
  1965. X    }
  1966. X    findproc(pid, &jn, &pn);/* find the process of this pid */
  1967. X    if (jn) {
  1968. X        pn->statusp = statusp;
  1969. X#ifdef HAS_RUSAGE
  1970. X        pn->ti.ru = ru;
  1971. X#else
  1972. X        pn->ti.st = shtms.tms_cstime - chlds;
  1973. X        pn->ti.ut = shtms.tms_cutime - chldu;
  1974. X#endif
  1975. X        gettimeofday(&pn->endtime, &dummy_tz);
  1976. X        updatestatus(jn);
  1977. X    }
  1978. X#if 0
  1979. X    else if (WIFSTOPPED(statusp))
  1980. X        kill(pid, SIGKILL);    /* kill stopped untraced children */
  1981. X#endif
  1982. X    }
  1983. X}
  1984. X
  1985. X#undef RETURN
  1986. X
  1987. X/* clean up after a $() or `` substitution */
  1988. X
  1989. Xvoid cmdoutdone(statusp)    /**/
  1990. Xint statusp;
  1991. X{
  1992. X    cmdoutpid = 0;
  1993. X    if (WIFSIGNALED(statusp)) {
  1994. X    cmdoutval = (0200 | WTERMSIG(statusp));
  1995. X    if (WTERMSIG(statusp) == SIGINT)
  1996. X        (void)kill(getpid(), SIGINT);
  1997. X    else if (sigtrapped[WTERMSIG(statusp)])
  1998. X        dotrap(WTERMSIG(statusp));
  1999. X    } else
  2000. X    cmdoutval = WEXITSTATUS(statusp);
  2001. X}
  2002. X
  2003. X/* change job table entry from stopped to running */
  2004. X
  2005. Xvoid makerunning(jn)        /**/
  2006. XJob jn;
  2007. X{
  2008. X    struct process *pn;
  2009. X
  2010. X    jn->stat &= ~STAT_STOPPED;
  2011. X    for (pn = jn->procs; pn; pn = pn->next)
  2012. X    if (WIFSTOPPED(pn->statusp))
  2013. X        pn->statusp = SP_RUNNING;
  2014. X}
  2015. X
  2016. X/* update status of job, possibly printing it */
  2017. X
  2018. Xvoid updatestatus(jn)        /**/
  2019. XJob jn;
  2020. X{
  2021. X    struct process *pn;
  2022. X    int notrunning = 1, alldone = 1, val = 0, job = jn - jobtab;
  2023. X    int statusp = 0, somestopped = 0, inforeground = 0;
  2024. X    int pgrp;
  2025. X
  2026. X    pgrp = gettygrp();
  2027. X    for (pn = jn->procs; pn; pn = pn->next) {
  2028. X    if (pn->statusp == SP_RUNNING)
  2029. X        notrunning = 0;
  2030. X    if (pn->statusp == SP_RUNNING || WIFSTOPPED(pn->statusp))
  2031. X        alldone = 0;
  2032. X    if (WIFSTOPPED(pn->statusp))
  2033. X        somestopped = 1;
  2034. X    if (!pn->next && jn)
  2035. X        val = (WIFSIGNALED(pn->statusp)) ?
  2036. X        0200 | WTERMSIG(pn->statusp) : WEXITSTATUS(pn->statusp);
  2037. X    if (pn->pid == jn->gleader) {
  2038. X        statusp = pn->statusp;
  2039. X        if (pgrp == 0 || pn->pid == pgrp || 
  2040. X        (pgrp > 1 && kill(-pgrp, 0) == -1))
  2041. X        inforeground = 1;
  2042. X    }
  2043. X    }
  2044. X    if (!notrunning)
  2045. X    return;
  2046. X    if (somestopped) {
  2047. X    if (jn->stty_in_env && !jn->ty) {
  2048. X        jn->ty = (struct ttyinfo *)zalloc(sizeof(struct ttyinfo));
  2049. X
  2050. X        gettyinfo(jn->ty);
  2051. X    }
  2052. X    if (jn->stat & STAT_STOPPED)
  2053. X        return;
  2054. X    }
  2055. X    if (alldone && job == thisjob)
  2056. X    lastval = val;
  2057. X    if (alldone)
  2058. X    lastval2 = val;
  2059. X    if (inforeground && !ttyfrozen && !val && !jn->stty_in_env)
  2060. X    gettyinfo(&shttyinfo);
  2061. X#ifdef TIOCGWINSZ
  2062. X    adjustwinsize();
  2063. X#endif
  2064. X    jn->stat |= (alldone) ? STAT_CHANGED | STAT_DONE :
  2065. X    STAT_CHANGED | STAT_STOPPED;
  2066. X    if ((jn->stat & (STAT_DONE | STAT_STOPPED)) == STAT_STOPPED) {
  2067. X    prevjob = curjob;
  2068. X    curjob = job;
  2069. X    }
  2070. X    if ((isset(NOTIFY) || job == thisjob) && (jn->stat & STAT_LOCKED)) {
  2071. X    printjob(jn, !!isset(LONGLISTJOBS));
  2072. X    if (zleactive)
  2073. X        refresh();
  2074. X    }
  2075. X    if (sigtrapped[SIGCHLD] && job != thisjob)
  2076. X    dotrap(SIGCHLD);
  2077. X
  2078. X /* If the foreground job got a signal, pretend we got it, too. */
  2079. X    if (inforeground && WIFSIGNALED(statusp)) {
  2080. X    if (sigtrapped[WTERMSIG(statusp)]) {
  2081. X        dotrap(WTERMSIG(statusp));
  2082. X    } else if (WTERMSIG(statusp) == SIGINT ||
  2083. X           WTERMSIG(statusp) == SIGQUIT) {
  2084. X        breaks = loops;
  2085. X        errflag = 1;
  2086. X    }
  2087. X    }
  2088. X}
  2089. X
  2090. X/* find process and job associated with pid */
  2091. X
  2092. Xvoid findproc(pid, jptr, pptr)    /**/
  2093. Xint pid;
  2094. XJob *jptr;
  2095. Xstruct process **pptr;
  2096. X{
  2097. X    struct process *pn;
  2098. X    int jn;
  2099. X
  2100. X    for (jn = 1; jn != MAXJOB; jn++)
  2101. X    for (pn = jobtab[jn].procs; pn; pn = pn->next)
  2102. X        if (pn->pid == pid) {
  2103. X        *pptr = pn;
  2104. X        *jptr = jobtab + jn;
  2105. X        return;
  2106. X        }
  2107. X    *pptr = NULL;
  2108. X    *jptr = NULL;
  2109. X}
  2110. X
  2111. X/*
  2112. X    lng = 0 means jobs
  2113. X    lng = 1 means jobs -l
  2114. X    lng = 2 means jobs -p
  2115. X*/
  2116. X
  2117. Xvoid printjob(jn, lng)        /**/
  2118. XJob jn;
  2119. Xint lng;
  2120. X{
  2121. X    int job = jn - jobtab, len = 9, sig, sflag = 0, llen;
  2122. X    int conted = 0, lineleng = columns, skip = 0, doputnl = 0;
  2123. X    struct process *pn;
  2124. X
  2125. X    if (lng < 0) {
  2126. X    conted = 1;
  2127. X    lng = 0;
  2128. X    }
  2129. X/* find length of longest signame, check to see if we
  2130. X        really need to print this job */
  2131. X
  2132. X    for (pn = jn->procs; pn; pn = pn->next) {
  2133. X    if (pn->statusp != SP_RUNNING)
  2134. X        if (WIFSIGNALED(pn->statusp)) {
  2135. X        sig = WTERMSIG(pn->statusp);
  2136. X        llen = strlen(sigmsg[sig]);
  2137. X        if (WCOREDUMP(pn->statusp))
  2138. X            llen += 14;
  2139. X        if (llen > len)
  2140. X            len = llen;
  2141. X        if (sig != SIGINT && sig != SIGPIPE)
  2142. X            sflag = 1;
  2143. X        else if (sig == SIGINT)
  2144. X            errflag = 1;
  2145. X        if (job == thisjob && sig == SIGINT)
  2146. X            doputnl = 1;
  2147. X        } else if (WIFSTOPPED(pn->statusp)) {
  2148. X        sig = WSTOPSIG(pn->statusp);
  2149. X        if ((int)strlen(sigmsg[sig]) > len)
  2150. X            len = strlen(sigmsg[sig]);
  2151. X        if (job == thisjob && sig == SIGTSTP)
  2152. X            doputnl = 1;
  2153. X        } else if (isset(PRINTEXITVALUE) && isset(SHINSTDIN) &&
  2154. X               WEXITSTATUS(pn->statusp))
  2155. X        sflag = 1;
  2156. X    }
  2157. X
  2158. X/* print if necessary */
  2159. X
  2160. X    if (interact && jobbing && ((jn->stat & STAT_STOPPED) || sflag ||
  2161. X                job != thisjob)) {
  2162. X    int len2, fline = 1;
  2163. X    struct process *qn;
  2164. X
  2165. X    trashzle();
  2166. X    if (doputnl)
  2167. X        putc('\n', stderr);
  2168. X    for (pn = jn->procs; pn;) {
  2169. X        len2 = ((job == thisjob) ? 5 : 10) + len;    /* 2 spaces */
  2170. X        if (lng)
  2171. X        qn = pn->next;
  2172. X        else
  2173. X        for (qn = pn->next; qn; qn = qn->next) {
  2174. X            if (qn->statusp != pn->statusp)
  2175. X            break;
  2176. X            if ((int)strlen(qn->text) + len2 + ((qn->next) ? 3 : 0) > lineleng)
  2177. X            break;
  2178. X            len2 += strlen(qn->text) + 2;
  2179. X        }
  2180. X        if (job != thisjob)
  2181. X        if (fline)
  2182. X            fprintf(stderr, "[%ld]  %c ",
  2183. X                (long)(jn - jobtab),
  2184. X                (job == curjob) ? '+'
  2185. X                : (job == prevjob) ? '-' : ' ');
  2186. X        else
  2187. X            fprintf(stderr, (job > 9) ? "        " : "       ");
  2188. X        else
  2189. X        fprintf(stderr, "zsh: ");
  2190. X        if (lng)
  2191. X        if (lng == 1)
  2192. X            fprintf(stderr, "%ld ", pn->pid);
  2193. X        else {
  2194. X            int x = jn->gleader;
  2195. X
  2196. X            fprintf(stderr, "%d ", x);
  2197. X            do
  2198. X            skip++;
  2199. X            while ((x /= 10));
  2200. X            skip++;
  2201. X            lng = 0;
  2202. X        } else
  2203. X        fprintf(stderr, "%*s", skip, "");
  2204. X        if (pn->statusp == SP_RUNNING)
  2205. X        if (!conted)
  2206. X            fprintf(stderr, "running%*s", len - 7 + 2, "");
  2207. X        else
  2208. X            fprintf(stderr, "continued%*s", len - 9 + 2, "");
  2209. X        else if (WIFEXITED(pn->statusp))
  2210. X        if (WEXITSTATUS(pn->statusp))
  2211. X            fprintf(stderr, "exit %-4d%*s", WEXITSTATUS(pn->statusp),
  2212. X                len - 9 + 2, "");
  2213. X        else
  2214. X            fprintf(stderr, "done%*s", len - 4 + 2, "");
  2215. X        else if (WIFSTOPPED(pn->statusp))
  2216. X        fprintf(stderr, "%-*s", len + 2, sigmsg[WSTOPSIG(pn->statusp)]);
  2217. X        else if (WCOREDUMP(pn->statusp))
  2218. X        fprintf(stderr, "%s (core dumped)%*s",
  2219. X            sigmsg[WTERMSIG(pn->statusp)],
  2220. X            (int)(len - 14 + 2 - strlen(sigmsg[WTERMSIG(pn->statusp)])), "");
  2221. X        else
  2222. X        fprintf(stderr, "%-*s", len + 2, sigmsg[WTERMSIG(pn->statusp)]);
  2223. X        for (; pn != qn; pn = pn->next)
  2224. X        fprintf(stderr, (pn->next) ? "%s | " : "%s", pn->text);
  2225. X        putc('\n', stderr);
  2226. X        fline = 0;
  2227. X    }
  2228. X    } else if (doputnl && interact)
  2229. X    putc('\n', stderr);
  2230. X    fflush(stderr);
  2231. X
  2232. X/* print "(pwd now: foo)" messages */
  2233. X
  2234. X    if (interact && job == thisjob && strcmp(jn->pwd, pwd)) {
  2235. X    printf("(pwd now: ");
  2236. X    printdir(pwd);
  2237. X    printf(")\n");
  2238. X    fflush(stdout);
  2239. X    }
  2240. X/* delete job if done */
  2241. X
  2242. X    if (jn->stat & STAT_DONE) {
  2243. X    if ((jn->stat & STAT_TIMED) || (reporttime != -1 && report(jn))) {
  2244. X        dumptime(jn);
  2245. X    }
  2246. X    deletejob(jn);
  2247. X    if (job == curjob) {
  2248. X        curjob = prevjob;
  2249. X        prevjob = job;
  2250. X    }
  2251. X    if (job == prevjob)
  2252. X        setprevjob();
  2253. X    } else
  2254. X    jn->stat &= ~STAT_CHANGED;
  2255. X}
  2256. X
  2257. Xvoid deletejob(jn)        /**/
  2258. XJob jn;
  2259. X{
  2260. X    struct process *pn, *nx;
  2261. X    char *s;
  2262. X
  2263. X    for (pn = jn->procs; pn; pn = nx) {
  2264. X    nx = pn->next;
  2265. X    zfree(pn, sizeof(struct process));
  2266. X    }
  2267. X    zsfree(jn->pwd);
  2268. X    if (jn->filelist) {
  2269. X    while ((s = (char *)getnode(jn->filelist))) {
  2270. X        unlink(s);
  2271. X        zsfree(s);
  2272. X    }
  2273. X    zfree(jn->filelist, sizeof(struct lklist));
  2274. X    }
  2275. X    if (jn->ty)
  2276. X    zfree(jn->ty, sizeof(struct ttyinfo));
  2277. X
  2278. X    *jn = zero;
  2279. X}
  2280. X
  2281. X/* set the previous job to something reasonable */
  2282. X
  2283. Xvoid setprevjob()
  2284. X{                /**/
  2285. X    int t0;
  2286. X
  2287. X    for (t0 = MAXJOB - 1; t0; t0--)
  2288. X    if ((jobtab[t0].stat & STAT_INUSE) && (jobtab[t0].stat & STAT_STOPPED) &&
  2289. X        t0 != curjob && t0 != thisjob)
  2290. X        break;
  2291. X    if (!t0)
  2292. X    for (t0 = MAXJOB - 1; t0; t0--)
  2293. X        if ((jobtab[t0].stat & STAT_INUSE) && t0 != curjob && t0 != thisjob)
  2294. X        break;
  2295. X    prevjob = (t0) ? t0 : -1;
  2296. X}
  2297. X
  2298. X/* initialize a job table entry */
  2299. X
  2300. Xvoid initjob()
  2301. X{                /**/
  2302. X    jobtab[thisjob].pwd = ztrdup(pwd);
  2303. X    jobtab[thisjob].stat = STAT_INUSE;
  2304. X    jobtab[thisjob].gleader = 0;
  2305. X}
  2306. X
  2307. X/* add a process to the current job */
  2308. X
  2309. Xvoid addproc(pid, text)        /**/
  2310. Xlong pid;
  2311. Xchar *text;
  2312. X{
  2313. X    struct process *process;
  2314. X
  2315. X    if (!jobtab[thisjob].gleader)
  2316. X    jobtab[thisjob].gleader = pid;
  2317. X    process = (struct process *)zcalloc(sizeof *process);
  2318. X    process->pid = pid;
  2319. X    if (text)
  2320. X    strcpy(process->text, text);
  2321. X    else
  2322. X    *process->text = '\0';
  2323. X    process->next = NULL;
  2324. X    process->statusp = SP_RUNNING;
  2325. X    gettimeofday(&process->bgtime, &dummy_tz);
  2326. X    if (jobtab[thisjob].procs) {
  2327. X    struct process *n;
  2328. X
  2329. X    for (n = jobtab[thisjob].procs; n->next; n = n->next);
  2330. X    process->next = NULL;
  2331. X    n->next = process;
  2332. X    } else
  2333. X    jobtab[thisjob].procs = process;
  2334. X}
  2335. X
  2336. X/* determine if it's all right to exec a command without
  2337. X    forking in last component of subshells; it's not ok if we have files
  2338. X    to delete */
  2339. X
  2340. Xint execok()
  2341. X{                /**/
  2342. X    Job jn;
  2343. X
  2344. X    if (!exiting)
  2345. X    return 0;
  2346. X    for (jn = jobtab + 1; jn != jobtab + MAXJOB; jn++)
  2347. X    if (jn->stat && jn->filelist)
  2348. X        return 0;
  2349. X    return 1;
  2350. X
  2351. X}
  2352. X
  2353. Xvoid waitforpid(pid)        /**/
  2354. Xlong pid;
  2355. X{
  2356. X/* blockchld() around this loop in case #ifndef WNOHANG */
  2357. X    blockchld();        /* unblocked in chldsuspend() */
  2358. X    while (!errflag && (kill(pid, 0) >= 0 || errno != ESRCH)) {
  2359. X    chldsuspend(SIGINT);
  2360. X    blockchld();
  2361. X    }
  2362. X    unblockchld();
  2363. X}
  2364. X
  2365. X/* wait for a job to finish */
  2366. X
  2367. Xvoid waitjob(job, sig)        /**/
  2368. Xint job;
  2369. Xint sig;
  2370. X{
  2371. X    Job jn = jobtab + job;
  2372. X
  2373. X    blockchld();        /* unblocked during chldsuspend() */
  2374. X    if (jn->procs) {        /* if any forks were done */
  2375. X    jn->stat |= STAT_LOCKED;
  2376. X    if (jn->stat & STAT_CHANGED)
  2377. X        printjob(jobtab + job, !!isset(LONGLISTJOBS));
  2378. X    while (!errflag && jn->stat &&
  2379. X           !(jn->stat & STAT_DONE) &&
  2380. X           !(interact && (jn->stat & STAT_STOPPED))) {
  2381. X        chldsuspend(sig);
  2382. X        blockchld();
  2383. X    }
  2384. X    } else
  2385. X    deletejob(jobtab + job);
  2386. X    unblockchld();
  2387. X}
  2388. X
  2389. X/* wait for running job to finish */
  2390. X
  2391. Xvoid waitjobs()
  2392. X{                /**/
  2393. X    waitjob(thisjob, 0);
  2394. X    thisjob = -1;
  2395. X}
  2396. X
  2397. X/* clear job table when entering subshells */
  2398. X
  2399. Xvoid clearjobtab()
  2400. X{                /**/
  2401. X    int t0;
  2402. X
  2403. X    for (t0 = 1; t0 != MAXJOB; t0++) {
  2404. X    if (jobtab[t0].pwd)
  2405. X        zsfree(jobtab[t0].pwd);
  2406. X    if (jobtab[t0].ty)
  2407. X        zfree(jobtab[t0].ty, sizeof(struct ttyinfo));
  2408. X
  2409. X    jobtab[t0] = zero;
  2410. X    }
  2411. X}
  2412. X
  2413. X/* get a free entry in the job table to use */
  2414. X
  2415. Xint getfreejob()
  2416. X{                /**/
  2417. X    int t0;
  2418. X
  2419. X    for (t0 = 1; t0 != MAXJOB; t0++)
  2420. X    if (!jobtab[t0].stat) {
  2421. X        jobtab[t0].stat |= STAT_INUSE;
  2422. X        return t0;
  2423. X    }
  2424. X    zerr("job table full or recursion limit exceeded", NULL, 0);
  2425. X    return -1;
  2426. X}
  2427. X
  2428. X/* print pids for & */
  2429. X
  2430. Xvoid spawnjob()
  2431. X{                /**/
  2432. X    struct process *pn;
  2433. X
  2434. X    if (!subsh) {
  2435. X    if (curjob == -1 || !(jobtab[curjob].stat & STAT_STOPPED)) {
  2436. X        curjob = thisjob;
  2437. X        setprevjob();
  2438. X    } else if (prevjob == -1 || !(jobtab[prevjob].stat & STAT_STOPPED))
  2439. X        prevjob = thisjob;
  2440. X    if (interact && jobbing && jobtab[thisjob].procs) {
  2441. X        fprintf(stderr, "[%d]", thisjob);
  2442. X        for (pn = jobtab[thisjob].procs; pn; pn = pn->next)
  2443. X        fprintf(stderr, " %ld", pn->pid);
  2444. X        fprintf(stderr, "\n");
  2445. X        fflush(stderr);
  2446. X    }
  2447. X    }
  2448. X    if (!jobtab[thisjob].procs)
  2449. X    deletejob(jobtab + thisjob);
  2450. X    else
  2451. X    jobtab[thisjob].stat |= STAT_LOCKED;
  2452. X    thisjob = -1;
  2453. X}
  2454. X
  2455. Xint report(j)            /**/
  2456. XJob j;
  2457. X{
  2458. X    if (!j->procs)
  2459. X    return 0;
  2460. X#ifdef HAS_RUSAGE
  2461. X    return (j->procs->ti.ru.ru_utime.tv_sec + j->procs->ti.ru.ru_stime.tv_sec)
  2462. X    >= reporttime;
  2463. X#else
  2464. X    return (j->procs->ti.ut + j->procs->ti.st) / HZ >= reporttime;
  2465. X#endif
  2466. X}
  2467. X
  2468. Xvoid printtime(real, ti, desc)    /**/
  2469. Xstruct timeval *real;
  2470. Xstruct timeinfo *ti;
  2471. Xchar *desc;
  2472. X{
  2473. X    char *s;
  2474. X    long real100;
  2475. X
  2476. X#ifdef HAS_RUSAGE
  2477. X#ifdef sun
  2478. X    long ticks = 1;
  2479. X    int pk = getpagesize() / 1024;
  2480. X
  2481. X#else
  2482. X    long sec;
  2483. X
  2484. X#endif
  2485. X    struct rusage *ru = &ti->ru;
  2486. X
  2487. X#endif
  2488. X
  2489. X    if (!desc)
  2490. X    desc = "";
  2491. X#ifdef HAS_RUSAGE
  2492. X#ifdef sun
  2493. X    ticks = (ru->ru_utime.tv_sec + ru->ru_stime.tv_sec) * HZ +
  2494. X    (ru->ru_utime.tv_usec + ru->ru_stime.tv_usec) * HZ / 1000000;
  2495. X    if (!ticks)
  2496. X    ticks = 1;
  2497. X#else
  2498. X    sec = ru->ru_utime.tv_sec + ru->ru_stime.tv_sec;
  2499. X    if (!sec)
  2500. X    sec = 1;
  2501. X#endif
  2502. X#endif
  2503. X    for (s = timefmt; *s; s++)
  2504. X    if (*s == '%')
  2505. X        switch (s++, *s) {
  2506. X        case 'E':
  2507. X        fprintf(stderr, "%ld.%03lds",
  2508. X            (long)real->tv_sec, (long)real->tv_usec / 1000);
  2509. X        break;
  2510. X#ifndef HAS_RUSAGE
  2511. X        case 'U':
  2512. X        fprintf(stderr, "%ld.%03lds",
  2513. X            ti->ut / HZ, ti->ut * 1000 / HZ % 1000);
  2514. X        break;
  2515. X        case 'S':
  2516. X        fprintf(stderr, "%ld.%03lds",
  2517. X            ti->st / HZ, ti->st * 1000 / HZ % 1000);
  2518. X        break;
  2519. X        case 'P':
  2520. X        if (real->tv_sec > 21000) {
  2521. X            real100 = (real->tv_sec + 99) / 100;
  2522. X            fprintf(stderr, "%d%%",
  2523. X                (int)((ti->ut + ti->st) / HZ) / real100);
  2524. X        } else {
  2525. X            if ((real100 = real->tv_sec * 1000 + real->tv_usec / 1000))
  2526. X            fprintf(stderr, "%d%%",
  2527. X                (int)(100000 * ((ti->ut + ti->st) / HZ)) / real100);
  2528. X        }
  2529. X        break;
  2530. X#else
  2531. X        case 'U':
  2532. X        fprintf(stderr, "%ld.%03lds",
  2533. X            (long)ru->ru_utime.tv_sec,
  2534. X            (long)ru->ru_utime.tv_usec / 1000);
  2535. X        break;
  2536. X        case 'S':
  2537. X        fprintf(stderr, "%ld.%03lds",
  2538. X            (long)ru->ru_stime.tv_sec,
  2539. X            (long)ru->ru_stime.tv_usec / 1000);
  2540. X        break;
  2541. X        case 'P':
  2542. X        if (real->tv_sec > 21000) {
  2543. X            real100 = (real->tv_sec + 99) / 100;
  2544. X            fprintf(stderr, "%ld%%",
  2545. X                (ru->ru_utime.tv_sec + ru->ru_stime.tv_sec) / real100);
  2546. X        } else {
  2547. X            if ((real100 = real->tv_sec * 1000 + real->tv_usec / 1000))
  2548. X            fprintf(stderr, "%ld%%",
  2549. X                (100000 * (ru->ru_utime.tv_sec + ru->ru_stime.tv_sec)
  2550. X                 +
  2551. X                 (ru->ru_utime.tv_usec + ru->ru_stime.tv_usec) / 10)
  2552. X                / real100);
  2553. X        }
  2554. X        break;
  2555. X        case 'W':
  2556. X        fprintf(stderr, "%ld", ru->ru_nswap);
  2557. X        break;
  2558. X#ifdef sun
  2559. X        case 'K':
  2560. X        case 'D':
  2561. X        fprintf(stderr, "%ld", ru->ru_idrss / ticks * pk);
  2562. X        break;
  2563. X        case 'M':
  2564. X        fprintf(stderr, "%ld", ru->ru_maxrss * pk);
  2565. X        break;
  2566. X#else
  2567. X        case 'X':
  2568. X        fprintf(stderr, "%ld", ru->ru_ixrss / sec);
  2569. X        break;
  2570. X        case 'D':
  2571. X        fprintf(stderr, "%ld",
  2572. X            (ru->ru_idrss + ru->ru_isrss) / sec);
  2573. X        break;
  2574. X        case 'K':
  2575. X        fprintf(stderr, "%ld",
  2576. X            (ru->ru_ixrss + ru->ru_idrss + ru->ru_isrss) / sec);
  2577. X        break;
  2578. X        case 'M':
  2579. X        fprintf(stderr, "%ld", ru->ru_maxrss / 1024);
  2580. X        break;
  2581. X#endif
  2582. X        case 'F':
  2583. X        fprintf(stderr, "%ld", ru->ru_majflt);
  2584. X        break;
  2585. X        case 'R':
  2586. X        fprintf(stderr, "%ld", ru->ru_minflt);
  2587. X        break;
  2588. X        case 'I':
  2589. X        fprintf(stderr, "%ld", ru->ru_inblock);
  2590. X        break;
  2591. X        case 'O':
  2592. X        fprintf(stderr, "%ld", ru->ru_oublock);
  2593. X        break;
  2594. X        case 'r':
  2595. X        fprintf(stderr, "%ld", ru->ru_msgrcv);
  2596. X        break;
  2597. X        case 's':
  2598. X        fprintf(stderr, "%ld", ru->ru_msgsnd);
  2599. X        break;
  2600. X        case 'k':
  2601. X        fprintf(stderr, "%ld", ru->ru_nsignals);
  2602. X        break;
  2603. X        case 'w':
  2604. X        fprintf(stderr, "%ld", ru->ru_nvcsw);
  2605. X        break;
  2606. X        case 'c':
  2607. X        fprintf(stderr, "%ld", ru->ru_nivcsw);
  2608. X        break;
  2609. X#endif
  2610. X        case 'J':
  2611. X        fprintf(stderr, "%s", desc);
  2612. X        break;
  2613. X        default:
  2614. X        fprintf(stderr, "%%%c", *s);
  2615. X        break;
  2616. X    } else
  2617. X        putc(*s, stderr);
  2618. X    putc('\n', stderr);
  2619. X    fflush(stderr);
  2620. X}
  2621. X
  2622. Xvoid dumptime(jn)        /**/
  2623. XJob jn;
  2624. X{
  2625. X    struct process *pn;
  2626. X
  2627. X    if (!jn->procs)
  2628. X    return;
  2629. X    for (pn = jn->procs; pn; pn = pn->next)
  2630. X    printtime(dtime(&dtimeval, &pn->bgtime, &pn->endtime), &pn->ti, pn->text);
  2631. X}
  2632. X
  2633. Xvoid shelltime()
  2634. X{                /**/
  2635. X    struct timeinfo ti;
  2636. X
  2637. X#ifdef HAS_RUSAGE
  2638. X    struct rusage ru;
  2639. X
  2640. X    getrusage(RUSAGE_SELF, &ru);
  2641. X    memcpy(&ti.ru, &ru, sizeof(ru));
  2642. X    gettimeofday(&now, &dummy_tz);
  2643. X    printtime(dtime(&dtimeval, &shtimer, &now), &ti, "shell");
  2644. X
  2645. X    getrusage(RUSAGE_CHILDREN, &ru);
  2646. X    memcpy(&ti.ru, &ru, sizeof(ru));
  2647. X    printtime(dtime(&dtimeval, &shtimer, &now), &ti, "children");
  2648. X#else
  2649. X    struct tms buf;
  2650. X
  2651. X    times(&buf);
  2652. X    ti.ut = buf.tms_utime;
  2653. X    ti.st = buf.tms_stime;
  2654. X    gettimeofday(&now, &dummy_tz);
  2655. X    printtime(dtime(&dtimeval, &shtimer, &now), &ti, "shell");
  2656. X    ti.ut = buf.tms_cutime;
  2657. X    ti.st = buf.tms_cstime;
  2658. X    printtime(dtime(&dtimeval, &shtimer, &now), &ti, "children");
  2659. X#endif
  2660. X}
  2661. X
  2662. X/* SIGHUP any jobs left running */
  2663. X
  2664. Xvoid killrunjobs()
  2665. X{                /**/
  2666. X    int t0, killed = 0;
  2667. X
  2668. X    if (isset(NOHUP))
  2669. X    return;
  2670. X    for (t0 = 1; t0 != MAXJOB; t0++)
  2671. X    if ((from_sig || t0 != thisjob) && (jobtab[t0].stat & STAT_LOCKED) &&
  2672. X        !(jobtab[t0].stat & STAT_STOPPED)) {
  2673. X        if (killpg(jobtab[t0].gleader, SIGHUP) != -1)
  2674. X        killed++;
  2675. X    }
  2676. X    if (killed)
  2677. X    zerr("warning: %d jobs SIGHUPed", NULL, killed);
  2678. X}
  2679. X
  2680. X/* check to see if user has jobs running/stopped */
  2681. X
  2682. Xvoid checkjobs()
  2683. X{                /**/
  2684. X    int t0;
  2685. X
  2686. X    scanjobs();
  2687. X    for (t0 = 1; t0 != MAXJOB; t0++)
  2688. X    if (t0 != thisjob && jobtab[t0].stat & STAT_LOCKED)
  2689. X        break;
  2690. X    if (t0 != MAXJOB) {
  2691. X    if (jobtab[t0].stat & STAT_STOPPED) {
  2692. X#ifdef USE_SUSPENDED
  2693. X        zerr("you have suspended jobs.", NULL, 0);
  2694. X#else
  2695. X        zerr("you have stopped jobs.", NULL, 0);
  2696. X#endif
  2697. X    } else
  2698. X        zerr("you have running jobs.", NULL, 0);
  2699. X    stopmsg = 1;
  2700. X    }
  2701. X}
  2702. X
  2703. X/* send a signal to a job (simply involves kill if monitoring is on) */
  2704. X
  2705. Xint killjb(jn, sig)        /**/
  2706. XJob jn;
  2707. Xint sig;
  2708. X{
  2709. X    struct process *pn;
  2710. X    int err = 0;
  2711. X
  2712. X    if (jobbing)
  2713. X    return (killpg(jn->gleader, sig));
  2714. X    for (pn = jn->procs; pn; pn = pn->next)
  2715. X    if ((err = kill(pn->pid, sig)) == -1 && errno != ESRCH)
  2716. X        return -1;
  2717. X    return err;
  2718. X}
  2719. END_OF_FILE
  2720.   if test 21649 -ne `wc -c <'zsh-2.5.0/src/jobs.c'`; then
  2721.     echo shar: \"'zsh-2.5.0/src/jobs.c'\" unpacked with wrong size!
  2722.   fi
  2723.   # end of 'zsh-2.5.0/src/jobs.c'
  2724. fi
  2725. if test -f 'zsh-2.5.0/src/zle_bindings.c' -a "${1}" != "-c" ; then 
  2726.   echo shar: Will not clobber existing file \"'zsh-2.5.0/src/zle_bindings.c'\"
  2727. else
  2728.   echo shar: Extracting \"'zsh-2.5.0/src/zle_bindings.c'\" \(20731 characters\)
  2729.   sed "s/^X//" >'zsh-2.5.0/src/zle_bindings.c' <<'END_OF_FILE'
  2730. X
  2731. X/*
  2732. X *
  2733. X * zle_bindings.c - commands and keymaps
  2734. X *
  2735. X * This file is part of zsh, the Z shell.
  2736. X *
  2737. X * This software is Copyright 1992 by Paul Falstad
  2738. X *
  2739. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  2740. X * use this software as long as: there is no monetary profit gained
  2741. X * specifically from the use or reproduction of this software, it is not
  2742. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  2743. X * included prominently in any copy made.
  2744. X *
  2745. X * The author make no claims as to the fitness or correctness of this software
  2746. X * for any use whatsoever, and it is provided as is. Any use of this software
  2747. X * is at the user's own risk.
  2748. X *
  2749. X */
  2750. X
  2751. X#define ZLE
  2752. X#include "zsh.h"
  2753. X
  2754. Xstruct zlecmd zlecmds[] =
  2755. X{
  2756. X    {"accept-and-hold", acceptandhold, 0},
  2757. X    {"accept-and-infer-next-history", acceptandinfernexthistory, 0},
  2758. X    {"accept-and-menu-complete", acceptandmenucomplete, ZLE_MENUCMP},
  2759. X    {"accept-line", acceptline, 0},
  2760. X    {"accept-line-and-down-history", acceptlineanddownhistory, 0},
  2761. X    {"backward-char", backwardchar, ZLE_MOVEMENT},
  2762. X    {"backward-delete-char", backwarddeletechar, ZLE_DELETE},
  2763. X    {"backward-delete-word", backwarddeleteword, ZLE_DELETE},
  2764. X    {"backward-kill-line", backwardkillline, ZLE_KILL},
  2765. X    {"backward-kill-word", backwardkillword, ZLE_KILL | ZLE_DELETE},
  2766. X    {"backward-word", backwardword, ZLE_MOVEMENT},
  2767. X    {"beginning-of-buffer-or-history", beginningofbufferorhistory, ZLE_MOVEMENT},
  2768. X    {"beginning-of-history", beginningofhistory, 0},
  2769. X    {"beginning-of-line", beginningofline, ZLE_MOVEMENT},
  2770. X    {"beginning-of-line-hist", beginningoflinehist, ZLE_MOVEMENT},
  2771. X    {"capitalize-word", capitalizeword, 0},
  2772. X    {"clear-screen", clearscreen, 0},
  2773. X    {"complete-word", completeword, ZLE_MENUCMP},
  2774. X    {"copy-prev-word", copyprevword, 0},
  2775. X    {"copy-region-as-kill", copyregionaskill, ZLE_KILL},
  2776. X    {"delete-char", deletechar, ZLE_DELETE},
  2777. X    {"delete-char-or-list", deletecharorlist, ZLE_MENUCMP},
  2778. X    {"delete-word", deleteword, ZLE_DELETE},
  2779. X    {"digit-argument", digitargument, ZLE_ARG},
  2780. X    {"down-case-word", downcaseword, 0},
  2781. X    {"down-history", downhistory, 0},
  2782. X    {"down-line-or-history", downlineorhistory, ZLE_MOVEMENT | ZLE_LINEMOVE},
  2783. X    {"end-of-buffer-or-history", endofbufferorhistory, ZLE_MOVEMENT},
  2784. X    {"end-of-history", endofhistory, 0},
  2785. X    {"end-of-line", endofline, ZLE_MOVEMENT},
  2786. X    {"end-of-line-hist", endoflinehist, ZLE_MOVEMENT},
  2787. X    {"exchange-point-and-mark", exchangepointandmark, ZLE_MOVEMENT},
  2788. X    {"execute-last-named-cmd", (F) 0, 0},
  2789. X    {"execute-named-cmd", (F) 0, 0},
  2790. X    {"expand-history", expandhistory, 0},
  2791. X    {"expand-or-complete", expandorcomplete, ZLE_MENUCMP},
  2792. X    {"expand-word", expandword, 0},
  2793. X    {"forward-char", forwardchar, ZLE_MOVEMENT},
  2794. X    {"forward-word", forwardword, ZLE_MOVEMENT},
  2795. X    {"get-line", getline, 0},
  2796. X    {"gosmacs-transpose-chars", gosmacstransposechars, 0},
  2797. X    {"history-incremental-search-backward", historyincrementalsearchbackward, 0},
  2798. X    {"history-incremental-search-forward", historyincrementalsearchforward, 0},
  2799. X    {"history-search-backward", historysearchbackward, ZLE_HISTSEARCH},
  2800. X    {"history-search-forward", historysearchforward, ZLE_HISTSEARCH},
  2801. X    {"infer-next-history", infernexthistory, 0},
  2802. X    {"insert-last-word", insertlastword, ZLE_INSERT},
  2803. X    {"kill-buffer", killbuffer, ZLE_KILL},
  2804. X    {"kill-line", killline, ZLE_KILL},
  2805. X    {"kill-region", killregion, ZLE_KILL},
  2806. X    {"kill-whole-line", killwholeline, ZLE_KILL},
  2807. X    {"list-choices", listchoices, ZLE_DELETE | ZLE_MENUCMP},    /* ZLE_DELETE fixes autoremoveslash */
  2808. X    {"list-expand", listexpand, ZLE_MENUCMP},
  2809. X    {"magic-space", magicspace, 0},
  2810. X    {"menu-complete", menucompleteword, ZLE_MENUCMP},
  2811. X    {"menu-expand-or-complete", menuexpandorcomplete, ZLE_MENUCMP},
  2812. X    {"overwrite-mode", overwritemode, 0},
  2813. X    {"push-line", pushline, 0},
  2814. X    {"quoted-insert", quotedinsert, ZLE_INSERT},
  2815. X    {"quote-line", quoteline, 0},
  2816. X    {"quote-region", quoteregion, 0},
  2817. X    {"redisplay", redisplay, 0},
  2818. X    {"reverse-menu-complete", reversemenucomplete, ZLE_MENUCMP},
  2819. X    {"run-help", processcmd, 0},
  2820. X    {"self-insert", selfinsert, ZLE_INSERT},
  2821. X    {"self-insert-unmeta", selfinsertunmeta, ZLE_INSERT},
  2822. X    {"send-break", sendbreak, 0},
  2823. X    {"send-string", sendstring, 0},
  2824. X    {"prefix", (F) 0, 0},
  2825. X    {"set-mark-command", setmarkcommand, 0},
  2826. X    {"spell-word", spellword, 0},
  2827. X    {"toggle-literal-history", toggleliteralhistory, 0},
  2828. X    {"transpose-chars", transposechars, 0},
  2829. X    {"transpose-words", transposewords, 0},
  2830. X    {"undefined-key", undefinedkey, 0},
  2831. X    {"undo", undo, ZLE_UNDO},
  2832. X    {"universal-argument", universalargument, ZLE_ARG},
  2833. X    {"up-case-word", upcaseword, 0},
  2834. X    {"up-history", uphistory, 0},
  2835. X    {"up-line-or-history", uplineorhistory, ZLE_LINEMOVE | ZLE_MOVEMENT},
  2836. X    {"vi-add-eol", viaddeol, 0},
  2837. X    {"vi-add-next", viaddnext, 0},
  2838. X    {"vi-backward-blank-word", vibackwardblankword, ZLE_MOVEMENT},
  2839. X    {"vi-backward-char", vibackwardchar, ZLE_MOVEMENT},
  2840. X    {"vi-backward-delete-char", vibackwarddeletechar, ZLE_DELETE},
  2841. X    {"vi-beginning-of-line", vibeginningofline, ZLE_MOVEMENT},
  2842. X    {"vi-caps-lock-panic", vicapslockpanic, 0},
  2843. X    {"vi-change", vichange, 0},
  2844. X    {"vi-change-eol", vichangeeol, 0},
  2845. X    {"vi-change-whole-line", vichangewholeline, 0},
  2846. X    {"vi-cmd-mode", vicmdmode, 0},
  2847. X    {"vi-delete", videlete, ZLE_KILL},
  2848. X    {"vi-delete-char", videletechar, ZLE_DELETE},
  2849. X    {"vi-digit-or-beginning-of-line", (F) 0, 0},
  2850. X    {"vi-end-of-line", viendofline, ZLE_MOVEMENT},
  2851. X    {"vi-fetch-history", vifetchhistory, 0},
  2852. X    {"vi-find-next-char", vifindnextchar, ZLE_MOVEMENT},
  2853. X    {"vi-find-next-char-skip", vifindnextcharskip, ZLE_MOVEMENT},
  2854. X    {"vi-find-prev-char", vifindprevchar, ZLE_MOVEMENT},
  2855. X    {"vi-find-prev-char-skip", vifindprevcharskip, ZLE_MOVEMENT},
  2856. X    {"vi-first-non-blank", vifirstnonblank, ZLE_MOVEMENT},
  2857. X    {"vi-forward-blank-word", viforwardblankword, ZLE_MOVEMENT},
  2858. X    {"vi-forward-blank-word-end", viforwardblankwordend, ZLE_MOVEMENT},
  2859. X    {"vi-forward-char", viforwardchar, ZLE_MOVEMENT},
  2860. X    {"vi-forward-word-end", viforwardwordend, ZLE_MOVEMENT},
  2861. X    {"vi-goto-column", vigotocolumn, ZLE_MOVEMENT},
  2862. X    {"vi-goto-mark", vigotomark, ZLE_MOVEMENT},
  2863. X    {"vi-goto-mark-line", vigotomarkline, ZLE_MOVEMENT},
  2864. X    {"vi-history-search-backward", vihistorysearchbackward, 0},
  2865. X    {"vi-history-search-forward", vihistorysearchforward, 0},
  2866. X    {"vi-indent", viindent, 0},
  2867. X    {"vi-insert", viinsert, 0},
  2868. X    {"vi-insert-bol", viinsertbol, 0},
  2869. X    {"vi-join", vijoin, 0},
  2870. X    {"vi-match-bracket", vimatchbracket, ZLE_MOVEMENT},
  2871. X    {"vi-open-line-above", viopenlineabove, 0},
  2872. X    {"vi-open-line-below", viopenlinebelow, 0},
  2873. X    {"vi-oper-swap-case", vioperswapcase, 0},
  2874. X    {"vi-put-after", viputafter, ZLE_YANK},
  2875. X    {"vi-repeat-change", virepeatchange, ZLE_ARG},
  2876. X    {"vi-repeat-find", virepeatfind, ZLE_MOVEMENT},
  2877. X    {"vi-repeat-search", virepeatsearch, ZLE_MOVEMENT},
  2878. X    {"vi-replace", vireplace, 0},
  2879. X    {"vi-replace-chars", vireplacechars, 0},
  2880. X    {"vi-rev-repeat-find", virevrepeatfind, ZLE_MOVEMENT},
  2881. X    {"vi-rev-repeat-search", virevrepeatsearch, ZLE_MOVEMENT},
  2882. X    {"vi-set-buffer", visetbuffer, 0},
  2883. X    {"vi-set-mark", visetmark, 0},
  2884. X    {"vi-substitute", visubstitute, 0},
  2885. X    {"vi-swap-case", viswapcase, 0},
  2886. X    {"vi-undo-change", undo, 0},
  2887. X    {"vi-unindent", viunindent, 0},
  2888. X    {"vi-yank", viyank, 0},
  2889. X    {"vi-yank-eol", viyankeol, 0},
  2890. X    {"which-command", processcmd, 0},
  2891. X    {"yank", yank, ZLE_YANK | ZLE_NAMEDBUFFER},
  2892. X    {"yank-pop", yankpop, ZLE_YANK},
  2893. X    {"emacs-backward-word", emacsbackwardword, ZLE_MOVEMENT},
  2894. X    {"emacs-forward-word", emacsforwardword, ZLE_MOVEMENT},
  2895. X    {"kill-word", killword, ZLE_KILL},
  2896. X    {"vi-kill-line", vikillline, ZLE_KILL},
  2897. X    {"vi-backward-kill-word", vibackwardkillword, ZLE_KILL},
  2898. X    {"expand-cmd-path", expandcmdpath, 0},
  2899. X    {"neg-argument", negargument, ZLE_NEGARG | ZLE_ARG},
  2900. X    {"pound-insert", poundinsert, 0},
  2901. X    {"vi-forward-word", viforwardword, ZLE_MOVEMENT},
  2902. X    {"vi-backward-word", vibackwardword, ZLE_MOVEMENT},
  2903. X    {"up-line-or-search", uplineorsearch, ZLE_MOVEMENT | ZLE_LINEMOVE | ZLE_HISTSEARCH},
  2904. X    {"down-line-or-search", downlineorsearch, ZLE_MOVEMENT | ZLE_LINEMOVE | ZLE_HISTSEARCH},
  2905. X    {"push-input", pushinput, 0},
  2906. X    {"push-line-or-edit", pushpopinput, 0},
  2907. X    {"history-beginning-search-backward", historybeginningsearchbackward, ZLE_HISTSEARCH},
  2908. X    {"history-beginning-search-forward", historybeginningsearchforward, ZLE_HISTSEARCH},
  2909. X    {"expand-or-complete-prefix", expandorcompleteprefix, ZLE_MENUCMP},
  2910. X    {"", (F) 0, 0}
  2911. X};
  2912. X
  2913. Xint emacsbind[256] =
  2914. X{
  2915. X    /* ^@ */ z_setmarkcommand,
  2916. X    /* ^A */ z_beginningofline,
  2917. X    /* ^B */ z_backwardchar,
  2918. X    /* ^C */ z_undefinedkey,
  2919. X    /* ^D */ z_deletecharorlist,
  2920. X    /* ^E */ z_endofline,
  2921. X    /* ^F */ z_forwardchar,
  2922. X    /* ^G */ z_sendbreak,
  2923. X    /* ^H */ z_backwarddeletechar,
  2924. X    /* ^I */ z_expandorcomplete,
  2925. X    /* ^J */ z_acceptline,
  2926. X    /* ^K */ z_killline,
  2927. X    /* ^L */ z_clearscreen,
  2928. X    /* ^M */ z_acceptline,
  2929. X    /* ^N */ z_downlineorhistory,
  2930. X    /* ^O */ z_acceptlineanddownhistory,
  2931. X    /* ^P */ z_uplineorhistory,
  2932. X    /* ^Q */ z_pushline,
  2933. X    /* ^R */ z_historyincrementalsearchbackward,
  2934. X    /* ^S */ z_historyincrementalsearchforward,
  2935. X    /* ^T */ z_transposechars,
  2936. X    /* ^U */ z_killwholeline,
  2937. X    /* ^V */ z_quotedinsert,
  2938. X    /* ^W */ z_backwardkillword,
  2939. X    /* ^X */ z_sequenceleadin,
  2940. X    /* ^Y */ z_yank,
  2941. X    /* ^Z */ z_undefinedkey,
  2942. X    /* ^[ */ z_sequenceleadin,
  2943. X    /* ^\ */ z_undefinedkey,
  2944. X    /* ^] */ z_undefinedkey,
  2945. X    /* ^^ */ z_undefinedkey,
  2946. X    /* ^_ */ z_undo,
  2947. X    /*   */ z_selfinsert,
  2948. X    /* ! */ z_selfinsert,
  2949. X    /* " */ z_selfinsert,
  2950. X    /* # */ z_selfinsert,
  2951. X    /* $ */ z_selfinsert,
  2952. X    /* % */ z_selfinsert,
  2953. X    /* & */ z_selfinsert,
  2954. X    /* ' */ z_selfinsert,
  2955. X    /* ( */ z_selfinsert,
  2956. X    /* ) */ z_selfinsert,
  2957. X    /* * */ z_selfinsert,
  2958. X    /* + */ z_selfinsert,
  2959. X    /* , */ z_selfinsert,
  2960. X    /* - */ z_selfinsert,
  2961. X    /* . */ z_selfinsert,
  2962. X    /* / */ z_selfinsert,
  2963. X    /* 0 */ z_selfinsert,
  2964. X    /* 1 */ z_selfinsert,
  2965. X    /* 2 */ z_selfinsert,
  2966. X    /* 3 */ z_selfinsert,
  2967. X    /* 4 */ z_selfinsert,
  2968. X    /* 5 */ z_selfinsert,
  2969. X    /* 6 */ z_selfinsert,
  2970. X    /* 7 */ z_selfinsert,
  2971. X    /* 8 */ z_selfinsert,
  2972. X    /* 9 */ z_selfinsert,
  2973. X    /* : */ z_selfinsert,
  2974. X    /* ; */ z_selfinsert,
  2975. X    /* < */ z_selfinsert,
  2976. X    /* = */ z_selfinsert,
  2977. X    /* > */ z_selfinsert,
  2978. X    /* ? */ z_selfinsert,
  2979. X    /* @ */ z_selfinsert,
  2980. X    /* A */ z_selfinsert,
  2981. X    /* B */ z_selfinsert,
  2982. X    /* C */ z_selfinsert,
  2983. X    /* D */ z_selfinsert,
  2984. X    /* E */ z_selfinsert,
  2985. X    /* F */ z_selfinsert,
  2986. X    /* G */ z_selfinsert,
  2987. X    /* H */ z_selfinsert,
  2988. X    /* I */ z_selfinsert,
  2989. X    /* J */ z_selfinsert,
  2990. X    /* K */ z_selfinsert,
  2991. X    /* L */ z_selfinsert,
  2992. X    /* M */ z_selfinsert,
  2993. X    /* N */ z_selfinsert,
  2994. X    /* O */ z_selfinsert,
  2995. X    /* P */ z_selfinsert,
  2996. X    /* Q */ z_selfinsert,
  2997. X    /* R */ z_selfinsert,
  2998. X    /* S */ z_selfinsert,
  2999. X    /* T */ z_selfinsert,
  3000. X    /* U */ z_selfinsert,
  3001. X    /* V */ z_selfinsert,
  3002. X    /* W */ z_selfinsert,
  3003. X    /* X */ z_selfinsert,
  3004. X    /* Y */ z_selfinsert,
  3005. X    /* Z */ z_selfinsert,
  3006. X    /* [ */ z_selfinsert,
  3007. X    /* \ */ z_selfinsert,
  3008. X    /* ] */ z_selfinsert,
  3009. X    /* ^ */ z_selfinsert,
  3010. X    /* _ */ z_selfinsert,
  3011. X    /* ` */ z_selfinsert,
  3012. X    /* a */ z_selfinsert,
  3013. X    /* b */ z_selfinsert,
  3014. X    /* c */ z_selfinsert,
  3015. X    /* d */ z_selfinsert,
  3016. X    /* e */ z_selfinsert,
  3017. X    /* f */ z_selfinsert,
  3018. X    /* g */ z_selfinsert,
  3019. X    /* h */ z_selfinsert,
  3020. X    /* i */ z_selfinsert,
  3021. X    /* j */ z_selfinsert,
  3022. X    /* k */ z_selfinsert,
  3023. X    /* l */ z_selfinsert,
  3024. X    /* m */ z_selfinsert,
  3025. X    /* n */ z_selfinsert,
  3026. X    /* o */ z_selfinsert,
  3027. X    /* p */ z_selfinsert,
  3028. X    /* q */ z_selfinsert,
  3029. X    /* r */ z_selfinsert,
  3030. X    /* s */ z_selfinsert,
  3031. X    /* t */ z_selfinsert,
  3032. X    /* u */ z_selfinsert,
  3033. X    /* v */ z_selfinsert,
  3034. X    /* w */ z_selfinsert,
  3035. X    /* x */ z_selfinsert,
  3036. X    /* y */ z_selfinsert,
  3037. X    /* z */ z_selfinsert,
  3038. X    /* { */ z_selfinsert,
  3039. X    /* | */ z_selfinsert,
  3040. X    /* } */ z_selfinsert,
  3041. X    /* ~ */ z_selfinsert,
  3042. X    /* ^? */ z_backwarddeletechar,
  3043. X    /* M-^@ */ z_undefinedkey,
  3044. X    /* M-^A */ z_undefinedkey,
  3045. X    /* M-^B */ z_undefinedkey,
  3046. X    /* M-^C */ z_undefinedkey,
  3047. X    /* M-^D */ z_listchoices,
  3048. X    /* M-^E */ z_undefinedkey,
  3049. X    /* M-^F */ z_undefinedkey,
  3050. X    /* M-^G */ z_sendbreak,
  3051. X    /* M-^H */ z_backwardkillword,
  3052. X    /* M-^I */ z_selfinsertunmeta,
  3053. X    /* M-^J */ z_selfinsertunmeta,
  3054. X    /* M-^K */ z_undefinedkey,
  3055. X    /* M-^L */ z_clearscreen,
  3056. X    /* M-^M */ z_selfinsertunmeta,
  3057. X    /* M-^N */ z_undefinedkey,
  3058. X    /* M-^O */ z_undefinedkey,
  3059. X    /* M-^P */ z_undefinedkey,
  3060. X    /* M-^Q */ z_undefinedkey,
  3061. X    /* M-^R */ z_undefinedkey,
  3062. X    /* M-^S */ z_undefinedkey,
  3063. X    /* M-^T */ z_undefinedkey,
  3064. X    /* M-^U */ z_undefinedkey,
  3065. X    /* M-^V */ z_undefinedkey,
  3066. X    /* M-^W */ z_undefinedkey,
  3067. X    /* M-^X */ z_undefinedkey,
  3068. X    /* M-^Y */ z_undefinedkey,
  3069. X    /* M-^Z */ z_undefinedkey,
  3070. X    /* M-^[ */ z_undefinedkey,
  3071. X    /* M-^\ */ z_undefinedkey,
  3072. X    /* M-^] */ z_undefinedkey,
  3073. X    /* M-^^ */ z_undefinedkey,
  3074. X    /* M-^_ */ z_copyprevword,
  3075. X    /* M-  */ z_expandhistory,
  3076. X    /* M-! */ z_expandhistory,
  3077. X    /* M-" */ z_quoteregion,
  3078. X    /* M-# */ z_undefinedkey,
  3079. X    /* M-$ */ z_spellword,
  3080. X    /* M-% */ z_undefinedkey,
  3081. X    /* M-& */ z_undefinedkey,
  3082. X    /* M-' */ z_quoteline,
  3083. X    /* M-( */ z_undefinedkey,
  3084. X    /* M-) */ z_undefinedkey,
  3085. X    /* M-* */ z_undefinedkey,
  3086. X    /* M-+ */ z_undefinedkey,
  3087. X    /* M-, */ z_undefinedkey,
  3088. X    /* M-- */ z_negargument,
  3089. X    /* M-. */ z_insertlastword,
  3090. X    /* M-/ */ z_undefinedkey,
  3091. X    /* M-0 */ z_digitargument,
  3092. X    /* M-1 */ z_digitargument,
  3093. X    /* M-2 */ z_digitargument,
  3094. X    /* M-3 */ z_digitargument,
  3095. X    /* M-4 */ z_digitargument,
  3096. X    /* M-5 */ z_digitargument,
  3097. X    /* M-6 */ z_digitargument,
  3098. X    /* M-7 */ z_digitargument,
  3099. X    /* M-8 */ z_digitargument,
  3100. X    /* M-9 */ z_digitargument,
  3101. X    /* M-: */ z_undefinedkey,
  3102. X    /* M-; */ z_undefinedkey,
  3103. X    /* M-< */ z_beginningofbufferorhistory,
  3104. X    /* M-= */ z_undefinedkey,
  3105. X    /* M-> */ z_endofbufferorhistory,
  3106. X    /* M-? */ z_whichcommand,
  3107. X    /* M-@ */ z_undefinedkey,
  3108. X    /* M-A */ z_acceptandhold,
  3109. X    /* M-B */ z_backwardword,
  3110. X    /* M-C */ z_capitalizeword,
  3111. X    /* M-D */ z_killword,
  3112. X    /* M-E */ z_undefinedkey,
  3113. X    /* M-F */ z_forwardword,
  3114. X    /* M-G */ z_getline,
  3115. X    /* M-H */ z_runhelp,
  3116. X    /* M-I */ z_undefinedkey,
  3117. X    /* M-J */ z_undefinedkey,
  3118. X    /* M-K */ z_undefinedkey,
  3119. X    /* M-L */ z_downcaseword,
  3120. X    /* M-M */ z_undefinedkey,
  3121. X    /* M-N */ z_historysearchforward,
  3122. X    /* M-O */ z_undefinedkey,
  3123. X    /* M-P */ z_historysearchbackward,
  3124. X    /* M-Q */ z_pushline,
  3125. X    /* M-R */ z_toggleliteralhistory,
  3126. X    /* M-S */ z_spellword,
  3127. X    /* M-T */ z_transposewords,
  3128. X    /* M-U */ z_upcaseword,
  3129. X    /* M-V */ z_undefinedkey,
  3130. X    /* M-W */ z_copyregionaskill,
  3131. X    /* M-X */ z_undefinedkey,
  3132. X    /* M-Y */ z_undefinedkey,
  3133. X    /* M-Z */ z_undefinedkey,
  3134. X    /* M-[ */ z_undefinedkey,
  3135. X    /* M-\ */ z_undefinedkey,
  3136. X    /* M-] */ z_undefinedkey,
  3137. X    /* M-^ */ z_undefinedkey,
  3138. X    /* M-_ */ z_insertlastword,
  3139. X    /* M-` */ z_undefinedkey,
  3140. X    /* M-a */ z_acceptandhold,
  3141. X    /* M-b */ z_backwardword,
  3142. X    /* M-c */ z_capitalizeword,
  3143. X    /* M-d */ z_killword,
  3144. X    /* M-e */ z_undefinedkey,
  3145. X    /* M-f */ z_forwardword,
  3146. X    /* M-g */ z_getline,
  3147. X    /* M-h */ z_runhelp,
  3148. X    /* M-i */ z_undefinedkey,
  3149. X    /* M-j */ z_undefinedkey,
  3150. X    /* M-k */ z_undefinedkey,
  3151. X    /* M-l */ z_downcaseword,
  3152. X    /* M-m */ z_undefinedkey,
  3153. X    /* M-n */ z_historysearchforward,
  3154. X    /* M-o */ z_undefinedkey,
  3155. X    /* M-p */ z_historysearchbackward,
  3156. X    /* M-q */ z_pushline,
  3157. X    /* M-r */ z_toggleliteralhistory,
  3158. X    /* M-s */ z_spellword,
  3159. X    /* M-t */ z_transposewords,
  3160. X    /* M-u */ z_upcaseword,
  3161. X    /* M-v */ z_undefinedkey,
  3162. X    /* M-w */ z_copyregionaskill,
  3163. X    /* M-x */ z_executenamedcmd,
  3164. X    /* M-y */ z_yankpop,
  3165. X    /* M-z */ z_executelastnamedcmd,
  3166. X    /* M-{ */ z_undefinedkey,
  3167. X    /* M-| */ z_vigotocolumn,
  3168. X    /* M-} */ z_undefinedkey,
  3169. X    /* M-~ */ z_undefinedkey,
  3170. X    /* M-^? */ z_backwardkillword,
  3171. X};
  3172. X
  3173. Xint viinsbind[32] =
  3174. X{
  3175. X    /* ^@ */ z_undefinedkey,
  3176. X    /* ^A */ z_selfinsert,
  3177. X    /* ^B */ z_selfinsert,
  3178. X    /* ^C */ z_undefinedkey,
  3179. X    /* ^D */ z_listchoices,
  3180. X    /* ^E */ z_selfinsert,
  3181. X    /* ^F */ z_selfinsert,
  3182. X    /* ^G */ z_selfinsert,
  3183. X    /* ^H */ z_vibackwarddeletechar,
  3184. X    /* ^I */ z_expandorcomplete,
  3185. X    /* ^J */ z_acceptline,
  3186. X    /* ^K */ z_killline,
  3187. X    /* ^L */ z_clearscreen,
  3188. X    /* ^M */ z_acceptline,
  3189. X    /* ^N */ z_selfinsert,
  3190. X    /* ^O */ z_selfinsert,
  3191. X    /* ^P */ z_selfinsert,
  3192. X    /* ^Q */ z_selfinsert,
  3193. X    /* ^R */ z_redisplay,
  3194. X    /* ^S */ z_selfinsert,
  3195. X    /* ^T */ z_selfinsert,
  3196. X    /* ^U */ z_vikillline,
  3197. X    /* ^V */ z_quotedinsert,
  3198. X    /* ^W */ z_vibackwardkillword,
  3199. X    /* ^X */ z_selfinsert,
  3200. X    /* ^Y */ z_selfinsert,
  3201. X    /* ^Z */ z_selfinsert,
  3202. X    /* ^[ */ z_sequenceleadin,
  3203. X    /* ^\ */ z_selfinsert,
  3204. X    /* ^] */ z_selfinsert,
  3205. X    /* ^^ */ z_selfinsert,
  3206. X    /* ^_ */ z_selfinsert,
  3207. X};
  3208. X
  3209. Xint vicmdbind[128] =
  3210. X{
  3211. X    /* ^@ */ z_undefinedkey,
  3212. X    /* ^A */ z_beginningofline,
  3213. X    /* ^B */ z_undefinedkey,
  3214. X    /* ^C */ z_undefinedkey,
  3215. X    /* ^D */ z_listchoices,
  3216. X    /* ^E */ z_endofline,
  3217. X    /* ^F */ z_undefinedkey,
  3218. X    /* ^G */ z_listexpand,
  3219. X    /* ^H */ z_backwarddeletechar,
  3220. X    /* ^I */ z_completeword,
  3221. X    /* ^J */ z_acceptline,
  3222. X    /* ^K */ z_killline,
  3223. X    /* ^L */ z_clearscreen,
  3224. X    /* ^M */ z_acceptline,
  3225. X    /* ^N */ z_downhistory,
  3226. X    /* ^O */ z_undefinedkey,
  3227. X    /* ^P */ z_uphistory,
  3228. X    /* ^Q */ z_undefinedkey,
  3229. X    /* ^R */ z_redisplay,
  3230. X    /* ^S */ z_undefinedkey,
  3231. X    /* ^T */ z_undefinedkey,
  3232. X    /* ^U */ z_killbuffer,
  3233. X    /* ^V */ z_undefinedkey,
  3234. X    /* ^W */ z_backwardkillword,
  3235. X    /* ^X */ z_expandorcomplete,
  3236. X    /* ^Y */ z_undefinedkey,
  3237. X    /* ^Z */ z_undefinedkey,
  3238. X    /* ^[ */ z_sequenceleadin,
  3239. X    /* ^\ */ z_undefinedkey,
  3240. X    /* ^] */ z_undefinedkey,
  3241. X    /* ^^ */ z_undefinedkey,
  3242. X    /* ^_ */ z_undefinedkey,
  3243. X    /*   */ z_viforwardchar,
  3244. X    /* ! */ z_undefinedkey,
  3245. X    /* " */ z_visetbuffer,
  3246. X    /* # */ z_poundinsert,
  3247. X    /* $ */ z_viendofline,
  3248. X    /* % */ z_vimatchbracket,
  3249. X    /* & */ z_undefinedkey,
  3250. X    /* ' */ z_vigotomarkline,
  3251. X    /* ( */ z_undefinedkey,
  3252. X    /* ) */ z_undefinedkey,
  3253. X    /* * */ z_undefinedkey,
  3254. X    /* + */ z_downlineorhistory,
  3255. X    /* , */ z_virevrepeatfind,
  3256. X    /* - */ z_uplineorhistory,
  3257. X    /* . */ z_virepeatchange,
  3258. X    /* / */ z_vihistorysearchbackward,
  3259. X    /* 0 */ z_vidigitorbeginningofline,
  3260. X    /* 1 */ z_digitargument,
  3261. X    /* 2 */ z_digitargument,
  3262. X    /* 3 */ z_digitargument,
  3263. X    /* 4 */ z_digitargument,
  3264. X    /* 5 */ z_digitargument,
  3265. X    /* 6 */ z_digitargument,
  3266. X    /* 7 */ z_digitargument,
  3267. X    /* 8 */ z_digitargument,
  3268. X    /* 9 */ z_digitargument,
  3269. X    /* : */ z_undefinedkey,
  3270. X    /* ; */ z_virepeatfind,
  3271. X    /* < */ z_viunindent,
  3272. X    /* = */ z_listchoices,
  3273. X    /* > */ z_viindent,
  3274. X    /* ? */ z_vihistorysearchforward,
  3275. X    /* @ */ z_undefinedkey,
  3276. X    /* A */ z_viaddeol,
  3277. X    /* B */ z_vibackwardblankword,
  3278. X    /* C */ z_vichangeeol,
  3279. X    /* D */ z_killline,
  3280. X    /* E */ z_viforwardblankwordend,
  3281. X    /* F */ z_vifindprevchar,
  3282. X    /* G */ z_vifetchhistory,
  3283. X    /* H */ z_vicapslockpanic,
  3284. X    /* I */ z_viinsertbol,
  3285. X    /* J */ z_historysearchforward,
  3286. X    /* K */ z_historysearchbackward,
  3287. X    /* L */ z_undefinedkey,
  3288. X    /* M */ z_undefinedkey,
  3289. X    /* N */ z_virevrepeatsearch,
  3290. X    /* O */ z_viopenlineabove,
  3291. X    /* P */ z_yank,
  3292. X    /* Q */ z_undefinedkey,
  3293. X    /* R */ z_vireplace,
  3294. X    /* S */ z_vichangewholeline,
  3295. X    /* T */ z_vifindprevcharskip,
  3296. X    /* U */ z_undefinedkey,
  3297. X    /* V */ z_undefinedkey,
  3298. X    /* W */ z_viforwardblankword,
  3299. X    /* X */ z_vibackwarddeletechar,
  3300. X    /* Y */ z_viyankeol,
  3301. X    /* Z */ z_undefinedkey,
  3302. X    /* [ */ z_undefinedkey,
  3303. X    /* \ */ z_completeword,
  3304. X    /* ] */ z_undefinedkey,
  3305. X    /* ^ */ z_vifirstnonblank,
  3306. X    /* _ */ z_undefinedkey,
  3307. X    /* ` */ z_vigotomark,
  3308. X    /* a */ z_viaddnext,
  3309. X    /* b */ z_vibackwardword,
  3310. X    /* c */ z_vichange,
  3311. X    /* d */ z_videlete,
  3312. X    /* e */ z_viforwardwordend,
  3313. X    /* f */ z_vifindnextchar,
  3314. X    /* g */ z_undefinedkey,
  3315. X    /* h */ z_vibackwardchar,
  3316. X    /* i */ z_viinsert,
  3317. X    /* j */ z_downlineorhistory,
  3318. X    /* k */ z_uplineorhistory,
  3319. X    /* l */ z_viforwardchar,
  3320. X    /* m */ z_visetmark,
  3321. X    /* n */ z_virepeatsearch,
  3322. X    /* o */ z_viopenlinebelow,
  3323. X    /* p */ z_viputafter,
  3324. X    /* q */ z_undefinedkey,
  3325. X    /* r */ z_vireplacechars,
  3326. X    /* s */ z_visubstitute,
  3327. X    /* t */ z_vifindnextcharskip,
  3328. X    /* u */ z_viundochange,
  3329. X    /* v */ z_undefinedkey,
  3330. X    /* w */ z_viforwardword,
  3331. X    /* x */ z_videletechar,
  3332. X    /* y */ z_viyank,
  3333. X    /* z */ z_undefinedkey,
  3334. X    /* { */ z_undefinedkey,
  3335. X    /* | */ z_vigotocolumn,
  3336. X    /* } */ z_undefinedkey,
  3337. X    /* ~ */ z_viswapcase,
  3338. X    /* ^? */ z_backwarddeletechar,
  3339. X};
  3340. END_OF_FILE
  3341.   if test 20731 -ne `wc -c <'zsh-2.5.0/src/zle_bindings.c'`; then
  3342.     echo shar: \"'zsh-2.5.0/src/zle_bindings.c'\" unpacked with wrong size!
  3343.   fi
  3344.   # end of 'zsh-2.5.0/src/zle_bindings.c'
  3345. fi
  3346. echo shar: End of archive 14 \(of 18\).
  3347. cp /dev/null ark14isdone
  3348. MISSING=""
  3349. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
  3350.     if test ! -f ark${I}isdone ; then
  3351.     MISSING="${MISSING} ${I}"
  3352.     fi
  3353. done
  3354. if test "${MISSING}" = "" ; then
  3355.     echo You have unpacked all 18 archives.
  3356.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  3357. else
  3358.     echo You still must unpack the following archives:
  3359.     echo "        " ${MISSING}
  3360. fi
  3361. exit 0
  3362. exit 0 # Just in case...
  3363.