home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume35 / zsh / part20 < prev    next >
Text File  |  1993-02-20  |  56KB  |  2,525 lines

  1. Newsgroups: comp.sources.misc
  2. From: zsh-list@cs.uow.edu.au (The Zsh Mailing List)
  3. Subject: v35i070:  zsh - The Z Shell, version 2.3.1, Part20/22
  4. Message-ID: <1993Feb20.212909.29520@sparky.imd.sterling.com>
  5. X-Md4-Signature: 5b503ac202a2325d8386bfc51e978f37
  6. Date: Sat, 20 Feb 1993 21:29:09 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: zsh-list@cs.uow.edu.au (The Zsh Mailing List)
  10. Posting-number: Volume 35, Issue 70
  11. Archive-name: zsh/part20
  12. Environment: UNIX
  13. Supersedes: zsh2.2: Volume 29, Issue 97-113
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  20. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  21. # Contents:  doc/intro.txt.02 help/limit help/source src/funcs.h
  22. #   src/text.c src/watch.c src/zle.h src/zle_vi.c src/zle_word.c
  23. # Wrapped by mattson@odin on Sat Feb  6 14:41:55 1993
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. echo If this archive is complete, you will see the following message:
  26. echo '          "shar: End of archive 20 (of 22)."'
  27. if test -f 'doc/intro.txt.02' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'doc/intro.txt.02'\"
  29. else
  30.   echo shar: Extracting \"'doc/intro.txt.02'\" \(8938 characters\)
  31.   sed "s/^X//" >'doc/intro.txt.02' <<'END_OF_FILE'
  32. XThus, you can view a file simply by typing:
  33. X
  34. X% <file
  35. Xfoo!
  36. X
  37. X
  38. XHowever, this is not csh or sh compatible.  To correct this,
  39. Xchange  the  value of the parameter NULLCMD, which is cat by
  40. Xdefault.
  41. X
  42. X% NULLCMD=:
  43. X% >file
  44. X% ls -l file
  45. X-rw-r--r--  1 pfalstad        0 May 24 05:41 file
  46. X
  47. X
  48. XIf NULLCMD is unset, the shell reports an error if  no  com-
  49. Xmand is specified (like csh).
  50. X
  51. X
  52. X
  53. X
  54. X
  55. X
  56. X
  57. X                           - 36 -
  58. X
  59. X% unset NULLCMD
  60. X% >file
  61. Xzsh: redirection with no command
  62. X
  63. X
  64. XActually, READNULLCMD is used whenever you have a null  com-
  65. Xmand  reading  input  from a single file.  Thus, you can set
  66. XREADNULLCMD to more or less rather than cat.  Also,  if  you
  67. Xset  NULLCMD  to  : for sh compatibility, you can still read
  68. Xfiles with < file if you leave READNULLCMD set to more.
  69. X
  70. XPrompting
  71. X
  72. XThe default prompt for zsh is:
  73. X
  74. Xphoenix% echo $PROMPT
  75. X%m%#
  76. X
  77. X
  78. XThe %m stands for the short form of  the  current  hostname,
  79. Xand  the  %# stands for a % or a #, depending on whether the
  80. Xshell is running as root or not.  zsh  supports  many  other
  81. Xcontrol sequences in the PROMPT variable.
  82. X
  83. X% PROMPT='%/> '
  84. X/u/pfalstad/etc/TeX/zsh>
  85. X
  86. X% PROMPT='%~> '
  87. X~/etc/TeX/zsh>
  88. X
  89. X% PROMPT='%h %~> '
  90. X6 ~/etc/TeX/zsh>
  91. X
  92. X
  93. X%h represents the number of current history event.
  94. X
  95. X% PROMPT='%h %~ %M> '
  96. X10 ~/etc/TeX/zsh apple-gunkies.gnu.ai.mit.edu>
  97. X
  98. X% PROMPT='%h %~ %m> '
  99. X11 ~/etc/TeX/zsh apple-gunkies>
  100. X
  101. X% PROMPT='%h %t> '
  102. X12 6:11am>
  103. X
  104. X% PROMPT='%n %w tty%l>'
  105. Xpfalstad Fri 24 ttyp0>
  106. X
  107. X
  108. XAlso available is the RPROMPT parameter.  If  this  is  set,
  109. Xthe shell puts a prompt on the right side of the screen.
  110. X
  111. X
  112. X
  113. X
  114. X
  115. X
  116. X
  117. X
  118. X
  119. X
  120. X
  121. X
  122. X
  123. X                           - 37 -
  124. X
  125. X% RPROMPT='%t'
  126. X%                                                      6:14am
  127. X
  128. X% RPROMPT='%~'
  129. X%                                               ~/etc/TeX/zsh
  130. X
  131. X% PROMPT='%l %T %m[%h] ' RPROMPT=' %~'
  132. Xp0 6:15 phoenix[5]                              ~/etc/TeX/zsh
  133. X
  134. X
  135. XThese special escape sequences can also be used with the  -P
  136. Xoption to print:
  137. X
  138. X% print -P %h tty%l
  139. X15 ttyp1
  140. X
  141. X
  142. X
  143. XThe POSTEDIT parameter is printed whenever the editor exits.
  144. XThis  can  be  useful  for termcap tricks.  To highlight the
  145. Xprompt  and  command  line  while  leaving  command   output
  146. Xunhighlighted, try this:
  147. X
  148. X% POSTEDIT=`echotc se`
  149. X% PROMPT='%S%% '
  150. X
  151. X
  152. X
  153. XLogin/logout watching
  154. X
  155. XYou can specify login or logout events to monitor by setting
  156. Xthe  watch variable.  Normally, this is done by specifying a
  157. Xlist of usernames.
  158. X
  159. X% watch=( pfalstad subbarao sukthnkr egsirer )
  160. X
  161. X
  162. XThe log command reports all people logged in  that  you  are
  163. Xwatching for.
  164. X
  165. X% log
  166. Xpfalstad has logged on p0 from mickey.
  167. Xpfalstad has logged on p5 from mickey.
  168. X% ...
  169. Xsubbarao has logged on p8 from phoenix.
  170. X% ...
  171. Xsubbarao has logged off p8 from phoenix.
  172. X% ...
  173. Xsukthnkr has logged on p8 from dew.
  174. X% ...
  175. Xsukthnkr has logged off p8 from dew.
  176. X
  177. X
  178. XIf you specify hostnames with an @ prepended, the shell will
  179. Xwatch for all users logging in from the specified host.
  180. X
  181. X
  182. X
  183. X
  184. X
  185. X
  186. X
  187. X
  188. X
  189. X                           - 38 -
  190. X
  191. X% watch=( @mickey @phoenix )
  192. X% log
  193. Xdjthongs has logged on q2 from phoenix.
  194. Xpfalstad has logged on p0 from mickey.
  195. Xpfalstad has logged on p5 from mickey.
  196. X
  197. X
  198. XIf you give a tty name with a % prepended,  the  shell  will
  199. Xwatch for all users logging in on that tty.
  200. X
  201. X% watch=( %ttyp0 %console )
  202. X% log
  203. Xroot has logged on console from .
  204. Xpfalstad has logged on p0 from mickey.
  205. X
  206. X
  207. XThe format of the reports may also be changed.
  208. X
  209. X
  210. X
  211. X
  212. X
  213. X
  214. X
  215. X
  216. X
  217. X
  218. X
  219. X
  220. X
  221. X
  222. X
  223. X
  224. X
  225. X
  226. X
  227. X
  228. X
  229. X
  230. X
  231. X
  232. X
  233. X
  234. X
  235. X
  236. X
  237. X
  238. X
  239. X
  240. X
  241. X
  242. X
  243. X
  244. X
  245. X
  246. X
  247. X
  248. X
  249. X
  250. X
  251. X
  252. X
  253. X
  254. X
  255. X                           - 39 -
  256. X
  257. X% watch=( pfalstad gettes eps djthongs jcorr bdavis )
  258. X% log
  259. Xjcorr has logged on tf from 128.112.176.3:0.
  260. Xjcorr has logged on r0 from 128.112.176.3:0.
  261. Xgettes has logged on p4 from yo:0.0.
  262. Xdjthongs has logged on pe from grumpy:0.0.
  263. Xdjthongs has logged on q2 from phoenix.
  264. Xbdavis has logged on qd from BRUNO.
  265. Xeps has logged on p3 from csx30:0.0.
  266. Xpfalstad has logged on p0 from mickey.
  267. Xpfalstad has logged on p5 from mickey.
  268. X% WATCHFMT='%n on tty%l from %M'
  269. X% log
  270. Xjcorr on ttytf from 128.112.176.3:0.
  271. Xjcorr on ttyr0 from 128.112.176.3:0.
  272. Xgettes on ttyp4 from yo:0.0
  273. Xdjthongs on ttype from grumpy:0.0
  274. Xdjthongs on ttyq2 from phoenix.Princeto
  275. Xbdavis on ttyqd from BRUNO.pppl.gov
  276. Xeps on ttyp3 from csx30:0.0
  277. Xpfalstad on ttyp0 from mickey.Princeton
  278. Xpfalstad on ttyp5 from mickey.Princeton
  279. X% WATCHFMT='%n fm %m'
  280. X% log
  281. Xjcorr fm 128.112.176.3:0
  282. Xjcorr fm 128.112.176.3:0
  283. Xgettes fm yo:0.0
  284. Xdjthongs fm grumpy:0.0
  285. Xdjthongs fm phoenix
  286. Xbdavis fm BRUNO
  287. Xeps fm csx30:0.0
  288. Xpfalstad fm mickey
  289. Xpfalstad fm mickey
  290. X% WATCHFMT='%n %a at %t %w.'
  291. X% log
  292. Xjcorr logged on at 3:15pm Mon 20.
  293. Xjcorr logged on at 3:16pm Wed 22.
  294. Xgettes logged on at 6:54pm Wed 22.
  295. Xdjthongs logged on at 7:19am Thu 23.
  296. Xdjthongs logged on at 7:20am Thu 23.
  297. Xbdavis logged on at 12:40pm Thu 23.
  298. Xeps logged on at 4:19pm Thu 23.
  299. Xpfalstad logged on at 3:39am Fri 24.
  300. Xpfalstad logged on at 3:42am Fri 24.
  301. X
  302. X
  303. XIf you have a .friends file in your home directory,  a  con-
  304. Xvenient  way to make zsh watch for all your friends is to do
  305. Xthis:
  306. X
  307. X% watch=( $(< ~/.friends) )
  308. X% echo $watch
  309. Xsubbarao maruchck root sukthnkr ...
  310. X
  311. X
  312. XIf watch is set to all, then all users  logging  in  or  out
  313. Xwill be reported.
  314. X
  315. X
  316. X
  317. X
  318. X
  319. X
  320. X
  321. X                           - 40 -
  322. XOptions
  323. X
  324. XSome options have already been mentioned;  here  are  a  few
  325. Xmore:
  326. X
  327. X% cd /
  328. X% setopt autocd
  329. X% bin
  330. X% pwd
  331. X/bin
  332. X% ../etc
  333. X% pwd
  334. X/etc
  335. X
  336. X
  337. XUsing the AUTOCD option, you can simply type the name  of  a
  338. Xdirectory, and it will become the current directory.
  339. X
  340. X% setopt cdablevars
  341. X% foo=/tmp
  342. X% cd foo
  343. X/tmp
  344. X
  345. X
  346. XWith CDABLEVARS, if the argument to cd  is  the  name  of  a
  347. Xparameter  whose  value is a valid directory, it will become
  348. Xthe current directory.
  349. X
  350. XCORRECT turns on spelling correction for commands,  and  the
  351. XCORRECTALL option turns on spelling correction for all argu-
  352. Xments.
  353. X
  354. X% setopt correct
  355. X% sl
  356. Xzsh: correct `sl' to `ls' [nyae]? y
  357. X% setopt correctall
  358. X% ls x.v11r4
  359. Xzsh: correct `x.v11r4' to `X.V11R4' [nyae]? n
  360. X/usr/princton/src/x.v11r4 not found
  361. X% ls /etc/paswd
  362. Xzsh: correct to `/etc/paswd' to `/etc/passwd' [nyae]? y
  363. X/etc/passwd
  364. X
  365. X
  366. XIf you press y when the  shell  asks  you  if  you  want  to
  367. Xcorrect  a  word,  it will be corrected.  If you press n, it
  368. Xwill be left alone.  Pressing  a  aborts  the  command,  and
  369. Xpressing e brings the line up for editing again, in case you
  370. Xagree the word is spelled  wrong  but  you  don't  like  the
  371. Xcorrection.
  372. X
  373. XNormally, a quoted expression may contain a newline:
  374. X
  375. X% echo '
  376. X> foo
  377. X> '
  378. X
  379. Xfoo
  380. X
  381. X%
  382. X
  383. X
  384. X
  385. X
  386. X
  387. X                           - 41 -
  388. XWith CSHJUNKIEQUOTES set, this is illegal, as it is in csh.
  389. X
  390. X% setopt cshjunkiequotes
  391. X% ls 'foo
  392. Xzsh: unmatched '
  393. X
  394. X
  395. XGLOBDOTS lets files beginning with a .  be  matched  without
  396. Xexplicitly specifying the dot.
  397. X
  398. X% ls -d *x*
  399. XMailboxes
  400. X% setopt globdots
  401. X% ls -d *x*
  402. X.exrc         .pnewsexpert  .xserverrc
  403. X.mushexpert   .xinitrc      Mailboxes
  404. X
  405. X
  406. XHISTIGNOREDUPS prevents the current line from being saved in
  407. Xthe  history  if it is the same as the previous one; HISTIG-
  408. XNORESPACE prevents the current line from being saved  if  it
  409. Xbegins with a space.
  410. X
  411. X% PROMPT='%h> '
  412. X39> setopt histignoredups
  413. X40> echo foo
  414. Xfoo
  415. X41> echo foo
  416. Xfoo
  417. X41> echo foo
  418. Xfoo
  419. X41> echo bar
  420. Xbar
  421. X42> setopt histignorespace
  422. X43>  echo foo
  423. Xfoo
  424. X43>  echo fubar
  425. Xfubar
  426. X43>  echo fubar
  427. Xfubar
  428. X
  429. X
  430. XIGNOREBRACES turns off csh-style brace expansion.
  431. X
  432. X% echo x{y{z,a},{b,c}d}e
  433. Xxyze xyae xbde xcde
  434. X% setopt ignorebraces
  435. X% echo x{y{z,a},{b,c}d}e
  436. Xx{y{z,a},{b,c}d}e
  437. X
  438. X
  439. XIGNOREEOF forces the user to type exit or logout, instead of
  440. Xjust pressing ^D.
  441. X
  442. X% setopt ignoreeof
  443. X% ^D
  444. Xzsh: use 'exit' to exit.
  445. X
  446. X
  447. XINTERACTIVECOMMENTS turns on interactive comments;  comments
  448. X
  449. X
  450. X
  451. X
  452. X
  453. X                           - 42 -
  454. Xbegin with a #.
  455. X
  456. X% setopt interactivecomments
  457. X% date # this is a comment
  458. XFri May 24 06:54:14 EDT 1991
  459. X
  460. X
  461. XNOCLOBBER prevents  you  from  accidentally  overwriting  an
  462. Xexisting file.
  463. X
  464. X% setopt noclobber
  465. X% cat /dev/null >~/.zshrc
  466. Xzsh: file exists: /u/pfalstad/.zshrc
  467. X
  468. X
  469. XIf you really do want to clobber a file, you can use the  >!
  470. Xoperator.   To  make  things  easier  in this case, the > is
  471. Xstored in the history list as a >!:
  472. X
  473. X% cat /dev/null >! ~/.zshrc
  474. X% cat /etc/motd > ~/.zshrc
  475. Xzsh: file exists: /u/pfalstad/.zshrc
  476. X% !!
  477. Xcat /etc/motd >! ~/.zshrc
  478. X% ...
  479. X
  480. X
  481. XRCQUOTES lets you use a more elegant  method  for  including
  482. Xsingle quotes in a singly quoted string:
  483. X
  484. X% echo '"don'\''t do that."'
  485. X"don't do that."
  486. X% echo '"don''t do that."'
  487. X"dont do that."
  488. X% setopt rcquotes
  489. X% echo '"don''t do that."'
  490. X"don't do that."
  491. X
  492. X
  493. XFinally, SUNKEYBOARDHACK wins the award  for  the  strangest
  494. Xoption.   If a line ends with `, and there are an odd number
  495. Xof them on the line, the shell will ignore the  trailing  `.
  496. XThis  is  provided  for  keyboards  whose  RETURN key is too
  497. Xsmall, and too close to the ` key.
  498. X
  499. X% setopt sunkeyboardhack
  500. X% date`
  501. XFri May 24 06:55:38 EDT 1991
  502. X
  503. X
  504. X
  505. XClosing Comments
  506. X
  507. XI would be happy to receive mail if anyone has any tricks or
  508. Xideas  to  add to this document, or if there are some points
  509. Xthat could be  made  clearer  or  covered  more  thoroughly.
  510. XPlease notify me of any errors in this document.
  511. X
  512. X
  513. X
  514. X
  515. X
  516. X
  517. END_OF_FILE
  518.   if test 8938 -ne `wc -c <'doc/intro.txt.02'`; then
  519.     echo shar: \"'doc/intro.txt.02'\" unpacked with wrong size!
  520.   fi
  521.   # end of 'doc/intro.txt.02'
  522. fi
  523. if test -f 'help/limit' -a "${1}" != "-c" ; then 
  524.   echo shar: Will not clobber existing file \"'help/limit'\"
  525. else
  526.   echo shar: Extracting \"'help/limit'\" \(1253 characters\)
  527.   sed "s/^X//" >'help/limit' <<'END_OF_FILE'
  528. X     limit [ -h ] [ resource [ limit ] ] ...
  529. X     limit -s
  530. X          Limit the  resource  consumption  of  children  of  the
  531. X          current  shell.   If  limit is not specified, print the
  532. X          current limit placed on  resource;  otherwise  set  the
  533. X          limit to the specified value.  If the -h flag is given,
  534. X          use hard limits instead of soft limits.  If no resource
  535. X          is given, print all limits.
  536. X
  537. X          resource is one of:
  538. X
  539. X          cputime
  540. X               Maximum CPU seconds per process.
  541. X          filesize
  542. X               Largest single file allowed.
  543. X          datasize
  544. X               Maximum data size (including stack) for each  pro-
  545. X               cess.
  546. X          stacksize
  547. X               Maximum stack size for each process.
  548. X          coredumpsize
  549. X               Maximum size of a core dump.
  550. X          resident
  551. X               Maximum resident set size.
  552. X          descriptors
  553. X               Maximum value for a file descriptor.
  554. X
  555. X          limit is a number, with an optional scaling factor,  as
  556. X          follows:
  557. X
  558. X          nh   hours.
  559. X          nk   kilobytes. This is the default for  all  but  cpu-
  560. X               time.
  561. X          nm   megabytes or minutes.
  562. X          mm:ss
  563. X               minutes and seconds.
  564. END_OF_FILE
  565.   if test 1253 -ne `wc -c <'help/limit'`; then
  566.     echo shar: \"'help/limit'\" unpacked with wrong size!
  567.   fi
  568.   # end of 'help/limit'
  569. fi
  570. if test -f 'help/source' -a "${1}" != "-c" ; then 
  571.   echo shar: Will not clobber existing file \"'help/source'\"
  572. else
  573.   echo shar: Extracting \"'help/source'\" \(552 characters\)
  574.   sed "s/^X//" >'help/source' <<'END_OF_FILE'
  575. X     source file [ arg ... ]
  576. X     . file [ arg ... ]
  577. X          Read and execute commands  from  file  in  the  current
  578. X          shell  environment.   If file does not contain a slash,
  579. X          the shell looks in the components of path to  find  the
  580. X          directory  containing  file.   If any arguments arg are
  581. X          given, they become the positional parameters;  the  old
  582. X          positional  parameters  are  restored  when the file is
  583. X          done executing.  The exit status is the exit status  of
  584. X          the last command executed.
  585. END_OF_FILE
  586.   if test 552 -ne `wc -c <'help/source'`; then
  587.     echo shar: \"'help/source'\" unpacked with wrong size!
  588.   fi
  589.   # end of 'help/source'
  590. fi
  591. if test -f 'src/funcs.h' -a "${1}" != "-c" ; then 
  592.   echo shar: Will not clobber existing file \"'src/funcs.h'\"
  593. else
  594.   echo shar: Extracting \"'src/funcs.h'\" \(1219 characters\)
  595.   sed "s/^X//" >'src/funcs.h' <<'END_OF_FILE'
  596. Xstruct asgment;
  597. Xstruct utmp;
  598. Xstruct hp;
  599. Xtypedef struct hp *Hp;
  600. X
  601. X#include "builtin.pro"
  602. X#include "cond.pro"
  603. X#include "exec.pro"
  604. X#include "glob.pro"
  605. X#include "hist.pro"
  606. X#include "init.pro"
  607. X#include "jobs.pro"
  608. X#include "lex.pro"
  609. X#include "loop.pro"
  610. X#include "math.pro"
  611. X#include "mem.pro"
  612. X#include "params.pro"
  613. X#include "parse.pro"
  614. X#include "subst.pro"
  615. X#include "table.pro"
  616. X#include "text.pro"
  617. X#include "utils.pro"
  618. X#include "watch.pro"
  619. X#include "zle_hist.pro"
  620. X#include "zle_main.pro"
  621. X#include "zle_misc.pro"
  622. X#include "zle_move.pro"
  623. X#include "zle_refresh.pro"
  624. X#include "zle_tricky.pro"
  625. X#include "zle_utils.pro"
  626. X#include "zle_vi.pro"
  627. X#include "zle_word.pro"
  628. X
  629. Xchar *mktemp DCLPROTO((char *));
  630. X#ifndef HAS_STDLIB
  631. Xchar *malloc DCLPROTO((int));
  632. Xchar *realloc DCLPROTO((char *,int));
  633. Xchar *calloc DCLPROTO((int,int));
  634. X#endif
  635. Xchar *ttyname DCLPROTO((int));
  636. X
  637. Xextern char PC, *BC, *UP;
  638. Xextern short ospeed;
  639. Xextern int tgetent DCLPROTO((char *bp, char *name));
  640. Xextern int tgetnum DCLPROTO((char *id));
  641. Xextern int tgetflag DCLPROTO((char *id));
  642. Xextern char *tgetstr DCLPROTO((char *id, char **area));
  643. Xextern char *tgoto DCLPROTO((char *cm, int destcol, int destline));
  644. Xextern int tputs DCLPROTO((char *cp, int affcnt, int (*outc)()));
  645. END_OF_FILE
  646.   if test 1219 -ne `wc -c <'src/funcs.h'`; then
  647.     echo shar: \"'src/funcs.h'\" unpacked with wrong size!
  648.   fi
  649.   # end of 'src/funcs.h'
  650. fi
  651. if test -f 'src/text.c' -a "${1}" != "-c" ; then 
  652.   echo shar: Will not clobber existing file \"'src/text.c'\"
  653. else
  654.   echo shar: Extracting \"'src/text.c'\" \(8624 characters\)
  655.   sed "s/^X//" >'src/text.c' <<'END_OF_FILE'
  656. X/*
  657. X *
  658. X * text.c - textual representations of syntax trees
  659. X *
  660. X * This file is part of zsh, the Z shell.
  661. X *
  662. X * This software is Copyright 1992 by Paul Falstad
  663. X *
  664. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  665. X * use this software as long as: there is no monetary profit gained
  666. X * specifically from the use or reproduction of this software, it is not
  667. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  668. X * included prominently in any copy made. 
  669. X *
  670. X * The author make no claims as to the fitness or correctness of this software
  671. X * for any use whatsoever, and it is provided as is. Any use of this software
  672. X * is at the user's own risk. 
  673. X *
  674. X */
  675. X
  676. X#include "zsh.h"
  677. X
  678. Xstatic char *tptr,*tbuf,*tlim;
  679. Xstatic int tsiz,tindent,tnewlins;
  680. X
  681. X/* add a character to the text buffer */
  682. X
  683. Xvoid taddchr(c) /**/
  684. Xint c;
  685. X{
  686. X    *tptr++ = c;
  687. X    if (tptr == tlim) {
  688. X        if (!tbuf) { tptr--; return; }
  689. X        tbuf = realloc(tbuf,tsiz *= 2);
  690. X        tlim = tbuf+tsiz;
  691. X        tptr = tbuf+tsiz/2;
  692. X    }
  693. X}
  694. X
  695. X/* add a string to the text buffer */
  696. X
  697. Xvoid taddstr(s) /**/
  698. Xchar *s;
  699. X{
  700. Xint sl = strlen(s);
  701. X
  702. X    while (tptr+sl >= tlim) {
  703. X        int x = tptr-tbuf;
  704. X
  705. X        if (!tbuf) return;
  706. X        tbuf = realloc(tbuf,tsiz *= 2);
  707. X        tlim = tbuf+tsiz;
  708. X        tptr = tbuf+x;
  709. X    }
  710. X    strcpy(tptr,s);
  711. X    tptr += sl;
  712. X}
  713. X
  714. X/* add an integer to the text buffer */
  715. X
  716. Xvoid taddint(x) /**/
  717. Xint x;
  718. X{
  719. Xchar buf[10];
  720. X
  721. X    sprintf(buf,"%d",x);
  722. X    taddstr(buf);
  723. X}
  724. X
  725. X/* add a newline, or something equivalent, to the text buffer */
  726. X
  727. Xvoid taddnl() /**/
  728. X{
  729. Xint t0;
  730. X
  731. X    if (tnewlins)
  732. X        {
  733. X        taddchr('\n');
  734. X        for (t0 = 0; t0 != tindent; t0++)
  735. X            taddchr('\t');
  736. X        }
  737. X    else
  738. X        taddstr("; ");
  739. X}
  740. X
  741. X/* get a permanent textual representation of n */
  742. X
  743. Xchar *getpermtext(n) /**/
  744. Xstruct node *n;
  745. X{
  746. X    tnewlins = 1;
  747. X    tbuf = zalloc(tsiz = 32);
  748. X    tptr = tbuf;
  749. X    tlim = tbuf+tsiz;
  750. X    tindent = 1;
  751. X    gettext2(n);
  752. X    *tptr = '\0';
  753. X    untokenize(tbuf);
  754. X    return tbuf;
  755. X}
  756. X
  757. X/* get a representation of n in a job text buffer */
  758. X
  759. Xchar *getjobtext(n) /**/
  760. Xstruct node *n;
  761. X{
  762. Xstatic char jbuf[JOBTEXTSIZE];
  763. X
  764. X    tnewlins = 0;
  765. X    tbuf = NULL;
  766. X    tptr = jbuf;
  767. X    tlim = tptr+JOBTEXTSIZE-1;
  768. X    tindent = 1;
  769. X    gettext2(n);
  770. X    *tptr = '\0';
  771. X    untokenize(jbuf);
  772. X    return jbuf;
  773. X}
  774. X
  775. X#define gt2(X) gettext2((struct node *) (X))
  776. X
  777. X/*
  778. X    "gettext2" or "type checking and how to avoid it"
  779. X    an epic function by Paul Falstad
  780. X*/
  781. X
  782. X#define _Cond(X) ((Cond) (X))
  783. X#define _Cmd(X) ((Cmd) (X))
  784. X#define _Pline(X) ((Pline) (X))
  785. X#define _Sublist(X) ((Sublist) (X))
  786. X#define _List(X) ((List) (X))
  787. X#define _casecmd(X) ((struct casecmd *) (X))
  788. X#define _ifcmd(X) ((struct ifcmd *) (X))
  789. X#define _whilecmd(X) ((struct whilecmd *) (X))
  790. X
  791. Xvoid gettext2(n) /**/
  792. Xstruct node *n;
  793. X{
  794. XCmd nn;
  795. XCond nm;
  796. X
  797. X    if (!n)
  798. X        return;
  799. X    switch (n->type)
  800. X        {
  801. X        case N_LIST:
  802. X            gt2(_List(n)->left);
  803. X            if (_List(n)->type == ASYNC)
  804. X                taddstr(" &");
  805. X            simplifyright(_List(n));
  806. X            if (_List(n)->right)
  807. X                {
  808. X                if (tnewlins)
  809. X                    taddnl();
  810. X                else
  811. X                    taddstr((_List(n)->type == ASYNC) ? " " : "; ");
  812. X                gt2(_List(n)->right);
  813. X                }
  814. X            break;
  815. X        case N_SUBLIST:
  816. X            if (_Sublist(n)->flags & PFLAG_NOT)
  817. X                taddstr("! ");
  818. X            if (_Sublist(n)->flags & PFLAG_COPROC)
  819. X                taddstr("coproc ");
  820. X            gt2(_Sublist(n)->left);
  821. X            if (_Sublist(n)->right)
  822. X                {
  823. X                taddstr((_Sublist(n)->type == ORNEXT) ? " || " : " && ");
  824. X                gt2(_Sublist(n)->right);
  825. X                }
  826. X            break;
  827. X        case N_PLINE:
  828. X            gt2(_Pline(n)->left);
  829. X            if (_Pline(n)->type == PIPE)
  830. X                {
  831. X                taddstr(" | ");
  832. X                gt2(_Pline(n)->right);
  833. X                }
  834. X            break;
  835. X        case N_CMD:
  836. X            nn = _Cmd(n);
  837. X            if (nn->flags & CFLAG_EXEC)
  838. X                taddstr("exec ");
  839. X            if (nn->flags & CFLAG_COMMAND)
  840. X                taddstr("command ");
  841. X            switch (nn->type)
  842. X                {
  843. X                case SIMPLE:
  844. X                    getsimptext(nn);
  845. X                    break;
  846. X                case SUBSH:
  847. X                    taddstr("( ");
  848. X                    tindent++;
  849. X                    gt2(nn->u.list);
  850. X                    tindent--;
  851. X                    taddstr(" )");
  852. X                    break;
  853. X                case ZCTIME:
  854. X                    taddstr("time ");
  855. X                    tindent++;
  856. X                    gt2(nn->u.pline);
  857. X                    tindent--;
  858. X                    break;
  859. X                case FUNCDEF:
  860. X                    taddlist(nn->args);
  861. X                    taddstr(" () {");
  862. X                    tindent++;
  863. X                    taddnl();
  864. X                    gt2(nn->u.list);
  865. X                    tindent--;
  866. X                    taddnl();
  867. X                    taddstr("}");
  868. X                    break;
  869. X                case CURSH:
  870. X                    taddstr("{ ");
  871. X                    tindent++;
  872. X                    gt2(nn->u.list);
  873. X                    tindent--;
  874. X                    taddstr(" }");
  875. X                    break;
  876. X                case CFOR:
  877. X                case CSELECT:
  878. X                    taddstr((nn->type == CFOR) ? "for " : "select ");
  879. X                    taddstr(nn->u.forcmd->name);
  880. X                    if (nn->u.forcmd->inflag)
  881. X                        {
  882. X                        taddstr(" in ");
  883. X                        taddlist(nn->args);
  884. X                        }
  885. X                    taddnl();
  886. X                    taddstr("do");
  887. X                    tindent++;
  888. X                    taddnl();
  889. X                    gt2(nn->u.forcmd->list);
  890. X                    taddnl();
  891. X                    tindent--;
  892. X                    taddstr("done");
  893. X                    break;
  894. X                case CIF:
  895. X                    gt2(nn->u.ifcmd);
  896. X                    taddstr("fi");
  897. X                    break;
  898. X                case CCASE:
  899. X                    taddstr("case ");
  900. X                    taddlist(nn->args);
  901. X                    taddstr(" in");
  902. X                    tindent++;
  903. X                    taddnl();
  904. X                    gt2(nn->u.casecmd);
  905. X                    tindent--;
  906. X                    if (tnewlins)
  907. X                        taddnl();
  908. X                    else
  909. X                        taddchr(' ');
  910. X                    taddstr("esac");
  911. X                    break;
  912. X                case COND:
  913. X                    taddstr("[[ ");
  914. X                    gt2(nn->u.cond);
  915. X                    taddstr(" ]]");
  916. X                    break;
  917. X                case CREPEAT:
  918. X                    taddstr("repeat ");
  919. X                    taddlist(nn->args);
  920. X                    taddnl();
  921. X                    taddstr("do");
  922. X                    tindent++;
  923. X                    taddnl();
  924. X                    gt2(nn->u.list);
  925. X                    tindent--;
  926. X                    taddnl();
  927. X                    taddstr("done");
  928. X                    break;
  929. X                case CWHILE:
  930. X                    gt2(nn->u.whilecmd);
  931. X                    break;
  932. X                }
  933. X            getredirs(nn);
  934. X            break;
  935. X        case N_COND:
  936. X            nm = _Cond(n);
  937. X            switch (nm->type)
  938. X                {
  939. X                case COND_NOT:
  940. X                    taddstr("! ");
  941. X                    gt2(nm->left);
  942. X                    break;
  943. X                case COND_AND:
  944. X                    taddstr("( ");
  945. X                    gt2(nm->left);
  946. X                    taddstr(" && ");
  947. X                    gt2(nm->right);
  948. X                    taddstr(" )");
  949. X                    break;
  950. X                case COND_OR:
  951. X                    taddstr("( ");
  952. X                    gt2(nm->left);
  953. X                    taddstr(" || ");
  954. X                    gt2(nm->right);
  955. X                    taddstr(" )");
  956. X                    break;
  957. X                default:
  958. X                    {
  959. X                    static char *c1[] = {
  960. X                        " = "," != "," < "," > "," -nt "," -ot "," -ef "," -eq ",
  961. X                        " -ne "," -lt "," -gt "," -le "," -ge "
  962. X                        };
  963. X                    if (nm->right)
  964. X                        taddstr(nm->left);
  965. X                    if (nm->type <= COND_GE)
  966. X                        taddstr(c1[nm->type-COND_STREQ]);
  967. X                    else
  968. X                        {
  969. X                        char c2[5];
  970. X                        c2[0] = ' '; c2[1] = '-';
  971. X                        c2[2] = nm->type;
  972. X                        c2[3] = ' '; c2[4] = '\0';
  973. X                        taddstr(c2);
  974. X                        }
  975. X                    taddstr((nm->right) ? nm->right : nm->left);
  976. X                    }
  977. X                    break;
  978. X                }
  979. X            break;
  980. X        case N_CASE:
  981. X            taddstr(_casecmd(n)->pat);
  982. X            taddstr(") ");
  983. X            tindent++;
  984. X            gt2(_casecmd(n)->list);
  985. X            tindent--;
  986. X            taddstr(";;");
  987. X            if (tnewlins)
  988. X                taddnl();
  989. X            else
  990. X                taddchr(' ');
  991. X            gt2(_casecmd(n)->next);
  992. X            break;
  993. X        case N_IF:
  994. X            if (_ifcmd(n)->ifl)
  995. X                {
  996. X                taddstr("if ");
  997. X                tindent++;
  998. X                gt2(_ifcmd(n)->ifl);
  999. X                tindent--;
  1000. X                taddnl();
  1001. X                taddstr("then");
  1002. X                }
  1003. X            else
  1004. X                taddchr('e');
  1005. X            tindent++;
  1006. X            taddnl();
  1007. X            gt2(_ifcmd(n)->thenl);
  1008. X            tindent--;
  1009. X            taddnl();
  1010. X            if (_ifcmd(n)->next)
  1011. X                {
  1012. X                taddstr("els");
  1013. X                gt2(_ifcmd(n)->next);
  1014. X                }
  1015. X            break;
  1016. X        case N_WHILE:
  1017. X            taddstr((_whilecmd(n)->cond) ? "until " : "while ");
  1018. X            tindent++;
  1019. X            gt2(_whilecmd(n)->cont);
  1020. X            tindent--;
  1021. X            taddnl();
  1022. X            taddstr("do");
  1023. X            tindent++;
  1024. X            taddnl();
  1025. X            gt2(_whilecmd(n)->loop);
  1026. X            tindent--;
  1027. X            taddnl();
  1028. X            taddstr("done");
  1029. X            break;
  1030. X        }
  1031. X}
  1032. X
  1033. Xvoid getsimptext(cmd) /**/
  1034. XCmd cmd;
  1035. X{
  1036. XLknode n;
  1037. X
  1038. X    for (n = firstnode(cmd->vars); n; incnode(n))
  1039. X        {
  1040. X        struct varasg *v = getdata(n);
  1041. X
  1042. X        taddstr(v->name);
  1043. X        taddchr('=');
  1044. X        if ((v->type & PMTYPE) == PMFLAG_A)
  1045. X            {
  1046. X            taddchr('(');
  1047. X            taddlist(v->arr);
  1048. X            taddstr(") ");
  1049. X            }
  1050. X        else
  1051. X            {
  1052. X            taddstr(v->str);
  1053. X            taddchr(' ');
  1054. X            }
  1055. X        }
  1056. X    taddlist(cmd->args);
  1057. X}
  1058. X
  1059. Xvoid getredirs(cmd) /**/
  1060. XCmd cmd;
  1061. X{
  1062. XLknode n;
  1063. Xstatic char *fstr[] = {
  1064. X    ">",">!",">>",">>!",">&",">&!",">>&",">>&!","<","<<",
  1065. X    "<<-","<<<","<&",">&-","..",".."
  1066. X    };
  1067. X
  1068. X    taddchr(' ');
  1069. X    for (n = firstnode(cmd->redir); n; incnode(n))
  1070. X        {
  1071. X        struct redir *f = getdata(n);
  1072. X
  1073. X        switch(f->type)
  1074. X            {
  1075. X            case WRITE: case WRITENOW: case APP: case APPNOW: case READ:
  1076. X            case HERESTR:
  1077. X                if (f->fd1 != ((f->type == READ) ? 0 : 1))
  1078. X                    taddchr('0'+f->fd1);
  1079. X                taddstr(fstr[f->type]);
  1080. X                taddchr(' ');
  1081. X                taddstr(f->name);
  1082. X                taddchr(' ');
  1083. X                break;
  1084. X            case MERGE: case MERGEOUT:
  1085. X                if (f->fd1 != ((f->type == MERGEOUT) ? 1 : 0))
  1086. X                    taddchr('0'+f->fd1);
  1087. X                taddstr(fstr[f->type]);
  1088. X                if (f->fd2 == FD_COPROC)
  1089. X                    taddchr('p');
  1090. X                else
  1091. X                    taddint(f->fd2);
  1092. X                taddchr(' ');
  1093. X                break;
  1094. X            case CLOSE:
  1095. X                taddchr(f->fd1+'0');
  1096. X                taddstr(">&- ");
  1097. X                break;
  1098. X            case INPIPE:
  1099. X            case OUTPIPE:
  1100. X                if (f->fd1 != ((f->type == INPIPE) ? 0 : 1))
  1101. X                    taddchr('0'+f->fd1);
  1102. X                taddstr((f->type == INPIPE) ? "< " : "> ");
  1103. X                taddstr(f->name);
  1104. X                taddchr(' ');
  1105. X                break;
  1106. X            }
  1107. X        }
  1108. X    tptr--;
  1109. X}
  1110. X
  1111. Xvoid taddlist(l) /**/
  1112. XLklist l;
  1113. X{
  1114. XLknode n;
  1115. X
  1116. X    for (n = firstnode(l); n; incnode(n))
  1117. X        {
  1118. X        taddstr(getdata(n));
  1119. X        taddchr(' ');
  1120. X        }
  1121. X    tptr--;
  1122. X}
  1123. END_OF_FILE
  1124.   if test 8624 -ne `wc -c <'src/text.c'`; then
  1125.     echo shar: \"'src/text.c'\" unpacked with wrong size!
  1126.   fi
  1127.   # end of 'src/text.c'
  1128. fi
  1129. if test -f 'src/watch.c' -a "${1}" != "-c" ; then 
  1130.   echo shar: Will not clobber existing file \"'src/watch.c'\"
  1131. else
  1132.   echo shar: Extracting \"'src/watch.c'\" \(7710 characters\)
  1133.   sed "s/^X//" >'src/watch.c' <<'END_OF_FILE'
  1134. X/*
  1135. X *
  1136. X * watch.c - login/logout watching
  1137. X *
  1138. X * This file is part of zsh, the Z shell.
  1139. X *
  1140. X * This software is Copyright 1992 by Paul Falstad
  1141. X *
  1142. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  1143. X * use this software as long as: there is no monetary profit gained
  1144. X * specifically from the use or reproduction of this software, it is not
  1145. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  1146. X * included prominently in any copy made. 
  1147. X *
  1148. X * The author make no claims as to the fitness or correctness of this software
  1149. X * for any use whatsoever, and it is provided as is. Any use of this software
  1150. X * is at the user's own risk. 
  1151. X *
  1152. X */
  1153. X
  1154. X#include "zsh.h"
  1155. X
  1156. Xstatic int wtabsz;
  1157. Xstruct utmp *wtab;
  1158. Xstatic time_t lastutmpcheck;
  1159. X
  1160. X/* get the time of login/logout for WATCH */
  1161. X
  1162. Xtime_t getlogtime(u,inout) /**/
  1163. Xstruct utmp *u;int inout;
  1164. X{
  1165. XFILE *in;
  1166. Xstruct utmp uu;
  1167. Xint first = 1;
  1168. Xint srchlimit = 50; /* max number of wtmp records to search */
  1169. X
  1170. X    if (inout)
  1171. X        return u->ut_time;
  1172. X    if (!(in = fopen(WTMP_FILE,"r")))
  1173. X        return time(NULL);
  1174. X    fseek(in,0,2);
  1175. X    do
  1176. X        {
  1177. X        if (fseek(in,((first) ? -1 : -2)*sizeof(struct utmp),1))
  1178. X            {
  1179. X            fclose(in);
  1180. X            return time(NULL);
  1181. X            }
  1182. X        first = 0;
  1183. X        if (!fread(&uu,sizeof(struct utmp),1,in))
  1184. X            {
  1185. X            fclose(in);
  1186. X            return time(NULL);
  1187. X            }
  1188. X        if (uu.ut_time < lastwatch || !srchlimit--)
  1189. X            {
  1190. X            fclose(in);
  1191. X            return time(NULL);
  1192. X            }
  1193. X        }
  1194. X    while (memcmp(&uu,u,sizeof(struct utmp)));
  1195. X    do
  1196. X        if (!fread(&uu,sizeof(struct utmp),1,in))
  1197. X            {
  1198. X            fclose(in);
  1199. X            return time(NULL);
  1200. X            }
  1201. X    while (strncmp(uu.ut_line,u->ut_line,sizeof(u->ut_line)));
  1202. X    fclose(in);
  1203. X    return uu.ut_time;
  1204. X}
  1205. X
  1206. X/* print a login/logout event */
  1207. X
  1208. Xvoid watchlog2(inout,u,fmt) /**/
  1209. Xint inout;struct utmp *u;char *fmt;
  1210. X{
  1211. Xchar *p,buf[40],*bf;
  1212. Xint i;
  1213. Xtime_t timet;
  1214. Xstruct tm *tm;
  1215. X
  1216. X    while (*fmt)
  1217. X        if (*fmt != '%')
  1218. X            putchar(*fmt++);
  1219. X        else
  1220. X            {
  1221. X            fmt++;
  1222. X            switch(*fmt++)
  1223. X                {
  1224. X                case 'n':
  1225. X                    printf("%.*s",sizeof(u->ut_name),u->ut_name);
  1226. X                    break;
  1227. X                case 'a':
  1228. X                    printf("%s",(!inout) ? "logged off" : "logged on");
  1229. X                    break;
  1230. X                case 'l':
  1231. X                    if (!strncmp(u->ut_line, "tty", 3))
  1232. X                        printf("%.*s",sizeof(u->ut_line)-3,u->ut_line+3);
  1233. X                    else
  1234. X                        printf("%.*s",sizeof(u->ut_line),u->ut_line);
  1235. X                    break;
  1236. X#ifdef UTMP_HOST
  1237. X                case 'm':
  1238. X                    for (p = u->ut_host,i = sizeof(u->ut_host); i && *p;i--,p++)
  1239. X                        {
  1240. X                        if (*p == '.' && !idigit(p[1]))
  1241. X                            break;
  1242. X                        putchar(*p);
  1243. X                        }
  1244. X                    break;
  1245. X                case 'M':
  1246. X                    printf("%.*s",sizeof(u->ut_host),u->ut_host);
  1247. X                    break;
  1248. X#endif
  1249. X                case 't':
  1250. X                case '@':
  1251. X                    timet = getlogtime(u,inout);
  1252. X                    tm = localtime(&timet);
  1253. X                    ztrftime(buf,40,"%l:%M%p",tm);
  1254. X                    printf("%s",(*buf == ' ') ? buf+1 : buf);
  1255. X                    break;
  1256. X                case 'T':
  1257. X                    timet = getlogtime(u,inout);
  1258. X                    tm = localtime(&timet);
  1259. X                    ztrftime(buf,40,"%k:%M",tm);
  1260. X                    printf("%s",buf);
  1261. X                    break;
  1262. X                case 'w':
  1263. X                    timet = getlogtime(u,inout);
  1264. X                    tm = localtime(&timet);
  1265. X                    ztrftime(buf,40,"%a %e",tm);
  1266. X                    printf("%s",buf);
  1267. X                    break;
  1268. X                case 'W':
  1269. X                    timet = getlogtime(u,inout);
  1270. X                    tm = localtime(&timet);
  1271. X                    ztrftime(buf,40,"%m/%d/%y",tm);
  1272. X                    printf("%s",buf);
  1273. X                    break;
  1274. X                case 'D':
  1275. X                    timet = getlogtime(u,inout);
  1276. X                    tm = localtime(&timet);
  1277. X                    ztrftime(buf,40,"%y-%m-%d",tm);
  1278. X                    printf("%s",buf);
  1279. X                    break;
  1280. X                case '%':
  1281. X                    putchar('%');
  1282. X                    break;
  1283. X                case 'S':
  1284. X                    bf = buf;
  1285. X                    if (tgetstr("so",&bf))
  1286. X                        fputs(buf,stdout);
  1287. X                    break;
  1288. X                case 's':
  1289. X                    bf = buf;
  1290. X                    if (tgetstr("se",&bf))
  1291. X                        fputs(buf,stdout);
  1292. X                    break;
  1293. X                case 'B':
  1294. X                    bf = buf;
  1295. X                    if (tgetstr("md",&bf))
  1296. X                        fputs(buf,stdout);
  1297. X                    break;
  1298. X                case 'b':
  1299. X                    bf = buf;
  1300. X                    if (tgetstr("me",&bf))
  1301. X                        fputs(buf,stdout);
  1302. X                    break;
  1303. X                case 'U':
  1304. X                    bf = buf;
  1305. X                    if (tgetstr("us",&bf))
  1306. X                        fputs(buf,stdout);
  1307. X                    break;
  1308. X                case 'u':
  1309. X                    bf = buf;
  1310. X                    if (tgetstr("ue",&bf))
  1311. X                        fputs(buf,stdout);
  1312. X                    break;
  1313. X                default:
  1314. X                    putchar('%');
  1315. X                    putchar(fmt[-1]);
  1316. X                    break;
  1317. X                }
  1318. X            }
  1319. X    putchar('\n');
  1320. X}
  1321. X
  1322. X/* check the List for login/logouts */
  1323. X
  1324. Xvoid watchlog(inout,u,w,fmt) /**/
  1325. Xint inout;struct utmp *u;char **w;char *fmt;
  1326. X{
  1327. Xchar *v,*vv,sav;
  1328. Xint bad;
  1329. X
  1330. X    if (*w && !strcmp(*w,"all"))
  1331. X        {
  1332. X        watchlog2(inout,u,fmt);
  1333. X        return;
  1334. X        }
  1335. X    if (*w && !strcmp(*w,"notme") &&
  1336. X      strncmp(u->ut_name, username, sizeof(u->ut_name)))
  1337. X        {
  1338. X        watchlog2(inout,u,fmt);
  1339. X        return;
  1340. X        }
  1341. X    for (; *w; w++)
  1342. X        {
  1343. X        bad = 0;
  1344. X        v = *w;
  1345. X        if (*v != '@' && *v != '%')
  1346. X            {
  1347. X            for (vv = v; *vv && *vv != '@' && *vv != '%'; vv++);
  1348. X            sav = *vv;
  1349. X            *vv = '\0';
  1350. X            if (strncmp(u->ut_name,v,sizeof(u->ut_name)))
  1351. X                bad = 1;
  1352. X            *vv = sav;
  1353. X            v = vv;
  1354. X            }
  1355. X        for (;;)
  1356. X            if (*v == '%')
  1357. X                {
  1358. X                for (vv = ++v; *vv && *vv != '@'; vv++);
  1359. X                sav = *vv;
  1360. X                *vv = '\0';
  1361. X                if (strncmp(u->ut_line,v,sizeof(u->ut_line)))
  1362. X                    bad = 1;
  1363. X                *vv = sav;
  1364. X                v = vv;
  1365. X                }
  1366. X#ifdef UTMP_HOST
  1367. X            else if (*v == '@')
  1368. X                {
  1369. X                for (vv = ++v; *vv && *vv != '%'; vv++);
  1370. X                sav = *vv;
  1371. X                *vv = '\0';
  1372. X                if (strncmp(u->ut_host,v,strlen(v)))
  1373. X                    bad = 1;
  1374. X                *vv = sav;
  1375. X                v = vv;
  1376. X                }
  1377. X#endif
  1378. X            else
  1379. X                break;
  1380. X        if (!bad)
  1381. X            {
  1382. X            watchlog2(inout,u,fmt);
  1383. X            return;
  1384. X            }
  1385. X        }
  1386. X}
  1387. X
  1388. X/* compare 2 utmp entries */
  1389. X
  1390. Xint ucmp(u,v) /**/
  1391. Xstruct utmp *u;struct utmp *v;
  1392. X{
  1393. X    if (u->ut_time == v->ut_time)
  1394. X        return strncmp(u->ut_line,v->ut_line,sizeof(u->ut_line));
  1395. X    return u->ut_time - v->ut_time;
  1396. X}
  1397. X
  1398. X/* initialize the user List */
  1399. X
  1400. Xvoid readwtab() /**/
  1401. X{
  1402. Xstruct utmp *uptr;
  1403. Xint wtabmax = 32;
  1404. XFILE *in;
  1405. X
  1406. X    wtabsz = 0;
  1407. X    if (!(in = fopen(UTMP_FILE,"r"))) return;
  1408. X    uptr = wtab = (struct utmp *) zalloc(wtabmax*sizeof(struct utmp));
  1409. X    while (fread(uptr,sizeof(struct utmp),1,in))
  1410. X#ifdef USER_PROCESS
  1411. X        if (uptr->ut_type == USER_PROCESS)
  1412. X#else
  1413. X        if (uptr->ut_name[0])
  1414. X#endif
  1415. X            {
  1416. X            uptr++;
  1417. X            if (++wtabsz == wtabmax)
  1418. X                uptr = (wtab = (struct utmp *) realloc((vptr) wtab,(wtabmax*=2)*
  1419. X                    sizeof(struct utmp)))+wtabsz;
  1420. X            }
  1421. X    fclose(in);
  1422. X    if (wtabsz)
  1423. X        qsort((vptr)wtab,wtabsz,sizeof(struct utmp),
  1424. X                (int (*) DCLPROTO((const void *, const void *)))ucmp);
  1425. X}
  1426. X
  1427. X/* check for login/logout events; executed before each prompt
  1428. X    if WATCH is set */
  1429. X
  1430. Xvoid dowatch() /**/
  1431. X{
  1432. Xchar **s = watch;
  1433. Xchar *fmt = (watchfmt) ? watchfmt : DEFWATCHFMT;
  1434. XFILE *in;
  1435. Xint utabsz = 0,utabmax = wtabsz+4,uct,wct;
  1436. Xstruct utmp *utab,*uptr,*wptr;
  1437. Xstruct stat st;
  1438. X
  1439. X    holdintr();
  1440. X    if (!fmt)
  1441. X        fmt = "%n has %a %l from %m.";
  1442. X    if (!wtab) {
  1443. X        readwtab();
  1444. X        noholdintr();
  1445. X        return;
  1446. X    }
  1447. X    if ((stat(UTMP_FILE,&st) == -1) || (st.st_mtime <= lastutmpcheck))
  1448. X        return;
  1449. X    lastutmpcheck = st.st_mtime;
  1450. X    uptr = utab = (struct utmp *) zalloc(utabmax*sizeof(struct utmp));
  1451. X    if (!(in = fopen(UTMP_FILE,"r"))) {
  1452. X        free(utab);
  1453. X        return;
  1454. X    }
  1455. X    while (fread(uptr,sizeof *uptr,1,in))
  1456. X#ifdef USER_PROCESS
  1457. X        if (uptr->ut_type == USER_PROCESS)
  1458. X#else
  1459. X        if (uptr->ut_name[0])
  1460. X#endif
  1461. X            {
  1462. X            uptr++;
  1463. X            if (++utabsz == utabmax)
  1464. X                uptr = (utab = (struct utmp *) realloc((vptr) utab,(utabmax*=2)*
  1465. X                    sizeof(struct utmp)))+utabsz;
  1466. X            }
  1467. X    fclose(in);
  1468. X    noholdintr();
  1469. X    if (errflag) {
  1470. X        free(utab);
  1471. X        return;
  1472. X    }
  1473. X    if (utabsz)
  1474. X        qsort((vptr)utab,utabsz,sizeof(struct utmp),
  1475. X                (int (*) DCLPROTO((const void *, const void *)))ucmp);
  1476. X
  1477. X    wct = wtabsz; uct = utabsz;
  1478. X    uptr = utab; wptr = wtab;
  1479. X    if (errflag) {
  1480. X        free(utab);
  1481. X        return;
  1482. X    }
  1483. X    while ((uct || wct) && !errflag)
  1484. X        if (!uct || (wct && ucmp(uptr,wptr) > 0))
  1485. X            wct--,watchlog(0,wptr++,s,fmt);
  1486. X        else if (!wct || (uct && ucmp(uptr,wptr) < 0))
  1487. X            uct--,watchlog(1,uptr++,s,fmt);
  1488. X        else
  1489. X            uptr++,wptr++,wct--,uct--;
  1490. X    free(wtab);
  1491. X    wtab = utab;
  1492. X    wtabsz = utabsz;
  1493. X    fflush(stdout);
  1494. X}
  1495. X
  1496. Xint bin_log(nam,argv,ops,func) /**/
  1497. Xchar *nam;char **argv;char *ops;int func;
  1498. X{
  1499. X    if (!watch)
  1500. X        return 1;
  1501. X    if (wtab)
  1502. X        free(wtab);
  1503. X    wtab = (struct utmp *) zalloc(1);
  1504. X    wtabsz = 0;
  1505. X    lastutmpcheck = 0;
  1506. X    dowatch();
  1507. X    return 0;
  1508. X}
  1509. X
  1510. END_OF_FILE
  1511.   if test 7710 -ne `wc -c <'src/watch.c'`; then
  1512.     echo shar: \"'src/watch.c'\" unpacked with wrong size!
  1513.   fi
  1514.   # end of 'src/watch.c'
  1515. fi
  1516. if test -f 'src/zle.h' -a "${1}" != "-c" ; then 
  1517.   echo shar: Will not clobber existing file \"'src/zle.h'\"
  1518. else
  1519.   echo shar: Extracting \"'src/zle.h'\" \(8560 characters\)
  1520.   sed "s/^X//" >'src/zle.h' <<'END_OF_FILE'
  1521. X/*
  1522. X *
  1523. X * zle.h - header file for line editor
  1524. X *
  1525. X * This file is part of zsh, the Z shell.
  1526. X *
  1527. X * This software is Copyright 1992 by Paul Falstad
  1528. X *
  1529. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  1530. X * use this software as long as: there is no monetary profit gained
  1531. X * specifically from the use or reproduction of this software, it is not
  1532. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  1533. X * included prominently in any copy made. 
  1534. X *
  1535. X * The author make no claims as to the fitness or correctness of this software
  1536. X * for any use whatsoever, and it is provided as is. Any use of this software
  1537. X * is at the user's own risk. 
  1538. X *
  1539. X */
  1540. X
  1541. X#ifdef ZLEGLOBALS
  1542. X#define ZLEXTERN
  1543. X#else
  1544. X#define ZLEXTERN extern
  1545. X#endif
  1546. X
  1547. X#ifdef ZLE
  1548. X
  1549. X/* cursor position */
  1550. XZLEXTERN int cs;
  1551. X
  1552. X/* line length */
  1553. XZLEXTERN int ll;
  1554. X
  1555. X/* size of line buffer */
  1556. XZLEXTERN int linesz;
  1557. X
  1558. X/* location of mark */
  1559. XZLEXTERN int mark;
  1560. X
  1561. X/* last character pressed */
  1562. XZLEXTERN int c;
  1563. X
  1564. X/* the z_ binding id for this key */
  1565. XZLEXTERN int bindk;
  1566. X
  1567. X/* command argument */
  1568. XZLEXTERN int mult;
  1569. X
  1570. X/* insert mode/overwrite mode flag */
  1571. XZLEXTERN int insmode;
  1572. X
  1573. X/* cost of last update */
  1574. XZLEXTERN int cost;
  1575. X
  1576. X/* flags associated with last command */
  1577. XZLEXTERN int lastcmd;
  1578. X
  1579. X/* column position before last LINEMOVE movement */
  1580. XZLEXTERN int lastcol;
  1581. X
  1582. X/* != 0 if we're getting a vi range */
  1583. XZLEXTERN int virangeflag;
  1584. X
  1585. X/* kludge to get cw and dw to work right */
  1586. XZLEXTERN int wordflag;
  1587. X
  1588. X/* Another kludge to lazy cache the usernames. Win on large systems */
  1589. XZLEXTERN int usernamescached;
  1590. X#endif
  1591. X
  1592. X/* last named command done */
  1593. XZLEXTERN int lastnamed;
  1594. X
  1595. X/* != 0 if we're done editing */
  1596. XZLEXTERN int done;
  1597. X
  1598. X/* length of prompt on screen */
  1599. XZLEXTERN int pptlen;
  1600. X
  1601. X/* current history line number */
  1602. XZLEXTERN int histline;
  1603. X
  1604. XZLEXTERN int eofsent;
  1605. X
  1606. X/* != 0 if we need to call resetvideo() */
  1607. XZLEXTERN int resetneeded;
  1608. X
  1609. X/* != 0 if the line editor is active */
  1610. XZLEXTERN int zleactive;
  1611. X
  1612. X/* the line buffer */
  1613. XZLEXTERN unsigned char *line;
  1614. X
  1615. X/* the cut buffer */
  1616. XZLEXTERN char *cutbuf;
  1617. X
  1618. X/* prompt and rprompt */
  1619. XZLEXTERN char *pmpt, *pmpt2;
  1620. X
  1621. X/* the last line in the history (the current one) */
  1622. XZLEXTERN char *curhistline;
  1623. X
  1624. X/* the status line */
  1625. XZLEXTERN char *statusline;
  1626. X
  1627. X/* 1 if a complete added a slash at the end of a directory name */
  1628. XZLEXTERN int addedslash;
  1629. X
  1630. X/*
  1631. X    the current history line and cursor position for the top line
  1632. X    on the buffer stack
  1633. X*/
  1634. X
  1635. XZLEXTERN int stackhist,stackcs;
  1636. X
  1637. X/* != 0 if we are in the middle of a menu completion */
  1638. XZLEXTERN int menucmp;
  1639. X
  1640. X/* != 0 if we are making undo records */
  1641. XZLEXTERN int undoing;
  1642. X
  1643. X/* last vi change buffer */
  1644. XZLEXTERN int vichgbufsz,vichgbufptr,vichgflag;
  1645. XZLEXTERN char *vichgbuf;
  1646. X
  1647. XZLEXTERN int viinsbegin;
  1648. X
  1649. Xtypedef void bindfunc DCLPROTO((void));
  1650. Xtypedef bindfunc *F;
  1651. X
  1652. Xstruct key {
  1653. X    struct hashnode *next; int canfree; char *nam; /* hash data */
  1654. X    int func;            /* function code for this key */
  1655. X    char *str;            /* string corresponding to this key,
  1656. X                                if func = z_sequenceleadin                 */
  1657. X    int len;                /* length of string */
  1658. X    };
  1659. Xstruct zlecmd {
  1660. X    char *name;            /* name of function */
  1661. X    F func;                /* handler function */
  1662. X    int flags;
  1663. X    };
  1664. X
  1665. X/* undo event */
  1666. X
  1667. Xstruct undoent {
  1668. X    int pref;        /* number of initial chars unchanged */
  1669. X    int suff;        /* number of trailing chars unchanged */
  1670. X    int len;            /* length of changed chars */
  1671. X    int cs;            /* cursor pos before change */
  1672. X    char *change;    /* NOT null terminated */
  1673. X    };
  1674. X
  1675. X#define UNDOCT 64
  1676. X
  1677. Xstruct undoent undos[UNDOCT];
  1678. X
  1679. X/* the line before last mod (for undo purposes) */
  1680. XZLEXTERN unsigned char *lastline;
  1681. X
  1682. X/* buffer specified with "x */
  1683. XZLEXTERN int vibufspec;
  1684. X
  1685. XZLEXTERN int undoct,lastcs;
  1686. X
  1687. XZLEXTERN char *visrchstr;
  1688. XZLEXTERN int visrchsense;
  1689. X
  1690. X#define ZLE_MOVEMENT       1
  1691. X#define ZLE_MENUCMP       2
  1692. X#define ZLE_UNDO           4
  1693. X#define ZLE_YANK          8
  1694. X#define ZLE_LINEMOVE      16
  1695. X#define ZLE_ARG           32
  1696. X#define ZLE_NAMEDBUFFER 128
  1697. X#define ZLE_KILL        (64|ZLE_NAMEDBUFFER)
  1698. X#define ZLE_HISTSEARCH  256
  1699. X#define ZLE_NEGARG      512
  1700. X#define ZLE_INSERT     1024
  1701. X#define ZLE_DELETE     2048
  1702. X
  1703. Xtypedef struct key *Key;
  1704. X
  1705. XZLEXTERN int *bindtab;
  1706. Xextern int emacsbind[256];
  1707. XZLEXTERN int altbindtab[256],mainbindtab[256];
  1708. Xextern int viinsbind[],vicmdbind[];
  1709. XZLEXTERN int vimarkcs[27],vimarkline[27];
  1710. X
  1711. X#define KRINGCT 8
  1712. XZLEXTERN char *kring[KRINGCT];
  1713. XZLEXTERN int kringnum;
  1714. XZLEXTERN char *vibuf[36];
  1715. X
  1716. X#define z_acceptandhold 0
  1717. X#define z_acceptandinfernexthistory 1
  1718. X#define z_acceptandmenucomplete 2
  1719. X#define z_acceptline 3
  1720. X#define z_acceptlineanddownhistory 4
  1721. X#define z_backwardchar 5
  1722. X#define z_backwarddeletechar 6
  1723. X#define z_backwarddeleteword 7
  1724. X#define z_backwardkillline 8
  1725. X#define z_backwardkillword 9
  1726. X#define z_backwardword 10
  1727. X#define z_beginningofbufferorhistory 11
  1728. X#define z_beginningofhistory 12
  1729. X#define z_beginningofline 13
  1730. X#define z_beginningoflinehist 14
  1731. X#define z_capitalizeword 15
  1732. X#define z_clearscreen 16
  1733. X#define z_completeword 17
  1734. X#define z_copyprevword 18
  1735. X#define z_copyregionaskill 19
  1736. X#define z_deletechar 20
  1737. X#define z_deletecharorlist 21
  1738. X#define z_deleteword 22
  1739. X#define z_digitargument 23
  1740. X#define z_downcaseword 24
  1741. X#define z_downhistory 25
  1742. X#define z_downlineorhistory 26
  1743. X#define z_endofbufferorhistory 27
  1744. X#define z_endofhistory 28
  1745. X#define z_endofline 29
  1746. X#define z_endoflinehist 30
  1747. X#define z_exchangepointandmark 31
  1748. X#define z_executelastnamedcmd 32
  1749. X#define z_executenamedcmd 33
  1750. X#define z_expandhistory 34
  1751. X#define z_expandorcomplete 35
  1752. X#define z_expandword 36
  1753. X#define z_forwardchar 37
  1754. X#define z_forwardword 38
  1755. X#define z_getline 39
  1756. X#define z_gosmacstransposechars 40
  1757. X#define z_historyincrementalsearchbackward 41
  1758. X#define z_historyincrementalsearchforward 42
  1759. X#define z_historysearchbackward 43
  1760. X#define z_historysearchforward 44
  1761. X#define z_infernexthistory 45
  1762. X#define z_insertlastword 46
  1763. X#define z_killbuffer 47
  1764. X#define z_killline 48
  1765. X#define z_killregion 49
  1766. X#define z_killwholeline 50
  1767. X#define z_listchoices 51
  1768. X#define z_listexpand 52
  1769. X#define z_magicspace 53
  1770. X#define z_menucompleteword 54
  1771. X#define z_menuexpandorcomplete 55
  1772. X#define z_overwritemode 56
  1773. X#define z_pushline 57
  1774. X#define z_quotedinsert 58
  1775. X#define z_quoteline 59
  1776. X#define z_quoteregion 60
  1777. X#define z_redisplay 61
  1778. X#define z_reversemenucomplete 62
  1779. X#define z_runhelp 63
  1780. X#define z_selfinsert 64
  1781. X#define z_selfinsertunmeta 65
  1782. X#define z_sendbreak 66
  1783. X#define z_sendstring 67
  1784. X#define z_sequenceleadin 68
  1785. X#define z_setmarkcommand 69
  1786. X#define z_spellword 70
  1787. X#define z_toggleliteralhistory 71
  1788. X#define z_transposechars 72
  1789. X#define z_transposewords 73
  1790. X#define z_undefinedkey 74
  1791. X#define z_undo 75
  1792. X#define z_universalargument 76
  1793. X#define z_upcaseword 77
  1794. X#define z_uphistory 78
  1795. X#define z_uplineorhistory 79
  1796. X#define z_viaddeol 80
  1797. X#define z_viaddnext 81
  1798. X#define z_vibackwardblankword 82
  1799. X#define z_vibackwardchar 83
  1800. X#define z_vibackwarddeletechar 84
  1801. X#define z_vibeginningofline 85
  1802. X#define z_vicapslockpanic 86
  1803. X#define z_vichange 87
  1804. X#define z_vichangeeol 88
  1805. X#define z_vichangewholeline 89
  1806. X#define z_vicmdmode 90
  1807. X#define z_videlete 91
  1808. X#define z_videletechar 92
  1809. X#define z_vidigitorbeginningofline 93
  1810. X#define z_viendofline 94
  1811. X#define z_vifetchhistory 95
  1812. X#define z_vifindnextchar 96
  1813. X#define z_vifindnextcharskip 97
  1814. X#define z_vifindprevchar 98
  1815. X#define z_vifindprevcharskip 99
  1816. X#define z_vifirstnonblank 100
  1817. X#define z_viforwardblankword 101
  1818. X#define z_viforwardblankwordend 102
  1819. X#define z_viforwardchar 103
  1820. X#define z_viforwardwordend 104
  1821. X#define z_vigotocolumn 105
  1822. X#define z_vigotomark 106
  1823. X#define z_vigotomarkline 107
  1824. X#define z_vihistorysearchbackward 108
  1825. X#define z_vihistorysearchforward 109
  1826. X#define z_viindent 110
  1827. X#define z_viinsert 111
  1828. X#define z_viinsertbol 112
  1829. X#define z_vijoin 113
  1830. X#define z_vimatchbracket 114
  1831. X#define z_viopenlineabove 115
  1832. X#define z_viopenlinebelow 116
  1833. X#define z_vioperswapcases 117
  1834. X#define z_viputafter 118
  1835. X#define z_virepeatchange 119
  1836. X#define z_virepeatfind 120
  1837. X#define z_virepeatsearch 121
  1838. X#define z_vireplace 122
  1839. X#define z_vireplacechars 123
  1840. X#define z_virevrepeatfind 124
  1841. X#define z_virevrepeatsearch 125
  1842. X#define z_visetbuffer 126
  1843. X#define z_visetmark 127
  1844. X#define z_visubstitute 128
  1845. X#define z_viswapcase 129
  1846. X#define z_viundochange 130
  1847. X#define z_viunindent 131
  1848. X#define z_viyank 132
  1849. X#define z_viyankeol 133
  1850. X#define z_whichcommand 134
  1851. X#define z_yank 135
  1852. X#define z_yankpop 136
  1853. X#define z_emacsbackwardword 137
  1854. X#define z_emacsforwardword 138
  1855. X#define z_killword 139
  1856. X#define z_vikillline 140
  1857. X#define z_vibackwardkillword 141
  1858. X#define z_expandcmdpath 142
  1859. X#define z_negargument 143
  1860. X#define z_poundinsert 144
  1861. X#define z_viforwardword 145
  1862. X#define z_vibackwardword 146
  1863. X#define z_uplineorsearch 147
  1864. X#define z_downlineorsearch 148
  1865. X#define ZLECMDCOUNT 149
  1866. X
  1867. Xextern struct zlecmd zlecmds[];
  1868. X
  1869. END_OF_FILE
  1870.   if test 8560 -ne `wc -c <'src/zle.h'`; then
  1871.     echo shar: \"'src/zle.h'\" unpacked with wrong size!
  1872.   fi
  1873.   # end of 'src/zle.h'
  1874. fi
  1875. if test -f 'src/zle_vi.c' -a "${1}" != "-c" ; then 
  1876.   echo shar: Will not clobber existing file \"'src/zle_vi.c'\"
  1877. else
  1878.   echo shar: Extracting \"'src/zle_vi.c'\" \(5195 characters\)
  1879.   sed "s/^X//" >'src/zle_vi.c' <<'END_OF_FILE'
  1880. X/*
  1881. X *
  1882. X * zle_vi.c - vi-specific functions
  1883. X *
  1884. X * This file is part of zsh, the Z shell.
  1885. X *
  1886. X * This software is Copyright 1992 by Paul Falstad
  1887. X *
  1888. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  1889. X * use this software as long as: there is no monetary profit gained
  1890. X * specifically from the use or reproduction of this software, it is not
  1891. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  1892. X * included prominently in any copy made. 
  1893. X *
  1894. X * The author make no claims as to the fitness or correctness of this software
  1895. X * for any use whatsoever, and it is provided as is. Any use of this software
  1896. X * is at the user's own risk. 
  1897. X *
  1898. X */
  1899. X
  1900. X#define ZLE
  1901. X#include "zsh.h"
  1902. X
  1903. X
  1904. Xstatic void startvichange(im)
  1905. Xint im;
  1906. X{
  1907. X    insmode = im;
  1908. X    if (vichgbuf) free(vichgbuf);
  1909. X    vichgbuf = zalloc(vichgbufsz = 16);
  1910. X    vichgbuf[0] = c;
  1911. X    vichgbufptr = 1;
  1912. X    vichgflag = 1;
  1913. X    viinsbegin = cs;
  1914. X}
  1915. X
  1916. Xstatic void startvitext(im)
  1917. Xint im;
  1918. X{
  1919. X    startvichange(im);
  1920. X    bindtab = mainbindtab;
  1921. X    undoing = 0;
  1922. X}
  1923. X
  1924. Xint vigetkey() /**/
  1925. X{
  1926. Xint ch;
  1927. X
  1928. X    if ((ch = getkey(0)) == -1)
  1929. X        return 0;
  1930. X    if (ch == 22)
  1931. X        {
  1932. X        if ((ch = getkey(0)) == -1)
  1933. X            return 0;
  1934. X        return ch;
  1935. X        }
  1936. X    else if (ch == 27)
  1937. X        return 0;
  1938. X    return ch;
  1939. X}
  1940. X
  1941. Xint getvirange(wf) /**/
  1942. Xint wf;
  1943. X{
  1944. Xint k2,t0,startline,endline;
  1945. X
  1946. X    startline = findbol();
  1947. X    endline = findeol();
  1948. X    for (;;) {
  1949. X        k2 = getkeycmd();
  1950. X        if (k2 == -1) {
  1951. X            feep();
  1952. X            return -1;
  1953. X        }
  1954. X        if (zlecmds[k2].flags & ZLE_ARG)
  1955. X            (*zlecmds[k2].func)();
  1956. X        else
  1957. X            break;
  1958. X    }
  1959. X    if (k2 == bindk) {
  1960. X        findline(&cs,&t0);
  1961. X        return (t0 == ll) ? t0 : t0+1;
  1962. X    }
  1963. X    if (!(zlecmds[k2].flags & ZLE_MOVEMENT)) {
  1964. X        feep();
  1965. X        return -1;
  1966. X    }
  1967. X    t0 = cs;
  1968. X
  1969. X    virangeflag = 1;
  1970. X    wordflag = wf;
  1971. X    (*zlecmds[k2].func)();
  1972. X    wordflag = virangeflag = 0;
  1973. X    if (cs == t0) {
  1974. X        feep();
  1975. X        return -1;
  1976. X    }
  1977. X    if (startline != findbol()) {
  1978. X        if (zlecmds[k2].flags & ZLE_LINEMOVE) {
  1979. X            if (cs < t0) {
  1980. X                cs = startline;
  1981. X                t0 = findeol()+1;
  1982. X            } else {
  1983. X                t0 = startline;
  1984. X                cs = findeol()+1;
  1985. X            }
  1986. X        } else {
  1987. X            if (cs < startline) cs = startline;
  1988. X            else if (cs >= endline) cs = endline-1;
  1989. X        }
  1990. X    }
  1991. X    if (cs > t0) {
  1992. X        k2 = cs;
  1993. X        cs = t0;
  1994. X        t0 = k2;
  1995. X    }
  1996. X    return t0;
  1997. X}
  1998. X
  1999. Xvoid viaddnext() /**/
  2000. X{
  2001. X    if (cs != ll)
  2002. X        cs++;
  2003. X    startvitext(1);
  2004. X}
  2005. X
  2006. Xvoid viaddeol() /**/
  2007. X{
  2008. X    cs = findeol();
  2009. X    startvitext(1);
  2010. X}
  2011. X
  2012. Xvoid viinsert() /**/
  2013. X{
  2014. X    startvitext(1);
  2015. X}
  2016. X
  2017. Xvoid viinsertbol() /**/
  2018. X{
  2019. X    cs = findbol();
  2020. X    startvitext(1);
  2021. X}
  2022. X
  2023. Xvoid videlete() /**/
  2024. X{
  2025. Xint c2;
  2026. X
  2027. X    startvichange(1);
  2028. X    if ((c2 = getvirange(0)) == -1)
  2029. X        { vichgflag = 0; return; }
  2030. X    forekill(c2-cs,0);
  2031. X    vichgflag = 0;
  2032. X}
  2033. X
  2034. Xvoid videletechar() /**/
  2035. X{
  2036. X    if (mult < 0) { mult = -mult; vibackwarddeletechar(); return; }
  2037. X    if (c == 4 && !ll) {
  2038. X        eofsent = 1;
  2039. X        return;
  2040. X    }
  2041. X    if (!(cs+mult > ll || line[cs] == '\n')) {
  2042. X        if ( vichgbuf == NULL ) vichgbuf = zalloc ( vichgbufsz = 16 );
  2043. X        vichgbufptr = 1;
  2044. X        vichgbuf[0] = c;
  2045. X        cs += mult;
  2046. X        backkill(mult,0);
  2047. X        if (cs && (cs == ll || line[cs] == '\n')) cs--;
  2048. X    } else
  2049. X        feep();
  2050. X}
  2051. X
  2052. Xvoid vichange() /**/
  2053. X{
  2054. Xint c2;
  2055. X
  2056. X    startvichange(1);
  2057. X    if ((c2 = getvirange(1)) == -1)
  2058. X        { vichgflag = 0; return; }
  2059. X    forekill(c2-cs,0);
  2060. X    bindtab = mainbindtab;
  2061. X    undoing = 0;
  2062. X}
  2063. X
  2064. Xvoid visubstitute() /**/
  2065. X{
  2066. X    if (mult < 0) return;
  2067. X    if (findeol()-cs < mult) mult = findeol()-cs;
  2068. X    if (mult) {
  2069. X        foredel(mult);
  2070. X        startvitext(1);
  2071. X    }
  2072. X}
  2073. X
  2074. Xvoid vichangeeol() /**/
  2075. X{
  2076. X    killline();
  2077. X    startvitext(1);
  2078. X}
  2079. X
  2080. Xvoid vichangewholeline() /**/
  2081. X{
  2082. Xint cq;
  2083. X
  2084. X    findline(&cs,&cq);
  2085. X    foredel(cq-cs);
  2086. X    startvitext(1);
  2087. X}
  2088. X
  2089. Xvoid viyank() /**/
  2090. X{
  2091. Xint c2;
  2092. X
  2093. X    if ((c2 = getvirange(0)) == -1) return;
  2094. X    cut(cs,c2-cs,0);
  2095. X}
  2096. X
  2097. Xvoid viyankeol() /**/
  2098. X{
  2099. Xint x = findeol();
  2100. X
  2101. X    if (x == cs)
  2102. X        feep();
  2103. X    else
  2104. X        cut(cs,x-cs,0);
  2105. X}
  2106. X
  2107. Xvoid vireplace() /**/
  2108. X{
  2109. X    startvitext(0);
  2110. X}
  2111. X
  2112. Xvoid vireplacechars() /**/
  2113. X{
  2114. Xint ch;
  2115. X
  2116. X    if (mult < 0) return;
  2117. X    if (mult+cs > ll) {
  2118. X        feep();
  2119. X        return;
  2120. X    }
  2121. X    startvichange(1);
  2122. X    if (ch = vigetkey()) while (mult--) line[cs++] = ch;
  2123. X    vichgflag = 0;
  2124. X    cs--;
  2125. X}
  2126. X
  2127. Xvoid vicmdmode() /**/
  2128. X{
  2129. X    bindtab = altbindtab;
  2130. X    if (cs) cs--;
  2131. X    undoing = 1;
  2132. X    if (vichgflag) vichgflag = 0;
  2133. X}
  2134. X
  2135. Xvoid viopenlinebelow() /**/
  2136. X{
  2137. X    cs = findeol();
  2138. X    spaceinline(1);
  2139. X    line[cs++] = '\n';
  2140. X    startvitext(1);
  2141. X}
  2142. X
  2143. Xvoid viopenlineabove() /**/
  2144. X{
  2145. X    cs = findbol();
  2146. X    spaceinline(1);
  2147. X    line[cs] = '\n';
  2148. X    startvitext(1);
  2149. X}
  2150. X
  2151. Xvoid vioperswapcase() /**/
  2152. X{
  2153. Xint c2;
  2154. X
  2155. X    if ((c2 = getvirange(0)) == -1)
  2156. X        return;
  2157. X    while (cs < c2)
  2158. X        {
  2159. X        int ch = line[cs];
  2160. X
  2161. X        if (islower(ch))
  2162. X            ch = tuupper(ch);
  2163. X        else if (isupper(ch))
  2164. X            ch = tulower(ch);
  2165. X        line[cs++] = ch;
  2166. X        }
  2167. X}
  2168. X
  2169. Xvoid virepeatchange() /**/
  2170. X{
  2171. X    if (!vichgbuf || bindtab == mainbindtab || vichgflag) feep();
  2172. X    else ungetkeys(vichgbuf,vichgbufptr);
  2173. X}
  2174. X
  2175. Xvoid viindent() /**/
  2176. X{
  2177. Xint c2,endcs,t0,rmult;
  2178. X
  2179. X    if (mult < 0) { mult = -mult; viunindent(); return; }
  2180. X    rmult = mult;
  2181. X    if ((c2 = getvirange(0)) == -1)
  2182. X        return;
  2183. X    if (cs != findbol()) { feep(); return; }
  2184. X    endcs = cs+rmult;
  2185. X    while (cs < c2) {
  2186. X        spaceinline(rmult);
  2187. X        for (t0 = 0; t0 != rmult; t0++) line[cs++] = '\t';
  2188. X        cs = findeol()+1;
  2189. X    }
  2190. X    cs = endcs;
  2191. X}
  2192. X
  2193. Xvoid viunindent() /**/
  2194. X{
  2195. Xint c2,endcs,t0,rmult;
  2196. X
  2197. X    rmult = mult;
  2198. X    if (mult < 0) { mult = -mult; viindent(); return; }
  2199. X    if ((c2 = getvirange(0)) == -1)
  2200. X        return;
  2201. X    if (cs != findbol()) { feep(); return; }
  2202. X    endcs = cs;
  2203. X    while (cs < c2) {
  2204. X        for (t0 = 0; t0 != rmult && line[cs] == '\t'; t0++) foredel(1);
  2205. X        cs = findeol()+1;
  2206. X    }
  2207. X    cs = endcs;
  2208. X}
  2209. END_OF_FILE
  2210.   if test 5195 -ne `wc -c <'src/zle_vi.c'`; then
  2211.     echo shar: \"'src/zle_vi.c'\" unpacked with wrong size!
  2212.   fi
  2213.   # end of 'src/zle_vi.c'
  2214. fi
  2215. if test -f 'src/zle_word.c' -a "${1}" != "-c" ; then 
  2216.   echo shar: Will not clobber existing file \"'src/zle_word.c'\"
  2217. else
  2218.   echo shar: Extracting \"'src/zle_word.c'\" \(6652 characters\)
  2219.   sed "s/^X//" >'src/zle_word.c' <<'END_OF_FILE'
  2220. X/*
  2221. X *
  2222. X * zle_word.c - word-related editor functions
  2223. X *
  2224. X * This file is part of zsh, the Z shell.
  2225. X *
  2226. X * This software is Copyright 1992 by Paul Falstad
  2227. X *
  2228. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  2229. X * use this software as long as: there is no monetary profit gained
  2230. X * specifically from the use or reproduction of this software, it is not
  2231. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  2232. X * included prominently in any copy made. 
  2233. X *
  2234. X * The author make no claims as to the fitness or correctness of this software
  2235. X * for any use whatsoever, and it is provided as is. Any use of this software
  2236. X * is at the user's own risk. 
  2237. X *
  2238. X */
  2239. X
  2240. X#define ZLE
  2241. X#include "zsh.h"
  2242. X
  2243. X
  2244. Xvoid forwardword() /**/
  2245. X{
  2246. X    if (mult < 0) { mult = -mult; backwardword(); return; }
  2247. X    while (mult--) {
  2248. X        while (cs != ll && iword(line[cs])) cs++;
  2249. X        if (wordflag && !mult) return;
  2250. X        while (cs != ll && !iword(line[cs])) cs++;
  2251. X    }
  2252. X}
  2253. X
  2254. Xvoid viforwardword() /**/
  2255. X{
  2256. X    if (mult < 0) { mult = -mult; backwardword(); return; }
  2257. X    while (mult--) {
  2258. X        if (iident(line[cs])) while (cs != ll && iident(line[cs])) cs++;
  2259. X        else while (cs != ll && !iident(line[cs]) && !iblank(line[cs])) cs++;
  2260. X        if (wordflag && !mult) return;
  2261. X        while (cs != ll && iblank(line[cs])) cs++;
  2262. X    }
  2263. X}
  2264. X
  2265. Xvoid viforwardblankword() /**/
  2266. X{
  2267. X    if (mult < 0) { mult = -mult; vibackwardblankword(); return; }
  2268. X    while (mult--) {
  2269. X        while (cs != ll && !iblank(line[cs])) cs++;
  2270. X        if (wordflag && !mult) return;
  2271. X        while (cs != ll && iblank(line[cs])) cs++;
  2272. X    }
  2273. X}
  2274. X
  2275. Xvoid emacsforwardword() /**/
  2276. X{
  2277. X    if (mult < 0) { mult = -mult; emacsbackwardword(); return; }
  2278. X    while (mult--)
  2279. X        {
  2280. X        while (cs != ll && !iword(line[cs])) cs++;
  2281. X        if (wordflag && !mult) return;
  2282. X        while (cs != ll && iword(line[cs])) cs++;
  2283. X        }
  2284. X}
  2285. X
  2286. Xvoid viforwardblankwordend() /**/
  2287. X{
  2288. X    if (mult < 0) return;
  2289. X    while (mult--) {
  2290. X        while (cs != ll && iblank(line[cs+1])) cs++;
  2291. X        while (cs != ll && !iblank(line[cs+1])) cs++;
  2292. X    }
  2293. X    if (cs != ll && virangeflag) cs++;
  2294. X}
  2295. X
  2296. Xvoid viforwardwordend() /**/
  2297. X{
  2298. X    if (mult < 0) { mult = -mult; backwardword(); return; }
  2299. X    while (mult--) {
  2300. X        if (iblank(line[cs+1])) while (cs != ll && iblank(line[cs+1])) cs++;
  2301. X        if (iident(line[cs+1])) while (cs != ll && iident(line[cs+1])) cs++;
  2302. X        else while (cs != ll && !iident(line[cs+1]) && !iblank(line[cs+1])) cs++;
  2303. X    }
  2304. X    if (cs != ll && virangeflag) cs++;
  2305. X}
  2306. X
  2307. Xvoid backwardword() /**/
  2308. X{
  2309. X    if (mult < 0) { mult = -mult; forwardword(); return; }
  2310. X    while (mult--) {
  2311. X        while (cs && !iword(line[cs-1])) cs--;
  2312. X        while (cs && iword(line[cs-1])) cs--;
  2313. X    }
  2314. X}
  2315. X
  2316. Xvoid vibackwardword() /**/
  2317. X{
  2318. X    if (mult < 0) { mult = -mult; backwardword(); return; }
  2319. X    while (mult--) {
  2320. X        while (cs && iblank(line[cs-1])) cs--;
  2321. X        if (iident(line[cs-1])) while (cs && iident(line[cs-1])) cs--;
  2322. X        else while (cs && !iident(line[cs-1]) && !iblank(line[cs-1])) cs--;
  2323. X    }
  2324. X}
  2325. X
  2326. Xvoid vibackwardblankword() /**/
  2327. X{
  2328. X    if (mult < 0) { mult = -mult; viforwardblankword(); return; }
  2329. X    while (mult--) {
  2330. X        while (cs && iblank(line[cs-1])) cs--;
  2331. X        while (cs && !iblank(line[cs-1])) cs--;
  2332. X    }
  2333. X}
  2334. X
  2335. Xvoid emacsbackwardword() /**/
  2336. X{
  2337. X    if (mult < 0) { mult = -mult; emacsforwardword(); return; }
  2338. X    while (mult--) {
  2339. X        while (cs && !iword(line[cs-1])) cs--;
  2340. X        while (cs && iword(line[cs-1])) cs--;
  2341. X    }
  2342. X}
  2343. X
  2344. Xvoid backwarddeleteword() /**/
  2345. X{
  2346. Xint x = cs;
  2347. X
  2348. X    if (mult < 0) { mult = -mult; deleteword(); return; }
  2349. X    while (mult--) {
  2350. X        while (x && !iword(line[x-1])) x--;
  2351. X        while (x && iword(line[x-1])) x--;
  2352. X    }
  2353. X    backdel(cs-x);
  2354. X}
  2355. X
  2356. Xvoid vibackwardkillword() /**/
  2357. X{
  2358. Xint x = cs;
  2359. X
  2360. X        if (mult < 0) { feep(); return; }
  2361. X    /* this taken from "vibackwardword" */
  2362. X        while (mult--) {
  2363. X                while ((x > viinsbegin) && iblank(line[x-1])) x--;
  2364. X                if (iident(line[x-1])) while ((x > viinsbegin) && iident(line[x-1])) x--;
  2365. X                else while ((x > viinsbegin) && !iident(line[x-1]) && !iblank(line[x-1])) x--;
  2366. X        }
  2367. X        /* 
  2368. X        while (mult--) {
  2369. X                while ( (x > viinsbegin) && (iwordsep(line[x-1]))) x--;
  2370. X                while ( (x > viinsbegin) && (!iwordsep(line[x-1]))) x--;
  2371. X        }
  2372. X        */ 
  2373. X        backkill(cs-x,1);
  2374. X}
  2375. X
  2376. Xvoid backwardkillword() /**/
  2377. X{
  2378. Xint x = cs;
  2379. X
  2380. X        if (mult < 0) { mult = -mult; killword(); return; }
  2381. X        while (mult--) {                       
  2382. X                while (x && !iword(line[x-1])) x--;
  2383. X                while (x && iword(line[x-1])) x--;
  2384. X        }                                      
  2385. X        backkill(cs-x,1);                      
  2386. X}                                              
  2387. X
  2388. X
  2389. Xvoid upcaseword() /**/
  2390. X{
  2391. Xint neg = mult < 0, ocs = cs;
  2392. X
  2393. X    if (neg) mult = -mult;
  2394. X    while (mult--) {
  2395. X        while (cs != ll && !iword(line[cs])) cs++;
  2396. X        while (cs != ll && iword(line[cs])) {
  2397. X            line[cs] = tuupper(line[cs]);
  2398. X            cs++;
  2399. X        }
  2400. X    }
  2401. X    if (neg) cs = ocs;
  2402. X}
  2403. X
  2404. Xvoid downcaseword() /**/
  2405. X{
  2406. Xint neg = mult < 0, ocs = cs;
  2407. X
  2408. X    if (neg) mult = -mult;
  2409. X    while (mult--) {
  2410. X        while (cs != ll && !iword(line[cs])) cs++;
  2411. X        while (cs != ll && iword(line[cs])) {
  2412. X            line[cs] = tulower(line[cs]);
  2413. X            cs++;
  2414. X        }
  2415. X    }
  2416. X    if (neg) cs = ocs;
  2417. X}
  2418. X
  2419. Xvoid capitalizeword() /**/
  2420. X{
  2421. Xint first;
  2422. Xint neg = mult < 0, ocs = cs;
  2423. X    
  2424. X    if (neg) mult = -mult;
  2425. X    while (mult--) {
  2426. X        first = 1;
  2427. X        while (cs != ll && !iword(line[cs])) cs++;
  2428. X        while (cs != ll && iword(line[cs])) {
  2429. X            line[cs] = (first) ? tuupper(line[cs]) : tulower(line[cs]);
  2430. X            first = 0;
  2431. X            cs++;
  2432. X        }
  2433. X    }
  2434. X    if (neg) cs = ocs;
  2435. X}
  2436. X
  2437. Xvoid deleteword() /**/
  2438. X{
  2439. Xint x = cs;
  2440. X
  2441. X    if (mult < 0) { mult = -mult; backwarddeleteword(); return; }
  2442. X    while (mult--) {
  2443. X        while (x != ll && !iword(line[x])) x++;
  2444. X        while (x != ll && iword(line[x])) x++;
  2445. X    }
  2446. X    foredel(x-cs);
  2447. X}
  2448. X
  2449. Xvoid killword() /**/
  2450. X{
  2451. Xint x = cs;
  2452. X
  2453. X    if (mult < 0) { mult = -mult; backwardkillword(); return; }
  2454. X    while (mult--) {
  2455. X        while (x != ll && !iword(line[x])) x++;
  2456. X        while (x != ll && iword(line[x])) x++;
  2457. X    }
  2458. X    forekill(x-cs,0);
  2459. X}
  2460. X
  2461. Xvoid transposewords() /**/
  2462. X{
  2463. Xint p1,p2,p3,p4,x = cs;
  2464. Xchar *temp,*pp;
  2465. Xint neg = mult < 0, ocs = cs;
  2466. X
  2467. X    if (neg) mult = -mult;
  2468. X    while (mult--) {
  2469. X        while (x != ll && line[x] != '\n' && !iword(line[x]))
  2470. X            x++;
  2471. X        if (x == ll || line[x] == '\n') {
  2472. X            x = cs;
  2473. X            while (x && line[x-1] != '\n' && !iword(line[x]))
  2474. X                x--;
  2475. X            if (!x || line[x-1] == '\n') {
  2476. X                feep();
  2477. X                return;
  2478. X            }
  2479. X        }
  2480. X        for (p4 = x; p4 != ll && iword(line[p4]); p4++);
  2481. X        for (p3 = p4; p3 && iword(line[p3-1]); p3--);
  2482. X        if (!p3) {
  2483. X            feep();
  2484. X            return;
  2485. X        }
  2486. X        for (p2 = p3; p2 && !iword(line[p2-1]); p2--);
  2487. X        if (!p2) {
  2488. X            feep();
  2489. X            return;
  2490. X        }
  2491. X        for (p1 = p2; p1 && iword(line[p1-1]); p1--);
  2492. X        pp = temp = halloc(p4-p1+1);
  2493. X        struncpy(&pp,UTOSCP(line+p3),p4-p3);
  2494. X        struncpy(&pp,UTOSCP(line+p2),p3-p2);
  2495. X        struncpy(&pp,UTOSCP(line+p1),p2-p1);
  2496. X        strncpy((char *) line+p1,temp,p4-p1);
  2497. X        cs = p4;
  2498. X    }
  2499. X    if (neg) cs = ocs;
  2500. X}
  2501. END_OF_FILE
  2502.   if test 6652 -ne `wc -c <'src/zle_word.c'`; then
  2503.     echo shar: \"'src/zle_word.c'\" unpacked with wrong size!
  2504.   fi
  2505.   # end of 'src/zle_word.c'
  2506. fi
  2507. echo shar: End of archive 20 \(of 22\).
  2508. cp /dev/null ark20isdone
  2509. MISSING=""
  2510. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ; do
  2511.     if test ! -f ark${I}isdone ; then
  2512.     MISSING="${MISSING} ${I}"
  2513.     fi
  2514. done
  2515. if test "${MISSING}" = "" ; then
  2516.     echo You have unpacked all 22 archives.
  2517.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2518. else
  2519.     echo You still must unpack the following archives:
  2520.     echo "        " ${MISSING}
  2521. fi
  2522. exit 0
  2523.  
  2524. exit 0 # Just in case...
  2525.