home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume35 / zsh / part01 < prev    next >
Encoding:
Text File  |  1993-02-19  |  53.1 KB  |  2,002 lines

  1. Newsgroups: comp.sources.misc
  2. From: zsh-list@cs.uow.edu.au (The Zsh Mailing List)
  3. Subject: v35i051:  zsh - The Z Shell, version 2.3.1, Part01/22
  4. Message-ID: <csm-v35i051=zsh.151804@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 545f86c0cd079712a9cd636b8310f7e3
  6. Date: Sat, 20 Feb 1993 21:18:54 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 51
  11. Archive-name: zsh/part01
  12. Environment: UNIX
  13. Supersedes: zsh2.2: Volume 29, Issue 97-113
  14.  
  15. Zsh is a shell designed for interactive use, although it is also a
  16. powerful scripting language.  Many of the useful features of bash,
  17. ksh, and tcsh were incorporated into zsh; many original features were
  18. added.  See the doc/intro.{troff,txt} document for more details.
  19.  
  20. Zsh was originally written by Paul Falstad, who has transferred the 
  21. current development of the shell to the zsh mailing list:
  22.  
  23.     zsh-list@cs.uow.edu.au
  24.  
  25. To subscribe to the list, send a request to "zsh-request@cs.uow.edu.au".  
  26. This release consists of patches contributed to the mailing list, and 
  27. the mailing list is continuing to work on zsh 2.4 as you read this.
  28.  
  29. --------
  30. #! /bin/sh
  31. # This is a shell archive.  Remove anything before this line, then feed it
  32. # into a shell via "sh file" or similar.  To overwrite existing files,
  33. # type "sh file -c".
  34. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  35. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  36. # Contents:  README doc dots func help man man/man1 scripts src
  37. #   src/params.c
  38. # Wrapped by mattson@odin on Sat Feb  6 14:41:50 1993
  39. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  40. echo If this archive is complete, you will see the following message:
  41. echo '          "shar: End of archive 1 (of 22)."'
  42. if test -f 'README' -a "${1}" != "-c" ; then 
  43.   echo shar: Will not clobber existing file \"'README'\"
  44. else
  45.   echo shar: Extracting \"'README'\" \(22439 characters\)
  46.   sed "s/^X//" >'README' <<'END_OF_FILE'
  47. XYou have permission to copy the zsh distribution in whole or in part
  48. Xas long as you don't try to make money off of it, or pretend that you
  49. Xwrote it.
  50. X
  51. XThis is zsh 2.3.1.
  52. X
  53. XTo get this shell running, cd into the src directory and type
  54. X"buildzsh".  Someone recently tested it on the following machines,
  55. Xwhere it compiled just by running this script:
  56. X
  57. XApollo (Motorola & PRISM) running Domain SR10.4 cc 6.9 
  58. XBBN TC2000 running nX 3.0.1, 3.1.0
  59. XCCI Tahoe running BSD 4.3-tahoe
  60. XDEC (various) running Ultrix 4.2, 4.2A
  61. XDEC Alpha running OSF-1
  62. XFujitsu F2600 running SVR4
  63. XHP 9000 (various) running HP-UX 7.0x, 8.0x, 9.01
  64. XIBM RS6000 running AIX 3.2
  65. XMIPS running RISC/OS 4.x
  66. XNeXT running NeXTSTEP 2.x, 3.0
  67. XSGI running IRIX 4.0.5
  68. XSequent running DYNIX (additional work needed for DYNIX/PTX)
  69. XSony running NeWS/OS 3.2 (BSD 4.3)
  70. XSun-3, Sun-4 running SunOS 4.0.3, 4.1.x
  71. X
  72. XZsh was originally written by Paul Falstad, who has transferred the 
  73. Xcurrent development of the shell to the zsh mailing list:
  74. X
  75. X    zsh-list@cs.uow.edu.au
  76. X
  77. XTo subscribe to the list, send a request to "zsh-request@cs.uow.edu.au".  
  78. XThis release consists of patches contributed to the mailing list, and 
  79. Xthe mailing list is continuing to work on zsh 2.4.
  80. X
  81. XThe following people contributed patches for the 2.3 release:
  82. X
  83. XHans Albertsson            Tero Kivinen
  84. XEric Arnold            Karsten Kuenne
  85. XBas de Bakker            Ben Liblit
  86. XMarc Boucher            Rick Lyons
  87. XCarlos Carvalho            Jim Mattson
  88. XRobert Clare            Jean-Jacques Moreau
  89. XDaniel Dignam            J.B. Nicholson-Owens
  90. XStephen Dum            Rick Ohnemus
  91. XCarl Edman            Wolf N. Paul
  92. XChristian Finger        Bart Schaefer
  93. XBrian Gregory            Dwight Shih
  94. XJohn Guthrie            Peter Stephenson
  95. XJohan Hagman            Klaus Wacker
  96. XJonathan Hardwick        Irving Wolfe
  97. X
  98. XTabstops are 3 spaces.  If you're going to look at this code, run it
  99. Xthough "expand -3" first, or set your tab stops every 3 spaces.
  100. X
  101. XModification history:
  102. X
  103. X2.3.1-2.3.0:
  104. Xo fewer compilation warnings
  105. Xo parsing error in function definition fixed
  106. Xo problems with '.' in vi-mode fixed
  107. Xo parsing bug with ! and coproc fixed
  108. Xo strange while loop behavior fixed
  109. Xo "TRAPx TRAPy {}; unfunction TRAPy" fixed
  110. Xo array-size checking for integers was off by one (fixed)
  111. X
  112. X2.3.0-2.2.0:
  113. Xo improved portability
  114. Xo fewer compilation warnings
  115. Xo texinfo documentation
  116. Xo several memory leaks fixed, and a few references to freed memory eliminated
  117. Xo several parsing bugs fixed, and now less illegal syntax is accepted
  118. Xo improved (i.e. repaired) signal handling
  119. Xo RFS support
  120. Xo rc files reorganized (see INVOCATION in the man page)
  121. Xo ksh compatibility mode when zsh is invoked as "ksh"
  122. Xo nested variables (e.g. echo ${${var#?}%?})
  123. Xo stringized array variables ("$a" where a is an array)
  124. Xo can now set array slices and array elements by subscript
  125. Xo 4 new glob identifiers:
  126. X    -  a[[-|+]n]   files accessed within last n days (-), files accessed
  127. X                   more than n days ago (+), or files accessed n days ago.
  128. X    -  m[[-|+]n]   as above for modified files.
  129. X    -  c[[-|+]n]   as above for the modification of an inode of a file.
  130. X    -  L[[-|+]n]   files less than n bytes (-), more than n bytes (+),
  131. X                   or exactly n bytes in length.
  132. Xo new prompt escapes and new syntax for numeric arguments to prompt escapes
  133. X   (e.g. %C3 -> %3C)
  134. Xo %R and %r now only recognized in spell-checking prompts
  135. Xo watch notme (like watch all, except for the user's own activity)
  136. Xo hash table listings (from set, alias, compctl...) are now sorted
  137. Xo New arguments to fc builtin:
  138. X    -f  print full time stamp (including date)
  139. X    -E  print date in European format (dd.mm.yyyy)
  140. X    -I  incremental history update (with -A or -W)
  141. Xo new EXTENDEDHISTORY option for saving timestamps to history file
  142. Xo new {up,down}-line-or-search keybindings
  143. Xo cd processing (chpwd, etc.) no longer occurs if new directory is the
  144. X  same as the previous one
  145. Xo filename completion works on named directories
  146. Xo named directories now have to be strings
  147. Xo username lookup more efficient, new username lookup routine for NIS
  148. Xo sample run-help function to make use of the help directory
  149. Xo sample zed function (use the zle line editor to edit a file)
  150. Xo If compctl is just -h for a command, hostname completion will now be
  151. X  performed after an @.  Compctl is set to just -h for commands in hostcmds.
  152. Xo zsh no longer forks /bin/sh for any shell commands (e.g. STTY)
  153. Xo old AUTOREMOVESLASH option documented and repaired.
  154. Xo lexically significant quotes and backslashes are now retained by builtins
  155. Xo backslashes now end variable names and suffice in a here document 
  156. X  terminator to inhibit interpretation of the here document
  157. Xo answering 'n' to 'remove all files in <arg>?' just removes the individual
  158. X  argument from the rm command line, as long as other arguments remain
  159. Xo ALLEXPORT now exports existing variables when they are modified
  160. Xo whitespace now handled properly by read builtin
  161. Xo ${#@} and ${#*} are now recognized
  162. Xo colon modifers now work with array variables 
  163. X  (except :x and :q, which only pretend to work)
  164. Xo ${...=...} handling fixed
  165. Xo cd xx/.. no longer takes you to first directory of $cdpath
  166. Xo return in a loop in a function now exits the function
  167. Xo return from a function in a loop no longer exits the loop
  168. Xo several fixes to 'fc' builtin
  169. Xo 'noglob rm *' no longer prompts for confirmation
  170. Xo changes to cdpath, manpath, etc. are now reflected in the environment
  171. Xo vibackwardkillword fixed to use vi style words
  172. Xo not found message no longer printed if 'whence -a foo' doesn't find anything
  173. Xo current dir is removed from directory stack if PUSHD_IGNORE_DUPS is set
  174. Xo cd now complains of invalid directory stack arguments
  175. Xo extra files are no longer left open on nullexec
  176. Xo exit status is set correctly for shells started '-c'
  177. Xo consistent handling of -i and -m options
  178. Xo null arguments are now included in array expansion
  179. Xo job text corrected for coprocesses
  180. Xo a quoted command substitution that returns no text is no longer discarded
  181. X  (e.g. set a "`echo`" b ; echo $#)
  182. Xo IFS allows null fields
  183. Xo read of more variables than available in the input no longer blocks shell
  184. Xo dups of nonexistent file handles fixed
  185. Xo confusion regarding controlling terminal fixed
  186. Xo canonical directory naming fixed
  187. Xo zsh no longer hangs on backquote expansion (e.g. echo `pwd`)
  188. Xo echo foo >>(cat) now redirects stdin before closing the pipe
  189. Xo problems with zsh not exiting fixed
  190. Xo bad patterns now work when NOBADPATTERN is set
  191. Xo exporting of special shell variables fixed
  192. Xo history references now work only in interactive shells
  193. Xo history file no longer saved if history is not established
  194. Xo killing a command in a loop now kills the loop
  195. Xo compctl -k now essentially ignores non-array arguments
  196. Xo transpose-chars now works on one character lines and on the second 
  197. X  character of a line
  198. Xo neg-argument now works for multiple digits
  199. Xo statusline no longer trashed when searching in vi mode
  200. Xo print -P can now be invoked from a signal handler without confusing zle
  201. Xo prototype files automatically generated during compilation
  202. Xo GLOBALZSHENV now defined by default as "/etc/zshenv"
  203. Xo off-by-one error in compiling signal list fixed
  204. X
  205. X2.2.0-2.1.0:
  206. Xo should be faster in general
  207. Xo fewer compilation warnings
  208. Xo SPROMPT now uses %R instead of %s for the incorrect string
  209. Xo no longer tries to create FIFOs on NeXTs (thereby causing a panic)
  210. Xo now gets usernames from NIS on irises without crashing (SGI's getpwnam()
  211. X  called my strdup(), the pricks.  Took me forever to find that.  :-) )
  212. Xo fewer 7-bit assumptions
  213. Xo which/whence/type have new options:
  214. X  -a = all (find all occurrences of command in path)
  215. X  -c = csh-style which (default for "which" command)
  216. Xo error message for cd str1 str2 is fixed
  217. Xo relative paths (including .) in cdpath now work
  218. Xo exclusion patterns in glob: ls *.c~lex.c prints all .c files but lex.c
  219. Xo bug with command substitution in chpwd fixed (buffers flushed twice)
  220. Xo relative paths in $path now work
  221. Xo "kill -9 -FOO" no longer kills shell
  222. Xo new options to history/fc:
  223. X    -d = prints date commands were entered
  224. X    -D = prints running time of commands
  225. Xo "history <num>" prints all commands SINCE <num> as well
  226. Xo history stored differently - should be more efficient
  227. Xo bg'ing a suspended zsh no longer causes problems
  228. Xo "set" no longer prints ONLY exported params (duh)
  229. Xo functions +t now allowed
  230. Xo redirection is done AFTER filename generation
  231. Xo print changes:
  232. X  o print -u# prints to fd #
  233. X  o print -p prints to coproc
  234. X  o -D and -P perform \ substitution first
  235. X  o print -0 changed to print -N
  236. Xo read changes:
  237. X  o read -u# reads from fd #
  238. X  o read -p reads from coproc
  239. X  o read -z waits for input if nothing on buffer stack
  240. X  o no longer reads from fd 0 if shell is getting input from there
  241. X  o echo -n foo | read x  now works
  242. Xo getopts is now POSIX conformant
  243. Xo compctl builtin added, replacing hostcmds, foocmds, etc.  Controls
  244. X  completion of various commands in zle.
  245. X  format: compctl -options cmdnams ...
  246. X  options tell where to get possible matches from, and include:
  247. X     -c = command names
  248. X     -f = filenames
  249. X     -h = hostnames ($hosts)
  250. X     -o = options
  251. X     -v = vars
  252. X     -b = bindings
  253. X     -k name = elements of $name array
  254. X  Any number of these options may be used together.
  255. X  In addition, compctl -C -options will set the default completion
  256. X  names when in command position (by default -c), and compctl -D -options
  257. X  will set the default completion names used after unrecognized commands
  258. X  or after redirections (by default -f).
  259. Xo foo && bar || fuu now works
  260. Xo ttyctl builtin added
  261. X  ttyctl -f freezes the tty.  no changes made to the tty settings by
  262. X     external programs will be honored when this command is in effect.
  263. X  ttyctl -u unfreezes the tty.
  264. X  typically, "ttyctl -f" would be used in a zlogin or zshrc script after
  265. X  "stty" has been called to set up the terminal.
  266. Xo [[ -e file ]] is now equivalent to [[ -a file ]]
  267. Xo [[ -h file ]] is now equivalent to [[ -L file ]]
  268. Xo the path is now hashed incrementally.
  269. X  o if the HASHCMDS option is unset, path hashing is not done at all.
  270. X  o if the HASHCMDS option is set but HASHDIRS is unset, commands are placed
  271. X     in the hash table when first executed.
  272. X  o if the HASHCMDS and HASHDIRS options are both set, commands are placed
  273. X     in the hash table when first executed, along with all commands in
  274. X     the directory that command was found in (and all directories earlier
  275. X     in the path).  This is the default situation.
  276. Xo "for i (*.c) do /bin/echo $i ; done | more" no longer hangs
  277. Xo coprocesses now work properly
  278. Xo READNULLCMD is now used instead of NULLCMD for "< file"
  279. Xo POSTEDIT is printed whenever the editor exits
  280. Xo rm path/path/* is now reported by checkrmall()
  281. Xo cmd >&- works
  282. Xo cmd >>! file works
  283. Xo time cmd no longer forks an extra process
  284. Xo setopt printexitvalue ; echo `false` no longer prints anything
  285. Xo here documents work inside eval, etc.
  286. Xo $(...) works inside here documents
  287. Xo "time" by itself prints the shell timings
  288. Xo locals in precmd() or chpwd() work
  289. Xo new glob qualifiers
  290. X  o pat(M) sets markdirs, pat(^M) unsets it
  291. X  o pat(N) sets nullglob, ...
  292. X  o pat(D) sets globdots, ...
  293. Xo ls * only sorts numeric filenames specially if NUMERICGLOBSORT is set
  294. Xo setopt braceccl lets "echo {a-zA-Z}" work
  295. Xo new options: pushdignoredups nohistbeep overstrike
  296. Xo ls **/file is now equivalent to ls ****/file
  297. Xo !'s in history are now escaped when you return to them
  298. Xo history substitution is not done in script files
  299. Xo echo $(!-2) works
  300. Xo histverify and correct 'e' no longer put the edit line in the history
  301. Xo the :x, :q, and :gs modifiers work properly now
  302. Xo zsh -c 'ls =(ls)' no longer hangs
  303. Xo VSWTCH is now set to ^Z on the irises
  304. Xo zsh & no longer causes havoc
  305. Xo USERNAME and LOGNAME are kept separate
  306. Xo $manpath has been added for easy access to the $MANPATH components
  307. Xo zsh now realizes if it is running under emacs, and resigns itself to
  308. X  the fact rather than panicking
  309. Xo SIGQUIT is ignored in the PRODUCTION version of zsh, and kills the shell
  310. X  in the DEBUG version, rather than vice versa.
  311. Xo GLOBALZSHENV has been added, and GLOBALZPROFILE is sourced in the
  312. X  proper place
  313. Xo "kill %" no longer causes the prompt to be printed 3 times if notify
  314. X  is set on a NeXT
  315. Xo REPORTTIME has been added; if a job runs longer than this many seconds,
  316. X  timing statistics are reported
  317. Xo timing statistics now include a job name (%J)
  318. Xo no longer talks about SIGHUPed jobs if the kill failed
  319. Xo no longer talks about running jobs which don't exist if you do eval exit
  320. X  or if you have notify unset
  321. Xo foo=bar comman[tab], for/select/foreach i (*.c[tab] both work
  322. Xo [base]num inside $[...] works
  323. Xo foo=pat(n|ern) works
  324. Xo cd - prints the new directory
  325. Xo l[tab] works if l is an alias
  326. Xo select foo ; ... works (in $argv is assumed)
  327. Xo select reads from the right input
  328. Xo math identifiers can now contain numbers and _'s.
  329. Xo lots of serious memory heap trashing and leaks fixed
  330. Xo echo $HOME[*] no longer crashes the shell
  331. Xo SIGWINCH now changes LINES and COLUMNS in the environment
  332. Xo typeset +r TTY; TTY=foo no longer causes problems
  333. Xo ~ substitution is no longer done in FIGNORE
  334. Xo assignment to SECONDS works
  335. Xo "else if" is no longer a synonym for "elif" <thud>
  336. Xo lots of problems with null lists in flow constructs fixed
  337. Xo no correction done for >file
  338. Xo echo ${foo%bar is no longer weird
  339. Xo modifying array substitutions works
  340. Xo ^O can be bound to something
  341. Xo command substitution in signal handlers no longer causes problems
  342. Xo spelling correction is better ($PATH is corrected), and SPROMPT
  343. X  allows all the regular PROMPT escapes
  344. Xo new prompt escape sequence: %D{...} formats ... part using strftime
  345. Xo shell input no longer butchered using IFS
  346. Xo vi cmd mode has 's' bound to visubstitute, as it should be
  347. Xo you can use ^XS and ^XR in i-search mode
  348. Xo bindings to ^Z and ^@ work now on the irises
  349. Xo ^V{^S,^Q,^Z,etc} now works on sgttyb victims
  350. Xo nopromptclobber changed to nopromptcr
  351. Xo vi 'u' undo works a little better (?)
  352. Xo ESC-key bindings aren't screwed up if VISUAL is set to vi
  353. Xo newline in prompt now works reliably
  354. Xo vi change and delete work with forward-word/search, etc.
  355. Xo somewhat suboptimal screen refresh on irises fixed (several seconds
  356. X  per character inserted when TERM=xterm??)
  357. Xo select list printing slightly different
  358. Xo magic-space's handling of hatchars "fixed"
  359. X
  360. X0.03-1.0:
  361. X    - "..../" is now "****/".  I know this isn't backward compatible,
  362. X      but I had no choice; the string "..../" was unquotable.
  363. X    - parser was rewritten and improved
  364. X    - completion was improved, several bugs fixed (including
  365. X      the "$([tab]" bug)
  366. X    - vi mode editing is improved
  367. X    - the value of PWD and OLDPWD in the environment now change
  368. X    - the PROMPT formatting strings %W and %D now print the month
  369. X      correctly
  370. X    - >&2 echo "error message" no longer prints "bad file number"
  371. X    - ${foo%pat} no longer alters the value of foo
  372. X    - $_ works
  373. X    - ALL_EXPORT no longer causes let statements to crash the shell
  374. X    - continue works
  375. X    - echo $MAIL no longer dumps core if MAIL is null
  376. X    - the new tty driver is selected by default
  377. X    - the s modifier no longer complains if it can't find the string
  378. X      to substitute
  379. X    - list-choices no longer fignores files
  380. X    - cd is now smarter about symlinks
  381. X    - negative subscripts other than -1 now work
  382. X    - $(<filename) works better if filename contains $, ~, or =
  383. X    - rehash no longer wastes memory
  384. X    - with name=value assignments, name is checked to see if it is
  385. X      a valid identifier
  386. X    - !1; !2 no longer eats the semicolon
  387. X    - $foo:h never returns the empty string if foo starts with /
  388. X    - select crashed with some compilers
  389. X    - problems with aliases in <(...) constructs have been fixed
  390. X    - links pointing to nowhere are denoted with an '&' in listtypes
  391. X    - negative arguments are supported
  392. X    - the shell does not screw around with the tty so much
  393. X    - lots of other stuff
  394. X
  395. X0.02-0.03:
  396. X    - two stupid bugs that were introduced in the last patch were fixed:
  397. X      - multiple command substitution on a line failed
  398. X      - a file descriptor leak caused the shell to crash after a while
  399. X    - added 'An Introduction to the Z Shell'
  400. X    - behaves properly when the tty session dies suddenly
  401. X    - had a serious memory leak on some systems
  402. X    - the test and [ builtins have been added, although [[...]]
  403. X      is more efficient
  404. X    - in your prompt, %m2 now prints foo.bar, %m3 prints foo.bar.com, etc.
  405. X    - the -D and -P options to print have been added
  406. X    - the NULLCMD and ZDOTDIR parameters have been added
  407. X    - ${*:-foo} works
  408. X    - "$@" and "$arr[@]" work like ksh
  409. X    - .zprofile is sourced before .zshrc in login shells
  410. X    - the CSHJUNKIEQUOTES and PUSHDMINUS options have been added
  411. X    - REAL_TTY compilation switch added
  412. X    - aliases beginning with a space cause the history line to be junked
  413. X      if HISTIGNORESPACE is set
  414. X    - echo prints bad options instead of complaining about them
  415. X    - "set -o" no longer dumps core
  416. X    - "alias a=alias; date >a" no longer creates a file called "alias"
  417. X    - "function foo() \n { date }" is now legal (the () and the newline
  418. X      are allowed)
  419. X    - nested brace expressions work properly
  420. X    - disabled commands stay disabled after a rehash (or after the shell
  421. X      finishes sourcing your .zshrc)
  422. X    - corrected aliases work
  423. X    - executables in the currect directory are now completed
  424. X    - in "case foo", "foo" is not interpreted as a directory name with autocd
  425. X    - aliases were not always interpreted properly after a completion
  426. X    - bindkey '^?' didn't work
  427. X    - echo ${HOST:-{bar}} didn't work
  428. X    - editor update is more efficient in some cases
  429. X    - menucomplete works even better
  430. X    - assign to an array element "foo[1]=bar" didn't always work
  431. X    - doesn't print directories like "~tmp" if HOME=/
  432. X    - quotes in case statement patterns caused problems
  433. X    - pressing ^C right after typing "fc" caused the editor to share
  434. X      the tty with the shell
  435. X    - echo $(echo 2) produced no output, but echo $(echo x) worked fine (weird)
  436. X
  437. X0.01-0.02:
  438. X    - added script to convert most csh aliases to zsh aliases or functions
  439. X    - fc -l (history) now appears in the history itself; HISTNOSTORE
  440. X      option added to get old behavior
  441. X    - the POSIX process group race has been fixed; so 'w | more' should
  442. X      no longer hang
  443. X    - FCEDIT added, to match the documentation
  444. X    - %{...%} in the prompt added
  445. X    - execute-named-cmd and execute-last-named-cmd bindings added
  446. X    - sources ~/.zshenv in all shells, even if not interactive, unless
  447. X      -f is given
  448. X    - ^ and # are no longer `magic' by default; use EXTENDEDGLOB option
  449. X      to use them
  450. X    - now checks for tty sanity before each command
  451. X    - if the right side of a variable assignment expands to more than
  452. X      one word, array assignment is assumed; so foo=*.c now works
  453. X    - ~foo is no longer expanded in completion
  454. X    - select now works even if the argument list is not sorted
  455. X    - menucompletebeep option added
  456. X    - emacs mode is now 8-bit clean by default; use bindkey -em
  457. X      to get your meta key back
  458. X    - fc -R, fc -W added
  459. X    - nocorrect added
  460. X    - lines from history file are now split into words at spaces
  461. X    - glob-complete, accept-and-menu-complete,
  462. X      beginning-of-line-hist, end-of-line-hist bindings added
  463. X    - insert-last-word bound to M-. in emacs mode by default; now moves
  464. X      back through the history if run repeatedly
  465. X    - J and K now bound to history search in vi mode
  466. X    - delete-char no longer core dumps on an empty line
  467. X    - menu-complete works better
  468. X    - the editor checks the settings of VISUAL and EDITOR to set
  469. X      default bindings
  470. X    - using [[ ... ]] expressions on a symbolic link works as expected
  471. X    - various problems with globbing were fixed
  472. X    - xx is now the same as !! if HISTCHARS=x
  473. X    - added config.h entry for compilers that don't know about void *
  474. X    - lexical analysis made more efficient
  475. X    - "if echo $? ; then : ; fi" no longer always prints 0
  476. X    - removed all enums, '\x7f's from code
  477. X    - in "case foo in bar) xxx ;; esac", foo and bar are no longer subject
  478. X      to command alias expansion
  479. X    - works on platforms where toupper('A') != 'A'
  480. X    - \e sequence added to echo
  481. X    - + options now work with set
  482. X    - AUTORESUME and AUTOCD work better
  483. X    - getopts works better (?)
  484. X    - spell checking works better
  485. X    - "let 2+3=" no longer crashes the shell
  486. X    - "foo=bar; echo ${=foo}" no longer crashes the shell
  487. X    - "zsh -c" or "zsh -o" no longer causes a core dump
  488. X    - "unset MAIL; echo $MAIL" no longer causes a core dump
  489. X    - "(xterm&xterm&)&" no longer causes a core dump
  490. X    - "echo $HOM[tab]" beeps instead of deleting "$HOM"
  491. X    - incremental history search works better
  492. X    - the pwd of a fg'd job is now printed _before_ resuming it
  493. X    - rv=`echo -n foo` no longer puts garbage in $rv
  494. X    - "=1/*" now works as expected
  495. X    - ^Z can now be bound to something
  496. X    - the STTY parameter and the builtin builtin are now documented
  497. X    - IFS=x; foo=`echo foo` no longer puts a newline in $foo
  498. X    - $status added for csh compatibility
  499. X    - arrays are automatically expanded if you say 'foo[1234]=x'
  500. X    - shell now ignores SIGQUIT (it was commented out before :-)
  501. X    - the times builtin works on systems where times() returns > 0
  502. X    - no longer hangs the terminal if you ^S before flow control
  503. X      is turned off
  504. X    - "date ; read foo" now works in interactive shells
  505. X    - <<-foo is now parsed as <<- foo, not << -foo
  506. X    - fixed various errors in the documentation
  507. X
  508. X0.00-0.01:
  509. X    - %M and %m now work as documented.
  510. X    - bad things no longer happen if COLUMNS is set to 0
  511. X    - SH_WORD_SPLIT and ${=foo} now work
  512. X    - the default value of WORDCHARS includes more characters
  513. X    - if the cursor is at the end of the line, vi-cmd-mode
  514. X      moves it back one position.
  515. X    - delete-char now acts more like x in vi.
  516. X    - a "prompt" parameter has been added, which is equivalent to
  517. X      PROMPT and PS1.
  518. X    - zsh no longer expands symbolic links.  The CHASELINKS option
  519. X      has been provided to get the old behavior.
  520. X    - history searches ignore lines that are the same as the line
  521. X      in the buffer.
  522. X    - you can get a literal ! in your prompt now with \!.
  523. X    - -z, -n, and != in [[ ... ]] expressions work.
  524. X    - the shell no longer hangs when inputting "[[ ]\n"
  525. X    - the "menu-complete" and "menu-expand-or-complete" bindings have
  526. X      been added.
  527. X    - menu-complete no longer beeps.
  528. X    - reverse-menu-complete no longer dumps core if it gets called before
  529. X      a normal completion.
  530. X    - typeahead lines are no longer thrown away on machines with sgttyb.
  531. X    - !foo no longer matches lines with 'foo' in them (not at the beginning)
  532. X    - kill -9 % no longer kills the shell
  533. X    - no longer sources .zshrc from shell scripts or with -c
  534. X    - no longer needs limits.h, strtol
  535. X    - exporting HOSTTYPE, etc. works
  536. X    - fixed serious bugs related to . in path
  537. X    - numbers in weird bases now work
  538. X
  539. XKnown Bugs
  540. X    - terminal acts weird under OpenWindows cmdtool
  541. X    - xterm run in background inherits bad terminal modes
  542. X
  543. END_OF_FILE
  544.   if test 22439 -ne `wc -c <'README'`; then
  545.     echo shar: \"'README'\" unpacked with wrong size!
  546.   fi
  547.   # end of 'README'
  548. fi
  549. if test ! -d 'doc' ; then
  550.     echo shar: Creating directory \"'doc'\"
  551.     mkdir 'doc'
  552. fi
  553. if test ! -d 'dots' ; then
  554.     echo shar: Creating directory \"'dots'\"
  555.     mkdir 'dots'
  556. fi
  557. if test ! -d 'func' ; then
  558.     echo shar: Creating directory \"'func'\"
  559.     mkdir 'func'
  560. fi
  561. if test ! -d 'help' ; then
  562.     echo shar: Creating directory \"'help'\"
  563.     mkdir 'help'
  564. fi
  565. if test ! -d 'man' ; then
  566.     echo shar: Creating directory \"'man'\"
  567.     mkdir 'man'
  568. fi
  569. if test ! -d 'man/man1' ; then
  570.     echo shar: Creating directory \"'man/man1'\"
  571.     mkdir 'man/man1'
  572. fi
  573. if test ! -d 'scripts' ; then
  574.     echo shar: Creating directory \"'scripts'\"
  575.     mkdir 'scripts'
  576. fi
  577. if test ! -d 'src' ; then
  578.     echo shar: Creating directory \"'src'\"
  579.     mkdir 'src'
  580. fi
  581. if test -f 'src/params.c' -a "${1}" != "-c" ; then 
  582.   echo shar: Will not clobber existing file \"'src/params.c'\"
  583. else
  584.   echo shar: Extracting \"'src/params.c'\" \(26353 characters\)
  585.   sed "s/^X//" >'src/params.c' <<'END_OF_FILE'
  586. X/*
  587. X *
  588. X * params.c - parameters
  589. X *
  590. X * This file is part of zsh, the Z shell.
  591. X *
  592. X * This software is Copyright 1992 by Paul Falstad
  593. X *
  594. X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  595. X * use this software as long as: there is no monetary profit gained
  596. X * specifically from the use or reproduction of this software, it is not
  597. X * sold, rented, traded or otherwise marketed, and this copyright notice is
  598. X * included prominently in any copy made. 
  599. X *
  600. X * The author make no claims as to the fitness or correctness of this software
  601. X * for any use whatsoever, and it is provided as is. Any use of this software
  602. X * is at the user's own risk. 
  603. X *
  604. X */
  605. X
  606. X#include "zsh.h"
  607. X#include "version.h"
  608. X#include <pwd.h>
  609. X
  610. X#define new(X) (X=(vptr)alloc(sizeof(*(X))))
  611. X
  612. Xstatic Param argvparam;
  613. X
  614. Xstruct iparam {
  615. X    struct hashnode *next; int canfree; char *nam; /* hash data */
  616. X    vptr value;
  617. X    int (*func1)(); /* set func */
  618. X    int (*func2)(); /* get func */
  619. X    int ct;                /* output base or field width */
  620. X    int flags;
  621. X    vptr data;            /* used by getfns */
  622. X    char *env;            /* location in environment, if exported */
  623. X    char *ename;        /* name of corresponding environment var */
  624. X    };
  625. X
  626. X#define IFN(X) ((int (*)())(X))
  627. X
  628. X/* put predefined params in hash table */
  629. X
  630. Xvoid setupparams() /**/
  631. X{
  632. Xstatic struct iparam pinit[] = {
  633. X#define IPDEF1(A,B,C,D) {NULL,0,A,NULL,IFN(C),IFN(B),10,\
  634. X        PMFLAG_i|PMFLAG_SPECIAL|D,NULL,NULL,NULL}
  635. X    IPDEF1("#",poundgetfn,IFN(nullsetfn),PMFLAG_r),
  636. X    IPDEF1("ARGC",poundgetfn,IFN(nullsetfn),PMFLAG_r),
  637. X    IPDEF1("ERRNO",errnogetfn,IFN(nullsetfn),PMFLAG_r),
  638. X    IPDEF1("GID",gidgetfn,IFN(nullsetfn),PMFLAG_r),
  639. X    IPDEF1("HISTSIZE",histsizegetfn,histsizesetfn,0),
  640. X    IPDEF1("LITHISTSIZE",lithistsizegetfn,lithistsizesetfn,0),
  641. X    IPDEF1("RANDOM",randomgetfn,randomsetfn,0),
  642. X    IPDEF1("SECONDS",secondsgetfn,secondssetfn,0),
  643. X    IPDEF1("UID",uidgetfn,IFN(nullsetfn),PMFLAG_r),
  644. X
  645. X#define IPDEF2(A,B,C,D) {NULL,0,A,NULL,IFN(C),IFN(B),0,\
  646. X        PMFLAG_SPECIAL|D,NULL,NULL,NULL}
  647. X    IPDEF2("-",dashgetfn,IFN(nullsetfn),PMFLAG_r),
  648. X    IPDEF2("HISTCHARS",histcharsgetfn,histcharssetfn,0),
  649. X    IPDEF2("HOME",homegetfn,homesetfn,0),
  650. X    IPDEF2("TERM",termgetfn,termsetfn,0),
  651. X    IPDEF2("WORDCHARS",wordcharsgetfn,wordcharssetfn,0),
  652. X    IPDEF2("IFS",ifsgetfn,ifssetfn,0),
  653. X    IPDEF2("_",underscoregetfn,IFN(nullsetfn),PMFLAG_r),
  654. X
  655. X#define IPDEF3(A) {NULL,0,A,NULL,IFN(nullsetfn),IFN(strconstgetfn),0,PMFLAG_r|\
  656. X        PMFLAG_SPECIAL,NULL,NULL,NULL}
  657. X    IPDEF3("HOSTTYPE"),
  658. X    IPDEF3("VERSION"),
  659. X
  660. X#define IPDEF4(A,B) {NULL,0,A,NULL,IFN(nullsetfn),IFN(intvargetfn),10,\
  661. X        PMFLAG_r|PMFLAG_i|PMFLAG_SPECIAL,(vptr)B,NULL,NULL}
  662. X    IPDEF4("!",&lastpid),
  663. X    IPDEF4("$",&mypid),
  664. X    IPDEF4("?",&lastval),
  665. X    IPDEF4("status",&lastval),
  666. X    IPDEF4("LINENO",&lineno),
  667. X    IPDEF4("PPID",&ppid),
  668. X
  669. X#define IPDEF5(A,B) {NULL,0,A,NULL,IFN(intvarsetfn),IFN(intvargetfn),10,\
  670. X        PMFLAG_i|PMFLAG_SPECIAL,(vptr)B,NULL,NULL}
  671. X    IPDEF5("BAUD",&baud),
  672. X    IPDEF5("COLUMNS",&columns),
  673. X    IPDEF5("DIRSTACKSIZE",&dirstacksize),
  674. X    IPDEF5("LINES",&lines),
  675. X    IPDEF5("LISTMAX",&listmax),
  676. X    IPDEF5("LOGCHECK",&logcheck),
  677. X    IPDEF5("MAILCHECK",&mailcheck),
  678. X    IPDEF5("OPTIND",&zoptind),
  679. X    IPDEF5("PERIOD",&period),
  680. X    IPDEF5("REPORTTIME",&reporttime),
  681. X    IPDEF5("SAVEHIST",&savehist),
  682. X    IPDEF5("SHLVL",&shlvl),
  683. X    IPDEF5("TMOUT",&tmout),
  684. X
  685. X#define IPDEF6(A,B) {NULL,0,A,NULL,IFN(nullsetfn),IFN(strvargetfn),0,\
  686. X        PMFLAG_r|PMFLAG_SPECIAL,(vptr)B,NULL,NULL}
  687. X    IPDEF6("LOGNAME",&logname),
  688. X    IPDEF6("PWD",&pwd),
  689. X    IPDEF6("TTY",&ttystrname),
  690. X    IPDEF6("USERNAME",&username),
  691. X
  692. X#define IPDEF7(A,B) {NULL,0,A,NULL,IFN(strvarsetfn),IFN(strvargetfn),0,\
  693. X        PMFLAG_SPECIAL,(vptr)B,NULL,NULL}
  694. X    IPDEF7("FCEDIT",&fceditparam),
  695. X    IPDEF7("HOST",&hostnam),
  696. X    IPDEF7("OLDPWD",&oldpwd),
  697. X    IPDEF7("OPTARG",&optarg),
  698. X    IPDEF7("MAIL",&mailfile),
  699. X    IPDEF7("NULLCMD",&nullcmd),
  700. X    IPDEF7("POSTEDIT",&postedit),
  701. X    IPDEF7("prompt",&prompt),
  702. X    IPDEF7("PROMPT",&prompt),
  703. X    IPDEF7("PROMPT2",&prompt2),
  704. X    IPDEF7("PROMPT3",&prompt3),
  705. X    IPDEF7("PROMPT4",&prompt4),
  706. X    IPDEF7("READNULLCMD",&readnullcmd),
  707. X    IPDEF7("RPROMPT",&rprompt),
  708. X    IPDEF7("PS1",&prompt),
  709. X    IPDEF7("PS2",&prompt2),
  710. X    IPDEF7("PS3",&prompt3),
  711. X    IPDEF7("PS4",&prompt4),
  712. X    IPDEF7("RPS1",&rprompt),
  713. X    IPDEF7("SPROMPT",&sprompt),
  714. X    IPDEF7("TIMEFMT",&timefmt),
  715. X    IPDEF7("TMPPREFIX",&tmpprefix),
  716. X    IPDEF7("WATCHFMT",&watchfmt),
  717. X    IPDEF7("0",&argzero),
  718. X
  719. X#define IPDEF8(A,B,C) {NULL,0,A,NULL,IFN(colonarrsetfn),IFN(colonarrgetfn),0,\
  720. X        PMFLAG_SPECIAL,(vptr)C,NULL,B}
  721. X    IPDEF8("CDPATH","cdpath",&cdpath),
  722. X    IPDEF8("FIGNORE","fignore",&fignore),
  723. X    IPDEF8("FPATH","fpath",&fpath),
  724. X    IPDEF8("MAILPATH","mailpath",&mailpath),
  725. X    IPDEF8("MANPATH","manpath",&manpath),
  726. X    IPDEF8("WATCH","watch",&watch),
  727. X    IPDEF8("HOSTS","hosts",&hosts),
  728. X    IPDEF8("PSVAR","psvar",&psvar),
  729. X    IPDEF8("PATH",NULL,NULL),
  730. X
  731. X#define IPDEF9(A,B,C,D) {NULL,0,A,NULL,IFN(arrvarsetfn),IFN(arrvargetfn),0,\
  732. X        PMFLAG_A|PMFLAG_SPECIAL|C,(vptr)B,NULL,D}
  733. X    IPDEF9("cdpath",&cdpath,0,"CDPATH"),
  734. X    IPDEF9("fignore",&fignore,0,"FIGNORE"),
  735. X    IPDEF9("fpath",&fpath,0,"FPATH"),
  736. X    IPDEF9("mailpath",&mailpath,0,"MAILPATH"),
  737. X    IPDEF9("manpath",&manpath,0,"MANPATH"),
  738. X    IPDEF9("watch",&watch,0,"WATCH"),
  739. X    IPDEF9("hosts",&hosts,0,"HOSTS"),
  740. X    IPDEF9("psvar",&psvar,0,"PSVAR"),
  741. X    IPDEF9("signals",&sigptr,PMFLAG_r,NULL),
  742. X    IPDEF9("argv",&pparams,0,NULL),
  743. X    IPDEF9("*",&pparams,0,NULL),
  744. X    IPDEF9("@",&pparams,0,NULL),
  745. X
  746. X#define IPDEF10(A,C,D) {NULL,0,A,NULL,IFN(D),IFN(C),0,\
  747. X        PMFLAG_A|PMFLAG_SPECIAL,NULL,NULL,NULL}
  748. X    IPDEF10("path",pathgetfn,pathsetfn),
  749. X    IPDEF10("hostcmds",nullgetfn,hostcmdssetfn),
  750. X    IPDEF10("optcmds",nullgetfn,optcmdssetfn),
  751. X    IPDEF10("bindcmds",nullgetfn,bindcmdssetfn),
  752. X    IPDEF10("varcmds",nullgetfn,varcmdssetfn),
  753. X    {NULL,}
  754. X    };
  755. Xstruct iparam *ip;
  756. X
  757. X    for (ip = pinit; ip->nam; ip++) addhperm(ip->nam,ip,paramtab,(FFunc) 0);
  758. X    argvparam = gethnode("argv",paramtab);
  759. X
  760. X    ((struct iparam *)gethnode("HOSTTYPE", paramtab))->data = ztrdup(HOSTTYPE);
  761. X    ((struct iparam *)gethnode("VERSION", paramtab))->data = ztrdup(VERSIONSTR);
  762. X}
  763. X
  764. Xstatic int unsetflag;
  765. X
  766. Xstruct param *createparam(name,value,flags) /**/
  767. Xchar *name;vptr value;int flags;
  768. X{
  769. Xstruct param *pm;
  770. Xchar buf[20];
  771. X
  772. X    pm = zcalloc(sizeof *pm);
  773. X    if (isset(ALLEXPORT))
  774. X        flags |= PMFLAG_x;
  775. X    pm->flags = flags;
  776. X    if ((flags & PMTYPE) == PMFLAG_s) {
  777. X        pm->u.str = value;
  778. X        pm->sets.cfn = strsetfn;
  779. X        pm->gets.cfn = strgetfn;
  780. X    } else if ((flags & PMTYPE) == PMFLAG_A) {
  781. X        pm->u.arr = value;
  782. X        pm->sets.afn = arrsetfn;
  783. X        pm->gets.afn = arrgetfn;
  784. X    } else {
  785. X        pm->u.val = (value) ? matheval(value) : 0;
  786. X        pm->sets.ifn = intsetfn;
  787. X        pm->gets.ifn = intgetfn;
  788. X        sprintf(buf,"%ld",pm->u.val);
  789. X        value = buf;
  790. X    }
  791. X    if (flags & PMFLAG_x)
  792. X        pm->env = addenv(name,value);
  793. X    addhnode(ztrdup(name),pm,paramtab,freepm);
  794. X    return pm;
  795. X}
  796. X
  797. Xint isident(s) /**/
  798. Xchar *s;
  799. X{
  800. Xchar *ss;
  801. X
  802. X    for (ss = s; *ss; ss++) if (!iident(*ss)) break;
  803. X    if (!*ss) return 1;
  804. X    if (*ss != '[') return 0;
  805. X    (void) mathevalarg(++ss, &ss);
  806. X    if(*ss == ',' || *ss == Comma)
  807. X        (void) mathevalarg(++ss,&ss);
  808. X    if(*ss != ']' || ss[1]) return 0;
  809. X    return 1;
  810. X}
  811. X
  812. XValue getvalue(pptr,bracks) /**/
  813. Xchar **pptr;int bracks;
  814. X{
  815. Xchar *s = *pptr,*t = *pptr;
  816. Xchar sav;
  817. XValue v;
  818. X
  819. X    if (idigit(*s)) while (idigit(*s)) s++;
  820. X    else if (iident(*s)) while (iident(*s)) s++;
  821. X    else if (*s == Quest) *s++ = '?';
  822. X    else if (*s == Pound) *s++ = '#';
  823. X    else if (*s == String) *s++ = '$';
  824. X    else if (*s == Qstring) *s++ = '$';
  825. X    else if (*s == Star) *s++ = '*';
  826. X    else if (*s == '#' || *s == '-' || *s == '?' || *s == '$' ||
  827. X                *s == '_' || *s == '!' || *s == '@' || *s == '*') s++;
  828. X    else return NULL;
  829. X    if (sav = *s) *s = '\0';
  830. X    if (idigit(*t) && *t != '0') {
  831. X        v = (Value) hcalloc(sizeof *v);
  832. X        v->pm = argvparam;
  833. X        v->a = v->b = atoi(t)-1;
  834. X        if (sav)
  835. X            *s = sav;
  836. X    } else {
  837. X        struct param *pm;
  838. X        int isvarat = !strcmp(t, "@");
  839. X
  840. X        pm = gethnode(t,paramtab);
  841. X        if (sav)
  842. X            *s = sav;
  843. X        *pptr = s;
  844. X        if (!pm)
  845. X            return NULL;
  846. X        v = hcalloc(sizeof *v);
  847. X        if (pmtype(pm) == PMFLAG_A)
  848. X            v->isarr = isvarat ? -1 : 1;
  849. X        v->pm = pm;
  850. X        v->a = 0; v->b = -1;
  851. X        if (bracks && (*s == '[' || *s == Inbrack)) {
  852. X            int a,b;
  853. X            char *olds = s,*t;
  854. X
  855. X            *s++ = '[';
  856. X            for (t = s; *t && *t != ']' && *t != Outbrack; t++)
  857. X                if (itok(*t))
  858. X                    *t = ztokens[*t-Pound];
  859. X            if (*t == Outbrack)
  860. X                *t = ']';
  861. X            if ((s[0] == '*' || s[0] == '@')  && s[1] == ']') {
  862. X                if (v->isarr) v->isarr = (s[0] == '*') ? 1 : -1;
  863. X                v->a = 0;
  864. X                v->b = -1;
  865. X                s += 2;
  866. X            } else {
  867. X                a = mathevalarg(s,&s);
  868. X                if (a > 0) a--;
  869. X                if (*s == ',' || *s == Comma) {
  870. X                    s++;
  871. X                    b = mathevalarg(s,&s);
  872. X                    if (b > 0) b--;
  873. X                } else
  874. X                    b = a;
  875. X                if (*s == ']') {
  876. X                    s++;
  877. X                    if (v->isarr && a == b)
  878. X                        v->isarr = 0;
  879. X                    v->a = a;
  880. X                    v->b = b;
  881. X                } else
  882. X                    s = olds;
  883. X            }
  884. X        }
  885. X    }
  886. X    if (!bracks && *s)
  887. X        return NULL;
  888. X    *pptr = s;
  889. X    return v;
  890. X}
  891. X
  892. Xchar *getstrvalue(v) /**/
  893. XValue v;
  894. X{
  895. Xchar *s,**ss;
  896. Xstatic char buf[20];
  897. X
  898. X    if (!v)
  899. X        return "";
  900. X    if (pmtype(v->pm) != PMFLAG_A) {
  901. X        if ((pmtype(v->pm) == PMFLAG_i))
  902. X            convbase(s = buf,v->pm->gets.ifn(v->pm),v->pm->ct);
  903. X        else
  904. X            s = v->pm->gets.cfn(v->pm);
  905. X        if (v->a == 0 && v->b == -1) return s;
  906. X        if (v->a < 0) v->a += strlen(s);
  907. X        if (v->b < 0) v->b += strlen(s);
  908. X        s = (v->a > strlen(s)) ? strdup("") : strdup(s+v->a);
  909. X        if (v->b < v->a) s[0] = '\0';
  910. X        else if (v->b-v->a < strlen(s)) s[v->b-v->a+1] = '\0';
  911. X        return s;
  912. X    }
  913. X    if (v->isarr) return spacejoin(v->pm->gets.afn(v->pm));
  914. X
  915. X    ss = v->pm->gets.afn(v->pm);
  916. X    if (v->a < 0) v->a += arrlen(ss);
  917. X    s = (v->a >= arrlen(ss) || v->a < 0) ? "" : ss[v->a];
  918. X    return s;
  919. X}
  920. X
  921. Xchar **getarrvalue(v) /**/
  922. XValue v;
  923. X{
  924. Xchar **s;
  925. Xstatic char *nular[] = { "", NULL };
  926. X
  927. X    if (!v)
  928. X        return arrdup(nular);
  929. X    s = v->pm->gets.afn(v->pm);
  930. X    if (v->a == 0 && v->b == -1) return s;
  931. X    if (v->a < 0) v->a += arrlen(s);
  932. X    if (v->b < 0) v->b += arrlen(s);
  933. X    if (v->a > arrlen(s) || v->a < 0)
  934. X        s = arrdup(nular);
  935. X    else
  936. X        s = arrdup(s)+v->a;
  937. X    if (v->b < v->a) s[0] = NULL;
  938. X    else if (v->b-v->a < arrlen(s)) s[v->b-v->a+1] = NULL;
  939. X    return s;
  940. X}
  941. X
  942. Xlong getintvalue(v) /**/
  943. XValue v;
  944. X{
  945. Xchar **ss;
  946. X
  947. X    if (!v || v->isarr)
  948. X        return 0;
  949. X    if (pmtype(v->pm) != PMFLAG_A) {
  950. X        if (pmtype(v->pm) == PMFLAG_i)
  951. X            return v->pm->gets.ifn(v->pm);
  952. X        return atol(v->pm->gets.cfn(v->pm));
  953. X    }
  954. X    ss = v->pm->gets.afn(v->pm);
  955. X    if (v->a < 0) v->a += arrlen(ss);
  956. X    if (v->a < 0 || v->a >= arrlen(ss)) return 0;
  957. X    return atol(ss[v->a]);
  958. X}
  959. X
  960. Xvoid setstrvalue(v,val) /**/
  961. XValue v;char *val;
  962. X{
  963. X    if (v->pm->flags & PMFLAG_r) {
  964. X        free(val);
  965. X        return;
  966. X    }
  967. X    if (v->pm->env)
  968. X        v->pm->env = replenv(v->pm->env,val);
  969. X    else if (isset(ALLEXPORT)) {
  970. X        v->pm->flags |= PMFLAG_x;
  971. X        v->pm->env = addenv(v->pm->nam,val);
  972. X    }
  973. X    switch (pmtype(v->pm)) {
  974. X        case PMFLAG_s:
  975. X            if (v->a == 0 && v->b == -1)
  976. X                (v->pm->sets.cfn)(v->pm,val);
  977. X            else {
  978. X                char *z,*y,*x;
  979. X
  980. X                z = strdup((v->pm->gets.cfn)(v->pm));
  981. X                if (v->a < 0) {
  982. X                    v->a += strlen(z);
  983. X                    if (v->a < 0) v->a = 0;
  984. X                }
  985. X                if (v->a > strlen(z)) v->a = strlen(z);
  986. X                if (v->b < 0) v->b += strlen(z);
  987. X                if (v->b < v->a) v->b = v->a;
  988. X                z[v->a] = '\0';
  989. X                y = z+v->b+1;
  990. X                x = zalloc(strlen(z)+strlen(y)+strlen(val)+1);
  991. X                strcpy(x,z);
  992. X                strcat(x,val);
  993. X                strcat(x,y);
  994. X                (v->pm->sets.cfn)(v->pm,x);
  995. X            }
  996. X            if (v->pm->flags & (PMFLAG_L|PMFLAG_R|PMFLAG_Z) && !v->pm->ct)
  997. X                v->pm->ct = strlen(val);
  998. X            break;
  999. X        case PMFLAG_i:
  1000. X            (v->pm->sets.ifn)(v->pm,matheval(val));
  1001. X            if (!v->pm->ct && lastbase != 1)
  1002. X                v->pm->ct = lastbase;
  1003. X            free(val);
  1004. X            break;
  1005. X        case PMFLAG_A:
  1006. X            if (v->a != v->b)
  1007. X                zerr("illegal array assignment",NULL,0);
  1008. X            else {
  1009. X                char **ss = (v->pm->gets.afn)(v->pm);
  1010. X                int ac,ad,t0;
  1011. X
  1012. X                ac = arrlen(ss);
  1013. X                if (v->a < 0) {
  1014. X                    v->a += ac;
  1015. X                    if (v->a < 0) v->a = 0;
  1016. X                }
  1017. X                if (v->a >= ac) {
  1018. X                    char **st = ss;
  1019. X
  1020. X                    ad = v->a+1;
  1021. X                    ss = zalloc((ad+1)*sizeof *ss);
  1022. X                    for (t0 = 0; t0 != ac; t0++)
  1023. X                        ss[t0] = ztrdup(st[t0]);
  1024. X                    while (ac < ad)
  1025. X                        ss[ac++] = ztrdup("");
  1026. X                    ss[ac] = NULL;
  1027. X                }
  1028. X                if (ss[v->a]) free(ss[v->a]);
  1029. X                ss[v->a] = val;
  1030. X                (v->pm->sets.afn)(v->pm,ss);
  1031. X            }
  1032. X            break;
  1033. X    }
  1034. X}
  1035. X
  1036. Xvoid setintvalue(v,val) /**/
  1037. XValue v;long val;
  1038. X{
  1039. Xchar buf[20];
  1040. X
  1041. X    if (v->pm->flags & PMFLAG_r)
  1042. X        return;
  1043. X    sprintf(buf,"%ld",val);
  1044. X    if (v->pm->env) {
  1045. X        v->pm->env = replenv(v->pm->env,buf);
  1046. X    }
  1047. X    else if (isset(ALLEXPORT)) {
  1048. X        v->pm->flags |= PMFLAG_x;
  1049. X        v->pm->env = addenv(v->pm->nam,buf);
  1050. X    }
  1051. X    switch (pmtype(v->pm))
  1052. X        {
  1053. X        case PMFLAG_s:
  1054. X            (v->pm->sets.cfn)(v->pm,ztrdup(buf));
  1055. X            break;
  1056. X        case PMFLAG_i:
  1057. X            (v->pm->sets.ifn)(v->pm,val);
  1058. X            if (!v->pm->ct && lastbase != -1)
  1059. X                v->pm->ct = lastbase;
  1060. X            break;
  1061. X        case PMFLAG_A:
  1062. X            zerr("attempt to assign integer to array",NULL,0);
  1063. X            break;
  1064. X        }
  1065. X}
  1066. X
  1067. Xvoid setintenv(s,val) /**/
  1068. Xchar *s; long val;
  1069. X{
  1070. XParam pm;
  1071. Xchar buf[20];
  1072. X
  1073. X    if ((pm = gethnode(s,paramtab)) && pm->env) {
  1074. X        sprintf(buf,"%ld",val);
  1075. X        pm->env = replenv(pm->env,buf);
  1076. X    }
  1077. X}
  1078. X
  1079. Xvoid setarrvalue(v,val) /**/
  1080. XValue v;char **val;
  1081. X{
  1082. X    if (v->pm->flags & PMFLAG_r) {
  1083. X        freearray(val);
  1084. X        return;
  1085. X    }
  1086. X    if (pmtype(v->pm) != PMFLAG_A)
  1087. X        {
  1088. X        freearray(val);
  1089. X        zerr("attempt to assign array value to non-array",NULL,0);
  1090. X        return;
  1091. X        }
  1092. X    if (v->a == 0 && v->b == -1)
  1093. X        (v->pm->sets.afn)(v->pm,val);
  1094. X    else {
  1095. X        char **ss = (v->pm->gets.afn)(v->pm);
  1096. X        int ac,ad,t0;
  1097. X
  1098. X        ac = arrlen(ss);
  1099. X        if (v->a < 0) {
  1100. X            v->a += ac;
  1101. X            if (v->a < 0) v->a = 0;
  1102. X        }
  1103. X        if (v->b < 0) v->b += ac;
  1104. X        if (v->b < v->a) v->b = v->a;
  1105. X        t0 = arrlen(val) - (v->b - v->a + 1);
  1106. X        if (v->b >= ac || t0 != 0) {
  1107. X            char **st = ss;
  1108. X
  1109. X            ad = (v->b > (ac - 1) ? v->b : (ac - 1)) + t0 + 1;
  1110. X            ss = zalloc((ad+1)*sizeof *ss);
  1111. X            for (t0 = 0; t0 < v->a; t0++)
  1112. X                ss[t0] = ztrdup(t0 < ac ? st[t0] : "");
  1113. X            while (*val) ss[t0++] = *val++;
  1114. X            while (++v->b < ac) ss[t0++] = ztrdup(st[v->b]);
  1115. X            ss[t0] = NULL;
  1116. X        } else {
  1117. X            for (t0 = v->a; t0 <= v->b; t0++) {
  1118. X                if (ss[t0]) free(ss[t0]);
  1119. X                ss[t0] = val[t0];
  1120. X            }
  1121. X        }
  1122. X        (v->pm->sets.afn)(v->pm,ss);
  1123. X    }
  1124. X}
  1125. X
  1126. Xint getparamtype(s,l) /**/
  1127. Xchar *s;int l;
  1128. X{
  1129. Xchar sav,*t = s;
  1130. XValue v;
  1131. X
  1132. X    sav = t[l];
  1133. X    t[l] = '\0';
  1134. X
  1135. X    if (!(v = getvalue(&s,0)))
  1136. X        return -1;
  1137. X
  1138. X    t[l] = sav;
  1139. X    return (pmtype(v->pm));
  1140. X}
  1141. X
  1142. Xchar *getsparamval(s,l) /**/
  1143. Xchar *s;int l;
  1144. X{
  1145. Xchar sav,*t = s;
  1146. XValue v;
  1147. X
  1148. X    sav = t[l];
  1149. X    t[l] = '\0';
  1150. X    
  1151. X    if (!(v = getvalue(&s,0)))
  1152. X        return NULL;
  1153. X    t[l] = sav;
  1154. X    t = getstrvalue(v);
  1155. X    return t;
  1156. X}
  1157. X
  1158. Xlong getiparam(s) /**/
  1159. Xchar *s;
  1160. X{
  1161. XValue v;
  1162. X
  1163. X    if (!(v = getvalue(&s,0)))
  1164. X        return 0;
  1165. X    return getintvalue(v);
  1166. X}
  1167. X
  1168. Xchar *getsparam(s) /**/
  1169. Xchar *s;
  1170. X{
  1171. XValue v;
  1172. X
  1173. X    if (!(v = getvalue(&s,0)))
  1174. X        return NULL;
  1175. X    return getstrvalue(v);
  1176. X}
  1177. X
  1178. Xchar **getaparam(s) /**/
  1179. Xchar *s;
  1180. X{
  1181. XValue v;
  1182. X
  1183. X    if (!((v = getvalue(&s,0)) && v->isarr))
  1184. X        return NULL;
  1185. X    return getarrvalue(v);
  1186. X}
  1187. X
  1188. XParam setsparam(s,val) /**/
  1189. Xchar *s;char *val;
  1190. X{
  1191. XValue v;
  1192. Xchar *t = s;
  1193. Xchar *ss;
  1194. X
  1195. X    if (!isident(s)) {
  1196. X        zerr("not an identifier: %s",s,0);
  1197. X        free(val);
  1198. X        return NULL;
  1199. X    }
  1200. X    if (ss = strchr(s, '[')) {
  1201. X        *ss = '\0';
  1202. X        if (!(v = getvalue(&s,1)))
  1203. X            createparam(t,zcalloc(sizeof val),PMFLAG_A);
  1204. X        *ss = '[';
  1205. X        v = getvalue(&t,1);
  1206. X    } else {
  1207. X        if (!(v = getvalue(&s,1)))
  1208. X            return createparam(t,val,PMFLAG_s);
  1209. X        if ((v->pm->flags & PMTYPE) != PMFLAG_s &&
  1210. X                !(v->pm->flags & PMFLAG_SPECIAL)) {
  1211. X            unsetparam(t);
  1212. X            return createparam(t,val,PMFLAG_s);
  1213. X        }
  1214. X    }
  1215. X    setstrvalue(v,val);
  1216. X    return v->pm;
  1217. X}
  1218. X
  1219. XParam setaparam(s,val) /**/
  1220. Xchar *s;char **val;
  1221. X{
  1222. XValue v;
  1223. Xchar *t = s;
  1224. Xchar *ss;
  1225. X
  1226. X    if (!isident(s))
  1227. X        {
  1228. X        zerr("not an identifier: %s",s,0);
  1229. X        freearray(val);
  1230. X        return NULL;
  1231. X        }
  1232. X    if(ss = strchr(s, '[')) {
  1233. X        *ss = '\0';
  1234. X        if (!(v = getvalue(&s,1)))
  1235. X            createparam(t,zcalloc(sizeof val),PMFLAG_A);
  1236. X        *ss = '[';
  1237. X        v = getvalue(&t,1);
  1238. X    } else {
  1239. X        if (!(v = getvalue(&s,1)))
  1240. X            return createparam(t,val,PMFLAG_A);
  1241. X        if ((v->pm->flags & PMTYPE) != PMFLAG_A &&
  1242. X                !(v->pm->flags & PMFLAG_SPECIAL)) {
  1243. X            unsetparam(t);
  1244. X            return createparam(t,val,PMFLAG_A);
  1245. X        }
  1246. X    }
  1247. X    setarrvalue(v,val);
  1248. X    return v->pm;
  1249. X}
  1250. X
  1251. XParam setiparam(s,val) /**/
  1252. Xchar *s;long val;
  1253. X{
  1254. XValue v;
  1255. Xchar *t = s;
  1256. XParam pm;
  1257. X
  1258. X    if (!isident(s))
  1259. X        {
  1260. X        zerr("not an identifier: %s",s,0);
  1261. X        return NULL;
  1262. X        }
  1263. X    if (!(v = getvalue(&s,0)))
  1264. X        {
  1265. X        pm = createparam(t,NULL,PMFLAG_i);
  1266. X        pm->u.val = val;
  1267. X        return pm;
  1268. X        }
  1269. X    setintvalue(v,val);
  1270. X    return v->pm;
  1271. X}
  1272. X
  1273. Xvoid unsetparam(s) /**/
  1274. Xchar *s;
  1275. X{
  1276. XParam pm;
  1277. X
  1278. X    if (!(pm = gethnode(s,paramtab)))
  1279. X        return;
  1280. X    if (pm->flags & PMFLAG_r)
  1281. X        return;
  1282. X    unsetflag = 1;
  1283. X    switch (pmtype(pm))
  1284. X        {
  1285. X        case 0:
  1286. X            (pm->sets.cfn)(pm,ztrdup(""));
  1287. X            break;
  1288. X        case PMFLAG_i:
  1289. X            (pm->sets.ifn)(pm,0);
  1290. X            break;
  1291. X        case PMFLAG_A:
  1292. X            (pm->sets.afn)(pm,mkarray(NULL));
  1293. X            break;
  1294. X        }
  1295. X    if (pmtype(pm) == PMFLAG_s && (pm->flags & PMFLAG_x)) {
  1296. X        delenv(pm->env);
  1297. X        free(pm->env);
  1298. X        if (pm->flags & PMFLAG_SPECIAL)
  1299. X            pm->env = NULL;
  1300. X    }
  1301. X    if (!(pm->flags & PMFLAG_SPECIAL))
  1302. X        freepm(remhnode(s,paramtab));
  1303. X    unsetflag = 0;
  1304. X}
  1305. X
  1306. Xvoid intsetfn(pm,x) /**/
  1307. XParam pm;long x;
  1308. X{
  1309. X    pm->u.val = x;
  1310. X}
  1311. X
  1312. Xlong intgetfn(pm) /**/
  1313. XParam pm;
  1314. X{
  1315. X    return pm->u.val;
  1316. X}
  1317. X
  1318. Xvoid strsetfn(pm,x) /**/
  1319. XParam pm;char *x;
  1320. X{
  1321. X    if (x) 
  1322. X        {
  1323. X        if (pm->u.str)
  1324. X            free(pm->u.str);
  1325. X        pm->u.str = x;
  1326. X        }
  1327. X}
  1328. X
  1329. Xchar *strgetfn(pm) /**/
  1330. XParam pm;
  1331. X{
  1332. X    return pm->u.str;
  1333. X}
  1334. X
  1335. Xvoid nullsetfn(pm,x) /**/
  1336. XParam pm; char *x;
  1337. X{
  1338. X    free(x);
  1339. X}
  1340. X
  1341. Xvoid arrsetfn(pm,x) /**/
  1342. XParam pm;char **x;
  1343. X{
  1344. Xint ct;
  1345. X
  1346. X    if (x)
  1347. X        {
  1348. X        if (pm->u.arr && pm->u.arr != x)
  1349. X            freearray(pm->u.arr);
  1350. X        pm->u.arr = x;
  1351. X        for (ct = 0; *x; x++,ct++);
  1352. X        pm->ct = ct;
  1353. X        }
  1354. X}
  1355. X
  1356. Xchar **arrgetfn(pm) /**/
  1357. XParam pm;
  1358. X{
  1359. X    return pm->u.arr;
  1360. X}
  1361. X
  1362. Xvoid intvarsetfn(pm,x) /**/
  1363. XParam pm;long x;
  1364. X{
  1365. X    *((long *) pm->data) = x;
  1366. X}
  1367. X
  1368. Xlong intvargetfn(pm) /**/
  1369. XParam pm;
  1370. X{
  1371. X    return *((long *) pm->data);
  1372. X}
  1373. X
  1374. Xvoid strvarsetfn(pm,x) /**/
  1375. XParam pm;char *x;
  1376. X{
  1377. Xchar **q = ((char **) pm->data);
  1378. X
  1379. X    if (*q) free(*q);
  1380. X    *q = x;
  1381. X}
  1382. X
  1383. Xvoid strvarnonullsetfn(pm,x) /**/
  1384. XParam pm;char *x;
  1385. X{
  1386. Xchar **q = ((char **) pm->data);
  1387. X
  1388. X    if (*q) free(*q);
  1389. X    *q = (x) ? x : ztrdup("");
  1390. X}
  1391. X
  1392. Xchar *strvargetfn(pm) /**/
  1393. XParam pm;
  1394. X{
  1395. Xchar *s;
  1396. X
  1397. X    s = *((char **) pm->data);
  1398. X    if (!s) return "";
  1399. X    return s;
  1400. X}
  1401. X
  1402. Xchar *strconstgetfn(pm) /**/
  1403. XParam pm;
  1404. X{
  1405. X    return (char *) pm->data;
  1406. X}
  1407. X
  1408. Xvoid colonarrsetfn(pm,x) /**/
  1409. XParam pm;char *x;
  1410. X{
  1411. Xchar **s,**t,*u,*up;
  1412. X
  1413. X    s = colonsplit(x);
  1414. X    free(x);
  1415. X    if (pm->data != &fignore)
  1416. X        for (t = s; *t; t++) {
  1417. X            u = *t;
  1418. X            if (*u == '~') *u = Tilde;
  1419. X            if (*u == '=') *u = Equals;
  1420. X            up = hcalloc(strlen(u)+1);
  1421. X            strcpy(up,u);
  1422. X            u = up;
  1423. X            filesub(&u);
  1424. X            if (!*u) u = ".";
  1425. X            free(*t);
  1426. X            *t = ztrdup(u);
  1427. X        }
  1428. X    if (pm->data) {
  1429. X        freearray(*((char ***) pm->data));
  1430. X        *((char ***) pm->data) = s;
  1431. X        if (pm->ename)
  1432. X            arrfixenv(pm->ename,s);
  1433. X    } else {
  1434. X        freearray(path);
  1435. X        path = s;
  1436. X        newcmdnamtab();
  1437. X        arrfixenv("PATH",s);
  1438. X    }
  1439. X}
  1440. X
  1441. Xchar *colonarrgetfn(pm) /**/
  1442. XParam pm;
  1443. X{
  1444. X    if ((char **) pm->data)
  1445. X        return colonjoin(*(char ***) pm->data);
  1446. X    else
  1447. X        return colonjoin(path);
  1448. X}
  1449. X
  1450. Xchar **arrvargetfn(pm) /**/
  1451. XParam pm;
  1452. X{
  1453. X    return *((char ***) pm->data);
  1454. X}
  1455. X
  1456. Xvoid arrvarsetfn(pm,x) /**/
  1457. XParam pm;char **x;
  1458. X{
  1459. X    if ((*(char ***) pm->data) != x)
  1460. X        freearray(*(char ***) pm->data);
  1461. X    *((char ***) pm->data) = x;
  1462. X    if (pm->ename)
  1463. X        arrfixenv(pm->ename,x);
  1464. X}
  1465. X
  1466. Xchar **pathgetfn(pm) /**/
  1467. XParam pm;
  1468. X{
  1469. X    return path;
  1470. X}
  1471. X
  1472. Xvoid pathsetfn(pm,x) /**/
  1473. XParam pm;char **x;
  1474. X{
  1475. X    if (path != x) freearray(path);
  1476. X    path = x;
  1477. X    newcmdnamtab();
  1478. X    arrfixenv("PATH",x);
  1479. X}
  1480. X
  1481. Xvoid hostcmdssetfn(pm,x) /**/
  1482. XParam pm;char **x;
  1483. X{
  1484. X    compctl_process(x,CC_HOSTS,NULL);
  1485. X    freearray(x);
  1486. X}
  1487. X
  1488. Xvoid optcmdssetfn(pm,x) /**/
  1489. XParam pm;char **x;
  1490. X{
  1491. X    compctl_process(x,CC_OPTIONS,NULL);
  1492. X    freearray(x);
  1493. X}
  1494. X
  1495. Xvoid bindcmdssetfn(pm,x) /**/
  1496. XParam pm;char **x;
  1497. X{
  1498. X    compctl_process(x,CC_BINDINGS,NULL);
  1499. X    freearray(x);
  1500. X}
  1501. X
  1502. Xvoid varcmdssetfn(pm,x) /**/
  1503. XParam pm;char **x;
  1504. X{
  1505. X    compctl_process(x,CC_VARS,NULL);
  1506. X    freearray(x);
  1507. X}
  1508. X
  1509. Xchar **nullgetfn(pm) /**/
  1510. XParam pm;
  1511. X{
  1512. Xstatic char *nl = NULL; return &nl;
  1513. X}
  1514. X
  1515. Xvoid unsettablesetfn(pm,x) /**/
  1516. XParam pm;char *x;
  1517. X{ ; }
  1518. X
  1519. Xlong poundgetfn(pm) /**/
  1520. XParam pm;
  1521. X{
  1522. X    return arrlen(pparams);
  1523. X}
  1524. X
  1525. Xlong randomgetfn(pm) /**/
  1526. XParam pm;
  1527. X{
  1528. X    return rand() & 0x7fff;
  1529. X}
  1530. X
  1531. Xvoid randomsetfn(pm,v) /**/
  1532. XParam pm;long v;
  1533. X{
  1534. X    srand((unsigned int) v);
  1535. X}
  1536. X
  1537. Xlong secondsgetfn(pm) /**/
  1538. XParam pm;
  1539. X{
  1540. X    return time(NULL)-shtimer;
  1541. X}
  1542. X
  1543. Xvoid secondssetfn(pm,x) /**/
  1544. XParam pm;long x;
  1545. X{
  1546. X    shtimer = time(NULL)-x;
  1547. X}
  1548. X
  1549. Xlong uidgetfn(pm) /**/
  1550. XParam pm;
  1551. X{
  1552. X    return getuid();
  1553. X}
  1554. X
  1555. Xlong gidgetfn(pm) /**/
  1556. XParam pm;
  1557. X{
  1558. X    return getegid();
  1559. X}
  1560. X
  1561. Xchar *usernamegetfn(pm) /**/
  1562. XParam pm;
  1563. X{
  1564. Xstruct passwd *pwd;
  1565. X
  1566. X    pwd = getpwuid(getuid());
  1567. X    return pwd->pw_name;
  1568. X}
  1569. X
  1570. Xchar *hostgetfn(pm) /**/
  1571. XParam pm;
  1572. X{
  1573. Xstatic char hostnam[65];
  1574. Xstatic int got = 0;
  1575. X
  1576. X    if (!got)
  1577. X        {
  1578. X        gethostname(hostnam,64);
  1579. X        hostnam[64] = '\0';
  1580. X        got = 1;
  1581. X        }
  1582. X    return hostnam;
  1583. X}
  1584. X
  1585. Xchar *ifsgetfn(pm) /**/
  1586. XParam pm;
  1587. X{
  1588. X    return ifs;
  1589. X}
  1590. X
  1591. Xvoid ifssetfn(pm,x) /**/
  1592. XParam pm;char *x;
  1593. X{
  1594. X    if (x) { free(ifs); ifs = x; }
  1595. X    inittyptab();
  1596. X}
  1597. X
  1598. Xvoid histsizesetfn(pm,v) /**/
  1599. XParam pm;long v;
  1600. X{
  1601. X    if ((histsiz = v) <= 2) histsiz = 2;
  1602. X    resizehistents();
  1603. X}
  1604. X
  1605. Xlong histsizegetfn(pm) /**/
  1606. XParam pm;
  1607. X{
  1608. X    return histsiz;
  1609. X}
  1610. X
  1611. Xvoid lithistsizesetfn(pm,v) /**/
  1612. XParam pm;long v;
  1613. X{
  1614. X    if ((lithistsiz = v) <= 2) lithistsiz = 2;
  1615. X    resizehistents();
  1616. X}
  1617. X
  1618. Xlong lithistsizegetfn(pm) /**/
  1619. XParam pm;
  1620. X{
  1621. X    return lithistsiz;
  1622. X}
  1623. X
  1624. Xvoid mailchecksetfn(pm,x) /**/
  1625. XParam pm;long x;
  1626. X{
  1627. X    mailcheck = (unsetflag) ? 600 : x;
  1628. X}
  1629. X
  1630. Xvoid pathasetfn(pm,x) /**/
  1631. XParam pm;char **x;
  1632. X{
  1633. X    freearray(path);
  1634. X    path = x;
  1635. X    newcmdnamtab();
  1636. X}
  1637. X
  1638. Xchar **pathagetfn(pm) /**/
  1639. XParam pm;
  1640. X{
  1641. X    return path;
  1642. X}
  1643. X
  1644. Xlong errnogetfn(pm) /**/
  1645. XParam pm;
  1646. X{
  1647. X    return errno;
  1648. X}
  1649. X
  1650. Xchar *dashgetfn(pm) /**/
  1651. XParam pm;
  1652. X{
  1653. Xstatic char buf[100];
  1654. Xchar *val;
  1655. Xint t0;
  1656. X
  1657. X    for (val = buf, t0 = ' ';t0 <= 'z'; t0++)
  1658. X        if (isset(t0))
  1659. X            *val++ = t0;
  1660. X    *val = '\0';
  1661. X    return buf;
  1662. X}
  1663. X
  1664. Xvoid histcharssetfn(pm,x) /**/
  1665. XParam pm;char *x;
  1666. X{
  1667. X    if (x) {
  1668. X        bangchar = x[0];
  1669. X        hatchar = (bangchar) ? x[1] : '\0';
  1670. X        hashchar = (hatchar) ? x[2] : '\0';
  1671. X        free(x);
  1672. X    }
  1673. X}
  1674. X
  1675. Xchar *histcharsgetfn(pm) /**/
  1676. XParam pm;
  1677. X{
  1678. Xstatic char buf[4];
  1679. X
  1680. X    buf[0] = bangchar;
  1681. X    buf[1] = hatchar;
  1682. X    buf[2] = hashchar;
  1683. X    buf[3] = '\0';
  1684. X    return buf;
  1685. X}
  1686. X
  1687. Xchar *homegetfn(pm) /**/
  1688. XParam pm;
  1689. X{
  1690. X    return home;
  1691. X}
  1692. X
  1693. Xvoid homesetfn(pm,x) /**/
  1694. XParam pm;char *x;
  1695. X{
  1696. X    free(home);
  1697. X    if (isset(CHASELINKS) && (home = xsymlink(x))) free(x);
  1698. X    else home = x;
  1699. X}
  1700. X
  1701. Xchar *wordcharsgetfn(pm) /**/
  1702. XParam pm;
  1703. X{
  1704. X    return wordchars;
  1705. X}
  1706. X
  1707. Xvoid wordcharssetfn(pm,x) /**/
  1708. XParam pm;char *x;
  1709. X{
  1710. X    free(wordchars);
  1711. X    if (x) wordchars = x;
  1712. X    else wordchars = ztrdup(DEFWORDCHARS);
  1713. X    inittyptab();
  1714. X}
  1715. X
  1716. Xchar *underscoregetfn(pm) /**/
  1717. XParam pm;
  1718. X{
  1719. Xchar *s,*t;
  1720. X
  1721. X    if (!(s = qgetevent(curhist-1)))
  1722. X        return "";
  1723. X    for (t = s+strlen(s); t > s; t--)
  1724. X        if (*t == HISTSPACE)
  1725. X            break;
  1726. X    if (t != s)
  1727. X        t++;
  1728. X    return t;
  1729. X}
  1730. X
  1731. Xchar *termgetfn(pm) /**/
  1732. XParam pm;
  1733. X{
  1734. X    return term;
  1735. X}
  1736. X
  1737. Xvoid termsetfn(pm,x) /**/
  1738. XParam pm;char *x;
  1739. X{
  1740. X    if (term) free(term);
  1741. X    term = x;
  1742. X    if (!interact || unset(USEZLE))
  1743. X        return;
  1744. X    if (tgetent(termbuf,term) != 1)
  1745. X        {
  1746. X        zerr("can't find termcap info for %s",term,0);
  1747. X        errflag = 0;
  1748. X        termok = 0;
  1749. X        }
  1750. X    else
  1751. X        {
  1752. X        char tbuf[1024],*pp;
  1753. X        int t0;
  1754. X
  1755. X        termok = 1;
  1756. X        for (t0 = 0; t0 != TC_COUNT; t0++)
  1757. X            {
  1758. X            pp = tbuf;
  1759. X            if (tcstr[t0])
  1760. X                free(tcstr[t0]);
  1761. X            /* AIX tgetstr() ignores second argument */
  1762. X            if (!(pp = tgetstr(tccapnams[t0],&pp)))
  1763. X                tcstr[t0] = NULL, tclen[t0] = 0;
  1764. X            else
  1765. X                {
  1766. X                tcstr[t0] = zalloc(tclen[t0] = strlen(pp)+1);
  1767. X                memcpy(tcstr[t0],pp,tclen[t0]);
  1768. X                }
  1769. X            }
  1770. X
  1771. X/* if there's no termcap entry for cursor left, use \b. */
  1772. X
  1773. X        if (!tccan(TCLEFT))
  1774. X            {
  1775. X            tcstr[TCLEFT] = ztrdup("\b");
  1776. X            tclen[TCLEFT] = 1;
  1777. X            }
  1778. X
  1779. X/* if there's no termcap entry for clear, use ^L. */
  1780. X
  1781. X        if (!tccan(TCCLEARSCREEN))
  1782. X            {
  1783. X            tcstr[TCCLEARSCREEN] = ztrdup("\14");
  1784. X            tclen[TCCLEARSCREEN] = 1;
  1785. X            }
  1786. X
  1787. X/* if the termcap entry for down is \n, don't use it. */
  1788. X
  1789. X        if (tccan(TCDOWN) && tcstr[TCDOWN][0] == '\n')
  1790. X            {
  1791. X            tclen[TCDOWN] = 0;
  1792. X            free(tcstr[TCDOWN]);
  1793. X            tcstr[TCDOWN] = NULL;
  1794. X            }
  1795. X
  1796. X/* if there's no termcap entry for cursor up, forget it.
  1797. X    Use single line mode. */
  1798. X
  1799. X        if (!tccan(TCUP))
  1800. X            termok = 0;
  1801. X        }
  1802. X}
  1803. X
  1804. Xvoid setparams() /**/
  1805. X{
  1806. Xchar **envp,**envp2,**envp3,*str;
  1807. Xchar buf[50];
  1808. Xstruct param *pm;
  1809. Xint ct;
  1810. X
  1811. X    noerrs = 1;
  1812. X    for (envp = environ, ct = 2; *envp; envp++,ct++);
  1813. X    envp = environ;
  1814. X    envp2 = envp3 = (char **) zalloc(sizeof(char *)*ct);
  1815. X    for (; *envp; envp++)
  1816. X        *envp2++ = ztrdup(*envp);
  1817. X    *envp2 = NULL;
  1818. X    envp = environ;
  1819. X    environ = envp2 = envp3;
  1820. X    for (; *envp; envp++,envp2++) {
  1821. X        for (str = *envp; *str && *str != '='; str++);
  1822. X        if (*str == '=') {
  1823. X            char *iname = NULL;
  1824. X
  1825. X            *str = '\0';
  1826. X            pm = (isident(*envp) && !strchr(*envp, '[')) ?
  1827. X                setsparam(iname = *envp,ztrdup(str+1)) : NULL;
  1828. X            if (pm) {
  1829. X                pm->flags |= PMFLAG_x;
  1830. X                pm->env = *envp2;
  1831. X                if (pm->flags & PMFLAG_SPECIAL)
  1832. X                    pm->env = replenv(pm->env,getsparam(iname));
  1833. X            }
  1834. X            *str = '=';
  1835. X        }
  1836. X    }
  1837. X    pm = gethnode("HOME",paramtab);
  1838. X    if (!(pm->flags & PMFLAG_x)) {
  1839. X        pm->flags |= PMFLAG_x;
  1840. X        pm->env = addenv("HOME",home);
  1841. X    }
  1842. X    pm = gethnode("PWD",paramtab);
  1843. X    if (!(pm->flags & PMFLAG_x)) {
  1844. X        pm->flags |= PMFLAG_x;
  1845. X        pm->env = addenv("PWD",pwd);
  1846. X    }
  1847. X    pm = gethnode("LOGNAME",paramtab);
  1848. X    if (!(pm->flags & PMFLAG_x)) {
  1849. X        pm->flags |= PMFLAG_x;
  1850. X        pm->env = addenv("LOGNAME",logname);
  1851. X    }
  1852. X    pm = gethnode("SHLVL",paramtab);
  1853. X    if (!(pm->flags & PMFLAG_x))
  1854. X        pm->flags |= PMFLAG_x;
  1855. X    sprintf(buf,"%d",++shlvl);
  1856. X    pm->env = addenv("SHLVL",buf);
  1857. X    noerrs = 0;
  1858. X}
  1859. X
  1860. Xchar *mkenvstr(x,y) /**/
  1861. Xchar *x;char *y;
  1862. X{
  1863. Xchar *z;
  1864. Xint xl = strlen(x),yl = strlen(y);
  1865. X
  1866. X    z = zalloc(xl+yl+2);
  1867. X    strcpy(z,x);
  1868. X    z[xl] = '=';
  1869. X    strcpy(z+xl+1,y);
  1870. X    z[xl+yl+1] = '\0';
  1871. X    return z;
  1872. X}
  1873. X
  1874. Xvoid arrfixenv(s,t) /**/
  1875. Xchar *s;char **t;
  1876. X{
  1877. Xchar **ep;
  1878. Xint sl = strlen(s);
  1879. X
  1880. X    for (ep = environ; *ep; ep++)
  1881. X        if (!strncmp(*ep,s,sl) && (*ep)[sl] == '=') {
  1882. X            char *u = colonjoin(t);
  1883. X            replenv(*ep,u);
  1884. X            break;
  1885. X        }
  1886. X}
  1887. X
  1888. Xchar *replenv(e,value) /**/
  1889. Xchar *e;char *value;
  1890. X{
  1891. Xchar **ep;
  1892. X
  1893. X    for (ep = environ; *ep; ep++)
  1894. X        if (*ep == e)
  1895. X            {
  1896. X            char *s = e;
  1897. X
  1898. X            while (*s++ != '=');
  1899. X            *s = '\0';
  1900. X            *ep = zalloc(strlen(e)+strlen(value)+2);
  1901. X            strcpy(*ep,e);
  1902. X            strcat(*ep,value);
  1903. X            free(e);
  1904. X            return *ep;
  1905. X            }
  1906. X    return NULL;
  1907. X}
  1908. X
  1909. Xchar *addenv(name,value) /**/
  1910. Xchar *name;char *value;
  1911. X{
  1912. Xchar **ep,**ep2,**ep3;
  1913. Xint envct;
  1914. X
  1915. X    for (ep = environ; *ep; ep++)
  1916. X        {
  1917. X        char *s = *ep,*t = name;
  1918. X
  1919. X        while (*s && *s == *t) s++,t++;
  1920. X        if (*s == '=' && !*t)
  1921. X            {
  1922. X            free(*ep);
  1923. X            return *ep = mkenvstr(name,value);
  1924. X            }
  1925. X        }
  1926. X    envct = arrlen(environ);
  1927. X    ep = ep2 = (char **) zalloc((sizeof (char *))*(envct+3));
  1928. X    for (ep3 = environ; *ep2 = *ep3; ep3++,ep2++);
  1929. X    *ep2 = mkenvstr(name,value);
  1930. X    ep2[1] = NULL;
  1931. X    free(environ);
  1932. X    environ = ep;
  1933. X    return *ep2;
  1934. X}
  1935. X
  1936. Xvoid delenv(x) /**/
  1937. Xchar *x;
  1938. X{
  1939. Xchar **ep;
  1940. X
  1941. X    ep = environ;
  1942. X    for (; *ep; ep++)
  1943. X        if (*ep == x)
  1944. X            break;
  1945. X    if (*ep)
  1946. X        for (; ep[0] = ep[1]; ep++);
  1947. X}
  1948. X
  1949. Xvoid convbase(s,v,base) /**/
  1950. Xchar *s;long v;int base;
  1951. X{
  1952. Xint digs = 0;
  1953. Xlong x;
  1954. X
  1955. X    if (base <= 1)
  1956. X        base = 10;
  1957. X    x = v;
  1958. X    if (x < 0)
  1959. X        {
  1960. X        x = -x;
  1961. X        digs++;
  1962. X        }
  1963. X    for (; x; digs++)
  1964. X        x /= base;
  1965. X    if (!digs)
  1966. X        digs = 1;
  1967. X    s[digs--] = '\0';
  1968. X    x = (v < 0) ? -v : v;
  1969. X    while (digs >= 0)
  1970. X        {
  1971. X        int dig = x%base;
  1972. X        s[digs--] = (dig < 10) ? '0'+dig : dig-10+'A';
  1973. X        x /= base;
  1974. X        }
  1975. X    if (v < 0)
  1976. X        s[0] = '-';
  1977. X}
  1978. END_OF_FILE
  1979.   if test 26353 -ne `wc -c <'src/params.c'`; then
  1980.     echo shar: \"'src/params.c'\" unpacked with wrong size!
  1981.   fi
  1982.   # end of 'src/params.c'
  1983. fi
  1984. echo shar: End of archive 1 \(of 22\).
  1985. cp /dev/null ark1isdone
  1986. MISSING=""
  1987. 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
  1988.     if test ! -f ark${I}isdone ; then
  1989.     MISSING="${MISSING} ${I}"
  1990.     fi
  1991. done
  1992. if test "${MISSING}" = "" ; then
  1993.     echo You have unpacked all 22 archives.
  1994.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1995. else
  1996.     echo You still must unpack the following archives:
  1997.     echo "        " ${MISSING}
  1998. fi
  1999. exit 0
  2000.  
  2001. exit 0 # Just in case...
  2002.