aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2000-04-01 20:49:47 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2000-04-01 20:49:47 +0000
commit48525452555a24b9d41748f26b4b77f160f01220 (patch)
treed814ca2f017d9d843fec7d286fefbca78244beb5
parente025336f2f6d9f107ee1e03b9900f04af0544ba9 (diff)
downloadzsh-48525452555a24b9d41748f26b4b77f160f01220.tar.gz
zsh-48525452555a24b9d41748f26b4b77f160f01220.tar.xz
zsh-48525452555a24b9d41748f26b4b77f160f01220.zip
Updated from list as far as 10376
-rw-r--r--Functions/Misc/is-at-least2
-rw-r--r--Functions/Misc/zrecompile13
-rw-r--r--Functions/Zftp/zfcd_match12
-rw-r--r--Functions/Zftp/zfget_match31
-rw-r--r--Functions/Zle/incremental-complete-word187
-rw-r--r--Functions/Zle/predict-on119
-rw-r--r--Misc/make-zsh-urls2
-rw-r--r--Src/Modules/parameter.c1699
-rw-r--r--Src/Modules/zpty.c153
-rw-r--r--Src/Zle/comp.h449
-rw-r--r--Src/Zle/compcore.c1500
-rw-r--r--Src/Zle/complete.c436
-rw-r--r--Src/Zle/compmatch.c124
-rw-r--r--Src/Zle/compresult.c515
-rw-r--r--Src/Zle/computil.c1498
-rw-r--r--Src/Zle/iwidgets.list43
-rw-r--r--Src/Zle/zle_utils.c92
-rw-r--r--Src/builtin.c1512
-rw-r--r--Src/cond.c326
-rw-r--r--Src/exec.c1882
-rw-r--r--Src/hashtable.c506
-rw-r--r--Src/jobs.c347
-rw-r--r--Src/loop.c380
-rw-r--r--Src/params.c1818
-rw-r--r--Src/parse.c2753
-rw-r--r--Src/pattern.c1116
-rw-r--r--Src/text.c858
-rw-r--r--Src/zsh.h964
-rw-r--r--Test/07cond.ztst35
-rw-r--r--Test/11glob.ztst19
-rw-r--r--Test/53completion.ztst13
31 files changed, 13788 insertions, 5616 deletions
diff --git a/Functions/Misc/is-at-least b/Functions/Misc/is-at-least
index b574c154f..3eb62ef67 100644
--- a/Functions/Misc/is-at-least
+++ b/Functions/Misc/is-at-least
@@ -1,4 +1,4 @@
-# $Id: is-at-least,v 1.1 2000/02/11 19:46:46 akr Exp $ -*- shell-script -*-
+# $Id: is-at-least,v 1.2 2000/04/01 20:49:47 pws Exp $ -*- shell-script -*-
#
# Test whether $ZSH_VERSION (or some value of your choice, if a second argument
# is provided) is greater than or equal to x.y.z-r (in argument one). In fact,
diff --git a/Functions/Misc/zrecompile b/Functions/Misc/zrecompile
index 70410a580..1cdd05e0e 100644
--- a/Functions/Misc/zrecompile
+++ b/Functions/Misc/zrecompile
@@ -18,8 +18,8 @@
# seperated by `--'. For example:
#
# zrecompile -p \
-# -r ~/.zshrc -- \
-# -m ~/.zcompdump -- \
+# -R ~/.zshrc -- \
+# -M ~/.zcompdump -- \
# ~/zsh/comp.zwc ~/zsh/Completion/*/_* \
#
# This makes ~/.zshrc be compiled into ~/.zshrc.zwc if that doesn't
@@ -33,8 +33,7 @@
# that needed re-compilation could be compiled and non-zero if compilation
# for at least one of the files failed.
-emulate -L zsh
-setopt extendedglob
+setopt localoptions extendedglob
local opt check quiet zwc files re file pre ret map tmp mesg pats
@@ -68,7 +67,7 @@ if [[ -n $pats ]]; then
fi
files=( ${files:#*(.zwc|~)} )
- if [[ $files[1] = -[rm] ]]; then
+ if [[ $files[1] = -[RM] ]]; then
map=( $files[1] )
shift 1 files
else
@@ -146,10 +145,10 @@ for zwc; do
# See if the wordcode file will be mapped.
if [[ $files[1] = *\(mapped\)* ]]; then
- map=-m
+ map=-M
mesg='succeeded (old saved)'
else
- map=-r
+ map=-R
mesg=succeeded
fi
diff --git a/Functions/Zftp/zfcd_match b/Functions/Zftp/zfcd_match
index 67e719888..02a19af21 100644
--- a/Functions/Zftp/zfcd_match
+++ b/Functions/Zftp/zfcd_match
@@ -15,7 +15,7 @@ local tmpf=${TMPPREFIX}zfcm$$
if [[ $ZFTP_SYSTEM = UNIX* ]]; then
# hoo, aren't we lucky: this makes things so much easier
- setopt localoptions rcexpandparam
+ setopt rcexpandparam
local dir
if [[ $1 = ?*/* ]]; then
dir=${1%/*}
@@ -25,13 +25,15 @@ if [[ $ZFTP_SYSTEM = UNIX* ]]; then
# If we're using -F, we get away with using a directory
# to list, but not a glob. Don't ask me why.
# I hate having to rely on awk here.
- zftp ls -F $dir >$tmpf
+ zftp ls -LF $dir >$tmpf
reply=($(awk '/\/$/ { print substr($1, 0, length($1)-1) }' $tmpf))
rm -f $tmpf
- if [[ $dir = / ]]; then
- reply=(${dir}$reply)
+ [[ -n $dir && $dir != */ ]] && dir="$dir/"
+ if [[ -n $WIDGET ]]; then
+ _all_labels directories expl 'remote directory'
+ compadd -S/ -q -P "$dir" - $reply
elif [[ -n $dir ]]; then
- reply=($dir/$reply)
+ reply=(${dir}$reply)
fi
else
# I simply don't know what to do here.
diff --git a/Functions/Zftp/zfget_match b/Functions/Zftp/zfget_match
index 677108ede..0fe2bc06f 100644
--- a/Functions/Zftp/zfget_match
+++ b/Functions/Zftp/zfget_match
@@ -10,18 +10,27 @@ fi
local tmpf=${TMPPREFIX}zfgm$$
if [[ $ZFTP_SYSTEM == UNIX* && $1 == */* ]]; then
- # On the first argument to ls, we usually get away with a glob.
- zftp ls "$1*$2" >$tmpf
- reply=($(<$tmpf))
- rm -f $tmpf
-else
- if (( $#zftp_fcache == 0 )); then
- # Always cache the current directory and use it
- # even if the system is UNIX.
- zftp ls >$tmpf
- zftp_fcache=($(<$tmpf))
+ if [[ -n $WIDGET ]]; then
+ local dir=${1:h}
+ [[ $dir = */ ]] || dir="$dir/"
+ zftp ls -LF $dir >$tmpf
+ local reply
+ reply=(${${${(f)"$(<$tmpf)"}##$dir}%\*})
+ rm -f $tmpf
+ _all_labels files expl 'remote file' compadd -P $dir - $reply
+ else
+ # On the first argument to ls, we usually get away with a glob.
+ zftp ls "$1*$2" >$tmpf
+ reply=($(<$tmpf))
rm -f $tmpf
fi
- reply=($zftp_fcache);
+else
+ local fcache_name
+ zffcache
+ if [[ -n $WIDGET ]]; then
+ _all_labels files expl 'remote file' compadd -F fignore - ${(P)fcache_name}
+ else
+ reply=(${(P)fcache_name});
+ fi
fi
# }
diff --git a/Functions/Zle/incremental-complete-word b/Functions/Zle/incremental-complete-word
index 2a9c1aff2..e021bf6f7 100644
--- a/Functions/Zle/incremental-complete-word
+++ b/Functions/Zle/incremental-complete-word
@@ -1,89 +1,124 @@
-# incremental-complete-word() {
-
# Autoload this function, run `zle -N <func-name>' and bind <func-name>
# to a key.
+
# This allows incremental completion of a word. After starting this
-# command, a list of completion choices is shown after every character you
-# type, which you can delete with ^h or DEL. RET will accept the
-# completion so far. You can hit TAB to do normal completion and ^g to
-# abort back to the state when you started.
+# command, a list of completion choices can be shown after every character
+# you type, which you can delete with ^h or DEL. RET will accept the
+# completion so far. You can hit TAB to do normal completion, ^g to
+# abort back to the state when you started, and ^d to list the matches.
#
-# Completion keys:
-# incremental_prompt Prompt to show in status line during icompletion;
-# the sequence `%u' is replaced by the unambiguous
-# part of all matches if there is any and it is
-# different from the word on the line
-# incremental_stop Pattern matching keys which will cause icompletion
-# to stop and the key to be re-executed
-# incremental_break Pattern matching keys which will cause icompletion
-# to stop and the key to be discarded
-# incremental_completer Set of completers, like the `completer' key
-# incremental_list If set to a non-empty string, the matches will be
-# listed on every key-press
-
-emulate -L zsh
-unsetopt autolist menucomplete automenu # doesn't work well
-
-local key lbuf="$LBUFFER" rbuf="$RBUFFER" pmpt word lastl lastr wid twid
-
-[[ -n "$compconfig[incremental_completer]" ]] &&
-set ${(s.:.)compconfig[incremental_completer]}
-pmpt="${compconfig[incremental_prompt]-incremental completion...}"
-
-if [[ -n "$compconfig[incremental_list]" ]]; then
- wid=list-choices
-else
- wid=complete-word
-fi
-
-zle $wid "$@"
-LBUFFER="$lbuf"
-RBUFFER="$rbuf"
-if [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
- word=''
-else
- word="${_lastcomp[unambiguous]}"
-fi
-zle -R "${pmpt//\\%u/$word}"
-read -k key
-
-while [[ '#key' -ne '#\\r' && '#key' -ne '#\\n' &&
- '#key' -ne '#\\C-g' ]]; do
- twid=$wid
- if [[ "$key" = ${~compconfig[incremental_stop]} ]]; then
- zle -U "$key"
- return
- elif [[ "$key" = ${~compconfig[incremental_break]} ]]; then
- return
- elif [[ '#key' -eq '#\\C-h' || '#key' -eq '#\\C-?' ]]; then
- [[ $#LBUFFER -gt $#l ]] && LBUFFER="$LBUFFER[1,-2]"
- elif [[ '#key' -eq '#\\t' ]]; then
- zle complete-word "$@"
- lbuf="$LBUFFER"
- rbuf="$RBUFFER"
- elif [[ '#key' -eq '#\\C-d' ]]; then
- twid=list-choices
+# This works only with the new function based completion system.
+
+# The main widget function.
+
+incremental-complete-word() {
+ #emulate -L zsh
+ unsetopt autolist menucomplete automenu # doesn't work well
+
+ local key lbuf="$LBUFFER" rbuf="$RBUFFER" pmpt pstr word
+ local lastl lastr wid twid num post toolong
+ local curcontext="${curcontext}" stop brk
+
+ [[ -z "$curcontext" ]] && curcontext=:::
+ curcontext="incremental:${curcontext#*:}"
+
+ zstyle -s ":completion:${curcontext}" prompt pmpt ||
+ pmpt='incremental (%c): %u%s %l'
+ zstyle -s ":completion:${curcontext}" stop stop
+ zstyle -s ":completion:${curcontext}" break brk
+
+ if zstyle -t ":completion:${curcontext}" list; then
+ wid=list-choices
+ post=( icw-list-helper )
else
- LBUFFER="$LBUFFER$key"
+ wid=complete-word
+ post=()
fi
- lastl="$LBUFFER"
- lastr="$RBUFFER"
- zle $twid "$@"
- LBUFFER="$lastl"
- RBUFFER="$lastr"
- if [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
+
+ comppostfuncs=( "$post[@]" )
+ zle $wid "$@"
+ LBUFFER="$lbuf"
+ RBUFFER="$rbuf"
+ num=$_lastcomp[nmatches]
+ if (( ! num )); then
+ word=''
+ state='-no match-'
+ elif [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
word=''
+ state='-no prefix-'
else
word="${_lastcomp[unambiguous]}"
+ state=''
fi
- zle -R "${pmpt//\\%u/$word}"
+ zformat -f pstr "$pmpt" "u:${word}" "s:$state" "n:$num" \
+ "l:$toolong" "c:${_lastcomp[completer][2,-1]}"
+ zle -R "$pstr"
read -k key
-done
-if [[ '#key' -eq '#\\C-g' ]]; then
- LBUFFER="$lbuf"
- RBUFFER="$rbuf"
-fi
-zle -Rc
-# }
+ while [[ '#key' -ne '#\\r' && '#key' -ne '#\\n' &&
+ '#key' -ne '#\\C-g' ]]; do
+ twid=$wid
+ if [[ "$key" = ${~stop} ]]; then
+ zle -U "$key"
+ return
+ elif [[ "$key" = ${~brk} ]]; then
+ return
+ elif [[ '#key' -eq '#\\C-h' || '#key' -eq '#\\C-?' ]]; then
+ [[ $#LBUFFER -gt $#l ]] && LBUFFER="$LBUFFER[1,-2]"
+ elif [[ '#key' -eq '#\\t' ]]; then
+ zle complete-word "$@"
+ lbuf="$LBUFFER"
+ rbuf="$RBUFFER"
+ elif [[ '#key' -eq '#\\C-d' ]]; then
+ twid=list-choices
+ else
+ LBUFFER="$LBUFFER$key"
+ fi
+ lastl="$LBUFFER"
+ lastr="$RBUFFER"
+ [[ "$twid" = "$wid" ]] && comppostfuncs=( "$post[@]" )
+ toolong=''
+ zle $twid "$@"
+ LBUFFER="$lastl"
+ RBUFFER="$lastr"
+ num=$_lastcomp[nmatches]
+ if (( ! num )); then
+ word=''
+ state='-no match-'
+ elif [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
+ word=''
+ state='-no prefix-'
+ else
+ word="${_lastcomp[unambiguous]}"
+ state=''
+ fi
+ zformat -f pstr "$pmpt" "u:${word}" "s:$state" "n:$num" \
+ "l:$toolong" "c:${_lastcomp[completer][2,-1]}"
+ zle -R "$pstr"
+ read -k key
+ done
+
+ if [[ '#key' -eq '#\\C-g' ]]; then
+ LBUFFER="$lbuf"
+ RBUFFER="$rbuf"
+ fi
+ zle -Rc
+}
+
+# Helper function used as a completion post-function used to make sure that
+# the list of matches in only shown if it fits on the screen.
+
+icw-list-helper() {
+
+ # +1 for the status line we will add...
+
+ if [[ compstate[list_lines]+BUFFERLINES+1 -gt LINES ]]; then
+ compstate[list]='list explanations'
+ [[ compstate[list_lines]+BUFFERLINES+1 -gt LINES ]] && compstate[list]=''
+
+ toolong='...'
+ fi
+}
+
+incremental-complete-word "$@"
diff --git a/Functions/Zle/predict-on b/Functions/Zle/predict-on
index 07ce0703a..bd7212050 100644
--- a/Functions/Zle/predict-on
+++ b/Functions/Zle/predict-on
@@ -1,64 +1,141 @@
# This set of functions implements a sort of magic history searching.
# After predict-on, typing characters causes the editor to look backward
-# in the history for the first line beginning with what you have typed
-# so far. After predict-off, editing returns to normal for the line found.
+# in the history for the first line beginning with what you have typed so
+# far. After predict-off, editing returns to normal for the line found.
# In fact, you often don't even need to use predict-off, because if the
-# line doesn't match something in the history, adding a key at the end
-# behaves as normal --- though editing in the middle is liable to delete
+# line doesn't match something in the history, adding a key performs
+# standard completion --- though editing in the middle is liable to delete
# the rest of the line.
#
+# With the function based completion system (which is needed for this),
+# you should be able to type TAB at almost any point to advance the cursor
+# to the next "interesting" character position (usually the end of the
+# current word, but sometimes somewhere in the middle of the word). And
+# of course as soon as the entire line is what you want, you can accept
+# with RETURN, without needing to move the cursor to the end first.
+#
# To use it:
# autoload -U predict-on
# zle -N predict-on
# zle -N predict-off
# bindkey '...' predict-on
# bindkey '...' predict-off
-# Note that all the functions are defined when you first call type the
-# predict-on key, which means typing the predict-off key before that gives
-# a harmless error message.
+# Note that all functions are defined when you first type the predict-on
+# key, which means typing the predict-off key before that gives a harmless
+# error message.
predict-on() {
- zle -N self-insert insert-and-predict
- zle -N magic-space insert-and-predict
- zle -N backward-delete-char delete-backward-and-predict
+ zle -N self-insert insert-and-predict
+ zle -N magic-space insert-and-predict
+ zle -N backward-delete-char delete-backward-and-predict
+ zle -N delete-char-or-list delete-no-predict
}
predict-off() {
- zle -A .self-insert self-insert
- zle -A .magic-space magic-space
- zle -A .backward-delete-char backward-delete-char
+ zle -A .self-insert self-insert
+ zle -A .magic-space magic-space
+ zle -A .backward-delete-char backward-delete-char
}
insert-and-predict () {
- emulate -L zsh
- if [[ ${RBUFFER[1]} = ${KEYS[-1]} ]]
+ setopt localoptions noshwordsplit noksharrays
+ if [[ $LBUFFER = *$'\012'* ]]
+ then
+ # Editing a multiline buffer, it's unlikely prediction is wanted
+ zle .$WIDGET "$@"
+ return
+ elif [[ ${RBUFFER[1]} = ${KEYS[-1]} ]]
then
- # same as what's typed, just move on
+ # Same as what's typed, just move on
((++CURSOR))
else
LBUFFER="$LBUFFER$KEYS"
if [[ $LASTWIDGET == (self-insert|magic-space|backward-delete-char) ]]
then
- zle .history-beginning-search-backward || RBUFFER=""
+ if ! zle .history-beginning-search-backward
+ then
+ RBUFFER=""
+ if [[ ${KEYS[-1]} != ' ' ]]
+ then
+ unsetopt automenu recexact
+ integer curs=$CURSOR pos nchar=${#LBUFFER//[^${KEYS[-1]}]}
+ local -a +h comppostfuncs
+ local crs curcontext="${curcontext}"
+
+ [[ -z "$curcontext" ]] && curcontext=:::
+ curcontext="predict:${curcontext#*:}"
+
+ comppostfuncs=( predict-limit-list )
+ zle complete-word
+ # Decide where to leave the cursor. The dummy loop is used to
+ # get out of that `case'.
+ repeat 1
+ do
+ zstyle -s ":completion:${curcontext}:" cursor crs
+ case $crs in
+ (complete)
+ # At the place where the completion left it, if it is after
+ # the character typed.
+ [[ ${LBUFFER[-1]} = ${KEYS[-1]} ]] && break
+ ;&
+ (key)
+ # Or maybe at the n'th occurrence of the character typed.
+ pos=${BUFFER[(in:nchar:)${KEYS[-1]}]}
+ if [[ pos -gt curs ]]
+ then
+ CURSOR=$pos
+ break
+ fi
+ ;&
+ (*)
+ # Or else at the previous position.
+ CURSOR=$curs
+ esac
+ done
+ fi
+ fi
fi
fi
return 0
}
delete-backward-and-predict() {
- emulate -L zsh
if [[ -n "$LBUFFER" ]]
then
+ setopt localoptions noshwordsplit noksharrays
+ if [[ $LBUFFER = *$'\012'* ]] then
+ # Editing a multiline buffer, it's unlikely prediction is wanted
+ zle .$WIDGET "$@"
# If the last widget was e.g. a motion, then probably the intent is
# to actually edit the line, not change the search prefix.
- if [[ $LASTWIDGET == (self-insert|magic-space|backward-delete-char) ]]
+ elif [[ $LASTWIDGET == (self-insert|magic-space|backward-delete-char) ]]
then
((--CURSOR))
zle .history-beginning-search-forward || RBUFFER=""
return 0
else
- # Depending on preference, you might call "predict-off" here,
- # and also set up forward deletions to turn off prediction.
+ # Depending on preference, you might call "predict-off" here.
LBUFFER="$LBUFFER[1,-2]"
fi
fi
}
+delete-no-predict() {
+ [[ $WIDGET != delete-char-or-list || -n $RBUFFER ]] && predict-off
+ zle .$WIDGET "$@"
+}
+
+# This is a helper function for autocompletion to prevent long lists
+# of matches from forcing a "do you wish to see all ...?" prompt.
+
+predict-limit-list() {
+ if (( compstate[list_lines]+BUFFERLINES > LINES ||
+ ( compstate[list_max] != 0 &&
+ compstate[nmatches] > compstate[list_max] ) ))
+ then
+ compstate[list]=''
+ elif zstyle -t ":completion:predict::::" list always
+ then
+ compstate[list]='force list'
+ fi
+}
+
+# Handle zsh autoloading conventions
[[ -o kshautoload ]] || predict-on "$@"
diff --git a/Misc/make-zsh-urls b/Misc/make-zsh-urls
index 35bbf9fbb..b74b8334e 100644
--- a/Misc/make-zsh-urls
+++ b/Misc/make-zsh-urls
@@ -1,6 +1,6 @@
#!/usr/bin/perl -w
#
-# $Id: make-zsh-urls,v 1.1 1999/11/09 02:36:42 akr Exp $
+# $Id: make-zsh-urls,v 1.2 2000/04/01 20:49:47 pws Exp $
use strict;
diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index 2257933f5..e8e387a59 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -30,6 +30,10 @@
#include "parameter.mdh"
#include "parameter.pro"
+/* This says if we are cleaning up when the module is unloaded. */
+
+static int incleanup;
+
/* Empty dummy function for special hash parameters. */
/**/
@@ -47,14 +51,14 @@ createspecialhash(char *name, GetNodeFunc get, ScanTabFunc scan)
Param pm;
HashTable ht;
- if (!(pm = createparam(name, PM_SPECIAL|PM_REMOVABLE|PM_HASHED)))
+ if (!(pm = createparam(name, PM_SPECIAL|PM_HIDE|PM_REMOVABLE|PM_HASHED)))
return NULL;
pm->level = pm->old ? locallevel : 0;
pm->gets.hfn = hashgetfn;
pm->sets.hfn = hashsetfn;
pm->unsetfn = stdunsetfn;
- pm->u.hash = ht = newhashtable(7, name, NULL);
+ pm->u.hash = ht = newhashtable(0, name, NULL);
ht->hash = hasher;
ht->emptytable = (TableFunc) shempty;
@@ -83,14 +87,21 @@ paramtypestr(Param pm)
int f = pm->flags;
if (!(f & PM_UNSET)) {
+ if (pm->flags & PM_AUTOLOAD)
+ return dupstring("undefined");
+
switch (PM_TYPE(f)) {
case PM_SCALAR: val = "scalar"; break;
case PM_ARRAY: val = "array"; break;
case PM_INTEGER: val = "integer"; break;
+ case PM_EFLOAT:
+ case PM_FFLOAT: val = "float"; break;
case PM_HASHED: val = "association"; break;
}
DPUTS(!val, "BUG: type not handled in parameter");
val = dupstring(val);
+ if (pm->level)
+ val = dyncat(val, "-local");
if (f & PM_LEFT)
val = dyncat(val, "-left");
if (f & PM_RIGHT_B)
@@ -109,6 +120,10 @@ paramtypestr(Param pm)
val = dyncat(val, "-export");
if (f & PM_UNIQUE)
val = dyncat(val, "-unique");
+ if (f & PM_HIDE)
+ val = dyncat(val, "-hide");
+ if (f & PM_SPECIAL)
+ val = dyncat(val, "-special");
} else
val = dupstring("");
@@ -121,27 +136,24 @@ getpmparameter(HashTable ht, char *name)
{
Param rpm, pm = NULL;
- HEAPALLOC {
- pm = (Param) zhalloc(sizeof(struct param));
- pm->nam = dupstring(name);
- pm->flags = PM_SCALAR | PM_READONLY;
- pm->sets.cfn = NULL;
- pm->gets.cfn = strgetfn;
- pm->unsetfn = NULL;
- pm->ct = 0;
- pm->env = NULL;
- pm->ename = NULL;
- pm->old = NULL;
- pm->level = 0;
- if ((rpm = (Param) realparamtab->getnode(realparamtab, name)) &&
- !(rpm->flags & PM_UNSET))
- pm->u.str = paramtypestr(rpm);
- else {
- pm->u.str = "";
- pm->flags |= PM_UNSET;
- }
- } LASTALLOC;
-
+ pm = (Param) zhalloc(sizeof(struct param));
+ pm->nam = dupstring(name);
+ pm->flags = PM_SCALAR | PM_READONLY;
+ pm->sets.cfn = NULL;
+ pm->gets.cfn = strgetfn;
+ pm->unsetfn = NULL;
+ pm->ct = 0;
+ pm->env = NULL;
+ pm->ename = NULL;
+ pm->old = NULL;
+ pm->level = 0;
+ if ((rpm = (Param) realparamtab->getnode(realparamtab, name)) &&
+ !(rpm->flags & PM_UNSET))
+ pm->u.str = paramtypestr(rpm);
+ else {
+ pm->u.str = dupstring("");
+ pm->flags |= PM_UNSET;
+ }
return (HashNode) pm;
}
@@ -166,7 +178,9 @@ scanpmparameters(HashTable ht, ScanFunc func, int flags)
for (i = 0; i < realparamtab->hsize; i++)
for (hn = realparamtab->nodes[i]; hn; hn = hn->next) {
pm.nam = hn->nam;
- if (func != scancountparams)
+ if (func != scancountparams &&
+ ((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
+ !(flags & SCANPM_WANTKEYS)))
pm.u.str = paramtypestr((Param) hn);
func((HashNode) &pm, flags);
}
@@ -179,12 +193,12 @@ static void
setpmcommand(Param pm, char *value)
{
if (isset(RESTRICTED))
- zwarnnam(NULL, "restricted: %s", value, 0);
+ zwarn("restricted: %s", value, 0);
else {
Cmdnam cn = zcalloc(sizeof(*cn));
cn->flags = HASHED;
- cn->u.cmd = ztrdup(value);
+ cn->u.cmd = value;
cmdnamtab->addnode(cmdnamtab, ztrdup(pm->nam), (HashNode) cn);
}
@@ -207,6 +221,9 @@ setpmcommands(Param pm, HashTable ht)
int i;
HashNode hn;
+ if (!ht)
+ return;
+
for (i = 0; i < ht->hsize; i++)
for (hn = ht->nodes[i]; hn; hn = hn->next) {
Cmdnam cn = zcalloc(sizeof(*cn));
@@ -222,6 +239,7 @@ setpmcommands(Param pm, HashTable ht)
cmdnamtab->addnode(cmdnamtab, ztrdup(hn->nam), (HashNode) cn);
}
+ deleteparamtable(ht);
}
/**/
@@ -236,34 +254,30 @@ getpmcommand(HashTable ht, char *name)
cmdnamtab->filltable(cmdnamtab);
cmd = (Cmdnam) cmdnamtab->getnode(cmdnamtab, name);
}
- HEAPALLOC {
- pm = (Param) zhalloc(sizeof(struct param));
- pm->nam = dupstring(name);
- pm->flags = PM_SCALAR;
- pm->sets.cfn = setpmcommand;
- pm->gets.cfn = strgetfn;
- pm->unsetfn = unsetpmcommand;
- pm->ct = 0;
- pm->env = NULL;
- pm->ename = NULL;
- pm->old = NULL;
- pm->level = 0;
- if (cmd) {
- if (cmd->flags & HASHED)
- pm->u.str = cmd->u.cmd;
- else {
- pm->u.str = zhalloc(strlen(*(cmd->u.name)) +
- strlen(name) + 2);
- strcpy(pm->u.str, *(cmd->u.name));
- strcat(pm->u.str, "/");
- strcat(pm->u.str, name);
- }
- } else {
- pm->u.str = "";
- pm->flags |= PM_UNSET;
+ pm = (Param) zhalloc(sizeof(struct param));
+ pm->nam = dupstring(name);
+ pm->flags = PM_SCALAR;
+ pm->sets.cfn = setpmcommand;
+ pm->gets.cfn = strgetfn;
+ pm->unsetfn = unsetpmcommand;
+ pm->ct = 0;
+ pm->env = NULL;
+ pm->ename = NULL;
+ pm->old = NULL;
+ pm->level = 0;
+ if (cmd) {
+ if (cmd->flags & HASHED)
+ pm->u.str = cmd->u.cmd;
+ else {
+ pm->u.str = zhalloc(strlen(*(cmd->u.name)) + strlen(name) + 2);
+ strcpy(pm->u.str, *(cmd->u.name));
+ strcat(pm->u.str, "/");
+ strcat(pm->u.str, name);
}
- } LASTALLOC;
-
+ } else {
+ pm->u.str = dupstring("");
+ pm->flags |= PM_UNSET;
+ }
return (HashNode) pm;
}
@@ -293,7 +307,9 @@ scanpmcommands(HashTable ht, ScanFunc func, int flags)
for (hn = cmdnamtab->nodes[i]; hn; hn = hn->next) {
pm.nam = hn->nam;
cmd = (Cmdnam) hn;
- if (func != scancountparams) {
+ if (func != scancountparams &&
+ ((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
+ !(flags & SCANPM_WANTKEYS))) {
if (cmd->flags & HASHED)
pm.u.str = cmd->u.cmd;
else {
@@ -312,43 +328,37 @@ scanpmcommands(HashTable ht, ScanFunc func, int flags)
/**/
static void
-setfunction(char *name, char *value)
+setfunction(char *name, char *val, int dis)
{
- char *val;
+ char *value = dupstring(val);
Shfunc shf;
- List list;
+ Eprog prog;
int sn;
- val = ztrdup(value);
val = metafy(val, strlen(val), META_REALLOC);
- HEAPALLOC {
- list = parse_string(val);
- } LASTALLOC;
+ prog = parse_string(val, 1);
- if (!list || list == &dummy_list) {
- zwarnnam(NULL, "invalid function definition", val, 0);
+ if (!prog || prog == &dummy_eprog) {
+ zwarn("invalid function definition", value, 0);
zsfree(val);
return;
}
- PERMALLOC {
- shf = (Shfunc) zalloc(sizeof(*shf));
- shf->funcdef = (List) dupstruct(list);
- shf->flags = 0;
-
- if (!strncmp(name, "TRAP", 4) &&
- (sn = getsignum(name + 4)) != -1) {
- if (settrap(sn, shf->funcdef)) {
- freestruct(shf->funcdef);
- zfree(shf, sizeof(*shf));
- zsfree(val);
- LASTALLOC_RETURN;
- }
- sigtrapped[sn] |= ZSIG_FUNC;
+ shf = (Shfunc) zalloc(sizeof(*shf));
+ shf->funcdef = dupeprog(prog, 0);
+ shf->flags = dis;
+
+ if (!strncmp(name, "TRAP", 4) &&
+ (sn = getsignum(name + 4)) != -1) {
+ if (settrap(sn, shf->funcdef)) {
+ freeeprog(shf->funcdef);
+ zfree(shf, sizeof(*shf));
+ zsfree(val);
+ return;
}
- shfunctab->addnode(shfunctab, ztrdup(name), shf);
- } LASTALLOC;
-
+ sigtrapped[sn] |= ZSIG_FUNC;
+ }
+ shfunctab->addnode(shfunctab, ztrdup(name), shf);
zsfree(val);
}
@@ -356,7 +366,14 @@ setfunction(char *name, char *value)
static void
setpmfunction(Param pm, char *value)
{
- setfunction(pm->nam, value);
+ setfunction(pm->nam, value, 0);
+}
+
+/**/
+static void
+setpmdisfunction(Param pm, char *value)
+{
+ setfunction(pm->nam, value,