refactor(zsh): use subs for plugins

This commit is contained in:
Price Hiller 2022-08-01 23:47:30 -05:00
parent 661fea7b45
commit cba02cdc43
720 changed files with 0 additions and 165334 deletions

View File

@ -1,2 +0,0 @@
modules/** linguist-vendored
modules/Src/aloxaf/*.c -linguist-vendored

View File

@ -1,42 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]"
labels: bug
assignees: ''
---
#### Describe the bug
A clear and concise description of what the bug is.
I can make sure:
- [ ] I am using the latest version of fzf-tab
- [ ] this is the minimal zshrc which can reproduce this bug
- [ ] fzf-tab is loaded after `compinit`
- [ ] fzf-tab is loaded after plugins which will wrap <kbd>Tab</kbd>, like [junegunn/fzf/completion.zsh](https://github.com/junegunn/fzf/blob/master/shell/completion.zsh)
- [ ] fzf-tab is loaded before zsh-autosuggestions, zsh-syntax-highlighting and fast-syntax-highlighting.
#### To Reproduce
Steps to reproduce the behavior:
1. Type '...'
2. Press <kbd>Tab</kbd>
4. See error
#### Expected behavior
A clear and concise description of what you expected to happen.
#### Screenshots
If applicable, add screenshots to help explain your problem.
#### Environment:
- OS: [e.g. Arch Linux]
- zsh version: [e.g. 5.8.1]
#### Minimal zshrc
If applicable, add a minimal zshrc to help us analyze.
#### Log
If applicable, use `C-x .` to trigger completion and provide the log.
If there are only three lines in your log, please make sure your fzf-tab is loaded with the correct order (see the checklist above).

View File

@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[FR]"
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -1,11 +0,0 @@
---
name: Question
about: Ask a question about fzf-tab
title: "[Q]"
labels: question
assignees: ''
---
**Describe your question**
A clear and concise description of your question.

View File

@ -1,36 +0,0 @@
name: ci
on:
pull_request:
push:
branches:
- master
jobs:
test:
name: run test
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- name: checkout
uses: actions/checkout@v1
with:
fetch-depth: 1
- name: install zsh (ubuntu)
if: matrix.os == 'ubuntu-latest'
run: sudo apt-get install zsh
- name: test completion (ubuntu)
if: matrix.os == 'ubuntu-latest'
run: cd test && zsh -f runtests.zsh fzftab.ztst
- name: build binary module
run: zsh -fc 'source ./fzf-tab.zsh && build-fzf-tab-module'
- name: test binary module (ubuntu)
if: matrix.os == 'ubuntu-latest'
run: cd test && zsh -f runtests.zsh fzftab.ztst

View File

@ -1 +0,0 @@
*.zwc

View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2019-2021 Aloxaf
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,138 +0,0 @@
# fzf-tab
[![CI](https://github.com/Aloxaf/fzf-tab/workflows/ci/badge.svg)](https://github.com/Aloxaf/fzf-tab/actions?query=workflow%3Aci)
[![GitHub license](https://img.shields.io/github/license/Aloxaf/fzf-tab)](https://github.com/Aloxaf/fzf-tab/blob/master/LICENSE)
Replace zsh's default completion selection menu with fzf!
[![asciicast](https://asciinema.org/a/293849.svg)](https://asciinema.org/a/293849)
<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc -->
**Table of Contents**
- [fzf-tab](#fzf-tab)
- [Install](#install)
- [Manual](#manual)
- [Antigen](#antigen)
- [Zinit](#zinit)
- [Oh-My-Zsh](#oh-my-zsh)
- [Prezto](#prezto)
- [Usage](#usage)
- [Configure](#configure)
- [Binary module](#binary-module)
- [Difference from other plugins](#difference-from-other-plugins)
- [Compatibility with other plugins](#compatibility-with-other-plugins)
- [Related projects](#related-projects)
<!-- markdown-toc end -->
# Install
**NOTE: fzf-tab needs to be loaded after `compinit`, but before plugins which will wrap widgets, such as [zsh-autosuggestions](https://github.com/zsh-users/zsh-autosuggestions) or [fast-syntax-highlighting](https://github.com/zdharma-continuum/fast-syntax-highlighting)!!**
### Manual
First, clone this repository.
```zsh
git clone https://github.com/Aloxaf/fzf-tab ~/somewhere
```
Then add the following line to your `~/.zshrc`.
```zsh
source ~/somewhere/fzf-tab.plugin.zsh
```
### Antigen
```zsh
antigen bundle Aloxaf/fzf-tab
```
### Zinit
```zsh
zinit light Aloxaf/fzf-tab
```
### Oh-My-Zsh
Clone this repository to your custom directory and then add `fzf-tab` to your plugin list.
```zsh
git clone https://github.com/Aloxaf/fzf-tab ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/fzf-tab
```
### Prezto
Clone this repository to your contrib directory and then add `fzf-tab` to your module list in `.zpreztorc`.
```zsh
git clone https://github.com/Aloxaf/fzf-tab $ZPREZTODIR/contrib/fzf-tab
```
# Usage
Just press <kbd>Tab</kbd> as usual~
Available keybindings:
- <kbd>Ctrl</kdb>+<kdb>Space</kbd>: select multiple results, can be configured by `fzf-bindings` tag
- <kbd>F1</kbd>/<kbd>F2</kbd>: switch between groups, can be configured by `switch-group` tag
- <kbd>/</kbd>: trigger continuous completion (useful when completing a deep path), can be configured by `continuous-trigger` tag
Available commands:
- `disable-fzf-tab`: disable fzf-tab and fallback to compsys
- `enable-fzf-tab`: enable fzf-tab
- `toggle-fzf-tab`: toggle the state of fzf-tab. This is also a zle widget.
## Configure
A common configuration is:
```zsh
# disable sort when completing `git checkout`
zstyle ':completion:*:git-checkout:*' sort false
# set descriptions format to enable group support
zstyle ':completion:*:descriptions' format '[%d]'
# set list-colors to enable filename colorizing
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
# preview directory's content with exa when completing cd
zstyle ':fzf-tab:complete:cd:*' fzf-preview 'exa -1 --color=always $realpath'
# switch group using `,` and `.`
zstyle ':fzf-tab:*' switch-group ',' '.'
```
For more information, please see [Wiki#Configuration](https://github.com/Aloxaf/fzf-tab/wiki/Configuration).
## Binary module
By default, fzf-tab uses [zsh-ls-colors](https://github.com/xPMo/zsh-ls-colors) to parse and apply ZLS_COLORS if you have set the `list-colors` tag.
However, it is a pure zsh script and is slow if you have too many files to colorize.
fzf-tab is shipped with a binary module to speed up this process. You can build it with `build-fzf-tab-module`, then it will be enabled automatically.
# Difference from other plugins
fzf-tab doesn't do "complete", it just shows you the results of the default completion system.
So it works EVERYWHERE (variables, function names, directory stack, in-word completion, etc.).
And most of your configuration for default completion system is still valid.
# Compatibility with other plugins
Some plugins may also bind "^I" to their custom widget, like [fzf/shell/completion.zsh](https://github.com/junegunn/fzf/blob/master/shell/completion.zsh) or [ohmyzsh/lib/completion.zsh](https://github.com/ohmyzsh/ohmyzsh/blob/master/lib/completion.zsh#L61-L73).
By default, fzf-tab will call the widget previously bound to "^I" to get the completion list. So there is no problem in most cases, unless fzf-tab is initialized before a plugin which doesn't handle the previous binding properly.
So if you find your fzf-tab doesn't work properly, **please make sure it is the last plugin to bind "^I"** (If you don't know what I mean, just put it to the end of your plugin list).
# Related projects
- https://github.com/lincheney/fzf-tab-completion (fzf tab completion for zsh, bash and GNU readline apps)

View File

@ -1,3 +0,0 @@
0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
0="${${(M)0:#/*}:-$PWD/$0}"
source "${0:A:h}/fzf-tab.zsh"

View File

@ -1,399 +0,0 @@
# temporarily change options
'builtin' 'local' '-a' '_ftb_opts'
[[ ! -o 'aliases' ]] || _ftb_opts+=('aliases')
[[ ! -o 'sh_glob' ]] || _ftb_opts+=('sh_glob')
[[ ! -o 'no_brace_expand' ]] || _ftb_opts+=('no_brace_expand')
'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand'
# thanks Valodim/zsh-capture-completion
-ftb-compadd() {
# parse all options
local -A apre hpre dscrs _oad
local -a isfile _opts __ expl
zparseopts -E -a _opts P:=apre p:=hpre d:=dscrs X+:=expl O:=_oad A:=_oad D:=_oad f=isfile \
i: S: s: I: x: r: R: W: F: M+: E: q e Q n U C \
J:=__ V:=__ a=__ l=__ k=__ o=__ 1=__ 2=__
# just delegate and leave if any of -O, -A or -D are given or fzf-tab is not enabled
if (( $#_oad != 0 || ! IN_FZF_TAB )); then
builtin compadd "$@"
return
fi
# store matches in $__hits and descriptions in $__dscr
local -a __hits __dscr
if (( $#dscrs == 1 )); then
__dscr=( "${(@P)${(v)dscrs}}" )
fi
builtin compadd -A __hits -D __dscr "$@"
local ret=$?
if (( $#__hits == 0 )); then
return $ret
fi
# store $curcontext for furthur usage
_ftb_curcontext=${curcontext#:}
# only store the fist `-X`
expl=$expl[2]
# keep order of group description
[[ -n $expl ]] && _ftb_groups+=$expl
# store these values in _ftb_compcap
local -a keys=(apre hpre PREFIX SUFFIX IPREFIX ISUFFIX)
local key expanded __tmp_value=$'<\0>' # placeholder
for key in $keys; do
expanded=${(P)key}
if [[ -n $expanded ]]; then
__tmp_value+=$'\0'$key$'\0'$expanded
fi
done
if [[ -n $expl ]]; then
# store group index
__tmp_value+=$'\0group\0'$_ftb_groups[(ie)$expl]
fi
if [[ -n $isfile ]]; then
# NOTE: need a extra ${} here or ~ expansion won't work
__tmp_value+=$'\0realdir\0'${${(Qe)~${:-$IPREFIX$hpre}}}
fi
_opts+=("${(@kv)apre}" "${(@kv)hpre}" $isfile)
__tmp_value+=$'\0args\0'${(pj:\1:)_opts}
if (( $+builtins[fzf-tab-compcap-generate] )); then
fzf-tab-compcap-generate __hits __dscr __tmp_value
else
# dscr - the string to show to users
# word - the string to be inserted
local dscr word i
for i in {1..$#__hits}; do
word=$__hits[i] dscr=$__dscr[i]
if [[ -n $dscr ]]; then
dscr=${dscr//$'\n'}
elif [[ -n $word ]]; then
dscr=$word
fi
_ftb_compcap+=$dscr$'\2'$__tmp_value$'\0word\0'$word
done
fi
# tell zsh that the match is successful
builtin compadd -U -qS '' -R -ftb-remove-space ''
}
# when insert multi results, a whitespace will be added to each result
# remove left space of our fake result because I can't remove right space
# FIXME: what if the left char is not whitespace: `echo $widgets[\t`
-ftb-remove-space() {
[[ $LBUFFER[-1] == ' ' ]] && LBUFFER[-1]=''
}
-ftb-zstyle() {
zstyle $1 ":fzf-tab:$_ftb_curcontext" ${@:2}
}
-ftb-complete() {
local -a _ftb_compcap
local -Ua _ftb_groups
local choice choices _ftb_curcontext continuous_trigger print_query accept_line bs=$'\2' nul=$'\0'
local ret=0
# must run with user options; don't move `emulate -L zsh` above this line
(( $+builtins[fzf-tab-compcap-generate] )) && fzf-tab-compcap-generate -i
COLUMNS=500 _ftb__main_complete "$@" || ret=$?
(( $+builtins[fzf-tab-compcap-generate] )) && fzf-tab-compcap-generate -o
emulate -L zsh -o extended_glob
local _ftb_query _ftb_complist=() _ftb_headers=() command opts
-ftb-generate-complist # sets `_ftb_complist`
-ftb-zstyle -s continuous-trigger continuous_trigger || {
[[ $OSTYPE == msys ]] && continuous_trigger=// || continuous_trigger=/
}
case $#_ftb_complist in
0) return 1;;
1)
choices=("EXPECT_KEY" "${_ftb_compcap[1]%$bs*}")
if (( _ftb_continue_last )); then
choices[1]=$continuous_trigger
fi
;;
*)
-ftb-generate-query # sets `_ftb_query`
-ftb-generate-header # sets `_ftb_headers`
-ftb-zstyle -s print-query print_query || print_query=alt-enter
-ftb-zstyle -s accept-line accept_line
choices=("${(@f)"$(builtin print -rl -- $_ftb_headers $_ftb_complist | -ftb-fzf)"}")
ret=$?
# choices=(query_string expect_key returned_word)
# insert query string directly
if [[ $choices[2] == $print_query ]] || [[ -n $choices[1] && $#choices == 1 ]] ; then
local -A v=("${(@0)${_ftb_compcap[1]}}")
local -a args=("${(@ps:\1:)v[args]}")
[[ -z $args[1] ]] && args=() # don't pass an empty string
IPREFIX=$v[IPREFIX] PREFIX=$v[PREFIX] SUFFIX=$v[SUFFIX] ISUFFIX=$v[ISUFFIX]
# NOTE: should I use `-U` here?, ../f\tabcd -> ../abcd
builtin compadd "${args[@]:--Q}" -Q -- $choices[1]
compstate[list]=
compstate[insert]=
if (( $#choices[1] > 0 )); then
compstate[insert]='2'
[[ $RBUFFER == ' '* ]] || compstate[insert]+=' '
fi
return $ret
fi
choices[1]=()
choices=("${(@)${(@)choices%$nul*}#*$nul}")
unset CTXT
;;
esac
if [[ -n $choices[1] && $choices[1] == $continuous_trigger ]]; then
typeset -gi _ftb_continue=1
typeset -gi _ftb_continue_last=1
fi
if [[ -n $choices[1] && $choices[1] == $accept_line ]]; then
typeset -gi _ftb_accept=1
fi
choices[1]=()
for choice in "$choices[@]"; do
local -A v=("${(@0)${_ftb_compcap[(r)${(b)choice}$bs*]#*$bs}}")
local -a args=("${(@ps:\1:)v[args]}")
[[ -z $args[1] ]] && args=() # don't pass an empty string
IPREFIX=$v[IPREFIX] PREFIX=$v[PREFIX] SUFFIX=$v[SUFFIX] ISUFFIX=$v[ISUFFIX]
builtin compadd "${args[@]:--Q}" -Q -- "$v[word]"
done
compstate[list]=
compstate[insert]=
if (( $#choices == 1 )); then
compstate[insert]='2'
[[ $RBUFFER == ' '* ]] || compstate[insert]+=' '
elif (( $#choices > 1 )); then
compstate[insert]='all'
fi
return $ret
}
fzf-tab-debug() {
(( $+_ftb_debug_cnt )) || typeset -gi _ftb_debug_cnt
local tmp=${TMPPREFIX:-/tmp/zsh}-$$-fzf-tab-$(( ++_ftb_debug_cnt )).log
local -i debug_fd=-1 IN_FZF_TAB=1
{
exec {debug_fd}>&2 2>| $tmp
local -a debug_indent; debug_indent=( '%'{3..20}'(e. .)' )
local PROMPT4 PS4="${(j::)debug_indent}+%N:%i> "
setopt xtrace
: $ZSH_NAME $ZSH_VERSION
zle .fzf-tab-orig-$_ftb_orig_widget
unsetopt xtrace
if (( debug_fd != -1 )); then
zle -M "fzf-tab-debug: Trace output left in $tmp"
fi
} always {
(( debug_fd != -1 )) && exec 2>&$debug_fd {debug_fd}>&-
}
}
fzf-tab-complete() {
# this name must be ugly to avoid clashes
local -i _ftb_continue=1 _ftb_continue_last=0 _ftb_accept=0 ret=0
# hide the cursor until finishing completion, so that users won't see cursor up and down
# NOTE: MacOS Terminal doesn't support civis & cnorm
echoti civis >/dev/tty 2>/dev/null
while (( _ftb_continue )); do
_ftb_continue=0
local IN_FZF_TAB=1
{
zle .fzf-tab-orig-$_ftb_orig_widget
ret=$?
} always {
IN_FZF_TAB=0
}
if (( _ftb_continue )); then
zle .split-undo
zle .reset-prompt
zle -R
zle fzf-tab-dummy
fi
done
echoti cnorm >/dev/tty 2>/dev/null
zle .redisplay
(( _ftb_accept )) && zle .accept-line
return $ret
}
# this function does nothing, it is used to be wrapped by other plugins like f-sy-h.
# this make it possible to call the wrapper function without causing any other side effects.
fzf-tab-dummy() { }
zle -N fzf-tab-debug
zle -N fzf-tab-complete
zle -N fzf-tab-dummy
disable-fzf-tab() {
emulate -L zsh -o extended_glob
(( $+_ftb_orig_widget )) || return 0
bindkey '^I' $_ftb_orig_widget
case $_ftb_orig_list_grouped in
0) zstyle ':completion:*' list-grouped false ;;
1) zstyle ':completion:*' list-grouped true ;;
2) zstyle -d ':completion:*' list-grouped ;;
esac
unset _ftb_orig_widget _ftb_orig_list_groupded
# unhook compadd so that _approximate can work properply
unfunction compadd 2>/dev/null
functions[_main_complete]=$functions[_ftb__main_complete]
functions[_approximate]=$functions[_ftb__approximate]
# Don't remove .fzf-tab-orig-$_ftb_orig_widget as we won't be able to reliably
# create it if enable-fzf-tab is called again.
}
enable-fzf-tab() {
emulate -L zsh -o extended_glob
(( ! $+_ftb_orig_widget )) || disable-fzf-tab
typeset -g _ftb_orig_widget="${${$(builtin bindkey '^I')##* }:-expand-or-complete}"
if (( ! $+widgets[.fzf-tab-orig-$_ftb_orig_widget] )); then
# Widgets that get replaced by compinit.
local compinit_widgets=(
complete-word
delete-char-or-list
expand-or-complete
expand-or-complete-prefix
list-choices
menu-complete
menu-expand-or-complete
reverse-menu-complete
)
# Note: We prefix the name of the widget with '.' so that it doesn't get wrapped.
if [[ $widgets[$_ftb_orig_widget] == builtin &&
$compinit_widgets[(Ie)$_ftb_orig_widget] != 0 ]]; then
# We are initializing before compinit and being asked to fall back to a completion
# widget that isn't defined yet. Create our own copy of the widget ahead of time.
zle -C .fzf-tab-orig-$_ftb_orig_widget .$_ftb_orig_widget _main_complete
else
# Copy the widget before it's wrapped by zsh-autosuggestions and zsh-syntax-highlighting.
zle -A $_ftb_orig_widget .fzf-tab-orig-$_ftb_orig_widget
fi
fi
zstyle -t ':completion:*' list-grouped false
typeset -g _ftb_orig_list_grouped=$?
zstyle ':completion:*' list-grouped false
bindkey -M emacs '^I' fzf-tab-complete
bindkey -M viins '^I' fzf-tab-complete
bindkey -M emacs '^X.' fzf-tab-debug
bindkey -M viins '^X.' fzf-tab-debug
# make sure we can copy them
autoload +X -Uz _main_complete _approximate
# hook compadd
functions[compadd]=$functions[-ftb-compadd]
# hook _main_complete to trigger fzf-tab
functions[_ftb__main_complete]=$functions[_main_complete]
function _main_complete() { -ftb-complete "$@" }
# TODO: This is not a full support, see #47
# _approximate will also hook compadd
# let it call -ftb-compadd instead of builtin compadd so that fzf-tab can capture result
# make sure _approximate has been loaded.
functions[_ftb__approximate]=$functions[_approximate]
function _approximate() {
# if not called by fzf-tab, don't do anything with compadd
(( ! IN_FZF_TAB )) || unfunction compadd
_ftb__approximate
(( ! IN_FZF_TAB )) || functions[compadd]=$functions[-ftb-compadd]
}
}
toggle-fzf-tab() {
emulate -L zsh -o extended_glob
if (( $+_ftb_orig_widget )); then
disable-fzf-tab
else
enable-fzf-tab
fi
}
build-fzf-tab-module() {
local MACOS
if [[ ${OSTYPE} == darwin* ]]; then
MACOS=true
fi
pushd $FZF_TAB_HOME/modules
CPPFLAGS=-I/usr/local/include CFLAGS="-g -Wall -O2" LDFLAGS=-L/usr/local/lib ./configure --disable-gdbm --without-tcsetpgrp ${MACOS:+DL_EXT=bundle}
make -j$(nproc)
popd
}
zmodload zsh/zutil
zmodload zsh/mapfile
zmodload -F zsh/stat b:zstat
0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
0="${${(M)0:#/*}:-$PWD/$0}"
FZF_TAB_HOME="${0:A:h}"
source "$FZF_TAB_HOME"/lib/zsh-ls-colors/ls-colors.zsh fzf-tab-lscolors
typeset -ga _ftb_group_colors=(
$'\x1b[94m' $'\x1b[32m' $'\x1b[33m' $'\x1b[35m' $'\x1b[31m' $'\x1b[38;5;27m' $'\x1b[36m'
$'\x1b[38;5;100m' $'\x1b[38;5;98m' $'\x1b[91m' $'\x1b[38;5;80m' $'\x1b[92m'
$'\x1b[38;5;214m' $'\x1b[38;5;165m' $'\x1b[38;5;124m' $'\x1b[38;5;120m'
)
# init
() {
emulate -L zsh -o extended_glob
fpath+=($FZF_TAB_HOME/lib)
autoload -Uz -- $FZF_TAB_HOME/lib/-#ftb*(:t)
if (( $+FZF_TAB_COMMAND || $+FZF_TAB_OPTS || $+FZF_TAB_QUERY || $+FZF_TAB_SINGLE_GROUP || $+fzf_tab_preview_init )) \
|| zstyle -m ":fzf-tab:*" command '*' \
|| zstyle -m ":fzf-tab:*" extra-opts '*'; then
print -P "%F{red}%B[fzf-tab] Sorry, your configuration is not supported anymore\n" \
"See https://github.com/Aloxaf/fzf-tab/pull/132 for more information%f%b"
fi
if [[ -n $FZF_TAB_HOME/modules/Src/aloxaf/fzftab.(so|bundle)(#qN) ]]; then
module_path+=("$FZF_TAB_HOME/modules/Src")
zmodload aloxaf/fzftab
if [[ $FZF_TAB_MODULE_VERSION != "0.2.2" ]]; then
zmodload -u aloxaf/fzftab
local rebuild
print -Pn "%F{yellow}fzftab module needs to be rebuild, rebuild now?[Y/n]:%f"
read -q rebuild
if [[ $rebuild == y ]]; then
build-fzf-tab-module
zmodload aloxaf/fzftab
fi
fi
fi
}
enable-fzf-tab
zle -N toggle-fzf-tab
# restore options
(( ${#_ftb_opts} )) && setopt ${_ftb_opts[@]}
'builtin' 'unset' '_ftb_opts'

View File

@ -1,34 +0,0 @@
#!/hint/zsh
emulate -L zsh -o cbases -o octalzeroes
local REPLY
local -a reply stat lstat
# fzf-tab-lscolors::match-by $1 lstat follow
zstat -A lstat -L -- $1
# follow symlink
(( lstat[3] & 0170000 )) && zstat -A stat -- $1 2>/dev/null
fzf-tab-lscolors::from-mode "$1" "$lstat[3]" $stat[3]
# fall back to name
[[ -z $REPLY ]] && fzf-tab-lscolors::from-name $1
# If this is a symlink
if [[ -n $lstat[14] ]]; then
local sym_color=$REPLY
local rsv_color=$REPLY
local rsv=$lstat[14]
# If this is not a broken symlink
if [[ -e $rsv ]]; then
# fzf-tab-lscolors::match-by $rsv stat
zstat -A stat -- $rsv
fzf-tab-lscolors::from-mode $rsv $stat[3]
# fall back to name
[[ -z $REPLY ]] && fzf-tab-lscolors::from-name $rsv
rsv_color=$REPLY
fi
dpre=$'\033[0m\033['$sym_color'm'
dsuf+=$'\033[0m -> \033['$rsv_color'm'$rsv
else
dpre=$'\033[0m\033['$REPLY'm'
fi

View File

@ -1,102 +0,0 @@
#!/hint/zsh
local tmp_dir=${TMPPREFIX:-/tmp/zsh}-fzf-tab-$USER
[[ -d $tmp_dir ]] || command mkdir $tmp_dir
local ftb_preview_init="
zmodload zsh/mapfile
local -a _ftb_compcap=(\"\${(@f)mapfile[$tmp_dir/compcap.$$]}\")
local -a _ftb_groups=(\"\${(@f)mapfile[$tmp_dir/groups.$$]}\")
local bs=\$'\2'
# get descriptoin
export desc=\${\${\"\$(<{f})\"%\$'\0'*}#*\$'\0'}
# get ctxt for current completion
local -A ctxt=(\"\${(@0)\${_ftb_compcap[(r)\${(b)desc}\$bs*]#*\$bs}}\")
# get group
if (( \$+ctxt[group] )); then
export group=\$_ftb_groups[\$ctxt[group]]
fi
# get original word
export word=\${(Q)ctxt[word]}
# get real path if it is file
if (( \$+ctxt[realdir] )); then
export realpath=\${ctxt[realdir]}\$word
fi
"
local binds=tab:down,btab:up,change:top,ctrl-space:toggle
local fzf_command fzf_flags fzf_preview debug_command tmp switch_group fzf_pad
local ret=0
-ftb-zstyle -s fzf-command fzf_command || fzf_command=fzf
-ftb-zstyle -a fzf-bindings tmp && binds+=,${(j:,:)tmp}
-ftb-zstyle -a fzf-flags fzf_flags
-ftb-zstyle -s fzf-preview fzf_preview
-ftb-zstyle -a switch-group switch_group || switch_group=(F1 F2)
-ftb-zstyle -s fzf-pad fzf_pad || fzf_pad=2
-ftb-zstyle -a debug-command debug_command && {
${(eX)debug_command} $fzf_flags
return
}
print -rl -- $_ftb_compcap > $tmp_dir/compcap.$$
print -rl -- $_ftb_groups > $tmp_dir/groups.$$
print -r -- ${ftb_preview_init/{f}/\$1} > $tmp_dir/ftb_preview_init.$$
binds=${binds//{_FTB_INIT_}/. $tmp_dir/ftb_preview_init.$$ {f} $'\n'}
local -i header_lines=$#_ftb_headers
local -i lines=$(( $#_ftb_compcap + fzf_pad + header_lines ))
local reload_command="$commands[zsh] -f $FZF_TAB_HOME/lib/ftb-switch-group $$ $header_lines $tmp_dir"
# detect if we will use tmux popup
local use_tmux_popup=0
if [[ $fzf_command == "ftb-tmux-popup" ]]; then
use_tmux_popup=1
fi
if (( ! use_tmux_popup )); then
# fzf will cause the current line to refresh, so move the cursor down.
echoti cud1 >/dev/tty
# reset cursor before call fzf
echoti cnorm >/dev/tty 2>/dev/null
fi
cat > $tmp_dir/completions.$$
local dd='gdd'
if (( ${+commands[$dd]} == 0 )) ; then
dd='dd'
fi
if (( ${+commands[$dd]} == 0 )) ; then
dd='true' # nop if dd is not installed
fi
_ftb_query="${_ftb_query}$(command "$dd" bs=1G count=1 status=none iflag=nonblock < /dev/tty 2>/dev/null)" || true
$fzf_command \
--ansi \
--bind=$binds \
--bind="${switch_group[1]}:reload($reload_command -1),${switch_group[2]}:reload($reload_command 1)" \
--color=hl:$(( header_lines == 0 ? 188 : 255 )) \
--cycle \
--delimiter='\x00' \
--expect=$continuous_trigger,$print_query,$accept_line \
--header-lines=$header_lines \
--height=${FZF_TMUX_HEIGHT:=$(( lines > LINES / 3 * 2 ? LINES / 3 * 2 : lines ))} \
--layout=reverse \
--multi \
--nth=2,3 \
--print-query \
--query=$_ftb_query \
--tiebreak=begin \
${fzf_preview:+--preview=$ftb_preview_init$fzf_preview} \
$fzf_flags < $tmp_dir/completions.$$ || ret=$?
if (( ! use_tmux_popup )); then
echoti civis >/dev/tty 2>/dev/null
echoti cuu1 >/dev/tty
fi
command rm $tmp_dir/*.$$ 2>/dev/null
return $ret

View File

@ -1,113 +0,0 @@
#!/hint/zsh
local dsuf dpre k _v filepath first_word show_group default_color prefix bs=$'\b'
local -a list_colors group_colors tcandidates reply match mbegin mend
local -i same_word=1 colorful=0
local -Ua duplicate_groups=()
local -A word_map=()
(( $#_ftb_compcap == 0 )) && return
-ftb-zstyle -s show-group show_group || show_group=full
-ftb-zstyle -s default-color default_color || default_color=$'\x1b[37m'
-ftb-zstyle -s prefix prefix || {
zstyle -m ':completion:*:descriptions' format '*' && prefix='·'
}
-ftb-zstyle -a group-colors group_colors || group_colors=($_ftb_group_colors)
zstyle -a ":completion:$_ftb_curcontext" list-colors list_colors
# init colorize
if (( $+builtins[fzf-tab-candidates-generate] )); then
fzf-tab-candidates-generate -i list_colors
else
local -A namecolors=(${(@s:=:)${(@s.:.)list_colors}:#[[:alpha:]][[:alpha:]]=*})
local -A modecolors=(${(@Ms:=:)${(@s.:.)list_colors}:#[[:alpha:]][[:alpha:]]=*})
(( $#namecolors == 0 && $#modecolors == 0 )) && list_colors=()
fi
if (( $#_ftb_groups == 1 )); then
-ftb-zstyle -m single-group prefix || prefix=''
-ftb-zstyle -m single-group color || group_colors=("$default_color")
fi
if (( $+builtins[fzf-tab-candidates-generate] )); then
fzf-tab-candidates-generate
else
for k _v in "${(@ps:\2:)_ftb_compcap}"; do
local -A v=("${(@0)_v}")
[[ $v[word] == ${first_word:=$v[word]} ]] || same_word=0
# add character and color to describe the type of the files
dsuf='' dpre=''
if (( $+v[realdir] )); then
filepath=$v[realdir]${(Q)v[word]}
if [[ -d $filepath ]]; then
dsuf=/
fi
# add color and resolve symlink if have list-colors
# detail: http://zsh.sourceforge.net/Doc/Release/Zsh-Modules.html#The-zsh_002fcomplist-Module
if (( $#list_colors )) && [[ -a $filepath || -L $filepath ]]; then
-ftb-colorize $filepath
colorful=1
elif [[ -L $filepath ]]; then
dsuf=@
fi
if [[ $options[list_types] == off ]]; then
dsuf=''
fi
fi
# add color to description if they have group index
if (( $+v[group] )); then
local color=$group_colors[$v[group]]
# add a hidden group index at start of string to keep group order when sorting
# first group index is for builtin sort, sencond is for GNU sort
tcandidates+=$v[group]$'\b'$color$prefix$dpre$'\0'$v[group]$'\b'$k$'\0'$dsuf
else
tcandidates+=$default_color$dpre$'\0'$k$'\0'$dsuf
fi
# check group with duplicate member
if [[ $show_group == brief ]]; then
if (( $+word_map[$v[word]] && $+v[group] )); then
duplicate_groups+=$v[group] # add this group
duplicate_groups+=$word_map[$v[word]] # add previous group
fi
word_map[$v[word]]=$v[group]
fi
done
fi
(( same_word )) && tcandidates[2,-1]=()
# sort and remove sort group or other index
zstyle -T ":completion:$_ftb_curcontext" sort
if (( $? != 1 )); then
if (( colorful )); then
# if enable list_colors, we should skip the first field
if [[ ${commands[sort]:A:t} != (|busybox*) ]]; then
# this is faster but doesn't work if `find` is from busybox
tcandidates=(${(f)"$(command sort -u -t '\0' -k 2 <<< ${(pj:\n:)tcandidates})"})
else
# slower but portable
tcandidates=(${(@o)${(@)tcandidates:/(#b)([^$'\0']#)$'\0'(*)/$match[2]$'\0'$match[1]}})
tcandidates=(${(@)tcandidates/(#b)(*)$'\0'([^$'\0']#)/$match[2]$'\0'$match[1]})
fi
else
tcandidates=("${(@o)tcandidates}")
fi
fi
typeset -gUa _ftb_complist=("${(@)tcandidates//[0-9]#$bs}")
# hide needless group
if (( $#_ftb_groups )); then
local i to_hide indexs=({1..$#_ftb_groups})
case $show_group in
brief) to_hide=(${indexs:|duplicate_groups}) ;;
none) to_hide=($indexs) ;;
esac
for i in $to_hide; do
# NOTE: _ftb_groups is unique array
_ftb_groups[i]="__hide__$i"
done
fi

View File

@ -1,35 +0,0 @@
#!/hint/zsh
typeset -ga _ftb_headers=()
local i tmp group_colors
local -i mlen=0 len=0
if (( $#_ftb_groups == 1 )) && { ! -ftb-zstyle -m single-group "header" }; then
return
fi
# calculate the max column width
for i in $_ftb_groups; do
(( $#i > mlen )) && mlen=$#i
done
mlen+=1
-ftb-zstyle -a group-colors group_colors || group_colors=($_ftb_group_colors)
for (( i=1; i<=$#_ftb_groups; i++ )); do
[[ $_ftb_groups[i] == "__hide__"* ]] && continue
if (( len + $#_ftb_groups[i] > COLUMNS - 5 )); then
_ftb_headers+=$tmp
tmp='' && len=0
fi
if (( len + mlen > COLUMNS - 5 )); then
# the last column doesn't need padding
_ftb_headers+=$tmp$group_colors[i]$_ftb_groups[i]$'\033[00m'
tmp='' && len=0
else
tmp+=$group_colors[i]${(r:$mlen:)_ftb_groups[i]}$'\033[00m'
len+=$mlen
fi
done
(( $#tmp )) && _ftb_headers+=$tmp

View File

@ -1,40 +0,0 @@
#!/hint/zsh
if zmodload -s zsh/pcre; then
setopt localoptions rematch_pcre
fi
local key qtype tmp query_string
typeset -g _ftb_query=
-ftb-zstyle -a query-string query_string || query_string=(prefix input first)
for qtype in $query_string; do
if [[ $qtype == prefix ]]; then
# find the longest common prefix among descriptions
local -a keys=(${_ftb_compcap%$'\2'*})
tmp=$keys[1]
local MATCH match mbegin mend prefix=(${(s::)tmp})
for key in ${keys:1}; do
(( $#tmp )) || break
[[ $key == $tmp* ]] && continue
# interpose characters from the current common prefix and $key and see how
# many pairs of equal characters we get at the start of the resulting string
[[ ${(j::)${${(s::)key[1,$#tmp]}:^prefix}} =~ '^(((.)\3)*)' ]]
# truncate common prefix and maintain loop invariant: ${(s::)tmp} == $prefix
tmp[$#MATCH/2+1,-1]=""
prefix[$#MATCH/2+1,-1]=()
done
elif [[ $qtype == input ]]; then
local fv=${_ftb_compcap[1]#*$'\2'}
local -A v=("${(@0)fv}")
tmp=$v[PREFIX]
if (( $RBUFFER[(i)$v[SUFFIX]] != 1 )); then
tmp=${tmp/%$v[SUFFIX]}
fi
tmp=${${tmp#$v[hpre]}#$v[apre]}
fi
if (( $query_string[(I)longest] )); then
(( $#tmp > $#_ftb_query )) && _ftb_query=$tmp
elif [[ -n $tmp ]]; then
_ftb_query=$tmp && break
fi
done

View File

@ -1,38 +0,0 @@
#!/hint/zsh
emulate -L zsh -o extended_glob
zmodload zsh/mapfile
# receive arguments
local pid=$1 header_lines=$2 tmp_dir=$3 offset=$@[-1]
# read completion list
local -a list=(${(f)mapfile[$tmp_dir/completions.$pid]})
# get total group count
if (( $#list > 10000 )); then
local -Ua total=(${(f)"$(print -l ${list:$header_lines} | grep -a -oP '^\x1b\[[0-9;]*m')"})
else
local -Ua total=(${(M)${list:$header_lines}#$'\x1b['[0-9;]#*m})
fi
# get current group index, start from 2
local current=2
if [[ -f $tmp_dir/current-group.$pid ]]; then
current=$(( $(<$tmp_dir/current-group.$pid) + offset ))
fi
(( current > $#total )) && current=1
(( current == 0 )) && current=$#total
echo $current > $tmp_dir/current-group.$pid
# print headers
if (( header_lines != 0 )); then
print -l ${list[1,header_lines]/${total[current]}/$'\x1b[1m'}
fi
# print current group
if (( $#list > 10000 )); then
print -l ${list:$header_lines} | grep -a -F "${total[current]}"
else
print -l ${(M)${list:$header_lines}:#${total[current]}*}
fi

View File

@ -1,88 +0,0 @@
#!/hint/zsh
# Show results with tmux popup
# Example usage:
# zstyle ':fzf-tab:*' fzf-command ftb-tmux-popup
# zstyle ':fzf-tab:*' popup-pad 0 0
# It can also be used as a standalone tool, like:
# ls | ftb-tmux-popup
emulate -L zsh -o extended_glob
# import min
autoload -Uz zmathfunc
zmathfunc
: ${tmp_dir:=${TMPPREFIX:-/tmp/zsh}-fzf-tab-$USER}
# fallback to fzf if it is not running in tmux
if (( ! $+TMUX_PANE )); then
fzf $@
return
fi
local ret=0
local -a fzf_opts=($@)
fzf_opts=(${${fzf_opts/--height*}/--layout*})
# get position of cursor and size of window
local -a tmp=($(command tmux display-message -p "#{pane_top} #{cursor_y} #{pane_left} #{cursor_x} #{window_height} #{window_width} #{status} #{status-position}"))
local cursor_y=$((tmp[1] + tmp[2])) cursor_x=$((tmp[3] + tmp[4])) window_height=$tmp[5] window_width=$tmp[6] window_top=0
if [[ $tmp[8] == 'top' ]]; then
window_top=$tmp[7]
cursor_y=$((cursor_y + window_top))
fi
# if not called by fzf-tab
if (( ! $+IN_FZF_TAB )); then
[[ -d $tmp_dir ]] || mkdir -p $tmp_dir
cat > $tmp_dir/completions.$$
fi
local text REPLY comp_lines comp_length length popup_pad
zstyle -a ":fzf-tab:$_ftb_curcontext" popup-pad popup_pad || popup_pad=(0 0)
# get the size of content, note we should remove all ANSI color code
comp_lines=$(( ${#${(f)mapfile[$tmp_dir/completions.$$]}} + $popup_pad[2] ))
if (( comp_lines <= 500 )); then
comp_length=0
for line in ${(f)mapfile[$tmp_dir/completions.$$]}; do
length=${(m)#${(S)line//$'\x1b['[0-9]#*m}}
(( length >= comp_length )) && comp_length=$length
done
else
# FIXME: can't get the correct width of CJK characters.
comp_length=$( command perl -ne 's/\x1b\[[0-9;]*m//g;s/\x00//g; $m= length() if $m < length(); END { print $m }' < $tmp_dir/completions.$$ )
fi
comp_length=$(( comp_length + $popup_pad[1] ))
local popup_height popup_y popup_width popup_x
# calculate the popup height and y position
if (( cursor_y * 2 > window_height )); then
# show above the cursor
popup_height=$(( min(comp_lines + 4, cursor_y - window_top) ))
popup_y=$cursor_y
else
# show below the cursor
popup_height=$(( min(comp_lines + 4, window_height - cursor_y + window_top - 1) ))
popup_y=$(( cursor_y + popup_height + 1 ))
fzf_opts+=(--layout=reverse)
fi
# calculate the popup width and x position
popup_width=$(( min(comp_length + 5, window_width) ))
popup_x=$(( cursor_x + popup_width > window_width ? window_width - popup_width : cursor_x ))
echo -E "$commands[fzf] ${(qq)fzf_opts[@]} < $tmp_dir/completions.$$ > $tmp_dir/result-$$" > $tmp_dir/fzf-$$
{
tmux popup -x $popup_x -y $popup_y \
-w $popup_width -h $popup_height \
-d $PWD -E ". $tmp_dir/fzf-$$" || ret=$?
echo -E "$(<$tmp_dir/result-$$)"
} always {
command rm $tmp_dir/*-$$
(( $+IN_FZF_TAB )) || command rm $tmp_dir/completions.$$
}
return $ret

View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2019 Gamma
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,114 +0,0 @@
# zsh-ls-colors
![Demo screenshot](https://raw.githubusercontent.com/xPMo/zsh-ls-colors/image/demo.png)
A zsh library to use `LS_COLORS` in scripts or other plugins.
For a simple demo, see the `demo` script in this repo.
For more advanced usage,
instructions are located at top of the source files for `from-mode` and `from-name`.
If a use case isn't adequately covered,
please open an issue!
## Using zsh-ls-colors in a plugin
You can use this as a submodule or a subtree.
### submodule:
```sh
# Add (only once)
git submodule add git://github.com/xPMo/zsh-ls-colors.git ls-colors
git commit -m 'Add ls-colors as submodule'
# Update
cd ls-colors
git fetch
git checkout origin/master
cd ..
git commit ls-colors -m 'Update ls-colors to latest'
```
### Subtree:
```sh
# Initial add
git subtree add --prefix=ls-colors/ --squash -m 'Add ls-colors as a subtree' \
git://github.com/xPMo/zsh-ls-colors.git master
# Update
git subtree pull --prefix=ls-colors/ --squash -m 'Update ls-colors to latest' \
git://github.com/xPMo/zsh-ls-colors.git master
# Or, after adding a remote:
git remote add ls-colors git://github.com/xPMo/zsh-ls-colors.git
# Initial add
git subtree add --prefix=ls-colors/ --squash -m 'Add ls-colors as a subtree' ls-colors master
# Update
git subtree pull --prefix=ls-colors/ --squash -m 'Update ls-colors to latest' ls-colors master
```
### Function namespacing
Since functions are a public namespace,
this plugin allows you to customize the preifix for your plugin:
```zsh
# load functions as my-lscolors::{init,match-by,from-name,from-mode}
source ${0:h}/ls-colors/ls-colors.zsh my-lscolors
```
### Parameter namespacing
While indirect parameter expansion exists with `${(P)var}`,
it doesn't play nicely with array parameters.
There are multiple strategies to prevent unnecessary re-parsing:
```zsh
# Call once when loading.
# Pollutes global namespace but prevents re-parsing
ls-color::init
```
```zsh
# Don't call init at all and only use ::match-by.
# Doesn't pollute global namespace but reparses LS_COLORS on every call
ls-color::match-by $file lstat
```
```zsh
# Initialize within a scope with local parameters.
# Best for not polluting global namespace when multiple filenames need to be parsed.
(){
local -A namecolors modecolors
ls-color::init
for arg; do
...
done
}
```
```zsh
# Serialize:
typeset -g LS_COLORS_CACHE_FILE=$(mktemp)
(){
local -A namecolors modecolors
ls-color::init
typeset -p modecolors namecolors >| $LS_COLORS_CACHE_FILE
zcompile $LS_COLORS_CACHE_FILE
}
my-function(){
local -A namecolors modecolors
source $LS_COLORS_CACHE_FILE
...
}
```

View File

@ -1,65 +0,0 @@
#!/usr/bin/env zsh
# set $0 (ref: zdharma.org/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html#zero-handling)
0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
0="${${(M)0:#/*}:-$PWD/$0}"
# load library functions
source ls-colors.zsh ''
# to name the functions with a different namespace
# call source with a different argument
#source my-plugin::ls
# init (sets modecolors and namecolors)
# You have options. Either you can pollute global namespace:
ls-color::init
# Or you can have ::match-by re-parse colors on every call
: # (do nothing)
# Or if you have multiple calls, you can parse colors once for a scope:
(){
local -A modecolors namecolors
ls-color::init
for arg; do
ls-color::match-by $arg lstat
: do something else
done
}
# colors can also be added for other globs after init as well:
namecolors[*.md]='01' # bold markdown files
# EXTENDED_GLOB is enabled when matching, so things like this are possible:
namecolors[(#i)(*/|)license(|.*)]='04' # underline LICENSE, or license.txt, or similar
local file reply
# color each file in the argument list
for file; do
ls-color::match-by $file all
# point to symlink resolution if it exists
print '\e['$reply[1]'m'$file'\e[0m'${reply[2]:+' → \e['$reply[3]'m'$reply[2]'\e[0m'}
done
# =======================
# Alternate manual method:
for file; do
ls-color::match-by $file lstat follow
if [[ $reply[2] ]]; then
# This is a symlink
symlink_color=$reply[1]
# If broken, use link color for destination
resolved_color=$reply[1]
resolved=$reply[2]
if [[ -e $file ]]; then
# Not broken, update destination color
ls-color::match-by $file stat
resolved_color=$reply[1]
fi
print '\e['$symlink_color'm'$file'\e[0m → \e['$resolved_color'm'$resolved'\e[0m'
else
# This is not a symlink
print '\e['$reply[1]'m'$file'\e[0m'
fi
done

View File

@ -1,186 +0,0 @@
#!/usr/bin/env zsh
# set the prefix for all functions
local pfx=${1:-'ls-color'}
# {{{ From mode
# Usage:
# $1: filename
# $2: The value of struct stat st_mode
# If empty, modecolors lookup will be skipped
# $3: (If symlink) The value of struct stat st_mode
# for the target of $1's symlink. If unset,
# interpret as a broken link.
# Sets REPLY to the console code
${pfx}::from-mode () {
emulate -L zsh
setopt cbases octalzeroes extendedglob
[[ -z $2 ]] && return 1
local -i reg=0
local -a codes
local -i st_mode=$(($2))
# See man 7 inode for more info
# file type
case $(( st_mode & 0170000 )) in
$(( 0140000 )) ) codes=( $modecolors[so] ) ;;
$(( 0120000 )) ) # symlink, special handling
if ! (($+3)); then
REPLY=$modecolors[or]
elif [[ $modecolors[ln] = target ]]; then
"$0" "$1" "${@:3}"
else
REPLY=$modecolors[ln]
fi
return
;;
$(( 0100000 )) ) codes=( ); reg=1 ;; # regular file
$(( 0060000 )) ) codes=( $modecolors[bd] ) ;;
$(( 0040000 )) ) codes=( $modecolors[di] ) ;;
$(( 0020000 )) ) codes=( $modecolors[cd] ) ;;
$(( 0010000 )) ) codes=( $modecolors[pi] ) ;;
esac
# setuid/setgid/sticky/other-writable
(( st_mode & 04000 )) && codes+=( $modecolors[su] )
(( st_mode & 02000 )) && codes+=( $modecolors[sg] )
(( ! reg )) && case $(( st_mode & 01002 )) in
# sticky
$(( 01000 )) ) codes+=( $modecolors[st] ) ;;
# other-writable
$(( 00002 )) ) codes+=( $modecolors[ow] ) ;;
# other-writable and sticky
$(( 01002 )) ) codes+=( $modecolors[tw] ) ;;
esac
# executable
if (( ! $#codes )); then
(( st_mode & 0111 )) && codes+=( $modecolors[ex] )
fi
# return nonzero if no matching code
[[ ${REPLY::=${(j:;:)codes}} ]]
} # }}}
# {{{ From name
# Usage:
# $1: filename
#
# Sets REPLY to the console code
${pfx}::from-name () {
emulate -L zsh
setopt extendedglob
# Return non-zero if no keys match
[[ ${REPLY::=$namecolors[(k)$1]} ]]
} # }}}
# {{{ Init
# WARNING: initializes namecolors and modecolors in global scope
${pfx}::init () {
emulate -L zsh
# Use $1 if provided, otherwise use LS_COLORS
# Use LSCOLORS on BSD
local LS_COLORS=${1:-${LS_COLORS:-$LSCOLORS}}
# read in LS_COLORS
typeset -gA namecolors=(${(@s:=:)${(@s.:.)LS_COLORS}:#[[:alpha:]][[:alpha:]]=*})
typeset -gA modecolors=(${(@Ms:=:)${(@s.:.)LS_COLORS}:#[[:alpha:]][[:alpha:]]=*})
}
# }}}
# {{{ Match by
# Usage:
# $1: filename
# Optional (must be $2): g[lobal]: Use existing stat | lstat in parent scope
# ${@:2}: Append to reply:
# - l[stat] : Look up using lstat (don't follow symlink), if empty match name
# - s[tat] : Look up using stat (do follow symlink), if empty match name
# - n[ame] : Only match name
# - f[ollow]: Get resolution path of symlink
# - L[stat] : Same as above but don't match name
# - S[tat] : Same as above but don't match name
# - a[ll] : If a broken symlink: lstat follow lstat
# : If a symlink : lstat follow stat
# : Otherwise : lstat
# - A[ll] : If a broken symlink: Lstat follow Lstat
# : If a symlink : Lstat follow Stat
# : Otherwise : Lstat
#
# or returns non-zero
${pfx}::match-by () {
emulate -L zsh
setopt extendedglob cbases octalzeroes
local arg REPLY name=$1 pfx=${0%::match-by}
shift
# init in local scope if not using global params
if ! [[ -v namecolors && -v modecolors ]]; then
local -A namecolors modecolors
${pfx}::init
fi
if [[ ${1:l} = (g|global) ]]; then
shift
else
local -a stat lstat
declare -ga reply=()
fi
zmodload -F zsh/stat b:zstat
for arg; do
case ${arg[1]:l} in
n|name)
${pfx}::from-name $name
reply+=("$REPLY")
;;
l|lstat)
(($#lstat)) || zstat -A lstat -L $name || return 1
if ((lstat[3] & 0170000 )); then
# follow symlink
(($#stat)) || zstat -A stat $name 2>/dev/null
fi
${pfx}::from-mode "$name" "$lstat[3]" $stat[3]
if [[ $REPLY || ${2[1]} = L ]]; then
reply+=("$REPLY")
else # fall back to name
"$0" "$name" g n
fi
;;
s|stat)
(($#stat)) || zstat -A stat $name || return 1
${pfx}::from-mode $name $stat[3]
reply+=("$REPLY")
if [[ $REPLY || ${arg[1]} = S ]]; then
reply+=("$REPLY")
else # fall back to name
"$0" "$name" g n
fi
;;
f|follow)
(($#lstat)) || zstat -A lstat -L $name || return 1
reply+=("$lstat[14]")
;;
a|all)
# Match case
"$0" "$name" g ${${${arg[1]%a}:+L}:-l}
# won't append if empty
reply+=($lstat[14])
# $stat[14] will be empty if not a symlink
if [[ $lstat[14] ]]; then
if [[ -e $name ]]; then
"$0" "$name" g ${${${arg[1]%a}:+S}:-s}
else
reply+=($reply[-2])
fi
fi
;;
*) return 2 ;;
esac
done
}
# }}}
# vim: set foldmethod=marker:

View File

@ -1,16 +0,0 @@
Makefile
META-FAQ
config.cache
config.h
config.h.in
config.log
config.modules
config.modules.sh
config.status
configure
cscope.out
stamp-h
stamp-h.in
autom4te.cache
*.swp
.git

View File

@ -1,4 +0,0 @@
DISTFILES_SRC='
META-FAQ
configure config.h.in stamp-h.in
'

View File

@ -1,15 +0,0 @@
# Top-most editorconfig file
root = true
[*]
end_of_line = lf
tab_width = 8
indent_size = 2
indent_style = tab
[ChangeLog]
indent_size = 8
[*.[ch]]
indent_size = 4

View File

@ -1,155 +0,0 @@
Makefile
tags
TAGS
*.o
*.o.c
*.orig
*.a
*.so
*.dll
*~
.*.sw?
\#*
/META-FAQ
/config.cache
/config.h
/config.log
/config.modules
/config.modules.sh
/config.status
/config.status.lineno
/cscope.out
/stamp-h
/autom4te.cache
Config/defs.mk
CVS
.#*
Doc/help
Doc/help.txt
Doc/help/[_a-zA-Z0-9]*
Doc/intro.pdf
Doc/intro.ps
Doc/intro.a4.pdf
Doc/intro.a4.ps
Doc/intro.us.pdf
Doc/intro.us.ps
Doc/version.yo
Doc/texi2html.conf
Doc/zsh*.1
Doc/zsh.texi
Doc/zsh.info*
Doc/*.html
Doc/zsh.aux
Doc/zsh.toc
Doc/zsh.cp
Doc/zsh.cps
Doc/zsh.fn
Doc/zsh.fns
Doc/zsh.ky
Doc/zsh.kys
Doc/zsh.pg
Doc/zsh.pgs
Doc/zsh.vr
Doc/zsh.vrs
Doc/zsh.log
Doc/zsh.dvi
Doc/zsh_a4.dvi
Doc/zsh_us.dvi
Doc/zsh.tp
Doc/zsh.tps
Doc/zsh.idx
Doc/zsh_*.ps
Doc/infodir
Doc/zsh.pdf
Doc/zsh_a4.pdf
Doc/zsh_us.pdf
Doc/Zsh/modlist.yo
Doc/Zsh/modmenu.yo
Doc/Zsh/manmodmenu.yo
Etc/FAQ
Etc/FAQ.html
Src/*.epro
Src/*.export
Src/*.mdh
Src/*.mdh.tmp
Src/*.mdhi
Src/*.mdhs
Src/*.syms
Src/Makemod.in
Src/Makemod
Src/[_a-zA-Z0-9]*.pro
Src/ansi2knr
Src/bltinmods.list
Src/cscope.out
Src/libzsh.so*
Src/modules-bltin
Src/modules.index
Src/modules.index.tmp
Src/modules.stamp
Src/patchlevel.h
Src/sigcount.h
Src/signames.c
Src/signames2.c
Src/stamp-modobjs
Src/stamp-modobjs.tmp
Src/tags
Src/TAGS
Src/version.h
Src/zsh
Src/zsh.exe
Src/zshcurses.h
Src/zshpaths.h
Src/zshterm.h
Src/zshxmods.h
Src/Builtins/Makefile.in
Src/Builtins/*.export
Src/Builtins/so_locations
Src/Builtins/*.pro
Src/Builtins/*.epro
Src/Builtins/*.syms
Src/Builtins/*.mdh
Src/Builtins/*.mdhi
Src/Builtins/*.mdhs
Src/Builtins/*.mdh.tmp
Src/Builtins/rlimits.h
Src/Modules/Makefile.in
Src/Modules/*.export
Src/Modules/so_locations
Src/Modules/*.pro
Src/Modules/*.epro
Src/Modules/*.syms
Src/Modules/*.mdh
Src/Modules/*.mdhi
Src/Modules/*.mdhs
Src/Modules/*.mdh.tmp
Src/Modules/errnames.c
Src/Modules/errcount.h
Src/Modules/curses_keys.h
Src/Zle/Makefile.in
Src/Zle/*.export
Src/Zle/so_locations
Src/Zle/*.pro
Src/Zle/*.epro
Src/Zle/*.syms
Src/Zle/*.mdh
Src/Zle/*.mdhi
Src/Zle/*.mdhs
Src/Zle/*.mdh.tmp
Src/Zle/thingies.list
Src/Zle/widgets.list
Src/Zle/zle_things.h
Src/Zle/zle_widget.h
Test/*.tmp
/.project

View File

@ -1,7 +0,0 @@
#! /bin/sh
set -e
autoconf
autoheader
echo > stamp-h.in

View File

@ -1,2 +0,0 @@
defs.mk
*.swp

View File

@ -1,2 +0,0 @@
DISTFILES_SRC='
'

View File

@ -1,8 +0,0 @@
AC_DEFUN([zsh_OOT],
[
AC_CHECK_HEADERS(stdarg.h varargs.h termios.h termio.h)
AC_TYPE_SIGNAL
AC_DEFINE([ZSH_OOT_MODULE], [], [Out-of-tree module])
])

View File

@ -1,43 +0,0 @@
#
# Makefile fragment for cleanup
#
# Copyright (c) 1995-1997 Richard Coleman
# All rights reserved.
#
# Permission is hereby granted, without written agreement and without
# license or royalty fees, to use, copy, modify, and distribute this
# software and to distribute modified versions of this software for any
# purpose, provided that the above copyright notice and the following
# two paragraphs appear in all copies of this software.
#
# In no event shall Richard Coleman or the Zsh Development Group be liable
# to any party for direct, indirect, special, incidental, or consequential
# damages arising out of the use of this software and its documentation,
# even if Richard Coleman and the Zsh Development Group have been advised of
# the possibility of such damage.
#
# Richard Coleman and the Zsh Development Group specifically disclaim any
# warranties, including, but not limited to, the implied warranties of
# merchantability and fitness for a particular purpose. The software
# provided hereunder is on an "as is" basis, and Richard Coleman and the
# Zsh Development Group have no obligation to provide maintenance,
# support, updates, enhancements, or modifications.
#
mostlyclean: mostlyclean-recursive mostlyclean-here
clean: clean-recursive clean-here
distclean: distclean-recursive distclean-here
realclean: realclean-recursive realclean-here
mostlyclean-here:
clean-here: mostlyclean-here
distclean-here: clean-here
realclean-here: distclean-here
mostlyclean-recursive clean-recursive distclean-recursive realclean-recursive:
@subdirs='$(SUBDIRS)'; if test -n "$$subdirs"; then \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$subdirs; do \
(cd $$subdir && $(MAKE) $(MAKEDEFS) $$target) || exit 1; \
done; \
fi

View File

@ -1,42 +0,0 @@
#
# Makefile fragment for building Makefiles
#
# Copyright (c) 1995-1997 Richard Coleman
# All rights reserved.
#
# Permission is hereby granted, without written agreement and without
# license or royalty fees, to use, copy, modify, and distribute this
# software and to distribute modified versions of this software for any
# purpose, provided that the above copyright notice and the following
# two paragraphs appear in all copies of this software.
#
# In no event shall Richard Coleman or the Zsh Development Group be liable
# to any party for direct, indirect, special, incidental, or consequential
# damages arising out of the use of this software and its documentation,
# even if Richard Coleman and the Zsh Development Group have been advised of
# the possibility of such damage.
#
# Richard Coleman and the Zsh Development Group specifically disclaim any
# warranties, including, but not limited to, the implied warranties of
# merchantability and fitness for a particular purpose. The software
# provided hereunder is on an "as is" basis, and Richard Coleman and the
# Zsh Development Group have no obligation to provide maintenance,
# support, updates, enhancements, or modifications.
#
config: Makefile
@subdirs='$(SUBDIRS)'; for subdir in $$subdirs; do \
(cd $$subdir && $(MAKE) $(MAKEDEFS) $@) || exit 1; \
done
CONFIG_INCS = \
$(dir_top)/Config/clean.mk $(dir_top)/Config/config.mk \
$(dir_top)/Config/defs.mk $(dir_top)/Config/version.mk
Makefile: Makefile.in $(dir_top)/config.status $(CONFIG_INCS)
cd $(dir_top) && \
$(SHELL) ./config.status `echo $(subdir)/$@ | sed 's%^./%%'`
$(dir_top)/Config/defs.mk: $(sdir_top)/Config/defs.mk.in $(dir_top)/config.status
cd $(dir_top) && \
$(SHELL) ./config.status Config/defs.mk

View File

@ -1,114 +0,0 @@
#
# Basic Makefile definitions
#
# Copyright (c) 1995-1997 Richard Coleman
# All rights reserved.
#
# Permission is hereby granted, without written agreement and without
# license or royalty fees, to use, copy, modify, and distribute this
# software and to distribute modified versions of this software for any
# purpose, provided that the above copyright notice and the following
# two paragraphs appear in all copies of this software.
#
# In no event shall Richard Coleman or the Zsh Development Group be liable
# to any party for direct, indirect, special, incidental, or consequential
# damages arising out of the use of this software and its documentation,
# even if Richard Coleman and the Zsh Development Group have been advised of
# the possibility of such damage.
#
# Richard Coleman and the Zsh Development Group specifically disclaim any
# warranties, including, but not limited to, the implied warranties of
# merchantability and fitness for a particular purpose. The software
# provided hereunder is on an "as is" basis, and Richard Coleman and the
# Zsh Development Group have no obligation to provide maintenance,
# support, updates, enhancements, or modifications.
#
# fundamentals
SHELL = /bin/sh
@SET_MAKE@
EXEEXT = @EXEEXT@
# headers
ZSH_CURSES_H = @ZSH_CURSES_H@
ZSH_TERM_H = @ZSH_TERM_H@
# install basename
tzsh = @tzsh@
# installation directories
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
libdir = @libdir@
MODDIR = $(libdir)/$(tzsh)/$(VERSION)
infodir = @infodir@
mandir = @mandir@
datarootdir = @datarootdir@
datadir = @datadir@
fndir = @fndir@
fixed_sitefndir = @fixed_sitefndir@
sitefndir = @sitefndir@
scriptdir = @scriptdir@
sitescriptdir = @sitescriptdir@
htmldir = @htmldir@
runhelpdir = @runhelpdir@
runhelp = @runhelp@
# compilation
CC = @CC@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
DEFS = @DEFS@
CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@
EXTRA_LDFLAGS = @EXTRA_LDFLAGS@
DLCFLAGS = @DLCFLAGS@
DLLDFLAGS = @DLLDFLAGS@
LIBLDFLAGS = @LIBLDFLAGS@
EXELDFLAGS = @EXELDFLAGS@
LIBS = @LIBS@
DL_EXT = @DL_EXT@
DLLD = @DLLD@
EXPOPT = @EXPOPT@
IMPOPT = @IMPOPT@
# utilities
AWK = @AWK@
ANSI2KNR = @ANSI2KNR@
YODL = @YODL@ @YODL_OPTIONS@
YODL2TXT = @YODL@2txt
YODL2HTML = @YODL@2html
# install utility
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
# variables used in determining what to install
FUNCTIONS_SUBDIRS = @FUNCTIONS_SUBDIRS@
# Additional fpath entries (eg. for vendor specific directories).
additionalfpath = @additionalfpath@
# flags passed to recursive makes in subdirectories
MAKEDEFS = \
prefix='$(prefix)' exec_prefix='$(exec_prefix)' bindir='$(bindir)' \
libdir='$(libdir)' MODDIR='$(MODDIR)' infodir='$(infodir)' mandir='$(mandir)' \
datadir='$(datadir)' fndir='$(fndir)' htmldir='$(htmldir)' runhelpdir='$(runhelpdir)' \
CC='$(CC)' CPPFLAGS='$(CPPFLAGS)' DEFS='$(DEFS)' CFLAGS='$(CFLAGS)' \
LDFLAGS='$(LDFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \
DLCFLAGS='$(DLCFLAGS)' DLLDFLAGS='$(DLLDFLAGS)' \
LIBLDFLAGS='$(LIBLDFLAGS)' EXELDFLAGS='$(EXELDFLAGS)' \
LIBS='$(LIBS)' DL_EXT='$(DL_EXT)' DLLD='$(DLLD)' \
AWK='$(AWK)' ANSI2KNR='$(ANSI2KNR)' \
YODL='$(YODL)' YODL2TXT='$(YODL2TXT)' YODL2HTML='$(YODL2HTML)' \
FUNCTIONS_INSTALL='$(FUNCTIONS_INSTALL)' tzsh='$(tzsh)'
# override built-in suffix list
.SUFFIXES:
# parallel build is not supported (pmake, gmake)
.NOTPARALLEL:
# parallel build is not supported (dmake)
.NO_PARALLEL:

View File

@ -1,74 +0,0 @@
#!/bin/sh
fndir=$DESTDIR$fndir
scriptdir=$DESTDIR$scriptdir
/bin/sh $sdir_top/mkinstalldirs $fndir || exit 1;
allfuncs="`grep ' functions=.' ${dir_top}/config.modules |
sed -e '/^#/d' -e '/ link=no/d' -e 's/^.* functions=//'`"
allfuncs="`cd $sdir_top; echo ${allfuncs}`"
test -d installfnsdir || mkdir installfnsdir
# We now have a list of files, but we need to use `test -f' to check
# (1) the glob got expanded (2) we are not looking at directories.
for file in $allfuncs; do
if test -f $sdir_top/$file; then
case "$file" in
*/CVS/*) continue;;
esac
if test x$FUNCTIONS_SUBDIRS != x && test x$FUNCTIONS_SUBDIRS != xno; then
case "$file" in
Completion/*/*)
subdir="`echo $file | sed -e 's%/[^/]*/[^/]*$%%'`"
instdir="$fndir/$subdir"
;;
Completion/*)
instdir="$fndir/Completion"
;;
Scripts/*)
instdir="$scriptdir"
;;
*)
subdir="`echo $file | sed -e 's%/[^/]*$%%' -e 's%^Functions/%%'`"
instdir="$fndir/$subdir"
;;
esac
else
case "$file" in
Scripts/*)
instdir="$scriptdir"
;;
*)
instdir="$fndir"
;;
esac
fi
basename=`basename $file`
ok=0
if test -d $instdir || /bin/sh $sdir_top/mkinstalldirs $instdir; then
if sed "s|@runhelpdir@|$runhelpdir|" <$sdir_top/$file \
>installfnsdir/$basename; then
if $INSTALL_DATA installfnsdir/$basename $instdir; then
ok=1
fi
fi
fi
case $ok in
0)
rm -rf installfnsdir
exit 1
;;
esac
read line < $sdir_top/$file
case "$line" in
'#!'*)
chmod +x $instdir/`echo $file | sed -e 's%^.*/%%'`
;;
esac
fi
done
rm -rf installfnsdir

View File

@ -1,59 +0,0 @@
#!/bin/sh
fndir=$DESTDIR$fndir
scriptdir=$DESTDIR$scriptdir
allfuncs="`grep ' functions=' ${dir_top}/config.modules |
sed -e '/^#/d' -e '/ link=no/d' -e 's/^.* functions=//'`"
allfuncs="`cd ${sdir_top}; echo ${allfuncs}`"
case $fndir in
*$VERSION*)
# Version specific function directory, safe to remove completely.
rm -rf $fndir
;;
*) # The following will only apply with a custom install directory
# with no version information. This is rather undesirable.
# But let's try and do the best we can.
# We now have a list of files, but we need to use `test -f' to check
# (1) the glob got expanded (2) we are not looking at directories.
for file in $allfuncs; do
case $file in
Scripts/*)
;;
*)
if test -f $sdir_top/$file; then
if test x$FUNCTIONS_SUBDIRS != x -a x$FUNCTIONS_SUBDIRS != xno; then
file=`echo $file | sed -e 's%%^(Functions|Completion)/%'`
rm -f $fndir/$file
else
bfile="`echo $file | sed -e 's%^.*/%%'`"
rm -f "$fndir/$bfile"
fi
fi
;;
esac
done
;;
esac
case $scriptdir in
*$VERSION*)
# $scriptdir might be the parent of fndir.
rm -rf $scriptdir
;;
*) for file in $allfuncs; do
case $file in
Scripts/*)
if test -f $sdir_top/$file; then
bfile="`echo $file | sed -e 's%^.*/%%'`"
rm -f "$scriptdir/$bfile"
fi
;;
esac
done
;;
esac
exit 0

View File

@ -1,31 +0,0 @@
#
# Makefile fragment for version numbers
#
# Copyright (c) 1995-1997 Richard Coleman
# All rights reserved.
#
# Permission is hereby granted, without written agreement and without
# license or royalty fees, to use, copy, modify, and distribute this
# software and to distribute modified versions of this software for any
# purpose, provided that the above copyright notice and the following
# two paragraphs appear in all copies of this software.
#
# In no event shall Richard Coleman or the Zsh Development Group be liable
# to any party for direct, indirect, special, incidental, or consequential
# damages arising out of the use of this software and its documentation,
# even if Richard Coleman and the Zsh Development Group have been advised of
# the possibility of such damage.
#
# Richard Coleman and the Zsh Development Group specifically disclaim any
# warranties, including, but not limited to, the implied warranties of
# merchantability and fitness for a particular purpose. The software
# provided hereunder is on an "as is" basis, and Richard Coleman and the
# Zsh Development Group have no obligation to provide maintenance,
# support, updates, enhancements, or modifications.
#
# This must also serve as a shell script, so do not add spaces around the
# `=' signs.
VERSION=5.3.1-dev-0
VERSION_DATE='December 22, 2016'

View File

@ -1,37 +0,0 @@
Unless otherwise noted in the header of specific files, files in this
distribution have the licence shown below.
However, note that certain shell functions are licensed under versions
of the GNU General Public Licence. Anyone distributing the shell as a
binary including those files needs to take account of this. Search
shell functions for "Copyright" for specific copyright information.
None of the core functions are affected by this, so those files may
simply be omitted.
--
The Z Shell is copyright (c) 1992-2017 Paul Falstad, Richard Coleman,
Zoltán Hidvégi, Andrew Main, Peter Stephenson, Sven Wischnowsky, and
others. All rights reserved. Individual authors, whether or not
specifically named, retain copyright in all changes; in what follows, they
are referred to as `the Zsh Development Group'. This is for convenience
only and this body has no legal status. The Z shell is distributed under
the following licence; any provisions made in individual files take
precedence.
Permission is hereby granted, without written agreement and without
licence or royalty fees, to use, copy, modify, and distribute this
software and to distribute modified versions of this software for any
purpose, provided that the above copyright notice and the following
two paragraphs appear in all copies of this software.
In no event shall the Zsh Development Group be liable to any party for
direct, indirect, special, incidental, or consequential damages arising out
of the use of this software and its documentation, even if the Zsh
Development Group have been advised of the possibility of such damage.
The Zsh Development Group specifically disclaim any warranties, including,
but not limited to, the implied warranties of merchantability and fitness
for a particular purpose. The software provided hereunder is on an "as is"
basis, and the Zsh Development Group have no obligation to provide
maintenance, support, updates, enhancements, or modifications.

View File

@ -1,87 +0,0 @@
#
# Makefile for top level of zsh distribution
#
# Copyright (c) 1995-1997 Richard Coleman
# All rights reserved.
#
# Permission is hereby granted, without written agreement and without
# license or royalty fees, to use, copy, modify, and distribute this
# software and to distribute modified versions of this software for any
# purpose, provided that the above copyright notice and the following
# two paragraphs appear in all copies of this software.
#
# In no event shall Richard Coleman or the Zsh Development Group be liable
# to any party for direct, indirect, special, incidental, or consequential
# damages arising out of the use of this software and its documentation,
# even if Richard Coleman and the Zsh Development Group have been advised of
# the possibility of such damage.
#
# Richard Coleman and the Zsh Development Group specifically disclaim any
# warranties, including, but not limited to, the implied warranties of
# merchantability and fitness for a particular purpose. The software
# provided hereunder is on an "as is" basis, and Richard Coleman and the
# Zsh Development Group have no obligation to provide maintenance,
# support, updates, enhancements, or modifications.
#
subdir = .
dir_top = .
SUBDIRS = Src
@VERSION_MK@
# source/build directories
VPATH = @srcdir@
sdir = @srcdir@
sdir_top = @top_srcdir@
INSTALL = @INSTALL@
@DEFS_MK@
# ========== DEPENDENCIES FOR BUILDING ==========
# default target
all: config.h config.modules
cd Src && $(MAKE) $(MAKEDEFS) $@
# prepare module configuration
prep:
@cd Src && $(MAKE) $(MAKEDEFS) $@
# ========== DEPENDENCIES FOR CLEANUP ==========
@CLEAN_MK@
distclean-here:
rm -f Makefile config.h config.status config.log config.cache config.modules config.modules.sh stamp-h Config/defs.mk
rm -rf autom4te.cache
realclean-here:
cd $(sdir) && rm -f config.h.in stamp-h.in configure
# ========== DEPENDENCIES FOR MAINTENANCE ==========
@CONFIG_MK@
config: config.h
config.status: $(sdir)/configure
$(SHELL) ./config.status --recheck
$(sdir)/configure: $(sdir)/aclocal.m4 $(sdir)/aczsh.m4 $(sdir)/configure.ac
cd $(sdir) && autoconf
config.h: stamp-h
stamp-h: $(sdir)/config.h.in config.status
cd $(dir_top) && $(SHELL) ./config.status config.h $@
config.modules: $(sdir)/config.h.in config.status config.modules.sh
cd $(dir_top) && $(SHELL) ./config.status $@ && \
$(SHELL) ./config.modules.sh
$(sdir)/config.h.in: $(sdir)/stamp-h.in
$(sdir)/stamp-h.in: $(sdir)/configure
cd $(sdir) && autoheader
echo > $(sdir)/stamp-h.in
FORCE:

View File

@ -1,35 +0,0 @@
*.dll
*.epro
*.export
*.mdh
*.mdh.tmp
*.mdhi
*.mdhs
*.o
*.o.c
*.so
*.swp
*.syms
Makefile
Makemod.in Makemod
[_a-zA-Z0-9]*.pro
ansi2knr
bltinmods.list
cscope.out
libzsh.so*
modules-bltin
modules.index
modules.index.tmp
modules.stamp
patchlevel.h
sigcount.h
signames.c signames2.c
stamp-modobjs
stamp-modobjs.tmp
tags TAGS
version.h
zsh
zshcurses.h
zshpaths.h
zshterm.h
zshxmods.h

View File

@ -1,2 +0,0 @@
DISTFILES_SRC='
'

View File

@ -1,2 +0,0 @@
set ai
set sw=4

View File

@ -1,27 +0,0 @@
--dont-format-comments
--procnames-start-lines
--no-parameter-indentation
--indent-level4
--line-comments-indentation4
--cuddle-else
--brace-indent0
--dont-star-comments
--blank-lines-after-declarations
--blank-lines-after-procedures
--no-blank-lines-after-commas
--comment-indentation33
--declaration-comment-column33
--no-comment-delimiters-on-blank-lines
--continuation-indentation4
--case-indentation0
--else-endif-column33
--no-space-after-casts
--no-blank-before-sizeof
--declaration-indentation0
--continue-at-parentheses
--no-space-after-function-call-names
--swallow-optional-blank-lines
--dont-space-special-semicolon
--tab-size8
--line-length132
--braces-on-if-line

View File

@ -1,164 +0,0 @@
#
# Makefile for Src subdirectory
#
# Copyright (c) 1995-1997 Richard Coleman
# All rights reserved.
#
# Permission is hereby granted, without written agreement and without
# license or royalty fees, to use, copy, modify, and distribute this
# software and to distribute modified versions of this software for any
# purpose, provided that the above copyright notice and the following
# two paragraphs appear in all copies of this software.
#
# In no event shall Richard Coleman or the Zsh Development Group be liable
# to any party for direct, indirect, special, incidental, or consequential
# damages arising out of the use of this software and its documentation,
# even if Richard Coleman and the Zsh Development Group have been advised of
# the possibility of such damage.
#
# Richard Coleman and the Zsh Development Group specifically disclaim any
# warranties, including, but not limited to, the implied warranties of
# merchantability and fitness for a particular purpose. The software
# provided hereunder is on an "as is" basis, and Richard Coleman and the
# Zsh Development Group have no obligation to provide maintenance,
# support, updates, enhancements, or modifications.
#
subdir = Src
dir_top = ..
SUBDIRS =
@VERSION_MK@
# source/build directories
VPATH = @srcdir@
sdir = @srcdir@
sdir_top = @top_srcdir@
INSTALL = @INSTALL@
LN = @LN@
@DEFS_MK@
sdir_src = $(sdir)
dir_src = .
# ========= DEPENDENCIES FOR BUILDING ==========
LINK = $(CC) $(LDFLAGS) $(EXELDFLAGS) $(EXTRA_LDFLAGS) -o $@
DLLINK = $(DLLD) $(LDFLAGS) $(LIBLDFLAGS) $(DLLDFLAGS) -o $@
all: zsh.export modules
.PHONY: all
modules: headers
.PHONY: modules
L = @L@
LSTMP =
LLIST =
NSTMP = stamp-modobjs
NLIST = `cat stamp-modobjs`
LIBZSH = libzsh-$(VERSION).$(DL_EXT)
NIBZSH =
INSTLIB = @INSTLIB@
UNINSTLIB = @UNINSTLIB@
ZSH_EXPORT = $(EXPOPT)zsh.export
ZSH_NXPORT =
ENTRYOBJ = modentry..o
NNTRYOBJ =
LDRUNPATH = LD_RUN_PATH=$(libdir)/$(tzsh)
NDRUNPATH =
EXTRAZSHOBJS = @EXTRAZSHOBJS@
stamp-modobjs: modobjs
@if cmp -s stamp-modobjs.tmp stamp-modobjs; then \
rm -f stamp-modobjs.tmp; \
echo "\`stamp-modobjs' is up to date."; \
else \
mv -f stamp-modobjs.tmp stamp-modobjs; \
echo "Updated \`stamp-modobjs'."; \
fi
modobjs: headers rm-modobjs-tmp
.PHONY: modobjs
rm-modobjs-tmp:
rm -f stamp-modobjs.tmp
.PHONY: rm-modobjs-tmp
@CONFIG_MK@
Makemod: $(CONFIG_INCS) $(dir_top)/config.modules
@case $(sdir_top) in \
/*) top_srcdir=$(sdir_top) ;; \
*) top_srcdir=$(subdir)/$(sdir_top) ;; \
esac; \
export top_srcdir; \
echo 'cd $(dir_top) && $(SHELL)' \
'$$top_srcdir/$(subdir)/mkmakemod.sh $(subdir) Makemod'; \
cd $(dir_top) && \
$(SHELL) $$top_srcdir/$(subdir)/mkmakemod.sh $(subdir) Makemod
prep: Makemod
@$(MAKE) -f Makemod $(MAKEDEFS) prep || rm -f Makemod
.PHONY: prep
FORCE:
.PHONY: FORCE
# ========== LINKING IN MODULES ==========
mymods.conf:
@echo Linking with the standard modules.
modules: $(@E@NTRYOBJ)
$(ENTRYOBJ): FORCE
@$(MAKE) -f Makemod $(MAKEDEFS) $@
# ========== DEPENDENCIES FOR CLEANUP ==========
# Since module cleanup rules depend on Makemod, they come first. This
# forces module stuff to get cleaned before Makemod itself gets
# deleted.
mostlyclean-here:
rm -f stamp-modobjs stamp-modobjs.tmp
.PHONY: mostlyclean-here
clean-here:
rm -f modules.stamp zsh$(EXEEXT)
rm -f libzsh-*.$(DL_EXT)
.PHONY: clean-here
distclean-here:
rm -f TAGS tags
rm -f Makefile
.PHONY: distclean-here
mostlyclean: mostlyclean-modules
clean: clean-modules
distclean: distclean-modules
realclean: realclean-modules
.PHONY: mostlyclean clean distclean realclean
# Don't remake Makemod just to delete things, even if it doesn't exist.
mostlyclean-modules clean-modules distclean-modules realclean-modules:
if test -f Makemod; then \
$(MAKE) -f Makemod $(MAKEDEFS) `echo $@ | sed 's/-modules//'`; \
fi; \
exit 0
.PHONY: mostlyclean-modules clean-modules distclean-modules \
realclean-modules
@CLEAN_MK@
# ========== RECURSIVE MAKES ==========
modobjs modules headers proto zsh.export: Makemod
@$(MAKE) -f Makemod $(MAKEDEFS) $@
.PHONY: headers proto

View File

@ -1,192 +0,0 @@
#
# Makemod.in.in
#
# Copyright (c) 1995-1997 Richard Coleman
# All rights reserved.
#
# Permission is hereby granted, without written agreement and without
# license or royalty fees, to use, copy, modify, and distribute this
# software and to distribute modified versions of this software for any
# purpose, provided that the above copyright notice and the following
# two paragraphs appear in all copies of this software.
#
# In no event shall Richard Coleman or the Zsh Development Group be liable
# to any party for direct, indirect, special, incidental, or consequential
# damages arising out of the use of this software and its documentation,
# even if Richard Coleman and the Zsh Development Group have been advised of
# the possibility of such damage.
#
# Richard Coleman and the Zsh Development Group specifically disclaim any
# warranties, including, but not limited to, the implied warranties of
# merchantability and fitness for a particular purpose. The software
# provided hereunder is on an "as is" basis, and Richard Coleman and the
# Zsh Development Group have no obligation to provide maintenance,
# support, updates, enhancements, or modifications.
#
# ========== OVERRIDABLE VARIABLES ==========
# subdir is done by mkmakemod.sh
# dir_top is done by mkmakemod.sh
# SUBDIRS is done by mkmakemod.sh
@VERSION_MK@
# source/build directories
VPATH = @srcdir@
sdir = @srcdir@
sdir_top = @top_srcdir@
INSTALL = @INSTALL@
@DEFS_MK@
sdir_src = $(sdir_top)/Src
dir_src = $(dir_top)/Src
# ========== COMPILATION RULES ==========
DNCFLAGS =
COMPILE = $(CC) -c -I. -I$(dir_top)/Src -I$(sdir_top)/Src -I$(sdir_top)/Src/Zle -I$(sdir) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(D@L@CFLAGS)
DLCOMPILE = $(CC) -c -I. -I$(dir_top)/Src -I$(sdir_top)/Src -I$(sdir_top)/Src/Zle -I$(sdir) $(CPPFLAGS) $(DEFS) -DMODULE $(CFLAGS) $(DLCFLAGS)
LINK = $(CC) $(LDFLAGS) $(EXELDFLAGS) $(EXTRA_LDFLAGS) -o $@
DLLINK = $(DLLD) $(LDFLAGS) $(LIBLDFLAGS) $(DLLDFLAGS) -o $@
KNR_OBJ=.o
KNROBJ=._foo_
ANSIOBJ=.o
ANSI_OBJ=._foo_
.SUFFIXES: .c .$(DL_EXT) ..o .._foo_ .o ._foo_ .syms .pro .epro
.c$(ANSI@U@OBJ):
$(COMPILE) -o $@ $<
@rm -f $(dir_src)/stamp-modobjs
.c$(KNR@U@OBJ):
@ANSI2KNR@ $< > $@.c
$(COMPILE) -o $@ $@.c
rm -f $@.c
@rm -f $(dir_src)/stamp-modobjs
.c.$(ANSI@U@OBJ):
$(DLCOMPILE) -o $@ $<
.c.$(KNR@U@OBJ):
@ANSI2KNR@ $< > $@.c
$(DLCOMPILE) -o $@ $@.c
rm -f $@.c
.c.syms:
$(AWK) -f $(sdir_src)/makepro.awk $< $(subdir) > $@
.syms.epro:
(echo '/* Generated automatically */'; sed -n '/^E/{s/^E//;p;}' < $<) \
> $@
(echo '/* Generated automatically */'; sed -n '/^L/{s/^L//;p;}' < $<) \
> `echo $@ | sed 's/\.epro$$/.pro/'`
PROTODEPS = $(sdir_src)/makepro.awk
# ========== DEPENDENCIES FOR BUILDING ==========
all: modobjs modules
.PHONY: all
modobjs: $(MODOBJS)
modules: $(MODULES)
headers: $(MDHS)
proto: $(PROTOS)
.PHONY: modobjs modules headers proto
prep:
@case $(sdir_top) in \
/*) top_srcdir=$(sdir_top) ;; \
*) top_srcdir=$(subdir)/$(sdir_top) ;; \
esac; \
export top_srcdir; \
cd $(dir_top) || exit 1; \
subdirs='$(SUBDIRS)'; \
for subdir in $$subdirs; do \
dir=$(subdir)/$$subdir; \
test -d $$dir || mkdir $$dir; \
$(SHELL) $$top_srcdir/Src/mkmakemod.sh $$dir Makefile || exit 1; \
( cd $$dir && $(MAKE) $(MAKEDEFS) $@ ) || exit 1; \
done
.PHONY: prep
headers: $(dir_src)/modules.stamp
$(dir_src)/modules.stamp: $(MDDS)
$(MAKE) -f $(makefile) $(MAKEDEFS) prep
echo 'timestamp for *.mdd files' > $@
.PHONY: headers
FORCE:
.PHONY: FORCE
# ========== DEPENDENCIES FOR INSTALLING ==========
install: install.bin install.modules
uninstall: uninstall.bin uninstall.modules
.PHONY: install uninstall
install.bin: install.bin-here
uninstall.bin: uninstall.bin-here
install.modules: install.modules-here
uninstall.modules: uninstall.modules-here
.PHONY: install.bin uninstall.bin install.modules uninstall.modules
install.bin-here uninstall.bin-here:
install.modules-here uninstall.modules-here:
.PHONY: install.bin-here install.modules-here
# ========== DEPENDENCIES FOR CLEANUP ==========
@CLEAN_MK@
mostlyclean-here:
rm -f *.o *.export *.$(DL_EXT)
.PHONY: mostlyclean-here
clean-here:
rm -f *.o.c *.syms *.pro *.epro *.mdh *.mdhi *.mdhs *.mdh.tmp
.PHONY: clean-here
distclean-here:
rm -f $(makefile) $(makefile).in
.PHONY: distclean-here
# ========== RECURSIVE MAKES ==========
install.bin uninstall.bin install.modules uninstall.modules \
modobjs modules headers proto:
@subdirs='$(SUBDIRS)'; for subdir in $$subdirs; do \
( cd $$subdir && $(MAKE) $(MAKEDEFS) $@ ) || exit 1; \
done
# ========== DEPENDENCIES FOR MAINTENANCE ==========
$(makefile): $(makefile).in $(dir_top)/config.status
@case $(sdir_top) in \
/*) top_srcdir=$(sdir_top) ;; \
*) top_srcdir=$(subdir)/$(sdir_top) ;; \
esac; \
export top_srcdir; \
echo 'cd $(dir_top) && $(SHELL)' \
'$$top_srcdir/Src/mkmakemod.sh -m $(subdir) $(makefile)'; \
cd $(dir_top) && \
$(SHELL) $$top_srcdir/Src/mkmakemod.sh -m $(subdir) $(makefile)
$(makefile).in: $(sdir_src)/mkmakemod.sh $(sdir_src)/Makemod.in.in $(MDDS) \
$(dir_top)/config.modules
@case $(sdir_top) in \
/*) top_srcdir=$(sdir_top) ;; \
*) top_srcdir=$(subdir)/$(sdir_top) ;; \
esac; \
export top_srcdir; \
echo 'cd $(dir_top) && $(SHELL)' \
'$$top_srcdir/Src/mkmakemod.sh -i $(subdir) $(makefile)'; \
cd $(dir_top) && \
$(SHELL) $$top_srcdir/Src/mkmakemod.sh -i $(subdir) $(makefile)

View File

@ -1,18 +0,0 @@
Makefile
Makefile.in
*.export
so_locations
*.pro
*.epro
*.syms
*.o
*.o.c
*.so
*.mdh
*.mdhi
*.mdhs
*.mdh.tmp
*.swp
errnames.c errcount.h
*.dll
curses_keys.h

View File

@ -1,2 +0,0 @@
DISTFILES_SRC='
'

View File

@ -1,2 +0,0 @@
set ai
set sw=4

View File

@ -1,8 +0,0 @@
Makefile.in
*.epro
*.export
*.mdh
*.mdhi
*.mdhs
*.pro
*.syms

View File

@ -1,543 +0,0 @@
#include "fzftab.mdh"
#include "fzftab.pro"
#include <stdarg.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
const char* get_color(char* file, const struct stat* sb);
const char* get_suffix(char* file, const struct stat* sb);
const char* colorize_from_mode(char* file, const struct stat* sb);
const char* colorize_from_name(char* file);
char** fzf_tab_colorize(char* file);
int compile_patterns(char* nam, char** list_colors);
char* ftb_strcat(char* dst, int n, ...);
/* Indixes into the terminal string arrays. */
#define COL_NO 0
#define COL_FI 1
#define COL_DI 2
#define COL_LN 3
#define COL_PI 4
#define COL_SO 5
#define COL_BD 6
#define COL_CD 7
#define COL_OR 8
#define COL_MI 9
#define COL_SU 10
#define COL_SG 11
#define COL_TW 12
#define COL_OW 13
#define COL_ST 14
#define COL_EX 15
#define COL_LC 16
#define COL_RC 17
#define COL_EC 18
#define COL_TC 19
#define COL_SP 20
#define COL_MA 21
#define COL_HI 22
#define COL_DU 23
#define COL_SA 24
#define NUM_COLS 25
/* Names of the terminal strings. */
static char* colnames[] = { "no", "fi", "di", "ln", "pi", "so", "bd", "cd", "or", "mi", "su", "sg",
"tw", "ow", "st", "ex", "lc", "rc", "ec", "tc", "sp", "ma", "hi", "du", "sa", NULL };
/* Default values. */
static char* defcols[]
= { "0", "0", "1;31", "1;36", "33", "1;35", "1;33", "1;33", NULL, NULL, "37;41", "30;43",
"30;42", "34;42", "37;44", "1;32", "\033[", "m", NULL, "0", "0", "7", NULL, NULL, "0" };
static char* fzf_tab_module_version;
struct pattern {
Patprog pat;
char color[50];
};
static int opt_list_type = OPT_INVALID;
static int pat_cnt = 0;
static struct pattern* name_color = NULL;
static char mode_color[NUM_COLS][20];
// TODO: use ZLS_COLORS ?
int compile_patterns(char* nam, char** list_colors)
{
// clean old name_color and set pat_cnt = 0
if (pat_cnt != 0) {
while (--pat_cnt) {
freepatprog(name_color[pat_cnt].pat);
}
free(name_color);
}
// initialize mode_color with default value
for (int i = 0; i < NUM_COLS; i++) {
if (defcols[i]) {
strcpy(mode_color[i], defcols[i]);
}
}
// empty array, just return
if (list_colors == NULL) {
return 0;
}
// how many pattens?
while (list_colors[pat_cnt] != NULL) {
pat_cnt++;
}
name_color = zshcalloc(pat_cnt * sizeof(struct pattern));
for (int i = 0; i < pat_cnt; i++) {
char* pat = ztrdup(list_colors[i]);
char* color = strrchr(pat, '=');
if (color == NULL)
continue;
*color = '\0';
tokenize(pat);
remnulargs(pat);
// mode=color
bool skip = false;
for (int j = 0; j < NUM_COLS; j++) {
if (strpfx(colnames[j], list_colors[i])) {
strcpy(mode_color[j], color + 1);
name_color[i].pat = NULL;
skip = true;
}
}
if (skip) {
continue;
}
// name=color
if (!(name_color[i].pat = patcompile(pat, PAT_ZDUP, NULL))) {
zwarnnam(nam, "bad pattern: %s", list_colors[i]);
return 1;
}
strcpy(name_color[i].color, color + 1);
free(pat);
}
return 0;
}
// TODO: use zsh mod_export function `file_type` ?
const char* get_suffix(char* file, const struct stat* sb)
{
struct stat sb2;
mode_t filemode = sb->st_mode;
if (S_ISBLK(filemode))
return "#";
else if (S_ISCHR(filemode))
return "%";
else if (S_ISDIR(filemode))
return "/";
else if (S_ISFIFO(filemode))
return "|";
else if (S_ISLNK(filemode))
if (strpfx(mode_color[COL_LN], "target")) {
if (stat(file, &sb2) == -1) {
return "@";
}
return get_suffix(file, &sb2);
} else {
return "@";
}
else if (S_ISREG(filemode))
return (filemode & S_IXUGO) ? "*" : "";
else if (S_ISSOCK(filemode))
return "=";
else
return "?";
}
const char* get_color(char* file, const struct stat* sb)
{
// no list-colors, return empty color
if (pat_cnt == 0) {
return "";
}
const char* ret;
if ((ret = colorize_from_mode(file, sb)) || (ret = colorize_from_name(file))) {
return ret;
}
return mode_color[COL_FI];
}
const char* colorize_from_name(char* file)
{
for (int i = 0; i < pat_cnt; i++) {
if (name_color && name_color[i].pat && pattry(name_color[i].pat, file)) {
return name_color[i].color;
}
}
return NULL;
}
const char* colorize_from_mode(char* file, const struct stat* sb)
{
struct stat sb2;
switch (sb->st_mode & S_IFMT) {
case S_IFDIR:
return mode_color[COL_DI];
case S_IFLNK: {
if (strpfx(mode_color[COL_LN], "target")) {
if (stat(file, &sb2) == -1) {
return mode_color[COL_OR];
}
return get_color(file, &sb2);
}
}
case S_IFIFO:
return mode_color[COL_PI];
case S_IFSOCK:
return mode_color[COL_SO];
case S_IFBLK:
return mode_color[COL_BD];
case S_IFCHR:
return mode_color[COL_CD];
default:
break;
}
if (sb->st_mode & S_ISUID) {
return mode_color[COL_SU];
} else if (sb->st_mode & S_ISGID) {
return mode_color[COL_SG];
// tw ow st ??
} else if (sb->st_mode & S_IXUSR) {
return mode_color[COL_EX];
}
/* Check for suffix alias */
size_t len = strlen(file);
/* shortest valid suffix format is a.b */
if (len > 2) {
const char* suf = file + len - 1;
while (suf > file + 1) {
if (suf[-1] == '.') {
if (sufaliastab->getnode(sufaliastab, suf)) {
return mode_color[COL_SA];
}
break;
}
suf--;
}
}
return NULL;
}
struct {
char** array;
size_t len;
size_t size;
} ftb_compcap;
// Usage:
// initialize fzf-tab-generate-compcap -i
// output to _ftb_compcap fzf-tab-generate-compcap -o
// add a entry fzf-tab-generate-compcap word desc opts
static int bin_fzf_tab_compcap_generate(char* nam, char** args, Options ops, UNUSED(int func))
{
if (OPT_ISSET(ops, 'o')) {
// write final result to _ftb_compcap
setaparam("_ftb_compcap", ftb_compcap.array);
ftb_compcap.array = NULL;
return 0;
} else if (OPT_ISSET(ops, 'i')) {
// init
if (ftb_compcap.array)
freearray(ftb_compcap.array);
ftb_compcap.array = zshcalloc(1024 * sizeof(char*));
ftb_compcap.len = 0, ftb_compcap.size = 1024;
return 0;
}
if (ftb_compcap.array == NULL) {
zwarnnam(nam, "please initialize it first");
return 1;
}
// get paramaters
char **words = getaparam(args[0]), **dscrs = getaparam(args[1]), *opts = getsparam(args[2]);
if (!words || !dscrs || !opts) {
zwarnnam(nam, "wrong argument");
return 1;
}
char *bs = metafy("\2", 1, META_DUP), *nul = metafy("\0word\0", 6, META_DUP);
size_t dscrs_cnt = arrlen(dscrs);
for (int i = 0; words[i]; i++) {
// TODO: replace '\n'
char* buffer = zshcalloc(256 * sizeof(char));
char* dscr = i < dscrs_cnt ? dscrs[i] : words[i];
buffer = ftb_strcat(buffer, 5, dscr, bs, opts, nul, words[i]);
ftb_compcap.array[ftb_compcap.len++] = buffer;
if (ftb_compcap.len == ftb_compcap.size) {
ftb_compcap.array
= zrealloc(ftb_compcap.array, (1024 + ftb_compcap.size) * sizeof(char*));
ftb_compcap.size += 1024;
memset(ftb_compcap.array + ftb_compcap.size - 1024, 0, 1024 * sizeof(char*));
}
}
zsfree(bs);
zsfree(nul);
return 0;
}
// cat n string, return the pointer to the new string
// `size` is the size of dst
// dst will be reallocated if is not big enough
char* ftb_strcat(char* dst, int n, ...)
{
va_list valist;
va_start(valist, n);
char* final = zrealloc(dst, 128);
size_t size = 128, max_len = 128 - 1;
dst = final;
for (int i = 0, idx = 0; i < n; i++) {
char* src = va_arg(valist, char*);
for (; *src != '\0'; dst++, src++, idx++) {
if (idx == max_len) {
size += size / 2;
final = zrealloc(final, size);
max_len = size - 1;
dst = &final[idx];
}
*dst = *src;
}
}
*dst = '\0';
va_end(valist);
return final;
}
// accept an
char** fzf_tab_colorize(char* file)
{
// TODO: can avoid so many zalloc here?
file = unmeta(file);
struct stat sb;
if (lstat(file, &sb) == -1) {
return NULL;
}
const char* suffix = "";
if (isset(opt_list_type)) {
suffix = get_suffix(file, &sb);
}
const char* color = get_color(file, &sb);
char* symlink = "";
const char* symcolor = "";
if ((sb.st_mode & S_IFMT) == S_IFLNK) {
symlink = zalloc(PATH_MAX);
int end = readlink(file, symlink, PATH_MAX);
symlink[end] = '\0';
if (stat(file, &sb) == -1) {
symcolor = mode_color[COL_OR];
} else {
char tmp[PATH_MAX];
realpath(file, tmp);
symcolor = get_color(file, &sb);
}
}
char** reply = zshcalloc((4 + 1) * sizeof(char*));
if (strlen(color) != 0) {
reply[0] = zalloc(128);
reply[1] = zalloc(128);
sprintf(reply[0], "%s%s%s", mode_color[COL_LC], color, mode_color[COL_RC]);
sprintf(reply[1], "%s%s%s", mode_color[COL_LC], "0", mode_color[COL_RC]);
} else {
reply[0] = ztrdup("");
reply[1] = ztrdup("");
}
reply[2] = ztrdup(suffix);
if (symlink[0] != '\0') {
reply[3] = zalloc(PATH_MAX);
sprintf(reply[3], "%s%s%s%s%s%s%s", mode_color[COL_LC], symcolor, mode_color[COL_RC],
symlink, mode_color[COL_LC], "0", mode_color[COL_RC]);
free(symlink);
} else {
reply[3] = ztrdup("");
}
for (int i = 0; i < 4; i++) {
reply[i] = metafy(reply[i], -1, META_REALLOC);
}
return reply;
}
static int bin_fzf_tab_candidates_generate(char* nam, char** args, Options ops, UNUSED(int func))
{
if (OPT_ISSET(ops, 'i')) {
// compile list_colors pattern
if (*args == NULL) {
zwarnnam(nam, "please specify an array");
return 1;
} else {
char** array = getaparam(*args);
return compile_patterns(nam, array);
}
}
char **ftb_compcap = getaparam("_ftb_compcap"), **group_colors = getaparam("group_colors"),
*default_color = getsparam("default_color"), *prefix = getsparam("prefix");
size_t group_colors_len = arrlen(group_colors);
size_t ftb_compcap_len = arrlen(ftb_compcap);
char *bs = metafy("\b", 1, META_DUP), *nul = metafy("\0", 1, META_DUP),
*soh = metafy("\2", 1, META_DUP);
char **candidates = zshcalloc(sizeof(char*) * (ftb_compcap_len + 1)),
*filepath = zshcalloc(PATH_MAX * sizeof(char)), *dpre = zshcalloc(128),
*dsuf = zshcalloc(128);
char* first_word = zshcalloc(512 * sizeof(char));
int same_word = 1;
for (int i = 0; i < ftb_compcap_len; i++) {
char *word = "", *group = NULL, *realdir = NULL;
strcpy(dpre, "");
strcpy(dsuf, "");
// extract all the variables what we need
char** compcap = sepsplit(ftb_compcap[i], soh, 1, 0);
char* desc = compcap[0];
char** info = sepsplit(compcap[1], nul, 1, 0);
for (int j = 0; info[j]; j += 2) {
if (!strcmp(info[j], "word")) {
word = info[j + 1];
// unquote word
parse_subst_string(word);
remnulargs(word);
untokenize(word);
} else if (!strcmp(info[j], "group")) {
group = info[j + 1];
} else if (!strcmp(info[j], "realdir")) {
realdir = info[j + 1];
}
}
// check if all the words are the same
if (i == 0) {
first_word = ftb_strcat(first_word, 1, word);
} else if (same_word && strcmp(word, first_word) != 0) {
same_word = 0;
}
// add character and color to describe the type of the files
if (realdir) {
filepath = ftb_strcat(filepath, 2, realdir, word);
char** reply = fzf_tab_colorize(filepath);
if (reply != NULL) {
dpre = ftb_strcat(dpre, 2, reply[1], reply[0]);
if (reply[3][0] != '\0') {
dsuf = ftb_strcat(dsuf, 4, reply[1], reply[2], " -> ", reply[3]);
} else {
dsuf = ftb_strcat(dsuf, 2, reply[1], reply[2]);
}
if (dpre[0] != '\0') {
setiparam("colorful", 1);
}
freearray(reply);
}
}
char* result = zshcalloc(256 * sizeof(char));
// add color to description if they have group index
if (group) {
// use strtol ?
int group_index = atoi(group);
char* color = group_index >= group_colors_len ? "" : group_colors[group_index - 1];
// add prefix
result = ftb_strcat(
result, 11, group, bs, color, prefix, dpre, nul, group, bs, desc, nul, dsuf);
} else {
result = ftb_strcat(result, 6, default_color, dpre, nul, desc, nul, dsuf);
}
// quotedzputs(result, stdout);
// putchar('\n');
candidates[i] = result;
freearray(info);
freearray(compcap);
}
setaparam("tcandidates", candidates);
setiparam("same_word", same_word);
zsfree(dpre);
zsfree(dsuf);
zsfree(filepath);
zsfree(first_word);
return 0;
}
static struct builtin bintab[] = {
BUILTIN("fzf-tab-compcap-generate", 0, bin_fzf_tab_compcap_generate, 0, -1, 0, "io", NULL),
BUILTIN("fzf-tab-candidates-generate", 0, bin_fzf_tab_candidates_generate, 0, -1, 0, "i", NULL),
};
static struct paramdef patab[] = {
STRPARAMDEF("FZF_TAB_MODULE_VERSION", &fzf_tab_module_version),
};
// clang-format off
static struct features module_features = {
bintab, sizeof(bintab) / sizeof(*bintab),
NULL, 0,
NULL, 0,
patab, sizeof(patab) / sizeof(*patab),
0,
};
// clang-format on
int setup_(UNUSED(Module m)) { return 0; }
int features_(Module m, char*** features)
{
*features = featuresarray(m, &module_features);
return 0;
}
int enables_(Module m, int** enables) { return handlefeatures(m, &module_features, enables); }
int boot_(UNUSED(Module m))
{
fzf_tab_module_version = ztrdup("0.2.2");
// different zsh version may have different value of list_type's index
// so query it dynamically
opt_list_type = optlookup("list_types");
return 0;
}
int cleanup_(UNUSED(Module m)) { return setfeatureenables(m, &module_features, NULL); }
int finish_(UNUSED(Module m))
{
printf("fzf-tab module unloaded.\n");
fflush(stdout);
return 0;
}

View File

@ -1,7 +0,0 @@
name=aloxaf/fzftab
link=dynamic
load=no
autofeatures="b:fzf-tab-colorize p:FZF_TAB_MODULE_VERSION"
objects="fzftab.o"

File diff suppressed because it is too large Load Diff

View File

@ -1,742 +0,0 @@
/*
* compat.c - compatibility routines for the deprived
*
* This file is part of zsh, the Z shell.
*
* Copyright (c) 1992-1997 Paul Falstad
* All rights reserved.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and to distribute modified versions of this software for any
* purpose, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* In no event shall Paul Falstad or the Zsh Development Group be liable
* to any party for direct, indirect, special, incidental, or consequential
* damages arising out of the use of this software and its documentation,
* even if Paul Falstad and the Zsh Development Group have been advised of
* the possibility of such damage.
*
* Paul Falstad and the Zsh Development Group specifically disclaim any
* warranties, including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose. The software
* provided hereunder is on an "as is" basis, and Paul Falstad and the
* Zsh Development Group have no obligation to provide maintenance,
* support, updates, enhancements, or modifications.
*
*/
#include "zsh.mdh"
#include "compat.pro"
/* Return pointer to first occurence of string t *
* in string s. Return NULL if not present. */
/**/
#ifndef HAVE_STRSTR
/**/
char *
strstr(const char *s, const char *t)
{
const char *p1, *p2;
for (; *s; s++) {
for (p1 = s, p2 = t; *p2; p1++, p2++)
if (*p1 != *p2)
break;
if (!*p2)
return (char *)s;
}
return NULL;
}
/**/
#endif
/**/
#ifndef HAVE_GETHOSTNAME
/**/
int
gethostname(char *name, size_t namelen)
{
struct utsname uts;
uname(&uts);
if(strlen(uts.nodename) >= namelen) {
errno = EINVAL;
return -1;
}
strcpy(name, uts.nodename);
return 0;
}
/**/
#endif
/**/
#ifndef HAVE_GETTIMEOFDAY
/**/
int
gettimeofday(struct timeval *tv, struct timezone *tz)
{
tv->tv_usec = 0;
tv->tv_sec = (long)time((time_t) 0);
return 0;
}
/**/
#endif
/* Provide clock time with nanoseconds */
/**/
mod_export int
zgettime(struct timespec *ts)
{
int ret = -1;
#ifdef HAVE_CLOCK_GETTIME
struct timespec dts;
if (clock_gettime(CLOCK_REALTIME, &dts) < 0) {
zwarn("unable to retrieve time: %e", errno);
ret--;
} else {
ret++;
ts->tv_sec = (time_t) dts.tv_sec;
ts->tv_nsec = (long) dts.tv_nsec;
}
#endif
if (ret) {
struct timeval dtv;
struct timezone dtz;
gettimeofday(&dtv, &dtz);
ret++;
ts->tv_sec = (time_t) dtv.tv_sec;
ts->tv_nsec = (long) dtv.tv_usec * 1000;
}
return ret;
}
/* compute the difference between two calendar times */
/**/
#ifndef HAVE_DIFFTIME
/**/
double
difftime(time_t t2, time_t t1)
{
return ((double)t2 - (double)t1);
}
/**/
#endif
/**/
#ifndef HAVE_STRERROR
extern char *sys_errlist[];
/* Get error message string associated with a particular *
* error number, and returns a pointer to that string. *
* This is not a particularly robust version of strerror. */
/**/
char *
strerror(int errnum)
{
return (sys_errlist[errnum]);
}
/**/
#endif
#if 0
/* pathconf(_PC_PATH_MAX) is not currently useful to zsh. The value *
* returned varies depending on a number of factors, e.g. the amount *
* of memory available to the operating system at a given time; thus *
* it can't be used for buffer allocation, or even as an indication *
* of whether an attempt to use or create a given pathname may fail *
* at any future time. *
* *
* The call is also permitted to fail if the argument path is not an *
* existing directory, so even to make sense of that one must search *
* for a valid directory somewhere in the path and adjust. Even if *
* it succeeds, the return value is relative to the input directory, *
* and therefore potentially relative to the length of the shortest *
* path either to that directory or to our working directory. *
* *
* Finally, see the note below for glibc; detection of pathconf() is *
* not by itself an indication that it works reliably. */
/* The documentation for pathconf() says something like: *
* The limit is returned, if one exists. If the system does *
* not have a limit for the requested resource, -1 is *
* returned, and errno is unchanged. If there is an error, *
* -1 is returned, and errno is set to reflect the nature of *
* the error. *
* *
* System calls are not permitted to set errno to 0; but we must (or *
* some other flag value) in order to determine that the resource is *
* unlimited. What use is leaving errno unchanged? Instead, define *
* a wrapper that resets errno to 0 and returns 0 for "the system *
* does not have a limit," so that -1 always means a real error. */
/**/
mod_export long
zpathmax(char *dir)
{
#ifdef HAVE_PATHCONF
long pathmax;
errno = 0;
if ((pathmax = pathconf(dir, _PC_PATH_MAX)) >= 0) {
/* Some versions of glibc pathconf return a hardwired value! */
return pathmax;
} else if (errno == EINVAL || errno == ENOENT || errno == ENOTDIR) {
/* Work backward to find a directory, until we run out of path. */
char *tail = strrchr(dir, '/');
while (tail > dir && tail[-1] == '/')
--tail;
if (tail > dir) {
*tail = 0;
pathmax = zpathmax(dir);
*tail = '/';
} else {
errno = 0;
if (tail)
pathmax = pathconf("/", _PC_PATH_MAX);
else
pathmax = pathconf(".", _PC_PATH_MAX);
}
if (pathmax > 0) {
long taillen = (tail ? strlen(tail) : (strlen(dir) + 1));
if (taillen < pathmax)
return pathmax - taillen;
else
errno = ENAMETOOLONG;
}
}
if (errno)
return -1;
else
return 0; /* pathmax should be considered unlimited */
#else
long dirlen = strlen(dir);
/* The following is wrong if dir is not an absolute path. */
return ((long) ((dirlen >= PATH_MAX) ?
((errno = ENAMETOOLONG), -1) :
((errno = 0), PATH_MAX - dirlen)));
#endif
}
#endif /* 0 */
/**/
#ifdef HAVE_SYSCONF
/*
* This is replaced by a macro from system.h if not HAVE_SYSCONF.
* 0 is returned by sysconf if _SC_OPEN_MAX is unavailable;
* -1 is returned on error
*
* Neither of these should happen, but resort to OPEN_MAX rather
* than return 0 or -1 just in case.
*
* We'll limit the open maximum to ZSH_INITIAL_OPEN_MAX to
* avoid probing ridiculous numbers of file descriptors.
*/
/**/
mod_export long
zopenmax(void)
{
long openmax;
if ((openmax = sysconf(_SC_OPEN_MAX)) < 1) {
openmax = OPEN_MAX;
} else if (openmax > OPEN_MAX) {
/* On some systems, "limit descriptors unlimited" or the *
* equivalent will set openmax to a huge number. Unless *
* there actually is a file descriptor > OPEN_MAX already *
* open, nothing in zsh requires the true maximum, and in *
* fact it causes inefficiency elsewhere if we report it. *
* So, report the maximum of OPEN_MAX or the largest open *
* descriptor (is there a better way to find that?). */
long i, j = OPEN_MAX;
if (openmax > ZSH_INITIAL_OPEN_MAX)
openmax = ZSH_INITIAL_OPEN_MAX;
for (i = j; i < openmax; i += (errno != EINTR)) {
errno = 0;
if (fcntl(i, F_GETFL, 0) < 0 &&
(errno == EBADF || errno == EINTR))
continue;
j = i;
}
openmax = j;
}
return (max_zsh_fd > openmax) ? max_zsh_fd : openmax;
}
/**/
#endif
/*
* Rationalise the current directory, returning the string.
*
* If "d" is not NULL, it is used to store information about the
* directory. The returned name is also present in d->dirname and is in
* permanently allocated memory. The handling of this case depends on
* whether the fchdir() system call is available; if it is, it is assumed
* the caller is able to restore the current directory. On successfully
* identifying the directory the function returns immediately rather
* than ascending the hierarchy.
*
* If "d" is NULL, no assumption about the caller's behaviour is
* made. The returned string is in heap memory. This case is
* always handled by changing directory up the hierarchy.
*
* On Cygwin or other systems where USE_GETCWD is defined (at the
* time of writing only QNX), we skip all the above and use the
* getcwd() system call.
*/
/**/
mod_export char *
zgetdir(struct dirsav *d)
{
char nbuf[PATH_MAX+3];
char *buf;
int bufsiz, pos;
struct stat sbuf;
ino_t pino;
dev_t pdev;
#if !defined(__CYGWIN__) && !defined(USE_GETCWD)
struct dirent *de;
DIR *dir;
dev_t dev;
ino_t ino;
int len;
#endif
buf = zhalloc(bufsiz = PATH_MAX+1);
pos = bufsiz - 1;
buf[pos] = '\0';
strcpy(nbuf, "../");
if (stat(".", &sbuf) < 0) {
return NULL;
}
/* Record the initial inode and device */
pino = sbuf.st_ino;
pdev = sbuf.st_dev;
if (d)
d->ino = pino, d->dev = pdev;
#if !defined(__CYGWIN__) && !defined(USE_GETCWD)
#ifdef HAVE_FCHDIR
else
#endif
holdintr();
for (;;) {
/* Examine the parent of the current directory. */
if (stat("..", &sbuf) < 0)
break;
/* Inode and device of curtent directory */
ino = pino;
dev = pdev;
/* Inode and device of current directory's parent */
pino = sbuf.st_ino;
pdev = sbuf.st_dev;
/* If they're the same, we've reached the root directory. */
if (ino == pino && dev == pdev) {
if (!buf[pos])
buf[--pos] = '/';
if (d) {
#ifndef HAVE_FCHDIR
zchdir(buf + pos);
noholdintr();
#endif
return d->dirname = ztrdup(buf + pos);
}
zchdir(buf + pos);
noholdintr();
return buf + pos;
}
/* Search the parent for the current directory. */
if (!(dir = opendir("..")))
break;
while ((de = readdir(dir))) {
char *fn = de->d_name;
/* Ignore `.' and `..'. */
if (fn[0] == '.' &&
(fn[1] == '\0' ||
(fn[1] == '.' && fn[2] == '\0')))
continue;
#ifdef HAVE_STRUCT_DIRENT_D_STAT
if(de->d_stat.st_dev == dev && de->d_stat.st_ino == ino) {
/* Found the directory we're currently in */
strncpy(nbuf + 3, fn, PATH_MAX);
break;
}
#else /* !HAVE_STRUCT_DIRENT_D_STAT */
# ifdef HAVE_STRUCT_DIRENT_D_INO
if (dev != pdev || (ino_t) de->d_ino == ino)
# endif /* HAVE_STRUCT_DIRENT_D_INO */
{
/* Maybe found directory, need to check device & inode */
strncpy(nbuf + 3, fn, PATH_MAX);
lstat(nbuf, &sbuf);
if (sbuf.st_dev == dev && sbuf.st_ino == ino)
break;
}
#endif /* !HAVE_STRUCT_DIRENT_D_STAT */
}
closedir(dir);
if (!de)
break; /* Not found */
/*
* We get the "/" free just by copying from nbuf+2 instead
* of nbuf+3, which is where we copied the path component.
* This means buf[pos] is always a "/".
*/
len = strlen(nbuf + 2);
pos -= len;
while (pos <= 1) {
char *newbuf = zhalloc(2*bufsiz);
memcpy(newbuf + bufsiz, buf, bufsiz);
buf = newbuf;
pos += bufsiz;
bufsiz *= 2;
}
memcpy(buf + pos, nbuf + 2, len);
#ifdef HAVE_FCHDIR
if (d)
return d->dirname = ztrdup(buf + pos + 1);
#endif
if (chdir(".."))
break;
}
/*
* Fix up the directory, if necessary.
* We're changing back down the hierarchy, ignore the
* "/" at buf[pos].
*/
if (d) {
#ifndef HAVE_FCHDIR
if (buf[pos])
zchdir(buf + pos + 1);
noholdintr();
#endif
return NULL;
}
if (buf[pos])
zchdir(buf + pos + 1);
noholdintr();
#else /* __CYGWIN__, USE_GETCWD cases */
if (!getcwd(buf, bufsiz)) {
if (d) {
return NULL;
}
} else {
if (d) {
return d->dirname = ztrdup(buf);
}
return buf;
}
#endif
/*
* Something bad happened.
* This has been seen when inside a special directory,
* such as the Netapp .snapshot directory, that doesn't
* appear as a directory entry in the parent directory.
* We'll just need our best guess.
*
* We only get here from zgetcwd(); let that fall back to pwd.
*/
return NULL;
}
/*
* Try to find the current directory.
* If we couldn't work it out internally, fall back to getcwd().
* If it fails, fall back to pwd; if zgetcwd() is being used
* to set pwd, pwd should be NULL and we just return ".".
*/
/**/
char *
zgetcwd(void)
{
char *ret = zgetdir(NULL);
#ifdef HAVE_GETCWD
if (!ret) {
#ifdef GETCWD_CALLS_MALLOC
char *cwd = getcwd(NULL, 0);
if (cwd) {
ret = dupstring(cwd);
free(cwd);
}
#else
char *cwdbuf = zalloc(PATH_MAX+1);
ret = getcwd(cwdbuf, PATH_MAX);
if (ret)
ret = dupstring(ret);
zfree(cwdbuf, PATH_MAX+1);
#endif /* GETCWD_CALLS_MALLOC */
}
#endif /* HAVE_GETCWD */
if (!ret)
ret = unmeta(pwd);
if (!ret)
ret = dupstring(".");
return ret;
}
/*
* chdir with arbitrary long pathname. Returns 0 on success, -1 on normal *
* failure and -2 when chdir failed and the current directory is lost.
*
* This is to be treated as if at system level, so dir is unmetafied but
* terminated by a NULL.
*/
/**/
mod_export int
zchdir(char *dir)
{
char *s;
int currdir = -2;
for (;;) {
if (!*dir || chdir(dir) == 0) {
#ifdef HAVE_FCHDIR
if (currdir >= 0)
close(currdir);
#endif
return 0;
}
if ((errno != ENAMETOOLONG && errno != ENOMEM) ||
strlen(dir) < PATH_MAX)
break;
for (s = dir + PATH_MAX - 1; s > dir && *s != '/'; s--)
;
if (s == dir)
break;
#ifdef HAVE_FCHDIR
if (currdir == -2)
currdir = open(".", O_RDONLY|O_NOCTTY);
#endif
*s = '\0';
if (chdir(dir) < 0) {
*s = '/';
break;
}
#ifndef HAVE_FCHDIR
currdir = -1;
#endif
*s = '/';
while (*++s == '/')
;
dir = s;
}
#ifdef HAVE_FCHDIR
if (currdir >= 0) {
if (fchdir(currdir) < 0) {
close(currdir);
return -2;
}
close(currdir);
return -1;
}
#endif
return currdir == -2 ? -1 : -2;
}
/*
* How to print out a 64 bit integer. This isn't needed (1) if longs
* are 64 bit, since ordinary %ld will work (2) if we couldn't find a
* 64 bit type anyway.
*/
/**/
#ifdef ZSH_64_BIT_TYPE
/**/
mod_export char *
output64(zlong val)
{
static char llbuf[DIGBUFSIZE];
convbase(llbuf, val, 0);
return llbuf;
}
/**/
#endif /* ZSH_64_BIT_TYPE */
/**/
#ifndef HAVE_STRTOUL
/*
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Convert a string to an unsigned long integer.
*
* Ignores `locale' stuff. Assumes that the upper and lower case
* alphabets and digits are each contiguous.
*/
/**/
unsigned long
strtoul(nptr, endptr, base)
const char *nptr;
char **endptr;
int base;
{
const char *s;
unsigned long acc, cutoff;
int c;
int neg, any, cutlim;
/* endptr may be NULL */
s = nptr;
do {
c = (unsigned char) *s++;
} while (isspace(c));
if (c == '-') {
neg = 1;
c = *s++;
} else {
neg = 0;
if (c == '+')
c = *s++;
}
if ((base == 0 || base == 16) &&
c == '0' && (*s == 'x' || *s == 'X')) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
cutoff = ULONG_MAX / (unsigned long)base;
cutlim = (int)(ULONG_MAX % (unsigned long)base);
for (acc = 0, any = 0;; c = (unsigned char) *s++) {
if (isdigit(c))
c -= '0';
else if (isalpha(c)) {
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
} else
break;
if (c >= base)
break;
if (any < 0)
continue;
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
any = -1;
acc = ULONG_MAX;
errno = ERANGE;
} else {
any = 1;
acc *= (unsigned long)base;
acc += c;
}
}
if (neg && any > 0)
acc = -acc;
if (endptr != NULL)
*endptr = any ? s - 1 : nptr;
return (acc);
}
/**/
#endif /* HAVE_STRTOUL */
/**/
#ifdef ENABLE_UNICODE9
#include "./wcwidth9.h"
/**/
int
u9_wcwidth(wchar_t ucs)
{
int w = wcwidth9(ucs);
if (w < -1)
return 1;
return w;
}
/**/
int
u9_iswprint(wint_t ucs)
{
if (ucs == 0)
return 0;
return wcwidth9(ucs) != -1;
}
/**/
#endif /* ENABLE_UNICODE9 */
/**/
#if defined(__APPLE__) && defined(BROKEN_ISPRINT)
/**/
int
isprint_ascii(int c)
{
if (!strcmp(nl_langinfo(CODESET), "UTF-8"))
return (c >= 0x20 && c <= 0x7e);
else
return isprint(c);
}
/**/
#endif /* __APPLE__ && BROKEN_ISPRINT */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,69 +0,0 @@
/*
* hashtable.h - header file for hash table handling code
*
* This file is part of zsh, the Z shell.
*
* Copyright (c) 1992-1997 Paul Falstad
* All rights reserved.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and to distribute modified versions of this software for any
* purpose, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* In no event shall Paul Falstad or the Zsh Development Group be liable
* to any party for direct, indirect, special, incidental, or consequential
* damages arising out of the use of this software and its documentation,
* even if Paul Falstad and the Zsh Development Group have been advised of
* the possibility of such damage.
*
* Paul Falstad and the Zsh Development Group specifically disclaim any
* warranties, including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose. The software
* provided hereunder is on an "as is" basis, and Paul Falstad and the
* Zsh Development Group have no obligation to provide maintenance,
* support, updates, enhancements, or modifications.
*
*/
/* Builtin function numbers; used by handler functions that handle more *
* than one builtin. Note that builtins such as compctl, that are not *
* overloaded, don't get a number. */
#define BIN_TYPESET 0
#define BIN_BG 1
#define BIN_FG 2
#define BIN_JOBS 3
#define BIN_WAIT 4
#define BIN_DISOWN 5
#define BIN_BREAK 6
#define BIN_CONTINUE 7
#define BIN_EXIT 8
#define BIN_RETURN 9
#define BIN_CD 10
#define BIN_POPD 11
#define BIN_PUSHD 12
#define BIN_PRINT 13
#define BIN_EVAL 14
#define BIN_SCHED 15
#define BIN_FC 16
#define BIN_R 17
#define BIN_PUSHLINE 18
#define BIN_LOGOUT 19
#define BIN_TEST 20
#define BIN_BRACKET 21
#define BIN_READONLY 22
#define BIN_ECHO 23
#define BIN_DISABLE 24
#define BIN_ENABLE 25
#define BIN_PRINTF 26
#define BIN_COMMAND 27
#define BIN_UNHASH 28
#define BIN_UNALIAS 29
#define BIN_UNFUNCTION 30
#define BIN_UNSET 31
/* These currently depend on being 0 and 1. */
#define BIN_SETOPT 0
#define BIN_UNSETOPT 1

File diff suppressed because it is too large Load Diff

View File

@ -1,701 +0,0 @@
/*
* input.c - read and store lines of input
*
* This file is part of zsh, the Z shell.
*
* Copyright (c) 1992-1997 Paul Falstad
* All rights reserved.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and to distribute modified versions of this software for any
* purpose, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* In no event shall Paul Falstad or the Zsh Development Group be liable
* to any party for direct, indirect, special, incidental, or consequential
* damages arising out of the use of this software and its documentation,
* even if Paul Falstad and the Zsh Development Group have been advised of
* the possibility of such damage.
*
* Paul Falstad and the Zsh Development Group specifically disclaim any
* warranties, including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose. The software
* provided hereunder is on an "as is" basis, and Paul Falstad and the
* Zsh Development Group have no obligation to provide maintenance,
* support, updates, enhancements, or modifications.
*
*/
/*
* This file deals with input buffering, supplying characters to the
* history expansion code a character at a time. Input is stored on a
* stack, which allows insertion of strings into the input, possibly with
* flags marking the end of alias expansion, with minimal copying of
* strings. The same stack is used to record the fact that the input
* is a history or alias expansion and to store the alias while it is in use.
*
* Input is taken either from zle, if appropriate, or read directly from
* the input file, or may be supplied by some other part of the shell (such
* as `eval' or $(...) substitution). In the last case, it should be
* supplied by pushing a new level onto the stack, via inpush(input_string,
* flag, alias); if the current input really needs to be altered, use
* inputsetline(input_string, flag). `Flag' can include or's of INP_FREE
* (if the input string is to be freed when used), INP_CONT (if the input
* is to continue onto what's already in the input queue), INP_ALIAS
* (push supplied alias onto stack) or INP_HIST (ditto, but used to
* mark history expansion). `alias' is ignored unless INP_ALIAS or
* INP_HIST is supplied. INP_ALIAS is always set if INP_HIST is.
*
* Note that the input string is itself used as the input buffer: it is not
* copied, nor is it every written back to, so using a constant string
* should work. Consequently, when passing areas of memory from the heap
* it is necessary that that heap last as long as the operation of reading
* the string. After the string is read, the stack should be popped with
* inpop(), which effectively flushes any unread input as well as restoring
* the previous input state.
*
* The internal flags INP_ALCONT and INP_HISTCONT show that the stack
* element was pushed by an alias or history expansion; they should not
* be needed elsewhere.
*
* The global variable inalmore is set to indicate aliases should
* continue to be expanded because the last alias expansion ended
* in a space. It is only reset after a complete word was read
* without expanding a new alias, in exalias().
*
* PWS 1996/12/10
*/
#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif
#include "zsh.mdh"
#include "input.pro"
/* the shell input fd */
/**/
int SHIN;
/* buffered shell input for non-interactive shells */
/**/
FILE *bshin;
/* != 0 means we are reading input from a string */
/**/
int strin;
/* total # of characters waiting to be read. */
/**/
mod_export int inbufct;
/* the flags controlling the input routines in input.c: see INP_* in zsh.h */
/**/
int inbufflags;
static char *inbuf; /* Current input buffer */
static char *inbufptr; /* Pointer into input buffer */
static char *inbufpush; /* Character at which to re-push alias */
static int inbufleft; /* Characters left in current input
stack element */
/* Input must be stacked since the input queue is used by
* various different parts of the shell.
*/
struct instacks {
char *buf, *bufptr;
Alias alias;
int bufleft, bufct, flags;
};
static struct instacks *instack, *instacktop;
/*
* Input stack size. We need to push the stack for aliases, history
* expansion, and reading from internal strings: only if these operations
* are nested do we need more than one extra level. Thus we shouldn't need
* too much space as a rule. Initially, INSTACK_INITIAL is allocated; if
* more is required, an extra INSTACK_EXPAND is added each time.
*/
#define INSTACK_INITIAL 4
#define INSTACK_EXPAND 4
static int instacksz = INSTACK_INITIAL;
/* Read a line from bshin. Convert tokens and *
* null characters to Meta c^32 character pairs. */
/**/
mod_export char *
shingetline(void)
{
char *line = NULL;
int ll = 0;
int c;
char buf[BUFSIZ];
char *p;
int q = queue_signal_level();
p = buf;
winch_unblock();
dont_queue_signals();
for (;;) {
/* Can't fgets() here because we need to accept '\0' bytes */
do {
errno = 0;
c = fgetc(bshin);
} while (c < 0 && errno == EINTR);
if (c < 0 || c == '\n') {
winch_block();
restore_queue_signals(q);
if (c == '\n')
*p++ = '\n';
if (p > buf) {
*p++ = '\0';
line = zrealloc(line, ll + (p - buf));
memcpy(line + ll, buf, p - buf);
}
return line;
}
if (imeta(c)) {
*p++ = Meta;
*p++ = c ^ 32;
} else
*p++ = c;
if (p >= buf + BUFSIZ - 1) {
winch_block();
queue_signals();
line = zrealloc(line, ll + (p - buf) + 1);
memcpy(line + ll, buf, p - buf);
ll += p - buf;
line[ll] = '\0';
p = buf;
winch_unblock();
dont_queue_signals();
}
}
}
/* Get the next character from the input.
* Will call inputline() to get a new line where necessary.
*/
/**/
int
ingetc(void)
{
int lastc = ' ';
if (lexstop)
return ' ';
for (;;) {
if (inbufleft) {
inbufleft--;
inbufct--;
if (itok(lastc = STOUC(*inbufptr++)))
continue;
if (((inbufflags & INP_LINENO) || !strin) && lastc == '\n')
lineno++;
break;
}
/*
* See if we have reached the end of input
* (due to an error, or to reading from a single string).
* Check the remaining characters left, since if there aren't
* any we don't want to pop the stack---it'll mark any aliases
* as not in use before we've finished processing.
*/
if (!inbufct && (strin || errflag)) {
lexstop = 1;
break;
}
/* If the next element down the input stack is a continuation of
* this, use it.
*/
if (inbufflags & INP_CONT) {
inpoptop();
continue;
}
/* As a last resort, get some more input */
if (inputline())
break;
}
if (!lexstop)
zshlex_raw_add(lastc);
return lastc;
}
/* Read a line from the current command stream and store it as input */
/**/
static int
inputline(void)
{
char *ingetcline, **ingetcpmptl = NULL, **ingetcpmptr = NULL;
int context = ZLCON_LINE_START;
/* If reading code interactively, work out the prompts. */
if (interact && isset(SHINSTDIN)) {
if (!isfirstln) {
ingetcpmptl = &prompt2;
if (rprompt2)
ingetcpmptr = &rprompt2;
context = ZLCON_LINE_CONT;
}
else {
ingetcpmptl = &prompt;
if (rprompt)
ingetcpmptr = &rprompt;
}
}
if (!(interact && isset(SHINSTDIN) && SHTTY != -1 && isset(USEZLE))) {
/*
* If not using zle, read the line straight from the input file.
* Possibly we don't get the whole line at once: in that case,
* we get another chunk with the next call to inputline().
*/
if (interact && isset(SHINSTDIN)) {
/*
* We may still be interactive (e.g. running under emacs),
* so output a prompt if necessary. We don't know enough
* about the input device to be able to handle an rprompt,
* though.
*/
char *pptbuf;
int pptlen;
pptbuf = unmetafy(promptexpand(ingetcpmptl ? *ingetcpmptl : NULL,
0, NULL, NULL, NULL), &pptlen);
write_loop(2, pptbuf, pptlen);
free(pptbuf);
}
ingetcline = shingetline();
} else {
/*
* Since we may have to read multiple lines before getting
* a complete piece of input, we tell zle not to restore the
* original tty settings after reading each chunk. Instead,
* this is done when the history mechanism for the current input
* terminates, which is not until we have the whole input.
* This is supposed to minimise problems on systems that clobber
* typeahead when the terminal settings are altered.
* pws 1998/03/12
*/
int flags = ZLRF_HISTORY|ZLRF_NOSETTY;
if (isset(IGNOREEOF))
flags |= ZLRF_IGNOREEOF;
ingetcline = zleentry(ZLE_CMD_READ, ingetcpmptl, ingetcpmptr,
flags, context);
histdone |= HISTFLAG_SETTY;
}
if (!ingetcline) {
return lexstop = 1;
}
if (errflag) {
free(ingetcline);
errflag |= ERRFLAG_ERROR;
return lexstop = 1;
}
if (isset(VERBOSE)) {
/* Output the whole line read so far. */
zputs(ingetcline, stderr);
fflush(stderr);
}
if (keyboardhackchar && *ingetcline &&
ingetcline[strlen(ingetcline) - 1] == '\n' &&
interact && isset(SHINSTDIN) &&
SHTTY != -1 && ingetcline[1])
{
char *stripptr = ingetcline + strlen(ingetcline) - 2;
if (*stripptr == keyboardhackchar) {
/* Junk an unwanted character at the end of the line.
(key too close to return key) */
int ct = 1; /* force odd */
char *ptr;
if (keyboardhackchar == '\'' || keyboardhackchar == '"' ||
keyboardhackchar == '`') {
/*
* for the chars above, also require an odd count before
* junking
*/
for (ct = 0, ptr = ingetcline; *ptr; ptr++)
if (*ptr == keyboardhackchar)
ct++;
}
if (ct & 1) {
stripptr[0] = '\n';
stripptr[1] = '\0';
}
}
}
isfirstch = 1;
if ((inbufflags & INP_APPEND) && inbuf) {
/*
* We need new input but need to be able to back up
* over the old input, so append this line.
* Pushing the line onto the stack doesn't have the right
* effect.
*
* This is quite a simple and inefficient fix, but currently
* we only need it when backing up over a multi-line $((...
* that turned out to be a command substitution rather than
* a math substitution, which is a very special case.
* So it's not worth rewriting.
*/
char *oinbuf = inbuf;
int newlen = strlen(ingetcline);
int oldlen = (int)(inbufptr - inbuf) + inbufleft;
if (inbufflags & INP_FREE) {
inbuf = realloc(inbuf, oldlen + newlen + 1);
} else {
inbuf = zalloc(oldlen + newlen + 1);
memcpy(inbuf, oinbuf, oldlen);
}
inbufptr += inbuf - oinbuf;
strcpy(inbuf + oldlen, ingetcline);
free(ingetcline);
inbufleft += newlen;
inbufct += newlen;
inbufflags |= INP_FREE;
} else {
/* Put this into the input channel. */
inputsetline(ingetcline, INP_FREE);
}
return 0;
}
/*
* Put a string in the input queue:
* inbuf is only freeable if the flags include INP_FREE.
*/
/**/
static void
inputsetline(char *str, int flags)
{
queue_signals();
if ((inbufflags & INP_FREE) && inbuf) {
free(inbuf);
}
inbuf = inbufptr = str;
inbufleft = strlen(inbuf);
/*
* inbufct must reflect the total number of characters left,
* as it used by other parts of the shell, so we need to take account
* of whether the input stack continues, and whether there
* is an extra space to add on at the end.
*/
if (flags & INP_CONT)
inbufct += inbufleft;
else
inbufct = inbufleft;
inbufflags = flags;
unqueue_signals();
}
/*
* Backup one character of the input.
* The last character can always be backed up, provided we didn't just
* expand an alias or a history reference.
* In fact, the character is ignored and the previous character is used.
* (If that's wrong, the bug is in the calling code. Use the #ifdef DEBUG
* code to check.)
*/
/**/
void
inungetc(int c)
{
if (!lexstop) {
if (inbufptr != inbuf) {
#ifdef DEBUG
/* Just for debugging: enable only if foul play suspected. */
if (inbufptr[-1] != (char) c)
fprintf(stderr, "Warning: backing up wrong character.\n");
#endif
/* Just decrement the pointer: if it's not the same
* character being pushed back, we're in trouble anyway.
*/
inbufptr--;
inbufct++;
inbufleft++;
if (((inbufflags & INP_LINENO) || !strin) && c == '\n')
lineno--;
}
else if (!(inbufflags & INP_CONT)) {
#ifdef DEBUG
/* Just for debugging */
fprintf(stderr, "Attempt to inungetc() at start of input.\n");
#endif
zerr("Garbled input at %c (binary file as commands?)", c);
return;
}
else {
/*
* The character is being backed up from a previous input stack
* layer. However, there was an expansion in the middle, so we
* can't back up where we want to. Instead, we just push it
* onto the input stack as an extra character.
*/
char *cback = (char *)zshcalloc(2);
cback[0] = (char) c;
inpush(cback, INP_FREE|INP_CONT, NULL);
}
/* If we are back at the start of a segment,
* we may need to restore an alias popped from the stack.
* Note this may be a dummy (history expansion) entry.
*/
if (inbufptr == inbufpush &&
(inbufflags & (INP_ALCONT|INP_HISTCONT))) {
/*
* Go back up the stack over all entries which were alias
* expansions and were pushed with nothing remaining to read.
*/
do {
if (instacktop->alias)
instacktop->alias->inuse = 1;
instacktop++;
} while ((instacktop->flags & (INP_ALCONT|INP_HISTCONT))
&& !instacktop->bufleft);
if (inbufflags & INP_HISTCONT)
inbufflags = INP_CONT|INP_ALIAS|INP_HIST;
else
inbufflags = INP_CONT|INP_ALIAS;
inbufleft = 0;
inbuf = inbufptr = "";
}
zshlex_raw_back();
}
}
/* stuff a whole file into the input queue and print it */
/**/
int
stuff(char *fn)
{
FILE *in;
char *buf;
off_t len;
if (!(in = fopen(unmeta(fn), "r"))) {
zerr("can't open %s", fn);
return 1;
}
fseek(in, 0, 2);
len = ftell(in);
fseek(in, 0, 0);
buf = (char *)zalloc(len + 1);
if (!(fread(buf, len, 1, in))) {
zerr("read error on %s", fn);
fclose(in);
zfree(buf, len + 1);
return 1;
}
fclose(in);
buf[len] = '\0';
fwrite(buf, len, 1, stderr);
fflush(stderr);
inputsetline(metafy(buf, len, META_REALLOC), INP_FREE);
return 0;
}
/* flush input queue */
/**/
void
inerrflush(void)
{
while (!lexstop && inbufct)
ingetc();
}
/* Set some new input onto a new element of the input stack */
/**/
mod_export void
inpush(char *str, int flags, Alias inalias)
{
if (!instack) {
/* Initial stack allocation */
instack = (struct instacks *)zalloc(instacksz*sizeof(struct instacks));
instacktop = instack;
}
instacktop->buf = inbuf;
instacktop->bufptr = inbufptr;
instacktop->bufleft = inbufleft;
instacktop->bufct = inbufct;
inbufflags &= ~(INP_ALCONT|INP_HISTCONT);
if (flags & (INP_ALIAS|INP_HIST)) {
/*
* Text is expansion for history or alias, so continue
* back to old level when done. Also mark stack top
* as alias continuation so as to back up if necessary,
* and mark alias as in use.
*/
flags |= INP_CONT|INP_ALIAS;
if (flags & INP_HIST)
instacktop->flags = inbufflags | INP_HISTCONT;
else
instacktop->flags = inbufflags | INP_ALCONT;
if ((instacktop->alias = inalias))
inalias->inuse = 1;
} else {
/* If we are continuing an alias expansion, record the alias
* expansion in new set of flags (do we need this?)
*/
if (((instacktop->flags = inbufflags) & INP_ALIAS) &&
(flags & INP_CONT))
flags |= INP_ALIAS;
}
instacktop++;
if (instacktop == instack + instacksz) {
/* Expand the stack */
instack = (struct instacks *)
realloc(instack,
(instacksz + INSTACK_EXPAND)*sizeof(struct instacks));
instacktop = instack + instacksz;
instacksz += INSTACK_EXPAND;
}
/*
* We maintain the entry above the highest one with real
* text as a flag to inungetc() that it can stop re-pushing the stack.
*/
instacktop->flags = 0;
inbufpush = inbuf = NULL;
inputsetline(str, flags);
}
/* Remove the top element of the stack */
/**/
static void
inpoptop(void)
{
if (!lexstop) {
inbufflags &= ~(INP_ALCONT|INP_HISTCONT);
while (inbufptr > inbuf) {
inbufptr--;
inbufct++;
inbufleft++;
/*
* As elsewhere in input and history mechanisms:
* unwinding aliases and unwinding history have different
* implications as aliases are after the lexer while
* history is before, but they're both pushed onto
* the input stack.
*/
if ((inbufflags & (INP_ALIAS|INP_HIST|INP_RAW_KEEP)) == INP_ALIAS)
zshlex_raw_back();
}
}
if (inbuf && (inbufflags & INP_FREE))
free(inbuf);
instacktop--;
inbuf = instacktop->buf;
inbufptr = inbufpush = instacktop->bufptr;
inbufleft = instacktop->bufleft;
inbufct = instacktop->bufct;
inbufflags = instacktop->flags;
if (!(inbufflags & (INP_ALCONT|INP_HISTCONT)))
return;
if (instacktop->alias) {
char *t = instacktop->alias->text;
/* a real alias: mark it as unused. */
instacktop->alias->inuse = 0;
if (*t && t[strlen(t) - 1] == ' ') {
inalmore = 1;
histbackword();
}
}
}
/* Remove the top element of the stack and all its continuations. */
/**/
mod_export void
inpop(void)
{
int remcont;
do {
remcont = inbufflags & INP_CONT;
inpoptop();
} while (remcont);
}
/*
* Expunge any aliases from the input stack; they shouldn't appear
* in the history and need to be flushed explicitly when we encounter
* an error.
*/
/**/
void
inpopalias(void)
{
while (inbufflags & INP_ALIAS)
inpoptop();
}
/*
* Get pointer to remaining string to read.
*/
/**/
char *
ingetptr(void)
{
return inbufptr;
}
/*
* Check if the current input line, including continuations, is
* expanding an alias. This does not detect alias expansions that
* have been fully processed and popped from the input stack.
* If there is an alias, the most recently expanded is returned,
* else NULL.
*/
/**/
char *input_hasalias(void)
{
int flags = inbufflags;
struct instacks *instackptr = instacktop;
for (;;)
{
if (!(flags & INP_CONT))
break;
instackptr--;
if (instackptr->alias)
return instackptr->alias->node.nam;
flags = instackptr->flags;
}
return NULL;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,795 +0,0 @@
/*
* loop.c - loop execution
*
* This file is part of zsh, the Z shell.
*
* Copyright (c) 1992-1997 Paul Falstad
* All rights reserved.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and to distribute modified versions of this software for any
* purpose, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* In no event shall Paul Falstad or the Zsh Development Group be liable
* to any party for direct, indirect, special, incidental, or consequential
* damages arising out of the use of this software and its documentation,
* even if Paul Falstad and the Zsh Development Group have been advised of
* the possibility of such damage.
*
* Paul Falstad and the Zsh Development Group specifically disclaim any
* warranties, including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose. The software
* provided hereunder is on an "as is" basis, and Paul Falstad and the
* Zsh Development Group have no obligation to provide maintenance,
* support, updates, enhancements, or modifications.
*
*/
#include "zsh.mdh"
#include "loop.pro"
/* # of nested loops we are in */
/**/
int loops;
/* # of continue levels */
/**/
mod_export int contflag;
/* # of break levels */
/**/
mod_export int breaks;
/**/
int
execfor(Estate state, int do_exec)
{
Wordcode end, loop;
wordcode code = state->pc[-1];
int iscond = (WC_FOR_TYPE(code) == WC_FOR_COND), ctok = 0, atok = 0;
int last = 0;
char *name, *str, *cond = NULL, *advance = NULL;
zlong val = 0;
LinkList vars = NULL, args = NULL;
int old_simple_pline = simple_pline;
/* See comments in execwhile() */
simple_pline = 1;
end = state->pc + WC_FOR_SKIP(code);
if (iscond) {
str = dupstring(ecgetstr(state, EC_NODUP, NULL));
singsub(&str);
if (isset(XTRACE)) {
char *str2 = dupstring(str);
untokenize(str2);
printprompt4();
fprintf(xtrerr, "%s\n", str2);
fflush(xtrerr);
}
if (!errflag) {
matheval(str);
}
if (errflag) {
state->pc = end;
simple_pline = old_simple_pline;
return 1;
}
cond = ecgetstr(state, EC_NODUP, &ctok);
advance = ecgetstr(state, EC_NODUP, &atok);
} else {
vars = ecgetlist(state, *state->pc++, EC_NODUP, NULL);
if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
int htok = 0;
if (!(args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok))) {
state->pc = end;
simple_pline = old_simple_pline;
return 0;
}
if (htok) {
execsubst(args);
if (errflag) {
state->pc = end;
simple_pline = old_simple_pline;
return 1;
}
}
} else {
char **x;
args = newlinklist();
for (x = pparams; *x; x++)
addlinknode(args, dupstring(*x));
}
}
if (!args || empty(args))
lastval = 0;
loops++;
pushheap();
cmdpush(CS_FOR);
loop = state->pc;
while (!last) {
if (iscond) {
if (ctok) {
str = dupstring(cond);
singsub(&str);
} else
str = cond;
if (!errflag) {
while (iblank(*str))
str++;
if (*str) {
if (isset(XTRACE)) {
printprompt4();
fprintf(xtrerr, "%s\n", str);
fflush(xtrerr);
}
val = mathevali(str);
} else
val = 1;
}
if (errflag) {
if (breaks)
breaks--;
lastval = 1;
break;
}
if (!val)
break;
} else {
LinkNode node;
int count = 0;
for (node = firstnode(vars); node; incnode(node))
{
name = (char *)getdata(node);
if (!args || !(str = (char *) ugetnode(args)))
{
if (count) {
str = "";
last = 1;
} else
break;
}
if (isset(XTRACE)) {
printprompt4();
fprintf(xtrerr, "%s=%s\n", name, str);
fflush(xtrerr);
}
setsparam(name, ztrdup(str));
count++;
}
if (!count)
break;
}
state->pc = loop;
execlist(state, 1, do_exec && args && empty(args));
if (breaks) {
breaks--;
if (breaks || !contflag)
break;
contflag = 0;
}
if (retflag)
break;
if (iscond && !errflag) {
if (atok) {
str = dupstring(advance);
singsub(&str);
} else
str = advance;
if (isset(XTRACE)) {
printprompt4();
fprintf(xtrerr, "%s\n", str);
fflush(xtrerr);
}
if (!errflag)
matheval(str);
}
if (errflag) {
if (breaks)
breaks--;
lastval = 1;
break;
}
freeheap();
}
popheap();
cmdpop();
loops--;
simple_pline = old_simple_pline;
state->pc = end;
this_noerrexit = 1;
return lastval;
}
/**/
int
execselect(Estate state, UNUSED(int do_exec))
{
Wordcode end, loop;
wordcode code = state->pc[-1];
char *str, *s, *name;
LinkNode n;
int i, usezle;
FILE *inp;
size_t more;
LinkList args;
int old_simple_pline = simple_pline;
/* See comments in execwhile() */
simple_pline = 1;
end = state->pc + WC_FOR_SKIP(code);
name = ecgetstr(state, EC_NODUP, NULL);
if (WC_SELECT_TYPE(code) == WC_SELECT_PPARAM) {
char **x;
args = newlinklist();
for (x = pparams; *x; x++)
addlinknode(args, dupstring(*x));
} else {
int htok = 0;
if (!(args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok))) {
state->pc = end;
simple_pline = old_simple_pline;
return 0;
}
if (htok) {
execsubst(args);
if (errflag) {
state->pc = end;
simple_pline = old_simple_pline;
return 1;
}
}
}
if (!args || empty(args)) {
state->pc = end;
simple_pline = old_simple_pline;
return 0;
}
loops++;
pushheap();
cmdpush(CS_SELECT);
usezle = interact && SHTTY != -1 && isset(USEZLE);
inp = fdopen(dup(usezle ? SHTTY : 0), "r");
more = selectlist(args, 0);
loop = state->pc;
for (;;) {
for (;;) {
if (empty(bufstack)) {
if (usezle) {
int oef = errflag;
isfirstln = 1;
str = zleentry(ZLE_CMD_READ, &prompt3, NULL,
0, ZLCON_SELECT);
if (errflag)
str = NULL;
/* Keep any user interrupt error status */
errflag = oef | (errflag & ERRFLAG_INT);
} else {
str = promptexpand(prompt3, 0, NULL, NULL, NULL);
zputs(str, stderr);
free(str);
fflush(stderr);
str = fgets(zhalloc(256), 256, inp);
}
} else
str = (char *)getlinknode(bufstack);
if (!str && !errflag)
setsparam("REPLY", ztrdup("")); /* EOF (user pressed Ctrl+D) */
if (!str || errflag) {
if (breaks)
breaks--;
fprintf(stderr, "\n");
fflush(stderr);
goto done;
}
if ((s = strchr(str, '\n')))
*s = '\0';
if (*str)
break;
more = selectlist(args, more);
}
setsparam("REPLY", ztrdup(str));
i = atoi(str);
if (!i)
str = "";
else {
for (i--, n = firstnode(args); n && i; incnode(n), i--);
if (n)
str = (char *) getdata(n);
else
str = "";
}
setsparam(name, ztrdup(str));
state->pc = loop;
execlist(state, 1, 0);
freeheap();
if (breaks) {
breaks--;
if (breaks || !contflag)
break;
contflag = 0;
}
if (retflag || errflag)
break;
}
done:
cmdpop();
popheap();
fclose(inp);
loops--;
simple_pline = old_simple_pline;
state->pc = end;
this_noerrexit = 1;
return lastval;
}
/* And this is used to print select lists. */
/**/
size_t
selectlist(LinkList l, size_t start)
{
size_t longest = 1, fct, fw = 0, colsz, t0, t1, ct;
char **arr, **ap;
zleentry(ZLE_CMD_TRASH);
arr = hlinklist2array(l, 0);
for (ap = arr; *ap; ap++)
if (strlen(*ap) > longest)
longest = strlen(*ap);
t0 = ct = ap - arr;
longest++;
while (t0)
t0 /= 10, longest++;
/* to compensate for added ')' */
fct = (zterm_columns - 1) / (longest + 3);
if (fct == 0)
fct = 1;
else
fw = (zterm_columns - 1) / fct;
colsz = (ct + fct - 1) / fct;
for (t1 = start; t1 != colsz && t1 - start < zterm_lines - 2; t1++) {
ap = arr + t1;
do {
size_t t2 = strlen(*ap) + 2;
int t3;
fprintf(stderr, "%d) %s", t3 = ap - arr + 1, *ap);
while (t3)
t2++, t3 /= 10;
for (; t2 < fw; t2++)
fputc(' ', stderr);
for (t0 = colsz; t0 && *ap; t0--, ap++);
}
while (*ap);
fputc('\n', stderr);
}
/* Below is a simple attempt at doing it the Korn Way..
ap = arr;
t0 = 0;
do {
t0++;
fprintf(stderr,"%d) %s\n",t0,*ap);
ap++;
}
while (*ap);*/
fflush(stderr);
return t1 < colsz ? t1 : 0;
}
/**/
int
execwhile(Estate state, UNUSED(int do_exec))
{
Wordcode end, loop;
wordcode code = state->pc[-1];
int olderrexit, oldval, isuntil = (WC_WHILE_TYPE(code) == WC_WHILE_UNTIL);
int old_simple_pline = simple_pline;
end = state->pc + WC_WHILE_SKIP(code);
olderrexit = noerrexit;
oldval = 0;
pushheap();
cmdpush(isuntil ? CS_UNTIL : CS_WHILE);
loops++;
loop = state->pc;
if (loop[0] == WC_END && loop[1] == WC_END) {
/* This is an empty loop. Make sure the signal handler sets the
* flags and then just wait for someone hitting ^C. */
simple_pline = 1;
while (!breaks)
;
breaks--;
simple_pline = old_simple_pline;
} else
for (;;) {
state->pc = loop;
noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN;
/* In case the test condition is a functional no-op,
* make sure signal handlers recognize ^C to end the loop. */
simple_pline = 1;
execlist(state, 1, 0);
simple_pline = old_simple_pline;
noerrexit = olderrexit;
if (!((lastval == 0) ^ isuntil)) {
if (breaks)
breaks--;
if (!retflag)
lastval = oldval;
break;
}
if (retflag)
break;
/* In case the loop body is also a functional no-op,
* make sure signal handlers recognize ^C as above. */
simple_pline = 1;
execlist(state, 1, 0);
simple_pline = old_simple_pline;
if (breaks) {
breaks--;
if (breaks || !contflag)
break;
contflag = 0;
}
if (errflag) {
lastval = 1;
break;
}
if (retflag)
break;
freeheap();
oldval = lastval;
}
cmdpop();
popheap();
loops--;
state->pc = end;
this_noerrexit = 1;
return lastval;
}
/**/
int
execrepeat(Estate state, UNUSED(int do_exec))
{
Wordcode end, loop;
wordcode code = state->pc[-1];
int count, htok = 0;
char *tmp;
int old_simple_pline = simple_pline;
/* See comments in execwhile() */
simple_pline = 1;
end = state->pc + WC_REPEAT_SKIP(code);
lastval = 0;
tmp = ecgetstr(state, EC_DUPTOK, &htok);
if (htok)
singsub(&tmp);
count = mathevali(tmp);
if (errflag)
return 1;
pushheap();
cmdpush(CS_REPEAT);
loops++;
loop = state->pc;
while (count-- > 0) {
state->pc = loop;
execlist(state, 1, 0);
freeheap();
if (breaks) {
breaks--;
if (breaks || !contflag)
break;
contflag = 0;
}
if (errflag) {
lastval = 1;
break;
}
if (retflag)
break;
}
cmdpop();
popheap();
loops--;
simple_pline = old_simple_pline;
state->pc = end;
this_noerrexit = 1;
return lastval;
}
/**/
int
execif(Estate state, int do_exec)
{
Wordcode end, next;
wordcode code = state->pc[-1];
int olderrexit, s = 0, run = 0;
olderrexit = noerrexit;
end = state->pc + WC_IF_SKIP(code);
noerrexit |= NOERREXIT_EXIT | NOERREXIT_RETURN;
while (state->pc < end) {
code = *state->pc++;
if (wc_code(code) != WC_IF ||
(run = (WC_IF_TYPE(code) == WC_IF_ELSE))) {
if (run)
run = 2;
break;
}
next = state->pc + WC_IF_SKIP(code);
cmdpush(s ? CS_ELIF : CS_IF);
execlist(state, 1, 0);
cmdpop();
if (!lastval) {
run = 1;
break;
}
if (retflag)
break;
s = 1;
state->pc = next;
}
if (run) {
/* we need to ignore lastval until we reach execcmd() */
if (olderrexit)
noerrexit = olderrexit;
else if (lastval)
noerrexit |= NOERREXIT_EXIT | NOERREXIT_RETURN | NOERREXIT_UNTIL_EXEC;
else
noerrexit &= ~ (NOERREXIT_EXIT | NOERREXIT_RETURN);
cmdpush(run == 2 ? CS_ELSE : (s ? CS_ELIFTHEN : CS_IFTHEN));
execlist(state, 1, do_exec);
cmdpop();
} else {
noerrexit = olderrexit;
if (!retflag)
lastval = 0;
}
state->pc = end;
this_noerrexit = 1;
return lastval;
}
/**/
int
execcase(Estate state, int do_exec)
{
Wordcode end, next;
wordcode code = state->pc[-1];
char *word, *pat;
int npat, save, nalts, ialt, patok, anypatok;
Patprog *spprog, pprog;
end = state->pc + WC_CASE_SKIP(code);
word = ecgetstr(state, EC_DUP, NULL);
singsub(&word);
untokenize(word);
anypatok = 0;
cmdpush(CS_CASE);
while (state->pc < end) {
code = *state->pc++;
if (wc_code(code) != WC_CASE)
break;
save = 0;
next = state->pc + WC_CASE_SKIP(code);
nalts = *state->pc++;
ialt = patok = 0;
if (isset(XTRACE)) {
printprompt4();
fprintf(xtrerr, "case %s (", word);
}
while (!patok && nalts) {
npat = state->pc[1];
spprog = state->prog->pats + npat;
pprog = NULL;
pat = NULL;
queue_signals();
if (isset(XTRACE)) {
int htok = 0;
pat = dupstring(ecrawstr(state->prog, state->pc, &htok));
if (htok)
singsub(&pat);
if (ialt++)
fprintf(stderr, " | ");
quote_tokenized_output(pat, xtrerr);
}
if (*spprog != dummy_patprog1 && *spprog != dummy_patprog2)
pprog = *spprog;
if (!pprog) {
if (!pat) {
char *opat;
int htok = 0;
pat = dupstring(opat = ecrawstr(state->prog,
state->pc, &htok));
if (htok)
singsub(&pat);
save = (!(state->prog->flags & EF_HEAP) &&
!strcmp(pat, opat) && *spprog != dummy_patprog2);
}
if (!(pprog = patcompile(pat, (save ? PAT_ZDUP : PAT_STATIC),
NULL)))
zerr("bad pattern: %s", pat);
else if (save)
*spprog = pprog;
}
if (pprog && pattry(pprog, word))
patok = anypatok = 1;
state->pc += 2;
nalts--;
unqueue_signals();
}
state->pc += 2 * nalts;
if (isset(XTRACE)) {
fprintf(xtrerr, ")\n");
fflush(xtrerr);
}
if (patok) {
execlist(state, 1, ((WC_CASE_TYPE(code) == WC_CASE_OR) &&
do_exec));
while (!retflag && wc_code(code) == WC_CASE &&
WC_CASE_TYPE(code) == WC_CASE_AND && state->pc < end) {
state->pc = next;
code = *state->pc++;
next = state->pc + WC_CASE_SKIP(code);
nalts = *state->pc++;
state->pc += 2 * nalts;
execlist(state, 1, ((WC_CASE_TYPE(code) == WC_CASE_OR) &&
do_exec));
}
if (WC_CASE_TYPE(code) != WC_CASE_TESTAND)
break;
}
state->pc = next;
}
cmdpop();
state->pc = end;
if (!anypatok)
lastval = 0;
this_noerrexit = 1;
return lastval;
}
/*
* Errflag from `try' block, may be reset in `always' block.
* Accessible from an integer parameter, so needs to be a zlong.
*/
/**/
zlong
try_errflag = -1;
/**
* Corresponding interrupt error status form `try' block.
*/
/**/
zlong
try_interrupt = -1;
/**/
zlong
try_tryflag = 0;
/**/
int
exectry(Estate state, int do_exec)
{
Wordcode end, always;
int endval;
int save_retflag, save_breaks, save_contflag;
zlong save_try_errflag, save_try_tryflag, save_try_interrupt;
end = state->pc + WC_TRY_SKIP(state->pc[-1]);
always = state->pc + 1 + WC_TRY_SKIP(*state->pc);
state->pc++;
pushheap();
cmdpush(CS_CURSH);
/* The :try clause */
save_try_tryflag = try_tryflag;
try_tryflag = 1;
execlist(state, 1, do_exec);
try_tryflag = save_try_tryflag;
/* Don't record errflag here, may be reset. However, */
/* endval should show failure when there is an error. */
endval = lastval ? lastval : errflag;
freeheap();
cmdpop();
cmdpush(CS_ALWAYS);
/* The always clause. */
save_try_errflag = try_errflag;
save_try_interrupt = try_interrupt;
try_errflag = (zlong)(errflag & ERRFLAG_ERROR);
try_interrupt = (zlong)((errflag & ERRFLAG_INT) ? 1 : 0);
/* We need to reset all errors to allow the block to execute */
errflag = 0;
save_retflag = retflag;
retflag = 0;
save_breaks = breaks;
breaks = 0;
save_contflag = contflag;
contflag = 0;
state->pc = always;
execlist(state, 1, do_exec);
if (try_errflag)
errflag |= ERRFLAG_ERROR;
else
errflag &= ~ERRFLAG_ERROR;
if (try_interrupt)
errflag |= ERRFLAG_INT;
else
errflag &= ~ERRFLAG_INT;
try_errflag = save_try_errflag;
try_interrupt = save_try_interrupt;
if (!retflag)
retflag = save_retflag;
if (!breaks)
breaks = save_breaks;
if (!contflag)
contflag = save_contflag;
cmdpop();
popheap();
state->pc = end;
return endval;
}

View File

@ -1,166 +0,0 @@
#
# makepro.awk - generate prototype lists
#
BEGIN {
aborting = 0
# arg 1 is the name of the file to process
# arg 2 is the name of the subdirectory it is in
if(ARGC != 3) {
aborting = 1
exit 1
}
name = ARGV[1]
gsub(/^.*\//, "", name)
gsub(/\.c$/, "", name)
name = ARGV[2] "_" name
gsub(/\//, "_", name)
ARGC--
printf "E#ifndef have_%s_globals\n", name
printf "E#define have_%s_globals\n", name
printf "E\n"
}
# all relevant declarations are preceded by "/**/" on a line by itself
/^\/\*\*\/$/ {
# The declaration is on following lines. The interesting part might
# be terminated by a `{' (`int foo(void) { }' or `int bar[] = {')
# or `;' (`int x;').
line = ""
isfunc = 0
while(1) {
if(getline <= 0) {
aborting = 1
exit 1
}
if (line == "" && $0 ~ /^[ \t]*#/) {
# Directly after the /**/ was a preprocessor line.
# Spit it out and re-start the outer loop.
printf "E%s\n", $0
printf "L%s\n", $0
next
}
gsub(/\t/, " ")
line = line " " $0
gsub(/\/\*([^*]|\*+[^*\/])*\*+\//, " ", line)
if(line ~ /\/\*/)
continue
# If it is a function definition, note so.
if(line ~ /\) *(VA_DCL )*[{].*$/) #}
isfunc = 1
if(sub(/ *[{;].*$/, "", line)) #}
break
}
if (!match(line, /VA_ALIST/)) {
# Put spaces around each identifier.
while(match(line, /[^_0-9A-Za-z ][_0-9A-Za-z]/) ||
match(line, /[_0-9A-Za-z][^_0-9A-Za-z ]/))
line = substr(line, 1, RSTART) " " substr(line, RSTART+1)
}
# Separate declarations into a type and a list of declarators.
# In each declarator, "@{" and "@}" are used in place of parens to
# mark function parameter lists, and "@!" is used in place of commas
# in parameter lists. "@<" and "@>" are used in place of
# non-parameter list parens.
gsub(/ _ +/, " _ ", line)
while(1) {
if(isfunc && match(line, /\([^()]*\)$/))
line = substr(line, 1, RSTART-1) " _ (" substr(line, RSTART) ")"
else if(match(line, / _ \(\([^,()]*,/))
line = substr(line, 1, RSTART+RLENGTH-2) "@!" substr(line, RSTART+RLENGTH)
else if(match(line, / _ \(\([^,()]*\)\)/))
line = substr(line, 1, RSTART-1) "@{" substr(line, RSTART+5, RLENGTH-7) "@}" substr(line, RSTART+RLENGTH)
else if(match(line, /\([^,()]*\)/))
line = substr(line, 1, RSTART-1) "@<" substr(line, RSTART+1, RLENGTH-2) "@>" substr(line, RSTART+RLENGTH)
else
break
}
sub(/^ */, "", line)
match(line, /^((const|enum|mod_export|static|struct|union) +)*([_0-9A-Za-z]+ +|((char|double|float|int|long|short|unsigned|void) +)+)((const|static) +)*/)
dtype = substr(line, 1, RLENGTH)
sub(/ *$/, "", dtype)
if(" " dtype " " ~ / static /)
locality = "L"
else
locality = "E"
exported = " " dtype " " ~ / mod_export /
line = substr(line, RLENGTH+1) ","
# Handle each declarator.
if (match(line, /VA_ALIST/)) {
# Already has VARARGS handling.
# Put parens etc. back
gsub(/@[{]/, "((", line)
gsub(/@}/, "))", line)
gsub(/@</, "(", line)
gsub(/@>/, ")", line)
gsub(/@!/, ",", line)
sub(/,$/, ";", line)
gsub(/mod_export/, "mod_import_function", dtype)
gsub(/VA_ALIST/, "VA_ALIST_PROTO", line)
sub(/ VA_DCL/, "", line)
if(locality ~ /E/)
dtype = "extern " dtype
if (match(line, /[_0-9A-Za-z]+\(VA_ALIST/))
dnam = substr(line, RSTART, RLENGTH-9)
# If this is exported, add it to the exported symbol list.
if (exported)
printf "X%s\n", dnam
printf "%s%s %s\n", locality, dtype, line
} else {
while(match(line, /^[^,]*,/)) {
# Separate out the name from the declarator. Use "@+" and "@-"
# to bracket the name within the declarator. Strip off any
# initialiser.
dcltor = substr(line, 1, RLENGTH-1)
line = substr(line, RLENGTH+1)
sub(/\=.*$/, "", dcltor)
match(dcltor, /^([^_0-9A-Za-z]| const )*/)
dcltor = substr(dcltor, 1, RLENGTH) "@+" substr(dcltor, RLENGTH+1)
match(dcltor, /^.*@\+[_0-9A-Za-z]+/)
dcltor = substr(dcltor, 1, RLENGTH) "@-" substr(dcltor, RLENGTH+1)
dnam = dcltor
sub(/^.*@\+/, "", dnam)
sub(/@-.*$/, "", dnam)
# Put parens etc. back
gsub(/@[{]/, " _((", dcltor)
gsub(/@}/, "))", dcltor)
gsub(/@</, "(", dcltor)
gsub(/@>/, ")", dcltor)
gsub(/@!/, ",", dcltor)
# If this is exported, add it to the exported symbol list.
if(exported)
printf "X%s\n", dnam
# Format the declaration for output
dcl = dtype " " dcltor ";"
if(locality ~ /E/)
dcl = "extern " dcl
if(isfunc)
gsub(/ mod_export /, " mod_import_function ", dcl)
else
gsub(/ mod_export /, " mod_import_variable ", dcl)
gsub(/@[+-]/, "", dcl)
gsub(/ +/, " ", dcl)
while(match(dcl, /[^_0-9A-Za-z] ./) || match(dcl, /. [^_0-9A-Za-z]/))
dcl = substr(dcl, 1, RSTART) substr(dcl, RSTART+2)
printf "%s%s\n", locality, dcl
}
}
}
END {
if(aborting)
exit 1
printf "E\n"
printf "E#endif /* !have_%s_globals */\n", name
}

File diff suppressed because it is too large Load Diff

View File

@ -1,116 +0,0 @@
#! /bin/sh
#
# mkbltnmlst.sh: generate boot code for linked-in modules
#
# Written by Andrew Main
#
srcdir=${srcdir-`echo $0|sed 's%/[^/][^/]*$%%'`}
test "x$srcdir" = "x$0" && srcdir=.
test "x$srcdir" = "x" && srcdir=.
CFMOD=${CFMOD-$srcdir/../config.modules}
bin_mods="`grep ' link=static' $CFMOD | sed -e '/^#/d' \
-e 's/ .*/ /' -e 's/^name=/ /'`"
x_mods="`grep ' load=yes' $CFMOD | sed -e '/^#/d' -e '/ link=no/d' \
-e 's/ .*/ /' -e 's/^name=/ /'`"
trap "rm -f $1; exit 1" 1 2 15
exec > $1
for x_mod in $x_mods; do
modfile="`grep '^name='$x_mod' ' $CFMOD | sed -e 's/^.* modfile=//' \
-e 's/ .*//'`"
if test "x$modfile" = x; then
echo >&2 "WARNING: no name for \`$x_mod' in $CFMOD (ignored)"
continue
fi
case "$bin_mods" in
*" $x_mod "*)
echo "/* linked-in known module \`$x_mod' */"
linked=yes
;;
*)
echo "#ifdef DYNAMIC"
echo "/* non-linked-in known module \`$x_mod' */"
linked=no
esac
unset moddeps autofeatures autofeatures_emu
. $srcdir/../$modfile
if test "x$autofeatures" != x; then
if test "x$autofeatures_emu" != x; then
echo " {"
echo " char *zsh_features[] = { "
for feature in $autofeatures; do
echo " \"$feature\","
done
echo " NULL"
echo " }; "
echo " char *emu_features[] = { "
for feature in $autofeatures_emu; do
echo " \"$feature\","
done
echo " NULL"
echo " }; "
echo " autofeatures(\"zsh\", \"$x_mod\","
echo " EMULATION(EMULATE_ZSH) ? zsh_features : emu_features,"
echo " 0, 1);"
echo " }"
else
echo " if (EMULATION(EMULATE_ZSH)) {"
echo " char *features[] = { "
for feature in $autofeatures; do
echo " \"$feature\","
done
echo " NULL"
echo " }; "
echo " autofeatures(\"zsh\", \"$x_mod\", features, 0, 1);"
echo " }"
fi
fi
for dep in $moddeps; do
echo " add_dep(\"$x_mod\", \"$dep\");"
done
test "x$linked" = xno && echo "#endif"
done
echo
done_mods=" "
for bin_mod in $bin_mods; do
q_bin_mod=`echo $bin_mod | sed 's,Q,Qq,g;s,_,Qu,g;s,/,Qs,g'`
modfile="`grep '^name='$bin_mod' ' $CFMOD | sed -e 's/^.* modfile=//' \
-e 's/ .*//'`"
echo "/* linked-in module \`$bin_mod' */"
unset moddeps
. $srcdir/../$modfile
for dep in $moddeps; do
# This assumes there are no circular dependencies in the builtin
# modules. Better ordering of config.modules would be necessary
# to enforce stricter dependency checking.
case $bin_mods in
*" $dep "*)
echo " /* depends on \`$dep' */" ;;
*) echo >&2 "ERROR: linked-in module \`$bin_mod' depends on \`$dep'"
rm -f $1
exit 1 ;;
esac
done
echo " {"
echo " extern int setup_${q_bin_mod} _((Module));"
echo " extern int boot_${q_bin_mod} _((Module));"
echo " extern int features_${q_bin_mod} _((Module,char***));"
echo " extern int enables_${q_bin_mod} _((Module,int**));"
echo " extern int cleanup_${q_bin_mod} _((Module));"
echo " extern int finish_${q_bin_mod} _((Module));"
echo
echo " register_module(\"$bin_mod\","
echo " setup_${q_bin_mod},"
echo " features_${q_bin_mod},"
echo " enables_${q_bin_mod},"
echo " boot_${q_bin_mod},"
echo " cleanup_${q_bin_mod}, finish_${q_bin_mod});"
echo " }"
done_mods="$done_mods$bin_mod "
done

View File

@ -1,468 +0,0 @@
#!/bin/sh
#
# mkmakemod.sh: generate Makefile.in files for module building
#
# Options:
# -m = file is already generated; only build the second stage
# -i = do not build second stage
#
# Args:
# $1 = subdirectory to look in, relative to $top_srcdir
# $2 = final output filename, within the $1 directory
#
# This script must be run from the top-level build directory, and $top_srcdir
# must be set correctly in the environment.
#
# This looks in $1, and uses all the *.mdd files there. Each .mdd file
# defines one module. The .mdd file is actually a shell script, which will
# be sourced. It may define the following shell variables:
#
# name name of this module
# moddeps modules on which this module depends (default none)
# nozshdep non-empty indicates no dependence on the `zsh/main' pseudo-module
# alwayslink if non-empty, always link the module into the executable
# autofeatures features defined by the module, for autoloading
# autofeatures_emu As autofeatures, but for non-zsh emulation modes
# objects .o files making up this module (*must* be defined)
# proto .syms files for this module (default generated from $objects)
# headers extra headers for this module (default none)
# hdrdeps extra headers on which the .mdh depends (default none)
# otherincs extra headers that are included indirectly (default none)
#
# The .mdd file may also include a Makefile.in fragment between lines
# `:<<\Make' and `Make' -- this will be copied into Makemod.in.
#
# The resulting Makemod.in knows how to build each module that is defined.
# For each module it also knows how to build a .mdh file. Each source file
# should #include the .mdh file for the module it is a part of. The .mdh
# file #includes the .mdh files for any module dependencies, then each of
# $headers, and then each .epro (for global declarations). It will
# be recreated if any of the dependency .mdh files changes, or if any of
# $headers or $hdrdeps changes. When anything depends on it, all the .epros
# and $otherincs will be made up to date, but the .mdh file won't actually
# be rebuilt if those files change.
#
# The order of sections of the output file is thus:
# simple generated macros
# macros generated from *.mdd
# included Makemod.in.in
# rules generated from *.mdd
# The order dependencies are basically that the generated macros are required
# in Makemod.in.in, but some of the macros that it creates are needed in the
# later rules.
#
# sed script to normalise a pathname
sed_normalise='
s,^,/,
s,$,/,
:1
s,/\./,/,
t1
:2
s,/[^/.][^/]*/\.\./,/,
s,/\.[^/.][^/]*/\.\./,/,
s,/\.\.[^/][^/]*/\.\./,/,
t2
s,^/$,.,
s,^/,,
s,\(.\)/$,\1,
'
# decide which stages to process
first_stage=true
second_stage=true
if test ."$1" = .-m; then
shift
first_stage=false
elif test ."$1" = .-i; then
shift
second_stage=false
fi
top_srcdir=`echo $top_srcdir | sed "$sed_normalise"`
the_subdir=$1
the_makefile=$2
if $first_stage; then
dir_top=`echo $the_subdir | sed 's,[^/][^/]*,..,g'`
trap "rm -f $the_subdir/${the_makefile}.in; exit 1" 1 2 15
echo "creating $the_subdir/${the_makefile}.in"
exec 3>&1 >$the_subdir/${the_makefile}.in
echo "##### ${the_makefile}.in generated automatically by mkmakemod.sh"
echo "##### DO NOT EDIT!"
echo
echo "##### ===== DEFINITIONS ===== #####"
echo
echo "makefile = ${the_makefile}"
echo "dir_top = ${dir_top}"
echo "subdir = ${the_subdir}"
echo
bin_mods=`grep link=static ./config.modules | \
sed -e '/^#/d' -e 's/ .*/ /' -e 's/^name=/ /'`
dyn_mods="`grep link=dynamic ./config.modules | \
sed -e '/^#/d' -e 's/ .*/ /' -e 's/^name=/ /'`"
module_list="${bin_mods}${dyn_mods}"
if grep '^#define DYNAMIC ' config.h >/dev/null; then
is_dynamic=true
else
is_dynamic=false
fi
here_mddnames=
all_subdirs=
all_modobjs=
all_modules=
all_mdds=
all_mdhs=
all_proto=
lastsub=//
for module in $module_list; do
modfile="`grep '^name='$module' ' ./config.modules | \
sed -e 's/^.* modfile=//' -e 's/ .*//'`"
case $modfile in
$the_subdir/$lastsub/*) ;;
$the_subdir/*/*)
lastsub=`echo $modfile | sed 's,^'$the_subdir'/,,;s,/[^/]*$,,'`
case "$all_subdirs " in
*" $lastsub "* ) ;;
* )
all_subdirs="$all_subdirs $lastsub"
;;
esac
;;
$the_subdir/*)
mddname=`echo $modfile | sed 's,^.*/,,;s,\.mdd$,,'`
here_mddnames="$here_mddnames $mddname"
build=$is_dynamic
case $is_dynamic@$bin_mods in
*" $module "*)
build=true
all_modobjs="$all_modobjs modobjs.${mddname}" ;;
true@*)
all_modules="$all_modules ${mddname}.\$(DL_EXT)" ;;
esac
all_mdds="$all_mdds ${mddname}.mdd"
$build && all_mdhs="$all_mdhs ${mddname}.mdh"
$build && all_proto="$all_proto proto.${mddname}"
;;
esac
done
echo "MODOBJS =$all_modobjs"
echo "MODULES =$all_modules"
echo "MDDS =$all_mdds"
echo "MDHS =$all_mdhs"
echo "PROTOS =$all_proto"
echo "SUBDIRS =$all_subdirs"
echo
echo "ENTRYOBJ = \$(dir_src)/modentry..o"
echo "NNTRYOBJ ="
echo "ENTRYOPT = -emodentry"
echo "NNTRYOPT ="
echo
echo "##### ===== INCLUDING Makemod.in.in ===== #####"
echo
cat $top_srcdir/Src/Makemod.in.in
echo
case $the_subdir in
Src) modobjs_sed= ;;
Src/*) modobjs_sed="| sed 's\" \" "`echo $the_subdir | sed 's,^Src/,,'`"/\"g' " ;;
*) modobjs_sed="| sed 's\" \" ../$the_subdir/\"g' " ;;
esac
other_mdhs=
remote_mdhs=
other_exports=
remote_exports=
other_modules=
remote_modules=
for mddname in $here_mddnames; do
unset name moddeps nozshdep alwayslink hasexport
unset autofeatures autofeatures_emu
unset objects proto headers hdrdeps otherincs
. $top_srcdir/$the_subdir/${mddname}.mdd
q_name=`echo $name | sed 's,Q,Qq,g;s,_,Qu,g;s,/,Qs,g'`
test -n "${moddeps+set}" || moddeps=
test -n "$nozshdep" || moddeps="$moddeps zsh/main"
test -n "${proto+set}" ||
proto=`echo $objects '' | sed 's,\.o ,.syms ,g'`
dobjects=`echo $objects '' | sed 's,\.o ,..o ,g'`
modhdeps=
mododeps=
exportdeps=
imports=
q_moddeps=
for dep in $moddeps; do
depfile="`grep '^name='$dep' ' ./config.modules | \
sed -e 's/^.* modfile=//' -e 's/ .*//'`"
q_dep=`echo $dep | sed 's,Q,Qq,g;s,_,Qu,g;s,/,Qs,g'`
q_moddeps="$q_moddeps $q_dep"
eval `echo $depfile | sed 's,/\([^/]*\)\.mdd$,;depbase=\1,;s,^,loc=,'`
case "$binmod" in
*" $dep "* )
dep=zsh/main
;;
esac
case $the_subdir in
$loc)
mdh="${depbase}.mdh"
export="${depbase}.export"
case "$dep" in
zsh/main )
mdll="\$(dir_top)/Src/libzsh-\$(VERSION).\$(DL_EXT) "
;;
* )
mdll="${depbase}.\$(DL_EXT) "
;;
esac
;;
$loc/*)
mdh="\$(dir_top)/$loc/${depbase}.mdh"
case "$other_mdhs " in
*" $mdh "*) ;;
*) other_mdhs="$other_mdhs $mdh" ;;
esac
export="\$(dir_top)/$loc/${depbase}.export"
case "$other_exports " in
*" $export "*) ;;
*) other_exports="$other_exports $export" ;;
esac
case "$dep" in
zsh/main )
mdll="\$(dir_top)/Src/libzsh-\$(VERSION).\$(DL_EXT) "
;;
* )
mdll="\$(dir_top)/$loc/${depbase}.\$(DL_EXT) "
;;
esac
case "$other_modules " in
*" $mdll "*) ;;
*) other_modules="$other_modules $mdll" ;;
esac
;;
*)
mdh="\$(dir_top)/$loc/${depbase}.mdh"
case "$remote_mdhs " in
*" $mdh "*) ;;
*) remote_mdhs="$remote_mdhs $mdh" ;;
esac
export="\$(dir_top)/$loc/${depbase}.export"
case "$remote_exports " in
*" $export "*) ;;
*) remote_exports="$remote_exports $export" ;;
esac
case "$dep" in
zsh/main )
mdll="\$(dir_top)/Src/libzsh-\$(VERSION).\$(DL_EXT) "
;;
* )
mdll="\$(dir_top)/$loc/${depbase}.\$(DL_EXT) "
;;
esac
case "$remote_modules " in
*" $mdll "*) ;;
*) remote_modules="$remote_modules $mdll" ;;
esac
;;
esac
modhdeps="$modhdeps $mdh"
exportdeps="$exportdeps $export"
imports="$imports \$(IMPOPT)$export"
case "$mododeps " in
*" $mdll "* )
:
;;
* )
mododeps="$mododeps $mdll"
;;
esac
done
echo "##### ===== DEPENDENCIES GENERATED FROM ${mddname}.mdd ===== #####"
echo
echo "MODOBJS_${mddname} = $objects"
echo "MODDOBJS_${mddname} = $dobjects \$(@E@NTRYOBJ)"
echo "SYMS_${mddname} = $proto"
echo "EPRO_${mddname} = "`echo $proto '' | sed 's,\.syms ,.epro ,g'`
echo "INCS_${mddname} = \$(EPRO_${mddname}) $otherincs"
echo "EXPIMP_${mddname} = $imports \$(EXPOPT)$mddname.export"
echo "NXPIMP_${mddname} ="
echo "LINKMODS_${mddname} = $mododeps"
echo "NOLINKMODS_${mddname} = "
echo
echo "proto.${mddname}: \$(EPRO_${mddname})"
echo "\$(SYMS_${mddname}): \$(PROTODEPS)"
echo
echo "${mddname}.export: \$(SYMS_${mddname})"
echo " @( echo '#!'; cat \$(SYMS_${mddname}) | sed -n '/^X/{s/^X//;p;}' | sort -u ) > \$@"
echo
echo "modobjs.${mddname}: \$(MODOBJS_${mddname})"
echo " @echo '' \$(MODOBJS_${mddname}) $modobjs_sed>> \$(dir_src)/stamp-modobjs.tmp"
echo
if test -z "$alwayslink"; then
case " $all_modules" in *" ${mddname}."*)
echo "install.modules-here: install.modules.${mddname}"
echo "uninstall.modules-here: uninstall.modules.${mddname}"
echo
;; esac
instsubdir=`echo $name | sed 's,^,/,;s,/[^/]*$,,'`
echo "install.modules.${mddname}: ${mddname}.\$(DL_EXT)"
echo " \$(SHELL) \$(sdir_top)/mkinstalldirs \$(DESTDIR)\$(MODDIR)${instsubdir}"
echo " \$(INSTALL_PROGRAM) \$(STRIPFLAGS) ${mddname}.\$(DL_EXT) \$(DESTDIR)\$(MODDIR)/${name}.\$(DL_EXT)"
echo
echo "uninstall.modules.${mddname}:"
echo " rm -f \$(DESTDIR)\$(MODDIR)/${name}.\$(DL_EXT)"
echo
echo "${mddname}.\$(DL_EXT): \$(MODDOBJS_${mddname}) ${mddname}.export $exportdeps \$(@LINKMODS@_${mddname})"
echo ' rm -f $@'
echo " \$(DLLINK) \$(@E@XPIMP_$mddname) \$(@E@NTRYOPT) \$(MODDOBJS_${mddname}) \$(@LINKMODS@_${mddname}) \$(LIBS) "
echo
fi
echo "${mddname}.mdhi: ${mddname}.mdhs \$(INCS_${mddname})"
echo " @test -f \$@ || echo 'do not delete this file' > \$@"
echo
echo "${mddname}.mdhs: ${mddname}.mdd"
echo " @\$(MAKE) -f \$(makefile) \$(MAKEDEFS) ${mddname}.mdh.tmp"
echo " @if cmp -s ${mddname}.mdh ${mddname}.mdh.tmp; then \\"
echo " rm -f ${mddname}.mdh.tmp; \\"
echo " echo \"\\\`${mddname}.mdh' is up to date.\"; \\"
echo " else \\"
echo " mv -f ${mddname}.mdh.tmp ${mddname}.mdh; \\"
echo " echo \"Updated \\\`${mddname}.mdh'.\"; \\"
echo " fi"
echo " echo 'timestamp for ${mddname}.mdh against ${mddname}.mdd' > \$@"
echo
echo "${mddname}.mdh: ${modhdeps} ${headers} ${hdrdeps} ${mddname}.mdhi"
echo " @\$(MAKE) -f \$(makefile) \$(MAKEDEFS) ${mddname}.mdh.tmp"
echo " @mv -f ${mddname}.mdh.tmp ${mddname}.mdh"
echo " @echo \"Updated \\\`${mddname}.mdh'.\""
echo
echo "${mddname}.mdh.tmp:"
echo " @( \\"
echo " echo '#ifndef have_${q_name}_module'; \\"
echo " echo '#define have_${q_name}_module'; \\"
echo " echo; \\"
echo " echo '# ifndef IMPORTING_MODULE_${q_name}'; \\"
echo " if test @SHORTBOOTNAMES@ = yes; then \\"
echo " echo '# ifndef MODULE'; \\"
echo " fi; \\"
echo " echo '# define boot_ boot_${q_name}'; \\"
echo " echo '# define cleanup_ cleanup_${q_name}'; \\"
echo " echo '# define features_ features_${q_name}'; \\"
echo " echo '# define enables_ enables_${q_name}'; \\"
echo " echo '# define setup_ setup_${q_name}'; \\"
echo " echo '# define finish_ finish_${q_name}'; \\"
echo " if test @SHORTBOOTNAMES@ = yes; then \\"
echo " echo '# endif /* !MODULE */'; \\"
echo " fi; \\"
echo " echo '# endif /* !IMPORTING_MODULE_${q_name} */'; \\"
echo " echo; \\"
if test -n "$moddeps"; then (
set x $q_moddeps
echo " echo '/* Module dependencies */'; \\"
for hdep in $modhdeps; do
shift
echo " echo '# define IMPORTING_MODULE_${1} 1'; \\"
echo " echo '# include \"${hdep}\"'; \\"
done
echo " echo; \\"
) fi
if test -n "$headers"; then
echo " echo '/* Extra headers for this module */'; \\"
echo " for hdr in $headers; do \\"
echo " echo '# include \"'\$\$hdr'\"'; \\"
echo " done; \\"
echo " echo; \\"
fi
if test -n "$proto"; then
echo " echo '# undef mod_import_variable'; \\"
echo " echo '# undef mod_import_function'; \\"
echo " echo '# if defined(IMPORTING_MODULE_${q_name}) && defined(MODULE)'; \\"
echo " echo '# define mod_import_variable @MOD_IMPORT_VARIABLE@'; \\"
echo " echo '# define mod_import_function @MOD_IMPORT_FUNCTION@'; \\"
echo " echo '# else'; \\"
echo " echo '# define mod_import_function'; \\"
echo " echo '# define mod_import_variable'; \\"
echo " echo '# endif /* IMPORTING_MODULE_${q_name} && MODULE */'; \\"
echo " for epro in \$(EPRO_${mddname}); do \\"
echo " echo '# include \"'\$\$epro'\"'; \\"
echo " done; \\"
echo " echo '# undef mod_import_variable'; \\"
echo " echo '# define mod_import_variable'; \\"
echo " echo '# undef mod_import_variable'; \\"
echo " echo '# define mod_import_variable'; \\"
echo " echo '# ifndef mod_export'; \\"
echo " echo '# define mod_export @MOD_EXPORT@'; \\"
echo " echo '# endif /* mod_export */'; \\"
echo " echo; \\"
fi
echo " echo '#endif /* !have_${q_name}_module */'; \\"
echo " ) > \$@"
echo
echo "\$(MODOBJS_${mddname}) \$(MODDOBJS_${mddname}): ${mddname}.mdh"
sed -e '/^ *: *<< *\\Make *$/,/^Make$/!d' \
-e 's/^ *: *<< *\\Make *$//; /^Make$/d' \
< $top_srcdir/$the_subdir/${mddname}.mdd
echo
done
if test -n "$remote_mdhs$other_mdhs$remote_exports$other_exports$remote_modules$other_modules"; then
echo "##### ===== DEPENDENCIES FOR REMOTE MODULES ===== #####"
echo
for mdh in $remote_mdhs; do
echo "$mdh: FORCE"
echo " @cd @%@ && \$(MAKE) \$(MAKEDEFS) @%@$mdh"
echo
done | sed 's,^\(.*\)@%@\(.*\)@%@\(.*\)/\([^/]*\)$,\1\3\2\4,'
if test -n "$other_mdhs"; then
echo "${other_mdhs}:" | sed 's,^ ,,'
echo " false # A. should only happen with make -n"
echo
fi
for export in $remote_exports; do
echo "$export: FORCE"
echo " @cd @%@ && \$(MAKE) \$(MAKEDEFS) @%@$export"
echo
done | sed 's,^\(.*\)@%@\(.*\)@%@\(.*\)/\([^/]*\)$,\1\3\2\4,'
if test -n "$other_exports"; then
echo "${other_exports}:" | sed 's,^ ,,'
echo " false # B. should only happen with make -n"
echo
fi
for mdll in $remote_modules; do
echo "$mdll: FORCE"
echo " @cd @%@ && \$(MAKE) \$(MAKEDEFS) @%@$mdll"
echo
done | sed 's,^\(.*\)@%@\(.*\)@%@\(.*\)/\([^/]*\)$,\1\3\2\4,'
if test -n "$other_modules"; then
echo "${other_modules}:" | sed 's,^ ,,'
echo " false # C. should only happen with make -n"
echo
fi
fi
echo "##### End of ${the_makefile}.in"
exec >&3 3>&-
fi
if $second_stage ; then
trap "rm -f $the_subdir/${the_makefile}; exit 1" 1 2 15
${CONFIG_SHELL-/bin/sh} ./config.status \
--file=$the_subdir/${the_makefile}:$the_subdir/${the_makefile}.in ||
exit 1
fi
exit 0

File diff suppressed because it is too large Load Diff

View File

@ -1,955 +0,0 @@
/*
* options.c - shell options
*
* This file is part of zsh, the Z shell.
*
* Copyright (c) 1992-1997 Paul Falstad
* All rights reserved.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and to distribute modified versions of this software for any
* purpose, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* In no event shall Paul Falstad or the Zsh Development Group be liable
* to any party for direct, indirect, special, incidental, or consequential
* damages arising out of the use of this software and its documentation,
* even if Paul Falstad and the Zsh Development Group have been advised of
* the possibility of such damage.
*
* Paul Falstad and the Zsh Development Group specifically disclaim any
* warranties, including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose. The software
* provided hereunder is on an "as is" basis, and Paul Falstad and the
* Zsh Development Group have no obligation to provide maintenance,
* support, updates, enhancements, or modifications.
*
*/
#include "zsh.mdh"
#include "options.pro"
/* current emulation (used to decide which set of option letters is used) */
/**/
mod_export int emulation;
/* current sticky emulation: sticky = NULL means none */
/**/
mod_export Emulation_options sticky;
/* the options; e.g. if opts[SHGLOB] != 0, SH_GLOB is turned on */
/**/
mod_export char opts[OPT_SIZE];
/* Option name hash table */
/**/
mod_export HashTable optiontab;
/* The canonical option name table */
#define OPT_CSH EMULATE_CSH
#define OPT_KSH EMULATE_KSH
#define OPT_SH EMULATE_SH
#define OPT_ZSH EMULATE_ZSH
#define OPT_ALL (OPT_CSH|OPT_KSH|OPT_SH|OPT_ZSH)
#define OPT_BOURNE (OPT_KSH|OPT_SH)
#define OPT_BSHELL (OPT_KSH|OPT_SH|OPT_ZSH)
#define OPT_NONBOURNE (OPT_ALL & ~OPT_BOURNE)
#define OPT_NONZSH (OPT_ALL & ~OPT_ZSH)
/* option is relevant to emulation */
#define OPT_EMULATE (EMULATE_UNUSED)
/* option should never be set by emulate() */
#define OPT_SPECIAL (EMULATE_UNUSED<<1)
/* option is an alias to an other option */
#define OPT_ALIAS (EMULATE_UNUSED<<2)
#define defset(X, my_emulation) (!!((X)->node.flags & my_emulation))
/*
* Note that option names should usually be fewer than 20 characters long
* to avoid formatting problems.
*/
static struct optname optns[] = {
{{NULL, "aliases", OPT_EMULATE|OPT_ALL}, ALIASESOPT},
{{NULL, "aliasfuncdef", OPT_EMULATE|OPT_BOURNE}, ALIASFUNCDEF},
{{NULL, "allexport", OPT_EMULATE}, ALLEXPORT},
{{NULL, "alwayslastprompt", OPT_ALL}, ALWAYSLASTPROMPT},
{{NULL, "alwaystoend", 0}, ALWAYSTOEND},
{{NULL, "appendcreate", OPT_EMULATE|OPT_BOURNE}, APPENDCREATE},
{{NULL, "appendhistory", OPT_ALL}, APPENDHISTORY},
{{NULL, "autocd", OPT_EMULATE}, AUTOCD},
{{NULL, "autocontinue", 0}, AUTOCONTINUE},
{{NULL, "autolist", OPT_ALL}, AUTOLIST},
{{NULL, "automenu", OPT_ALL}, AUTOMENU},
{{NULL, "autonamedirs", 0}, AUTONAMEDIRS},
{{NULL, "autoparamkeys", OPT_ALL}, AUTOPARAMKEYS},
{{NULL, "autoparamslash", OPT_ALL}, AUTOPARAMSLASH},
{{NULL, "autopushd", 0}, AUTOPUSHD},
{{NULL, "autoremoveslash", OPT_ALL}, AUTOREMOVESLASH},
{{NULL, "autoresume", 0}, AUTORESUME},
{{NULL, "badpattern", OPT_EMULATE|OPT_NONBOURNE},BADPATTERN},
{{NULL, "banghist", OPT_NONBOURNE}, BANGHIST},
{{NULL, "bareglobqual", OPT_EMULATE|OPT_ZSH}, BAREGLOBQUAL},
{{NULL, "bashautolist", 0}, BASHAUTOLIST},
{{NULL, "bashrematch", 0}, BASHREMATCH},
{{NULL, "beep", OPT_ALL}, BEEP},
{{NULL, "bgnice", OPT_EMULATE|OPT_NONBOURNE},BGNICE},
{{NULL, "braceccl", OPT_EMULATE}, BRACECCL},
{{NULL, "bsdecho", OPT_EMULATE|OPT_SH}, BSDECHO},
{{NULL, "caseglob", OPT_ALL}, CASEGLOB},
{{NULL, "casematch", OPT_ALL}, CASEMATCH},
{{NULL, "cbases", 0}, CBASES},
{{NULL, "cprecedences", OPT_EMULATE|OPT_NONZSH}, CPRECEDENCES},
{{NULL, "cdablevars", OPT_EMULATE}, CDABLEVARS},
{{NULL, "chasedots", OPT_EMULATE}, CHASEDOTS},
{{NULL, "chaselinks", OPT_EMULATE}, CHASELINKS},
{{NULL, "checkjobs", OPT_EMULATE|OPT_ZSH}, CHECKJOBS},
{{NULL, "checkrunningjobs", OPT_EMULATE|OPT_ZSH}, CHECKRUNNINGJOBS},
{{NULL, "clobber", OPT_EMULATE|OPT_ALL}, CLOBBER},
{{NULL, "combiningchars", 0}, COMBININGCHARS},
{{NULL, "completealiases", 0}, COMPLETEALIASES},
{{NULL, "completeinword", 0}, COMPLETEINWORD},
{{NULL, "continueonerror", 0}, CONTINUEONERROR},
{{NULL, "correct", 0}, CORRECT},
{{NULL, "correctall", 0}, CORRECTALL},
{{NULL, "cshjunkiehistory", OPT_EMULATE|OPT_CSH}, CSHJUNKIEHISTORY},
{{NULL, "cshjunkieloops", OPT_EMULATE|OPT_CSH}, CSHJUNKIELOOPS},
{{NULL, "cshjunkiequotes", OPT_EMULATE|OPT_CSH}, CSHJUNKIEQUOTES},
{{NULL, "cshnullcmd", OPT_EMULATE|OPT_CSH}, CSHNULLCMD},
{{NULL, "cshnullglob", OPT_EMULATE|OPT_CSH}, CSHNULLGLOB},
{{NULL, "debugbeforecmd", OPT_ALL}, DEBUGBEFORECMD},
{{NULL, "emacs", 0}, EMACSMODE},
{{NULL, "equals", OPT_EMULATE|OPT_ZSH}, EQUALS},
{{NULL, "errexit", OPT_EMULATE}, ERREXIT},
{{NULL, "errreturn", OPT_EMULATE}, ERRRETURN},
{{NULL, "exec", OPT_ALL}, EXECOPT},
{{NULL, "extendedglob", OPT_EMULATE}, EXTENDEDGLOB},
{{NULL, "extendedhistory", OPT_CSH}, EXTENDEDHISTORY},
{{NULL, "evallineno", OPT_EMULATE|OPT_ZSH}, EVALLINENO},
{{NULL, "flowcontrol", OPT_ALL}, FLOWCONTROL},
{{NULL, "forcefloat", 0}, FORCEFLOAT},
{{NULL, "functionargzero", OPT_EMULATE|OPT_NONBOURNE},FUNCTIONARGZERO},
{{NULL, "glob", OPT_EMULATE|OPT_ALL}, GLOBOPT},
{{NULL, "globalexport", OPT_EMULATE|OPT_ZSH}, GLOBALEXPORT},
{{NULL, "globalrcs", OPT_ALL}, GLOBALRCS},
{{NULL, "globassign", OPT_EMULATE|OPT_CSH}, GLOBASSIGN},
{{NULL, "globcomplete", 0}, GLOBCOMPLETE},
{{NULL, "globdots", OPT_EMULATE}, GLOBDOTS},
{{NULL, "globstarshort", OPT_EMULATE}, GLOBSTARSHORT},
{{NULL, "globsubst", OPT_EMULATE|OPT_NONZSH}, GLOBSUBST},
{{NULL, "hashcmds", OPT_ALL}, HASHCMDS},
{{NULL, "hashdirs", OPT_ALL}, HASHDIRS},
{{NULL, "hashexecutablesonly", 0}, HASHEXECUTABLESONLY},
{{NULL, "hashlistall", OPT_ALL}, HASHLISTALL},
{{NULL, "histallowclobber", 0}, HISTALLOWCLOBBER},
{{NULL, "histbeep", OPT_ALL}, HISTBEEP},
{{NULL, "histexpiredupsfirst",0}, HISTEXPIREDUPSFIRST},
{{NULL, "histfcntllock", 0}, HISTFCNTLLOCK},
{{NULL, "histfindnodups", 0}, HISTFINDNODUPS},
{{NULL, "histignorealldups", 0}, HISTIGNOREALLDUPS},
{{NULL, "histignoredups", 0}, HISTIGNOREDUPS},
{{NULL, "histignorespace", 0}, HISTIGNORESPACE},
{{NULL, "histlexwords", 0}, HISTLEXWORDS},
{{NULL, "histnofunctions", 0}, HISTNOFUNCTIONS},
{{NULL, "histnostore", 0}, HISTNOSTORE},
{{NULL, "histsubstpattern", OPT_EMULATE}, HISTSUBSTPATTERN},
{{NULL, "histreduceblanks", 0}, HISTREDUCEBLANKS},
{{NULL, "histsavebycopy", OPT_ALL}, HISTSAVEBYCOPY},
{{NULL, "histsavenodups", 0}, HISTSAVENODUPS},
{{NULL, "histverify", 0}, HISTVERIFY},
{{NULL, "hup", OPT_EMULATE|OPT_ZSH}, HUP},
{{NULL, "ignorebraces", OPT_EMULATE|OPT_SH}, IGNOREBRACES},
{{NULL, "ignoreclosebraces", OPT_EMULATE}, IGNORECLOSEBRACES},
{{NULL, "ignoreeof", 0}, IGNOREEOF},
{{NULL, "incappendhistory", 0}, INCAPPENDHISTORY},
{{NULL, "incappendhistorytime", 0}, INCAPPENDHISTORYTIME},
{{NULL, "interactive", OPT_SPECIAL}, INTERACTIVE},
{{NULL, "interactivecomments",OPT_BOURNE}, INTERACTIVECOMMENTS},
{{NULL, "ksharrays", OPT_EMULATE|OPT_BOURNE}, KSHARRAYS},
{{NULL, "kshautoload", OPT_EMULATE|OPT_BOURNE}, KSHAUTOLOAD},
{{NULL, "kshglob", OPT_EMULATE|OPT_KSH}, KSHGLOB},
{{NULL, "kshoptionprint", OPT_EMULATE|OPT_KSH}, KSHOPTIONPRINT},
{{NULL, "kshtypeset", 0}, KSHTYPESET},
{{NULL, "kshzerosubscript", 0}, KSHZEROSUBSCRIPT},
{{NULL, "listambiguous", OPT_ALL}, LISTAMBIGUOUS},
{{NULL, "listbeep", OPT_ALL}, LISTBEEP},
{{NULL, "listpacked", 0}, LISTPACKED},
{{NULL, "listrowsfirst", 0}, LISTROWSFIRST},
{{NULL, "listtypes", OPT_ALL}, LISTTYPES},
{{NULL, "localoptions", OPT_EMULATE|OPT_KSH}, LOCALOPTIONS},
{{NULL, "localloops", OPT_EMULATE}, LOCALLOOPS},
{{NULL, "localpatterns", OPT_EMULATE}, LOCALPATTERNS},
{{NULL, "localtraps", OPT_EMULATE|OPT_KSH}, LOCALTRAPS},
{{NULL, "login", OPT_SPECIAL}, LOGINSHELL},
{{NULL, "longlistjobs", 0}, LONGLISTJOBS},
{{NULL, "magicequalsubst", OPT_EMULATE}, MAGICEQUALSUBST},
{{NULL, "mailwarning", 0}, MAILWARNING},
{{NULL, "markdirs", 0}, MARKDIRS},
{{NULL, "menucomplete", 0}, MENUCOMPLETE},
{{NULL, "monitor", OPT_SPECIAL}, MONITOR},
{{NULL, "multibyte",
#ifdef MULTIBYTE_SUPPORT
OPT_ALL
#else
0
#endif
}, MULTIBYTE},
{{NULL, "multifuncdef", OPT_EMULATE|OPT_ZSH}, MULTIFUNCDEF},
{{NULL, "multios", OPT_EMULATE|OPT_ZSH}, MULTIOS},
{{NULL, "nomatch", OPT_EMULATE|OPT_NONBOURNE},NOMATCH},
{{NULL, "notify", OPT_ZSH}, NOTIFY},
{{NULL, "nullglob", OPT_EMULATE}, NULLGLOB},
{{NULL, "numericglobsort", OPT_EMULATE}, NUMERICGLOBSORT},
{{NULL, "octalzeroes", OPT_EMULATE|OPT_SH}, OCTALZEROES},
{{NULL, "overstrike", 0}, OVERSTRIKE},
{{NULL, "pathdirs", OPT_EMULATE}, PATHDIRS},
{{NULL, "pathscript", OPT_EMULATE|OPT_BOURNE}, PATHSCRIPT},
{{NULL, "pipefail", OPT_EMULATE}, PIPEFAIL},
{{NULL, "posixaliases", OPT_EMULATE|OPT_BOURNE}, POSIXALIASES},
{{NULL, "posixargzero", OPT_EMULATE}, POSIXARGZERO},
{{NULL, "posixbuiltins", OPT_EMULATE|OPT_BOURNE}, POSIXBUILTINS},
{{NULL, "posixcd", OPT_EMULATE|OPT_BOURNE}, POSIXCD},
{{NULL, "posixidentifiers", OPT_EMULATE|OPT_BOURNE}, POSIXIDENTIFIERS},
{{NULL, "posixjobs", OPT_EMULATE|OPT_BOURNE}, POSIXJOBS},
{{NULL, "posixstrings", OPT_EMULATE|OPT_BOURNE}, POSIXSTRINGS},
{{NULL, "posixtraps", OPT_EMULATE|OPT_BOURNE}, POSIXTRAPS},
{{NULL, "printeightbit", 0}, PRINTEIGHTBIT},
{{NULL, "printexitvalue", 0}, PRINTEXITVALUE},
{{NULL, "privileged", OPT_SPECIAL}, PRIVILEGED},
{{NULL, "promptbang", OPT_KSH}, PROMPTBANG},
{{NULL, "promptcr", OPT_ALL}, PROMPTCR},
{{NULL, "promptpercent", OPT_NONBOURNE}, PROMPTPERCENT},
{{NULL, "promptsp", OPT_ALL}, PROMPTSP},
{{NULL, "promptsubst", OPT_BOURNE}, PROMPTSUBST},
{{NULL, "pushdignoredups", OPT_EMULATE}, PUSHDIGNOREDUPS},
{{NULL, "pushdminus", OPT_EMULATE}, PUSHDMINUS},
{{NULL, "pushdsilent", 0}, PUSHDSILENT},
{{NULL, "pushdtohome", OPT_EMULATE}, PUSHDTOHOME},
{{NULL, "rcexpandparam", OPT_EMULATE}, RCEXPANDPARAM},
{{NULL, "rcquotes", OPT_EMULATE}, RCQUOTES},
{{NULL, "rcs", OPT_ALL}, RCS},
{{NULL, "recexact", 0}, RECEXACT},
{{NULL, "rematchpcre", 0}, REMATCHPCRE},
{{NULL, "restricted", OPT_SPECIAL}, RESTRICTED},
{{NULL, "rmstarsilent", OPT_BOURNE}, RMSTARSILENT},
{{NULL, "rmstarwait", 0}, RMSTARWAIT},
{{NULL, "sharehistory", OPT_KSH}, SHAREHISTORY},
{{NULL, "shfileexpansion", OPT_EMULATE|OPT_BOURNE}, SHFILEEXPANSION},
{{NULL, "shglob", OPT_EMULATE|OPT_BOURNE}, SHGLOB},
{{NULL, "shinstdin", OPT_SPECIAL}, SHINSTDIN},
{{NULL, "shnullcmd", OPT_EMULATE|OPT_BOURNE}, SHNULLCMD},
{{NULL, "shoptionletters", OPT_EMULATE|OPT_BOURNE}, SHOPTIONLETTERS},
{{NULL, "shortloops", OPT_EMULATE|OPT_NONBOURNE},SHORTLOOPS},
{{NULL, "shwordsplit", OPT_EMULATE|OPT_BOURNE}, SHWORDSPLIT},
{{NULL, "singlecommand", OPT_SPECIAL}, SINGLECOMMAND},
{{NULL, "singlelinezle", OPT_KSH}, SINGLELINEZLE},
{{NULL, "sourcetrace", 0}, SOURCETRACE},
{{NULL, "sunkeyboardhack", 0}, SUNKEYBOARDHACK},
{{NULL, "transientrprompt", 0}, TRANSIENTRPROMPT},
{{NULL, "trapsasync", 0}, TRAPSASYNC},
{{NULL, "typesetsilent", OPT_EMULATE|OPT_BOURNE}, TYPESETSILENT},
{{NULL, "unset", OPT_EMULATE|OPT_BSHELL}, UNSET},
{{NULL, "verbose", 0}, VERBOSE},
{{NULL, "vi", 0}, VIMODE},
{{NULL, "warncreateglobal", OPT_EMULATE}, WARNCREATEGLOBAL},
{{NULL, "warnnestedvar", OPT_EMULATE}, WARNNESTEDVAR},
{{NULL, "xtrace", 0}, XTRACE},
{{NULL, "zle", OPT_SPECIAL}, USEZLE},
{{NULL, "braceexpand", OPT_ALIAS}, /* ksh/bash */ -IGNOREBRACES},
{{NULL, "dotglob", OPT_ALIAS}, /* bash */ GLOBDOTS},
{{NULL, "hashall", OPT_ALIAS}, /* bash */ HASHCMDS},
{{NULL, "histappend", OPT_ALIAS}, /* bash */ APPENDHISTORY},
{{NULL, "histexpand", OPT_ALIAS}, /* bash */ BANGHIST},
{{NULL, "log", OPT_ALIAS}, /* ksh */ -HISTNOFUNCTIONS},
{{NULL, "mailwarn", OPT_ALIAS}, /* bash */ MAILWARNING},
{{NULL, "onecmd", OPT_ALIAS}, /* bash */ SINGLECOMMAND},
{{NULL, "physical", OPT_ALIAS}, /* ksh/bash */ CHASELINKS},
{{NULL, "promptvars", OPT_ALIAS}, /* bash */ PROMPTSUBST},
{{NULL, "stdin", OPT_ALIAS}, /* ksh */ SHINSTDIN},
{{NULL, "trackall", OPT_ALIAS}, /* ksh */ HASHCMDS},
{{NULL, "dvorak", 0}, DVORAK},
{{NULL, NULL, 0}, 0}
};
/* Option letters */
#define optletters (isset(SHOPTIONLETTERS) ? kshletters : zshletters)
#define FIRST_OPT '0'
#define LAST_OPT 'y'
static short zshletters[LAST_OPT - FIRST_OPT + 1] = {
/* 0 */ CORRECT,
/* 1 */ PRINTEXITVALUE,
/* 2 */ -BADPATTERN,
/* 3 */ -NOMATCH,
/* 4 */ GLOBDOTS,
/* 5 */ NOTIFY,
/* 6 */ BGNICE,
/* 7 */ IGNOREEOF,
/* 8 */ MARKDIRS,
/* 9 */ AUTOLIST,
/* : */ 0,
/* ; */ 0,
/* < */ 0,
/* = */ 0,
/* > */ 0,
/* ? */ 0,
/* @ */ 0,
/* A */ 0, /* use with set for arrays */
/* B */ -BEEP,
/* C */ -CLOBBER,
/* D */ PUSHDTOHOME,
/* E */ PUSHDSILENT,
/* F */ -GLOBOPT,
/* G */ NULLGLOB,
/* H */ RMSTARSILENT,
/* I */ IGNOREBRACES,
/* J */ AUTOCD,
/* K */ -BANGHIST,
/* L */ SUNKEYBOARDHACK,
/* M */ SINGLELINEZLE,
/* N */ AUTOPUSHD,
/* O */ CORRECTALL,
/* P */ RCEXPANDPARAM,
/* Q */ PATHDIRS,
/* R */ LONGLISTJOBS,
/* S */ RECEXACT,
/* T */ CDABLEVARS,
/* U */ MAILWARNING,
/* V */ -PROMPTCR,
/* W */ AUTORESUME,
/* X */ LISTTYPES,
/* Y */ MENUCOMPLETE,
/* Z */ USEZLE,
/* [ */ 0,
/* \ */ 0,
/* ] */ 0,
/* ^ */ 0,
/* _ */ 0,
/* ` */ 0,
/* a */ ALLEXPORT,
/* b */ 0, /* in non-Bourne shells, end of options */
/* c */ 0, /* command follows */
/* d */ -GLOBALRCS,
/* e */ ERREXIT,
/* f */ -RCS,
/* g */ HISTIGNORESPACE,
/* h */ HISTIGNOREDUPS,
/* i */ INTERACTIVE,
/* j */ 0,
/* k */ INTERACTIVECOMMENTS,
/* l */ LOGINSHELL,
/* m */ MONITOR,
/* n */ -EXECOPT,
/* o */ 0, /* long option name follows */
/* p */ PRIVILEGED,
/* q */ 0,
/* r */ RESTRICTED,
/* s */ SHINSTDIN,
/* t */ SINGLECOMMAND,
/* u */ -UNSET,
/* v */ VERBOSE,
/* w */ CHASELINKS,
/* x */ XTRACE,
/* y */ SHWORDSPLIT,
};
static short kshletters[LAST_OPT - FIRST_OPT + 1] = {
/* 0 */ 0,
/* 1 */ 0,
/* 2 */ 0,
/* 3 */ 0,
/* 4 */ 0,
/* 5 */ 0,
/* 6 */ 0,
/* 7 */ 0,
/* 8 */ 0,
/* 9 */ 0,
/* : */ 0,
/* ; */ 0,
/* < */ 0,
/* = */ 0,
/* > */ 0,
/* ? */ 0,
/* @ */ 0,
/* A */ 0,
/* B */ 0,
/* C */ -CLOBBER,
/* D */ 0,
/* E */ 0,
/* F */ 0,
/* G */ 0,
/* H */ 0,
/* I */ 0,
/* J */ 0,
/* K */ 0,
/* L */ 0,
/* M */ 0,
/* N */ 0,
/* O */ 0,
/* P */ 0,
/* Q */ 0,
/* R */ 0,
/* S */ 0,
/* T */ TRAPSASYNC,
/* U */ 0,
/* V */ 0,
/* W */ 0,
/* X */ MARKDIRS,
/* Y */ 0,
/* Z */ 0,
/* [ */ 0,
/* \ */ 0,
/* ] */ 0,
/* ^ */ 0,
/* _ */ 0,
/* ` */ 0,
/* a */ ALLEXPORT,
/* b */ NOTIFY,
/* c */ 0,
/* d */ 0,
/* e */ ERREXIT,
/* f */ -GLOBOPT,
/* g */ 0,
/* h */ 0,
/* i */ INTERACTIVE,
/* j */ 0,
/* k */ 0,
/* l */ LOGINSHELL,
/* m */ MONITOR,
/* n */ -EXECOPT,
/* o */ 0,
/* p */ PRIVILEGED,
/* q */ 0,
/* r */ RESTRICTED,
/* s */ SHINSTDIN,
/* t */ SINGLECOMMAND,
/* u */ -UNSET,
/* v */ VERBOSE,
/* w */ 0,
/* x */ XTRACE,
/* y */ 0,
};
/* Initialisation of the option name hash table */
/**/
static void
printoptionnode(HashNode hn, int set)
{
Optname on = (Optname) hn;
int optno = on->optno;
if (optno < 0)
optno = -optno;
if (isset(KSHOPTIONPRINT)) {
if (defset(on, emulation))
printf("no%-19s %s\n", on->node.nam, isset(optno) ? "off" : "on");
else
printf("%-21s %s\n", on->node.nam, isset(optno) ? "on" : "off");
} else if (set == (isset(optno) ^ defset(on, emulation))) {
if (set ^ isset(optno))
fputs("no", stdout);
puts(on->node.nam);
}
}
/**/
void
createoptiontable(void)
{
Optname on;
optiontab = newhashtable(101, "optiontab", NULL);
optiontab->hash = hasher;
optiontab->emptytable = NULL;
optiontab->filltable = NULL;
optiontab->cmpnodes = strcmp;
optiontab->addnode = addhashnode;
optiontab->getnode = gethashnode;
optiontab->getnode2 = gethashnode2;
optiontab->removenode = NULL;
optiontab->disablenode = disablehashnode;
optiontab->enablenode = enablehashnode;
optiontab->freenode = NULL;
optiontab->printnode = printoptionnode;
for (on = optns; on->node.nam; on++)
optiontab->addnode(optiontab, on->node.nam, on);
}
/* Emulation appropriate to the setemulate function */
static int setemulate_emulation;
/* Option array manipulated within the setemulate function */
/**/
static char *setemulate_opts;
/* Setting of default options */
/**/
static void
setemulate(HashNode hn, int fully)
{
Optname on = (Optname) hn;
/* Set options: each non-special option is set according to the *
* current emulation mode if either it is considered relevant *
* to emulation or we are doing a full emulation (as indicated *
* by the `fully' parameter). */
if (!(on->node.flags & OPT_ALIAS) &&
((fully && !(on->node.flags & OPT_SPECIAL)) ||
(on->node.flags & OPT_EMULATE)))
setemulate_opts[on->optno] = defset(on, setemulate_emulation);
}
/**/
void
installemulation(int new_emulation, char *new_opts)
{
setemulate_emulation = new_emulation;
setemulate_opts = new_opts;
scanhashtable(optiontab, 0, 0, 0, setemulate,
!!(new_emulation & EMULATE_FULLY));
}
/**/
void
emulate(const char *zsh_name, int fully, int *new_emulation, char *new_opts)
{
char ch = *zsh_name;
if (ch == 'r')
ch = zsh_name[1];
/* Work out the new emulation mode */
if (ch == 'c')
*new_emulation = EMULATE_CSH;
else if (ch == 'k')
*new_emulation = EMULATE_KSH;
else if (ch == 's' || ch == 'b')
*new_emulation = EMULATE_SH;
else
*new_emulation = EMULATE_ZSH;
if (fully)
*new_emulation |= EMULATE_FULLY;
installemulation(*new_emulation, new_opts);
if (funcstack && funcstack->tp == FS_FUNC) {
/*
* We are inside a function. Decide if it's traced.
* Pedantic note: the function in the function table isn't
* guaranteed to be what we're executing, but it's
* close enough.
*/
Shfunc shf = (Shfunc)shfunctab->getnode(shfunctab, funcstack->name);
if (shf && (shf->node.flags & (PM_TAGGED|PM_TAGGED_LOCAL))) {
/* Tracing is on, so set xtrace */
new_opts[XTRACE] = 1;
}
}
}
/* setopt, unsetopt */
/**/
static void
setoption(HashNode hn, int value)
{
dosetopt(((Optname) hn)->optno, value, 0, opts);
}
/**/
int
bin_setopt(char *nam, char **args, UNUSED(Options ops), int isun)
{
int action, optno, match = 0;
/* With no arguments or options, display options. */
if (!*args) {
scanhashtable(optiontab, 1, 0, OPT_ALIAS, optiontab->printnode, !isun);
return 0;
}
/* loop through command line options (begins with "-" or "+") */
while (*args && (**args == '-' || **args == '+')) {
action = (**args == '-') ^ isun;
if(!args[0][1])
*args = "--";
while (*++*args) {
if(**args == Meta)
*++*args ^= 32;
/* The pseudo-option `--' signifies the end of options. */
if (**args == '-') {
args++;
goto doneoptions;
} else if (**args == 'o') {
if (!*++*args)
args++;
if (!*args) {
zwarnnam(nam, "string expected after -o");
inittyptab();
return 1;
}
if(!(optno = optlookup(*args)))
zwarnnam(nam, "no such option: %s", *args);
else if(dosetopt(optno, action, 0, opts))
zwarnnam(nam, "can't change option: %s", *args);
break;
} else if(**args == 'm') {
match = 1;
} else {
if (!(optno = optlookupc(**args)))
zwarnnam(nam, "bad option: -%c", **args);
else if(dosetopt(optno, action, 0, opts))
zwarnnam(nam, "can't change option: -%c", **args);
}
}
args++;
}
doneoptions:
if (!match) {
/* Not globbing the arguments -- arguments are simply option names. */
while (*args) {
if(!(optno = optlookup(*args++)))
zwarnnam(nam, "no such option: %s", args[-1]);
else if(dosetopt(optno, !isun, 0, opts))
zwarnnam(nam, "can't change option: %s", args[-1]);
}
} else {
/* Globbing option (-m) set. */
while (*args) {
Patprog pprog;
char *s, *t;
t = s = dupstring(*args);
while (*t)
if (*t == '_')
chuck(t);
else {
/* See comment in optlookup() */
if (*t >= 'A' && *t <= 'Z')
*t = (*t - 'A') + 'a';
t++;
}
/* Expand the current arg. */
tokenize(s);
if (!(pprog = patcompile(s, PAT_HEAPDUP, NULL))) {
zwarnnam(nam, "bad pattern: %s", *args);
continue;
}
/* Loop over expansions. */
scanmatchtable(optiontab, pprog, 0, 0, OPT_ALIAS,
setoption, !isun);
args++;
}
}
inittyptab();
return 0;
}
/* Identify an option name */
/**/
mod_export int
optlookup(char const *name)
{
char *s, *t;
Optname n;
s = t = dupstring(name);
/* exorcise underscores, and change to lowercase */
while (*t)
if (*t == '_')
chuck(t);
else {
/*
* Some locales (in particular tr_TR.UTF-8) may
* have non-standard mappings of ASCII characters,
* so be careful. Option names must be ASCII so
* we don't need to be too clever.
*/
if (*t >= 'A' && *t <= 'Z')
*t = (*t - 'A') + 'a';
t++;
}
/* look up name in the table */
if (s[0] == 'n' && s[1] == 'o' &&
(n = (Optname) optiontab->getnode(optiontab, s + 2))) {
return -n->optno;
} else if ((n = (Optname) optiontab->getnode(optiontab, s)))
return n->optno;
else
return OPT_INVALID;
}
/* Identify an option letter */
/**/
int
optlookupc(char c)
{
if(c < FIRST_OPT || c > LAST_OPT)
return 0;
return optletters[c - FIRST_OPT];
}
/**/
static void
restrictparam(char *nam)
{
Param pm = (Param) paramtab->getnode(paramtab, nam);
if (pm) {
pm->node.flags |= PM_SPECIAL | PM_RESTRICTED;
return;
}
createparam(nam, PM_SCALAR | PM_UNSET | PM_SPECIAL | PM_RESTRICTED);
}
/* list of restricted parameters which are not otherwise special */
static char *rparams[] = {
"SHELL", "HISTFILE", "LD_LIBRARY_PATH", "LD_AOUT_LIBRARY_PATH",
"LD_PRELOAD", "LD_AOUT_PRELOAD", NULL
};
/* Set or unset an option, as a result of user request. The option *
* number may be negative, indicating that the sense is reversed *
* from the usual meaning of the option. */
/**/
mod_export int
dosetopt(int optno, int value, int force, char *new_opts)
{
if(!optno)
return -1;
if(optno < 0) {
optno = -optno;
value = !value;
}
if (optno == RESTRICTED) {
if (isset(RESTRICTED))
return value ? 0 : -1;
if (value) {
char **s;
for (s = rparams; *s; s++)
restrictparam(*s);
}
} else if(!force && optno == EXECOPT && !value && interact) {
/* cannot set noexec when interactive */
return -1;
} else if(!force && (optno == INTERACTIVE || optno == SHINSTDIN ||
optno == SINGLECOMMAND)) {
if (new_opts[optno] == value)
return 0;
/* it is not permitted to change the value of these options */
return -1;
} else if(!force && optno == USEZLE && value) {
/* we require a terminal in order to use ZLE */
if(!interact || SHTTY == -1 || !shout)
return -1;
} else if(optno == PRIVILEGED && !value) {
/* unsetting PRIVILEGED causes the shell to make itself unprivileged */
#ifdef HAVE_SETUID
int ignore_err;
errno = 0;
/*
* Set the GID first as if we set the UID to non-privileged it
* might be impossible to restore the GID.
*
* Some OSes (possibly no longer around) have been known to
* fail silently the first time, so we attempt the change twice.
* If it fails we are guaranteed to pick this up the second
* time, so ignore the first time.
*
* Some versions of gcc make it hard to ignore the results the
* first time, hence the following. (These are probably not
* systems that require the doubled calls.)
*/
ignore_err = setgid(getgid());
(void)ignore_err;
ignore_err = setuid(getuid());
(void)ignore_err;
if (setgid(getgid())) {
zwarn("failed to change group ID: %e", errno);
return -1;
} else if (setuid(getuid())) {
zwarn("failed to change user ID: %e", errno);
return -1;
}
#else
zwarn("setuid not available");
return -1;
#endif /* not HAVE_SETUID */
#ifdef JOB_CONTROL
} else if (!force && optno == MONITOR && value) {
if (new_opts[optno] == value)
return 0;
if (SHTTY != -1) {
origpgrp = GETPGRP();
acquire_pgrp();
} else
return -1;
#else
} else if(optno == MONITOR && value) {
return -1;
#endif /* not JOB_CONTROL */
#ifdef GETPWNAM_FAKED
} else if(optno == CDABLEVARS && value) {
return -1;
#endif /* GETPWNAM_FAKED */
} else if ((optno == EMACSMODE || optno == VIMODE) && value) {
if (sticky && sticky->emulation)
return -1;
zleentry(ZLE_CMD_SET_KEYMAP, optno);
new_opts[(optno == EMACSMODE) ? VIMODE : EMACSMODE] = 0;
} else if (optno == SUNKEYBOARDHACK) {
/* for backward compatibility */
keyboardhackchar = (value ? '`' : '\0');
}
new_opts[optno] = value;
if (optno == BANGHIST || optno == SHINSTDIN)
inittyptab();
return 0;
}
/* Function to get value for special parameter `-' */
/**/
char *
dashgetfn(UNUSED(Param pm))
{
static char buf[LAST_OPT - FIRST_OPT + 2];
char *val = buf;
int i;
for(i = 0; i <= LAST_OPT - FIRST_OPT; i++) {
int optno = optletters[i];
if(optno && ((optno > 0) ? isset(optno) : unset(-optno)))
*val++ = FIRST_OPT + i;
}
*val = '\0';
return buf;
}
/* print options for set -o/+o */
/**/
void
printoptionstates(int hadplus)
{
scanhashtable(optiontab, 1, 0, OPT_ALIAS, printoptionnodestate, hadplus);
}
/**/
static void
printoptionnodestate(HashNode hn, int hadplus)
{
Optname on = (Optname) hn;
int optno = on->optno;
if (hadplus) {
printf("set %co %s%s\n",
defset(on, emulation) != isset(optno) ? '-' : '+',
defset(on, emulation) ? "no" : "",
on->node.nam);
} else {
if (defset(on, emulation))
printf("no%-19s %s\n", on->node.nam, isset(optno) ? "off" : "on");
else
printf("%-21s %s\n", on->node.nam, isset(optno) ? "on" : "off");
}
}
/* Print option list for --help */
/**/
void
printoptionlist(void)
{
short *lp;
char c;
printf("\nNamed options:\n");
scanhashtable(optiontab, 1, 0, OPT_ALIAS, printoptionlist_printoption, 0);
printf("\nOption aliases:\n");
scanhashtable(optiontab, 1, OPT_ALIAS, 0, printoptionlist_printoption, 0);
printf("\nOption letters:\n");
for(lp = optletters, c = FIRST_OPT; c <= LAST_OPT; lp++, c++) {
if(!*lp)
continue;
printf(" -%c ", c);
printoptionlist_printequiv(*lp);
}
}
/**/
static void
printoptionlist_printoption(HashNode hn, UNUSED(int ignored))
{
Optname on = (Optname) hn;
if(on->node.flags & OPT_ALIAS) {
printf(" --%-19s ", on->node.nam);
printoptionlist_printequiv(on->optno);
} else
printf(" --%s\n", on->node.nam);
}
/**/
static void
printoptionlist_printequiv(int optno)
{
int isneg = optno < 0;
optno *= (isneg ? -1 : 1);
printf(" equivalent to --%s%s\n", isneg ? "no-" : "", optns[optno-1].node.nam);
}
/**/
static char *print_emulate_opts;
/**/
static void
print_emulate_option(HashNode hn, int fully)
{
Optname on = (Optname) hn;
if (!(on->node.flags & OPT_ALIAS) &&
((fully && !(on->node.flags & OPT_SPECIAL)) ||
(on->node.flags & OPT_EMULATE)))
{
if (!print_emulate_opts[on->optno])
fputs("no", stdout);
puts(on->node.nam);
}
}
/*
* List the settings of options associated with an emulation
*/
/**/
void list_emulate_options(char *cmdopts, int fully)
{
print_emulate_opts = cmdopts;
scanhashtable(optiontab, 1, 0, 0, print_emulate_option, fully);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,134 +0,0 @@
/*
* prototypes.h - prototypes header file
*
* This file is part of zsh, the Z shell.
*
* Copyright (c) 1992-1997 Paul Falstad
* All rights reserved.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and to distribute modified versions of this software for any
* purpose, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* In no event shall Paul Falstad or the Zsh Development Group be liable
* to any party for direct, indirect, special, incidental, or consequential
* damages arising out of the use of this software and its documentation,
* even if Paul Falstad and the Zsh Development Group have been advised of
* the possibility of such damage.
*
* Paul Falstad and the Zsh Development Group specifically disclaim any
* warranties, including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose. The software
* provided hereunder is on an "as is" basis, and Paul Falstad and the
* Zsh Development Group have no obligation to provide maintenance,
* support, updates, enhancements, or modifications.
*
*/
#ifndef HAVE_STDLIB_H
char *malloc _((size_t));
char *realloc _((void *, size_t));
char *calloc _((size_t, size_t));
#endif
#if !(defined(USES_TERMCAP_H) || defined(USES_TERM_H))
/*
* These prototypes are only used where we don't have the
* headers. In some cases they need tweaking.
* TBD: we'd much prefer to get hold of the header where
* these are defined.
*/
#ifdef _AIX
#define TC_CONST const
#else
#define TC_CONST
#endif
extern int tgetent _((char *bp, TC_CONST char *name));
extern int tgetnum _((char *id));
extern int tgetflag _((char *id));
extern char *tgetstr _((char *id, char **area));
extern int tputs _((TC_CONST char *cp, int affcnt, int (*outc) (int)));
#undef TC_CONST
#endif
/*
* Some systems that do have termcap headers nonetheless don't
* declare tgoto, so we detect if that is missing separately.
*/
#ifdef TGOTO_PROTO_MISSING
char *tgoto(const char *cap, int col, int row);
#endif
/* MISSING PROTOTYPES FOR VARIOUS OPERATING SYSTEMS */
#if defined(__hpux) && defined(_HPUX_SOURCE) && !defined(_XPG4_EXTENDED)
# define SELECT_ARG_2_T int *
#else
# define SELECT_ARG_2_T fd_set *
#endif
#ifdef __osf__
char *mktemp _((char *));
#endif
#if defined(__osf__) && defined(__alpha) && defined(__GNUC__)
/* Digital cc does not need these prototypes, gcc does need them */
# ifndef HAVE_IOCTL_PROTO
int ioctl _((int d, unsigned long request, void *argp));
# endif
# ifndef HAVE_MKNOD_PROTO
int mknod _((const char *pathname, int mode, dev_t device));
# endif
int nice _((int increment));
int select _((int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval *timeout));
#endif
#if defined(DGUX) && defined(__STDC__)
/* Just plain missing. */
extern int getrlimit _((int resource, struct rlimit *rlp));
extern int setrlimit _((int resource, const struct rlimit *rlp));
extern int getrusage _((int who, struct rusage *rusage));
extern int gettimeofday _((struct timeval *tv, struct timezone *tz));
extern int wait3 _((union wait *wait_status, int options, struct rusage *rusage));
extern int getdomainname _((char *name, int maxlength));
extern int select _((int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval *timeout));
#endif /* DGUX and __STDC__ */
#ifdef __NeXT__
extern pid_t getppid(void);
#endif
#if defined(__sun__) && !defined(__SVR4) /* SunOS */
extern char *strerror _((int errnum));
#endif
/**************************************************/
/*** prototypes for functions built in compat.c ***/
#ifndef HAVE_STRSTR
extern char *strstr _((const char *s, const char *t));
#endif
#ifndef HAVE_GETHOSTNAME
extern int gethostname _((char *name, size_t namelen));
#endif
#ifndef HAVE_GETTIMEOFDAY
extern int gettimeofday _((struct timeval *tv, struct timezone *tz));
#endif
#ifndef HAVE_DIFFTIME
extern double difftime _((time_t t2, time_t t1));
#endif
#ifndef HAVE_STRERROR
extern char *strerror _((int errnum));
#endif
/*** end of prototypes for functions in compat.c ***/
/***************************************************/
#ifndef HAVE_MEMMOVE
extern void bcopy _((const void *, void *, size_t));
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,142 +0,0 @@
/*
* signals.h - header file for signals handling code
*
* This file is part of zsh, the Z shell.
*
* Copyright (c) 1992-1997 Paul Falstad
* All rights reserved.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and to distribute modified versions of this software for any
* purpose, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* In no event shall Paul Falstad or the Zsh Development Group be liable
* to any party for direct, indirect, special, incidental, or consequential
* damages arising out of the use of this software and its documentation,
* even if Paul Falstad and the Zsh Development Group have been advised of
* the possibility of such damage.
*
* Paul Falstad and the Zsh Development Group specifically disclaim any
* warranties, including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose. The software
* provided hereunder is on an "as is" basis, and Paul Falstad and the
* Zsh Development Group have no obligation to provide maintenance,
* support, updates, enhancements, or modifications.
*
*/
#define SIGNAL_HANDTYPE void (*)_((int))
#ifndef HAVE_KILLPG
# define killpg(pgrp,sig) kill(-(pgrp),sig)
#endif
#define SIGZERR (SIGCOUNT+1)
#define SIGDEBUG (SIGCOUNT+2)
#define VSIGCOUNT (SIGCOUNT+3)
#define SIGEXIT 0
#ifdef SV_BSDSIG
# define SV_INTERRUPT SV_BSDSIG
#endif
/* If not a POSIX machine, then we create our *
* own POSIX style signal sets functions. */
#ifndef POSIX_SIGNALS
# define sigemptyset(s) (*(s) = 0)
# if NSIG == 32
# define sigfillset(s) (*(s) = ~(sigset_t)0, 0)
# else
# define sigfillset(s) (*(s) = (1 << NSIG) - 1, 0)
# endif
# define sigaddset(s,n) (*(s) |= (1 << ((n) - 1)), 0)
# define sigdelset(s,n) (*(s) &= ~(1 << ((n) - 1)), 0)
# define sigismember(s,n) ((*(s) & (1 << ((n) - 1))) != 0)
#endif /* ifndef POSIX_SIGNALS */
#define child_block() signal_block(sigchld_mask)
#define child_unblock() signal_unblock(sigchld_mask)
#ifdef SIGWINCH
# define winch_block() signal_block(signal_mask(SIGWINCH))
# define winch_unblock() signal_unblock(signal_mask(SIGWINCH))
#else
# define winch_block() 0
# define winch_unblock() 0
#endif
/* ignore a signal */
#define signal_ignore(S) signal(S, SIG_IGN)
/* return a signal to it default action */
#define signal_default(S) signal(S, SIG_DFL)
/* Use a circular queue to save signals caught during *
* critical sections of code. You call queue_signals to *
* start queueing, and unqueue_signals to process the *
* queue and stop queueing. Since the kernel doesn't *
* queue signals, it is probably overkill for zsh to do *
* this, but it shouldn't hurt anything to do it anyway. */
#define MAX_QUEUE_SIZE 128
#define run_queued_signals() do { \
while (queue_front != queue_rear) { /* while signals in queue */ \
sigset_t oset; \
queue_front = (queue_front + 1) % MAX_QUEUE_SIZE; \
oset = signal_setmask(signal_mask_queue[queue_front]); \
zhandler(signal_queue[queue_front]); /* handle queued signal */ \
signal_setmask(oset); \
} \
} while (0)
#ifdef DEBUG
#define queue_signals() (queue_in++, queueing_enabled++)
#define unqueue_signals() do { \
DPUTS(!queueing_enabled, "BUG: unqueue_signals called but not queueing"); \
--queue_in; \
if (!--queueing_enabled) run_queued_signals(); \
} while (0)
#define dont_queue_signals() do { \
queue_in = queueing_enabled; \
queueing_enabled = 0; \
run_queued_signals(); \
} while (0)
#define restore_queue_signals(q) do { \
DPUTS2(queueing_enabled && queue_in != q, \
"BUG: q = %d != queue_in = %d", q, queue_in); \
queue_in = (queueing_enabled = (q)); \
} while (0)
#else /* !DEBUG */
#define queue_signals() (queueing_enabled++)
#define unqueue_signals() do { \
if (!--queueing_enabled) run_queued_signals(); \
} while (0)
#define dont_queue_signals() do { \
queueing_enabled = 0; \
run_queued_signals(); \
} while (0)
#define restore_queue_signals(q) (queueing_enabled = (q))
#endif /* DEBUG */
#define queue_signal_level() queueing_enabled
#ifdef BSD_SIGNALS
#define signal_block(S) sigblock(S)
#else
extern sigset_t signal_block _((sigset_t));
#endif /* BSD_SIGNALS */
extern sigset_t signal_unblock _((sigset_t));

View File

@ -1,19 +0,0 @@
# This is an awk script which finds out what the possibilities for
# the signal names are, and dumps them out so that cpp can turn them
# into numbers. Since we don't need to decide here what the
# real signals are, we can afford to be generous about definitions,
# in case the definitions are in terms of other definitions.
# However, we need to avoid definitions with parentheses, which will
# mess up the syntax.
BEGIN { printf "#include <signal.h>\n\n" }
/^[\t ]*#[\t ]*define[\t _]*SIG[A-Z][A-Z0-9]*[\t ][\t ]*[^(\t ]/ {
sigindex = index($0, "SIG")
sigtail = substr($0, sigindex, 80)
split(sigtail, tmp)
signam = substr(tmp[1], 4, 20)
if (substr($0, sigindex-1, 1) == "_")
printf("XXNAMES XXSIG%s _SIG%s\n", signam, signam)
else
printf("XXNAMES XXSIG%s SIG%s\n", signam, signam)
}

View File

@ -1,106 +0,0 @@
#
# {g,n}awk script to generate signames.c
# This version relies on the previous output of the preprocessor
# on sigtmp.c, sigtmp.out, which is in turn generated by signames1.awk.
#
# NB: On SunOS 4.1.3 - user-functions don't work properly, also \" problems
# Without 0 + hacks some nawks compare numbers as strings
#
/^[\t ]*XXNAMES XXSIG[A-Z][A-Z0-9]*[\t ][\t ]*[1-9][0-9]*/ {
sigindex = index($0, "SIG")
sigtail = substr($0, sigindex, 80)
split(sigtail, tmp)
signam = substr(tmp[1], 4, 20)
signum = tmp[2]
if (signam == "CHLD" && sig[signum] == "CLD") sig[signum] = ""
if (signam == "POLL" && sig[signum] == "IO") sig[signum] = ""
if (sig[signum] == "") {
sig[signum] = signam
if (0 + max < 0 + signum && signum < 60)
max = signum
if (signam == "ABRT") { msg[signum] = "abort" }
if (signam == "ALRM") { msg[signum] = "alarm" }
if (signam == "BUS") { msg[signum] = "bus error" }
if (signam == "CHLD") { msg[signum] = "death of child" }
if (signam == "CLD") { msg[signum] = "death of child" }
if (signam == "CONT") { msg[signum] = "continued" }
if (signam == "EMT") { msg[signum] = "EMT instruction" }
if (signam == "FPE") { msg[signum] = "floating point exception" }
if (signam == "HUP") { msg[signum] = "hangup" }
if (signam == "ILL") { msg[signum] = "illegal hardware instruction" }
if (signam == "INFO") { msg[signum] = "status request from keyboard" }
if (signam == "INT") { msg[signum] = "interrupt" }
if (signam == "IO") { msg[signum] = "i/o ready" }
if (signam == "IOT") { msg[signum] = "IOT instruction" }
if (signam == "KILL") { msg[signum] = "killed" }
if (signam == "LOST") { msg[signum] = "resource lost" }
if (signam == "PIPE") { msg[signum] = "broken pipe" }
if (signam == "POLL") { msg[signum] = "pollable event occurred" }
if (signam == "PROF") { msg[signum] = "profile signal" }
if (signam == "PWR") { msg[signum] = "power fail" }
if (signam == "QUIT") { msg[signum] = "quit" }
if (signam == "SEGV") { msg[signum] = "segmentation fault" }
if (signam == "SYS") { msg[signum] = "invalid system call" }
if (signam == "TERM") { msg[signum] = "terminated" }
if (signam == "TRAP") { msg[signum] = "trace trap" }
if (signam == "URG") { msg[signum] = "urgent condition" }
if (signam == "USR1") { msg[signum] = "user-defined signal 1" }
if (signam == "USR2") { msg[signum] = "user-defined signal 2" }
if (signam == "VTALRM") { msg[signum] = "virtual time alarm" }
if (signam == "WINCH") { msg[signum] = "window size changed" }
if (signam == "XCPU") { msg[signum] = "cpu limit exceeded" }
if (signam == "XFSZ") { msg[signum] = "file size limit exceeded" }
}
}
END {
ps = "%s"
ifdstr = sprintf("# ifdef USE_SUSPENDED\n\t%csuspended%s%c,\n%s else\n\t%cstopped%s%c,\n# endif\n", 34, ps, 34, "#", 34, ps, 34)
printf "/** signames.c **/\n"
printf "/** architecture-customized signames.c for zsh **/\n"
printf "\n"
printf "#define SIGCOUNT\t%d\n", max
printf "\n"
printf "#include %czsh.mdh%c\n", 34, 34
printf "\n"
printf "/**/\n"
printf "#define sigmsg(sig) ((sig) <= SIGCOUNT ? sig_msg[sig]"
printf " : %c%s%c)", 34, "unknown signal", 34
printf "\n"
printf "/**/\n"
printf "mod_export char *sig_msg[SIGCOUNT+2] = {\n"
printf "\t%c%s%c,\n", 34, "done", 34
for (i = 1; i <= 0 + max; i++)
if (msg[i] == "") {
if (sig[i] == "")
printf("\t%c%c,\n", 34, 34)
else if (sig[i] == "STOP")
printf ifdstr, " (signal)", " (signal)"
else if (sig[i] == "TSTP")
printf ifdstr, "", ""
else if (sig[i] == "TTIN")
printf ifdstr, " (tty input)", " (tty input)"
else if (sig[i] == "TTOU")
printf ifdstr, " (tty output)", " (tty output)"
else
printf("\t%cSIG%s%c,\n", 34, sig[i], 34)
} else
printf("\t%c%s%c,\n", 34, msg[i], 34)
print "\tNULL"
print "};"
print ""
print "/**/"
printf "char *sigs[SIGCOUNT+4] = {\n"
printf("\t%cEXIT%c,\n", 34, 34)
for (i = 1; i <= 0 + max; i++)
if (sig[i] == "")
printf("\t%c%d%c,\n", 34, i, 34)
else
printf("\t%c%s%c,\n", 34, sig[i], 34)
printf("\t%cZERR%c,\n", 34, 34)
printf("\t%cDEBUG%c,\n", 34, 34)
print "\tNULL"
print "};"
}

View File

@ -1,213 +0,0 @@
/*
* string.c - string manipulation
*
* This file is part of zsh, the Z shell.
*
* Copyright (c) 2000 Peter Stephenson
* All rights reserved.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and to distribute modified versions of this software for any
* purpose, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* In no event shall Peter Stephenson or the Zsh Development Group be liable
* to any party for direct, indirect, special, incidental, or consequential
* damages arising out of the use of this software and its documentation,
* even if Peter Stephenson and the Zsh Development Group have been advised of
* the possibility of such damage.
*
* Peter Stephenson and the Zsh Development Group specifically disclaim any
* warranties, including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose. The software
* provided hereunder is on an "as is" basis, and Peter Stephenson and the
* Zsh Development Group have no obligation to provide maintenance,
* support, updates, enhancements, or modifications.
*/
#include "zsh.mdh"
/**/
mod_export char *
dupstring(const char *s)
{
char *t;
if (!s)
return NULL;
t = (char *) zhalloc(strlen((char *)s) + 1);
strcpy(t, s);
return t;
}
/* Duplicate string on heap when length is known */
/**/
mod_export char *
dupstring_wlen(const char *s, unsigned len)
{
char *t;
if (!s)
return NULL;
t = (char *) zhalloc(len + 1);
memcpy(t, s, len);
t[len] = '\0';
return t;
}
/* Duplicate string on heap, returning length of string */
/**/
mod_export char *
dupstring_glen(const char *s, unsigned *len_ret)
{
char *t;
if (!s)
return NULL;
t = (char *) zhalloc((*len_ret = strlen((char *)s)) + 1);
strcpy(t, s);
return t;
}
/**/
mod_export char *
ztrdup(const char *s)
{
char *t;
if (!s)
return NULL;
t = (char *)zalloc(strlen((char *)s) + 1);
strcpy(t, s);
return t;
}
/**/
#ifdef MULTIBYTE_SUPPORT
/**/
mod_export wchar_t *
wcs_ztrdup(const wchar_t *s)
{
wchar_t *t;
if (!s)
return NULL;
t = (wchar_t *)zalloc(sizeof(wchar_t) * (wcslen((wchar_t *)s) + 1));
wcscpy(t, s);
return t;
}
/**/
#endif /* MULTIBYTE_SUPPORT */
/* concatenate s1, s2, and s3 in dynamically allocated buffer */
/**/
mod_export char *
tricat(char const *s1, char const *s2, char const *s3)
{
/* This version always uses permanently-allocated space. */
char *ptr;
size_t l1 = strlen(s1);
size_t l2 = strlen(s2);
ptr = (char *)zalloc(l1 + l2 + strlen(s3) + 1);
strcpy(ptr, s1);
strcpy(ptr + l1, s2);
strcpy(ptr + l1 + l2, s3);
return ptr;
}
/**/
mod_export char *
zhtricat(char const *s1, char const *s2, char const *s3)
{
char *ptr;
size_t l1 = strlen(s1);
size_t l2 = strlen(s2);
ptr = (char *)zhalloc(l1 + l2 + strlen(s3) + 1);
strcpy(ptr, s1);
strcpy(ptr + l1, s2);
strcpy(ptr + l1 + l2, s3);
return ptr;
}
/* concatenate s1 and s2 in dynamically allocated buffer */
/**/
mod_export char *
dyncat(const char *s1, const char *s2)
{
/* This version always uses space from the current heap. */
char *ptr;
size_t l1 = strlen(s1);
ptr = (char *)zhalloc(l1 + strlen(s2) + 1);
strcpy(ptr, s1);
strcpy(ptr + l1, s2);
return ptr;
}
/**/
mod_export char *
bicat(const char *s1, const char *s2)
{
/* This version always uses permanently-allocated space. */
char *ptr;
size_t l1 = strlen(s1);
ptr = (char *)zalloc(l1 + strlen(s2) + 1);
strcpy(ptr, s1);
strcpy(ptr + l1, s2);
return ptr;
}
/* like dupstring(), but with a specified length */
/**/
mod_export char *
dupstrpfx(const char *s, int len)
{
char *r = zhalloc(len + 1);
memcpy(r, s, len);
r[len] = '\0';
return r;
}
/**/
mod_export char *
ztrduppfx(const char *s, int len)
{
/* This version always uses permanently-allocated space. */
char *r = zalloc(len + 1);
memcpy(r, s, len);
r[len] = '\0';
return r;
}
/* Append a string to an allocated string, reallocating to make room. */
/**/
mod_export char *
appstr(char *base, char const *append)
{
return strcat(realloc(base, strlen(base) + strlen(append) + 1), append);
}
/* Return a pointer to the last character of a string,
unless the string is empty. */
/**/
mod_export char *
strend(char *str)
{
if (*str == '\0')
return str;
return str + strlen (str) - 1;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,147 +0,0 @@
name=zsh/main
link=static
load=yes
# load=static should replace use of alwayslink
functions='Functions/Chpwd/* Functions/Exceptions/* Functions/Math/* Functions/Misc/* Functions/MIME/* Functions/Prompts/* Functions/VCS_Info/* Functions/VCS_Info/Backends/*'
nozshdep=1
alwayslink=1
# autofeatures not specified because of alwayslink
objects="signames.o builtin.o module.o lex.o exec.o mem.o \
string.o parse.o hashtable.o init.o input.o loop.o utils.o params.o options.o \
signals.o pattern.o prompt.o compat.o jobs.o glob.o"
headers="../config.h zsh_system.h zsh.h sigcount.h signals.h \
prototypes.h hashtable.h ztype.h"
hdrdeps="zshcurses.h zshterm.h"
:<<\Make
@CONFIG_MK@
# If we're using gcc as the preprocessor, get rid of the additional
# lines generated by the preprocessor as they can confuse the script.
# We don't need these in other cases either, but can't necessarily rely
# on the option to remove them being the same.
signames.c: signames1.awk signames2.awk ../config.h @SIGNAL_H@
$(AWK) -f $(sdir)/signames1.awk @SIGNAL_H@ >sigtmp.c
case "`$(CPP) --version </dev/null 2>&1`" in \
*"Free Software Foundation"*) \
$(CPP) -P sigtmp.c >sigtmp.out;; \
*) \
$(CPP) sigtmp.c >sigtmp.out;; \
esac
$(AWK) -f $(sdir)/signames2.awk sigtmp.out > $@
rm -f sigtmp.c sigtmp.out
sigcount.h: signames.c
grep 'define.*SIGCOUNT' signames.c > $@
init.o: bltinmods.list zshpaths.h zshxmods.h
init.o params.o parse.o: version.h
params.o: patchlevel.h
version.h: $(sdir_top)/Config/version.mk zshcurses.h zshterm.h
echo '#define ZSH_VERSION "'$(VERSION)'"' > $@
patchlevel.h: FORCE
@if [ -f $(sdir)/$@.release ]; then \
cp -f $(sdir)/$@.release $@; \
else \
echo '#define ZSH_PATCHLEVEL "'`cd $(sdir) && git describe --tags --long`'"' > $@.tmp; \
cmp $@ $@.tmp >/dev/null 2>&1 && rm -f $@.tmp || mv $@.tmp $@; \
fi
FORCE:
zshcurses.h: ../config.h
@if test x$(ZSH_CURSES_H) != x; then \
echo "#include <$(ZSH_CURSES_H)>" >zshcurses.h; \
else \
echo >zshcurses.h; \
fi
zshterm.h: ../config.h
@if test x$(ZSH_TERM_H) != x; then \
echo "#include <$(ZSH_TERM_H)>" >zshterm.h; \
else \
echo >zshterm.h; \
fi
zshpaths.h: Makemod $(CONFIG_INCS)
@echo '#define MODULE_DIR "'$(MODDIR)'"' > zshpaths.h.tmp
@if test x$(sitescriptdir) != xno; then \
echo '#define SITESCRIPT_DIR "'$(sitescriptdir)'"' >> zshpaths.h.tmp; \
fi
@if test x$(scriptdir) != xno; then \
echo '#define SCRIPT_DIR "'$(scriptdir)'"' >> zshpaths.h.tmp; \
fi
@if test x$(sitefndir) != xno; then \
echo '#define SITEFPATH_DIR "'$(sitefndir)'"' >> zshpaths.h.tmp; \
fi
@if test x$(fixed_sitefndir) != x; then \
echo '#define FIXED_FPATH_DIR "'$(fixed_sitefndir)'"' >> zshpaths.h.tmp; \
fi
@if test x$(fndir) != xno; then \
echo '#define FPATH_DIR "'$(fndir)'"' >> zshpaths.h.tmp; \
if test x$(FUNCTIONS_SUBDIRS) != x && \
test x$(FUNCTIONS_SUBDIRS) != xno; then \
fpath_tmp="`grep ' functions=.' \
$(dir_top)/config.modules | sed -e '/^#/d' -e '/ link=no/d' \
-e 's/^.* functions=//'`"; \
fpath_tmp=`for f in $$fpath_tmp; do \
echo $$f | sed -e 's%^Functions/%%' -e 's%/[^/]*$$%%' -e 's%/\*%%'; \
done | grep -v Scripts | sort | uniq`; \
fpath_tmp=`echo $$fpath_tmp | sed 's/ /\", \"/g'`; \
echo "#define FPATH_SUBDIRS { \"$$fpath_tmp\" }" \
>>zshpaths.h.tmp; \
fi; \
fi
@if test x$(additionalfpath) != x; then \
fpath_tmp="`echo $(additionalfpath) | sed -e 's:,:\", \":g'`"; \
echo "#define ADDITIONAL_FPATH { \"$$fpath_tmp\" }" >> zshpaths.h.tmp; \
fi
@if cmp -s zshpaths.h zshpaths.h.tmp; then \
rm -f zshpaths.h.tmp; \
echo "\`zshpaths.h' is up to date." ; \
else \
mv -f zshpaths.h.tmp zshpaths.h; \
echo "Updated \`zshpaths.h'." ; \
fi
bltinmods.list: modules.stamp mkbltnmlst.sh $(dir_top)/config.modules
srcdir='$(sdir)' CFMOD='$(dir_top)/config.modules' \
$(SHELL) $(sdir)/mkbltnmlst.sh $@
zshxmods.h: $(dir_top)/config.modules
@echo "Creating \`$@'."
@( \
for q_mod in `grep ' load=yes' $(dir_top)/config.modules | \
grep ' link=static' | sed -e '/^#/d' -e 's/ .*//' \
-e 's/^name=//' -e 's,Q,Qq,g;s,_,Qu,g;s,/,Qs,g'`; do \
test x$q_mod = xzshQsmain && continue; \
echo "#define LINKED_XMOD_$$q_mod 1"; \
done; \
for q_mod in `grep ' load=yes' $(dir_top)/config.modules | \
grep ' link=dynamic' | sed -e '/^#/d' -e 's/ .*//' \
-e 's/^name=//' -e 's,Q,Qq,g;s,_,Qu,g;s,/,Qs,g'`; do \
test x$q_mod = x && continue; \
echo "#ifdef DYNAMIC"; \
echo "# define UNLINKED_XMOD_$$q_mod 1"; \
echo "#endif"; \
done; \
) > $@
clean-here: clean.zsh
clean.zsh:
rm -f sigcount.h signames.c bltinmods.list version.h zshpaths.h zshxmods.h
# This is not properly part of this module, but it is built as if it were.
main.o: main.c zsh.mdh main.epro
$(CC) -c -I. -I$(sdir_top)/Src $(CPPFLAGS) $(DEFS) $(CFLAGS) -o $@ $(sdir)/main.c
main.syms: $(PROTODEPS)
proto.zsh: main.epro
Make

View File

@ -1,8 +0,0 @@
// Use this file as follows
//
// myapp.exe : myapp.o myapp.res
// gcc -mwindows myapp.o myapp.res -o $@
//
// myapp.res : myapp.rc resource.h
// windres $< -O coff -o $@
IDR_MAINFRAME ICON DISCARDABLE "zsh.ico"

View File

@ -1,900 +0,0 @@
/*
* system.h - system configuration header file
*
* This file is part of zsh, the Z shell.
*
* Copyright (c) 1992-1997 Paul Falstad
* All rights reserved.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and to distribute modified versions of this software for any
* purpose, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* In no event shall Paul Falstad or the Zsh Development Group be liable
* to any party for direct, indirect, special, incidental, or consequential
* damages arising out of the use of this software and its documentation,
* even if Paul Falstad and the Zsh Development Group have been advised of
* the possibility of such damage.
*
* Paul Falstad and the Zsh Development Group specifically disclaim any
* warranties, including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose. The software
* provided hereunder is on an "as is" basis, and Paul Falstad and the
* Zsh Development Group have no obligation to provide maintenance,
* support, updates, enhancements, or modifications.
*
*/
#if 0
/*
* Setting _XPG_IV here is actually wrong and is not needed
* with currently supported versions (5.43C20 and above)
*/
#ifdef sinix
# define _XPG_IV 1
#endif
#endif
#if defined(__linux) || defined(__GNU__) || defined(__GLIBC__) || defined(LIBC_MUSL) || defined(__CYGWIN__)
/*
* Turn on numerous extensions.
* This is in order to get the functions for manipulating /dev/ptmx.
*/
#define _GNU_SOURCE 1
#endif
#ifdef LIBC_MUSL
#define _POSIX_C_SOURCE 200809L
#endif
/* NeXT has half-implemented POSIX support *
* which currently fools configure */
#ifdef __NeXT__
# undef HAVE_TERMIOS_H
# undef HAVE_SYS_UTSNAME_H
#endif
#ifndef ZSH_NO_XOPEN
# ifdef ZSH_CURSES_SOURCE
# define _XOPEN_SOURCE_EXTENDED 1
# else
# ifdef MULTIBYTE_SUPPORT
/*
* Needed for wcwidth() which is part of XSI.
* Various other uses of the interface mean we can't get away with just
* _XOPEN_SOURCE.
*/
# define _XOPEN_SOURCE_EXTENDED 1
# endif /* MULTIBYTE_SUPPORT */
# endif /* ZSH_CURSES_SOURCE */
#endif /* ZSH_NO_XOPEN */
/*
* Solaris by default zeroes all elements of the tm structure in
* strptime(). Unfortunately that gives us no way of telling whether
* the tm_isdst element has been set from the input pattern. If it
* hasn't we want it to be -1 (undetermined) on input to mktime(). So
* we stop strptime() zeroing the struct tm and instead set all the
* elements ourselves.
*
* This is likely to be harmless everywhere else.
*/
#define _STRPTIME_DONTZERO
#ifdef PROTOTYPES
# define _(Args) Args
#else
# define _(Args) ()
#endif
#ifndef HAVE_ALLOCA
# define alloca zhalloc
#else
# ifdef __GNUC__
# define alloca __builtin_alloca
# else
# if HAVE_ALLOCA_H
# include <alloca.h>
# else
# ifdef _AIX
# pragma alloca
# else
# ifndef alloca
char *alloca _((size_t));
# endif
# endif
# endif
# endif
#endif
/*
* libc.h in an optional package for Debian Linux is broken (it
* defines dup() as a synonym for dup2(), which has a different
* number of arguments), so just include it for next.
*/
#ifdef __NeXT__
# ifdef HAVE_LIBC_H
# include <libc.h>
# endif
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_STDDEF_H
/*
* Seen on Solaris 8 with gcc: stddef defines offsetof, which clashes
* with system.h's definition of the symbol unless we include this
* first. Otherwise, this will be hooked in by wchar.h, too late
* for comfort.
*/
#include <stddef.h>
#endif
#include <stdio.h>
#include <ctype.h>
#include <sys/stat.h>
#include <signal.h>
#include <setjmp.h>
#ifdef HAVE_PWD_H
# include <pwd.h>
#endif
#ifdef HAVE_GRP_H
# include <grp.h>
#endif
#ifdef HAVE_DIRENT_H
# include <dirent.h>
#else /* !HAVE_DIRENT_H */
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
# ifdef HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif
# ifdef HAVE_NDIR_H
# include <ndir.h>
# endif
# define dirent direct
# undef HAVE_STRUCT_DIRENT_D_INO
# undef HAVE_STRUCT_DIRENT_D_STAT
# ifdef HAVE_STRUCT_DIRECT_D_INO
# define HAVE_STRUCT_DIRENT_D_INO HAVE_STRUCT_DIRECT_D_INO
# endif
# ifdef HAVE_STRUCT_DIRECT_D_STAT
# define HAVE_STRUCT_DIRENT_D_STAT HAVE_STRUCT_DIRECT_D_STAT
# endif
#endif /* !HAVE_DIRENT_H */
#ifdef HAVE_STDLIB_H
# ifdef ZSH_MEM
/* malloc and calloc are macros in GNU's stdlib.h unless the
* the __MALLOC_0_RETURNS_NULL macro is defined */
# define __MALLOC_0_RETURNS_NULL
# endif
# include <stdlib.h>
#endif
/*
* Stuff with variable arguments. We use definitions to make the
* same code work with varargs (the original K&R-style, just to
* be maximally compatible) and stdarg (which all modern systems
* should have).
*
* Ideally this should somehow be merged with the tricks performed
* with "_" in makepro.awk, but I don't understand makepro.awk.
* Currently we simply rely on the fact that makepro.awk has been
* hacked to leave alone argument lists that already contains VA_ALIST
* except for removing the VA_DCL and turning VA_ALIST into VA_ALIST_PROTO.
*/
#ifdef HAVE_STDARG_H
# include <stdarg.h>
# define VA_ALIST1(x) x, ...
# define VA_ALIST2(x,y) x, y, ...
# define VA_ALIST_PROTO1(x) VA_ALIST1(x)
# define VA_ALIST_PROTO2(x,y) VA_ALIST2(x,y)
# define VA_DCL
# define VA_DEF_ARG(x)
# define VA_START(ap,x) va_start(ap, x)
# define VA_GET_ARG(ap,x,t)
#else
# if HAVE_VARARGS_H
# include <varargs.h>
# define VA_ALIST1(x) va_alist
# define VA_ALIST2(x,y) va_alist
/*
* In prototypes, assume K&R form and remove the variable list.
* This is about the best we can do without second-guessing the way
* varargs works on this system. The _ trick should be able to
* do this for us but we've turned it off here.
*/
# define VA_ALIST_PROTO1(x)
# define VA_ALIST_PROTO2(x,y)
# define VA_DCL va_dcl
# define VA_DEF_ARG(x) x
# define VA_START(ap,x) va_start(ap);
# define VA_GET_ARG(ap,x,t) (x = va_arg(ap, t))
# else
# error "Your system has neither stdarg.h or varargs.h."
# endif
#endif
#ifdef HAVE_ERRNO_H
# include <errno.h>
#endif
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
/* This is needed by some old SCO unices */
#if !defined(HAVE_STRUCT_TIMEZONE) && !defined(ZSH_OOT_MODULE)
struct timezone {
int tz_minuteswest;
int tz_dsttime;
};
#endif
/* Used to provide compatibility with clock_gettime() */
#if !defined(HAVE_STRUCT_TIMESPEC) && !defined(ZSH_OOT_MODULE)
struct timespec {
time_t tv_sec;
long tv_nsec;
};
#endif
/* There's more than one non-standard way to get at this data */
#if !defined(HAVE_STRUCT_DIRENT_D_INO) && defined(HAVE_STRUCT_DIRENT_D_STAT)
# define d_ino d_stat.st_ino
# define HAVE_STRUCT_DIRENT_D_INO HAVE_STRUCT_DIRENT_D_STAT
#endif /* !HAVE_STRUCT_DIRENT_D_INO && HAVE_STRUCT_DIRENT_D_STAT */
/* Sco needs the following include for struct utimbuf *
* which is strange considering we do not use that *
* anywhere in the code */
#ifdef __sco
# include <utime.h>
#endif
#ifdef HAVE_SYS_TIMES_H
# include <sys/times.h>
#endif
#if STDC_HEADERS || HAVE_STRING_H
# include <string.h>
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
# if !STDC_HEADERS && HAVE_MEMORY_H
# include <memory.h>
# endif /* not STDC_HEADERS and HAVE_MEMORY_H */
#else /* not STDC_HEADERS and not HAVE_STRING_H */
# include <strings.h>
/* memory.h and strings.h conflict on some systems. */
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
#ifdef USE_STACK_ALLOCATION
#ifdef HAVE_VARIABLE_LENGTH_ARRAYS
# define VARARR(X,Y,Z) X (Y)[Z]
#else
# define VARARR(X,Y,Z) X *(Y) = (X *) alloca(sizeof(X) * (Z))
#endif
#else
# define VARARR(X,Y,Z) X *(Y) = (X *) zhalloc(sizeof(X) * (Z))
#endif
/* we should handle unlimited sizes from pathconf(_PC_PATH_MAX) */
/* but this is too much trouble */
#ifndef PATH_MAX
# ifdef MAXPATHLEN
# define PATH_MAX MAXPATHLEN
# else
# ifdef _POSIX_PATH_MAX
# define PATH_MAX _POSIX_PATH_MAX
# else
/* so we will just pick something */
# define PATH_MAX 1024
# endif
# endif
#endif
/*
* The number of file descriptors we'll allocate initially.
* We will reallocate later if necessary.
*/
#define ZSH_INITIAL_OPEN_MAX 64
#ifndef OPEN_MAX
# ifdef NOFILE
# define OPEN_MAX NOFILE
# else
/* so we will just pick something */
# define OPEN_MAX ZSH_INITIAL_OPEN_MAX
# endif
#endif
#ifndef HAVE_SYSCONF
# define zopenmax() ((long) (OPEN_MAX > ZSH_INITIAL_OPEN_MAX ? \
ZSH_INITIAL_OPEN_MAX : OPEN_MAX))
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#else
# include <sys/file.h>
#endif
/* The following will only be defined if <sys/wait.h> is POSIX. *
* So we don't have to worry about union wait. But some machines *
* (NeXT) include <sys/wait.h> from other include files, so we *
* need to undef and then redefine the wait macros if <sys/wait.h> *
* is not POSIX. */
#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
#else
# undef WIFEXITED
# undef WEXITSTATUS
# undef WIFSIGNALED
# undef WTERMSIG
# undef WCOREDUMP
# undef WIFSTOPPED
# undef WSTOPSIG
#endif
/* missing macros for wait/waitpid/wait3 */
#ifndef WIFEXITED
# define WIFEXITED(X) (((X)&0377)==0)
#endif
#ifndef WEXITSTATUS
# define WEXITSTATUS(X) (((X)>>8)&0377)
#endif
#ifndef WIFSIGNALED
# define WIFSIGNALED(X) (((X)&0377)!=0&&((X)&0377)!=0177)
#endif
#ifndef WTERMSIG
# define WTERMSIG(X) ((X)&0177)
#endif
#ifndef WCOREDUMP
# define WCOREDUMP(X) ((X)&0200)
#endif
#ifndef WIFSTOPPED
# define WIFSTOPPED(X) (((X)&0377)==0177)
#endif
#ifndef WSTOPSIG
# define WSTOPSIG(X) (((X)>>8)&0377)
#endif
#ifdef HAVE_SYS_SELECT_H
# ifndef TIME_H_SELECT_H_CONFLICTS
# include <sys/select.h>
# endif
#elif defined(SELECT_IN_SYS_SOCKET_H)
# include <sys/socket.h>
#endif
#if defined(__APPLE__) && defined(HAVE_SELECT)
/*
* Prefer select() to poll() on MacOS X since poll() is known
* to be problematic in 10.4
*/
#undef HAVE_POLL
#undef HAVE_POLL_H
#endif
#ifdef HAVE_SYS_FILIO_H
# include <sys/filio.h>
#endif
#ifdef HAVE_TERMIOS_H
# ifdef __sco
/* termios.h includes sys/termio.h instead of sys/termios.h; *
* hence the declaration for struct termios is missing */
# include <sys/termios.h>
# else
# include <termios.h>
# endif
# ifdef _POSIX_VDISABLE
# define VDISABLEVAL _POSIX_VDISABLE
# else
# define VDISABLEVAL 0
# endif
# define HAS_TIO 1
#else /* not TERMIOS */
# ifdef HAVE_TERMIO_H
# include <termio.h>
# define VDISABLEVAL -1
# define HAS_TIO 1
# else /* not TERMIOS and TERMIO */
# include <sgtty.h>
# endif /* HAVE_TERMIO_H */
#endif /* HAVE_TERMIOS_H */
#if defined(GWINSZ_IN_SYS_IOCTL) || defined(IOCTL_IN_SYS_IOCTL)
# include <sys/ioctl.h>
#endif
#ifdef WINSIZE_IN_PTEM
# include <sys/stream.h>
# include <sys/ptem.h>
#endif
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#ifdef HAVE_SYS_UTSNAME_H
# include <sys/utsname.h>
#endif
#define DEFAULT_WORDCHARS "*?_-.[]~=/&;!#$%^(){}<>"
#define DEFAULT_TIMEFMT "%J %U user %S system %P cpu %*E total"
/* Posix getpgrp takes no argument, while the BSD version *
* takes the process ID as an argument */
#ifdef GETPGRP_VOID
# define GETPGRP() getpgrp()
#else
# define GETPGRP() getpgrp(0)
#endif
#ifndef HAVE_GETLOGIN
# define getlogin() cuserid(NULL)
#endif
#ifdef HAVE_SETPGID
# define setpgrp setpgid
#endif
/* can we set the user/group id of a process */
#ifndef HAVE_SETUID
# ifdef HAVE_SETREUID
# define setuid(X) setreuid(X,X)
# define setgid(X) setregid(X,X)
# define HAVE_SETUID
# endif
#endif
/* can we set the effective user/group id of a process */
#ifndef HAVE_SETEUID
# ifdef HAVE_SETREUID
# define seteuid(X) setreuid(-1,X)
# define setegid(X) setregid(-1,X)
# define HAVE_SETEUID
# else
# ifdef HAVE_SETRESUID
# define seteuid(X) setresuid(-1,X,-1)
# define setegid(X) setresgid(-1,X,-1)
# define HAVE_SETEUID
# endif
# endif
#endif
#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
# if defined(__hpux) && !defined(RLIMIT_CPU)
/* HPUX does have the BSD rlimits in the kernel. Officially they are *
* unsupported but quite a few of them like RLIMIT_CORE seem to work. *
* All the following are in the <sys/resource.h> but made visible *
* only for the kernel. */
# define RLIMIT_CPU 0
# define RLIMIT_FSIZE 1
# define RLIMIT_DATA 2
# define RLIMIT_STACK 3
# define RLIMIT_CORE 4
# define RLIMIT_RSS 5
# define RLIMIT_NOFILE 6
# define RLIMIT_OPEN_MAX RLIMIT_NOFILE
# define RLIM_NLIMITS 7
# define RLIM_INFINITY 0x7fffffff
# endif
#endif
/* we use the SVR4 constant instead of the BSD one */
#if !defined(RLIMIT_NOFILE) && defined(RLIMIT_OFILE)
# define RLIMIT_NOFILE RLIMIT_OFILE
#endif
#if !defined(RLIMIT_VMEM) && defined(RLIMIT_AS)
# define RLIMIT_VMEM RLIMIT_AS
#endif
#ifdef HAVE_SYS_CAPABILITY_H
# include <sys/capability.h>
#endif
/* DIGBUFSIZ is the length of a buffer which can hold the -LONG_MAX-1 *
* (or with ZSH_64_BIT_TYPE maybe -LONG_LONG_MAX-1) *
* converted to printable decimal form including the sign and the *
* terminating null character. Below 0.30103 > lg 2. *
* BDIGBUFSIZE is for a number converted to printable binary form. */
#define DIGBUFSIZE ((int)(((sizeof(zlong) * 8) - 1) * 30103/100000) + 3)
#define BDIGBUFSIZE ((int)((sizeof(zlong) * 8) + 4))
/* If your stat macros are broken, we will *
* just undefine them. */
#ifdef STAT_MACROS_BROKEN
# undef S_ISBLK
# undef S_ISCHR
# undef S_ISDIR
# undef S_ISDOOR
# undef S_ISFIFO
# undef S_ISLNK
# undef S_ISMPB
# undef S_ISMPC
# undef S_ISNWK
# undef S_ISOFD
# undef S_ISOFL
# undef S_ISREG
# undef S_ISSOCK
#endif /* STAT_MACROS_BROKEN. */
/* If you are missing the stat macros, we *
* define our own */
#ifndef S_IFMT
# define S_IFMT 0170000
#endif
#if !defined(S_ISBLK) && defined(S_IFBLK)
# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#endif
#if !defined(S_ISCHR) && defined(S_IFCHR)
# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#endif
#if !defined(S_ISDIR) && defined(S_IFDIR)
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
#if !defined(S_ISDOOR) && defined(S_IFDOOR) /* Solaris */
# define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR)
#endif
#if !defined(S_ISFIFO) && defined(S_IFIFO)
# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#endif
#if !defined(S_ISLNK) && defined(S_IFLNK)
# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#endif
#if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
#endif
#if !defined(S_ISMPC) && defined(S_IFMPC) /* V7 */
# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
#endif
#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
# define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
#endif
#if !defined(S_ISOFD) && defined(S_IFOFD) /* Cray */
# define S_ISOFD(m) (((m) & S_IFMT) == S_IFOFD)
#endif
#if !defined(S_ISOFL) && defined(S_IFOFL) /* Cray */
# define S_ISOFL(m) (((m) & S_IFMT) == S_IFOFL)
#endif
#if !defined(S_ISREG) && defined(S_IFREG)
# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif
#if !defined(S_ISSOCK) && defined(S_IFSOCK)
# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
#endif
/* We will pretend to have all file types on any system. */
#ifndef S_ISBLK
# define S_ISBLK(m) ((void)(m), 0)
#endif
#ifndef S_ISCHR
# define S_ISCHR(m) ((void)(m), 0)
#endif
#ifndef S_ISDIR
# define S_ISDIR(m) ((void)(m), 0)
#endif
#ifndef S_ISDOOR
# define S_ISDOOR(m) ((void)(m), 0)
#endif
#ifndef S_ISFIFO
# define S_ISFIFO(m) ((void)(m), 0)
#endif
#ifndef S_ISLNK
# define S_ISLNK(m) ((void)(m), 0)
#endif
#ifndef S_ISMPB
# define S_ISMPB(m) ((void)(m), 0)
#endif
#ifndef S_ISMPC
# define S_ISMPC(m) ((void)(m), 0)
#endif
#ifndef S_ISNWK
# define S_ISNWK(m) ((void)(m), 0)
#endif
#ifndef S_ISOFD
# define S_ISOFD(m) ((void)(m), 0)
#endif
#ifndef S_ISOFL
# define S_ISOFL(m) ((void)(m), 0)
#endif
#ifndef S_ISREG
# define S_ISREG(m) ((void)(m), 0)
#endif
#ifndef S_ISSOCK
# define S_ISSOCK(m) ((void)(m), 0)
#endif
/* file mode permission bits */
#ifndef S_ISUID
# define S_ISUID 04000
#endif
#ifndef S_ISGID
# define S_ISGID 02000
#endif
#ifndef S_ISVTX
# define S_ISVTX 01000
#endif
#ifndef S_IRUSR
# define S_IRUSR 00400
#endif
#ifndef S_IWUSR
# define S_IWUSR 00200
#endif
#ifndef S_IXUSR
# define S_IXUSR 00100
#endif
#ifndef S_IRGRP
# define S_IRGRP 00040
#endif
#ifndef S_IWGRP
# define S_IWGRP 00020
#endif
#ifndef S_IXGRP
# define S_IXGRP 00010
#endif
#ifndef S_IROTH
# define S_IROTH 00004
#endif
#ifndef S_IWOTH
# define S_IWOTH 00002
#endif
#ifndef S_IXOTH
# define S_IXOTH 00001
#endif
#ifndef S_IRWXU
# define S_IRWXU (S_IRUSR|S_IWUSR|S_IXUSR)
#endif
#ifndef S_IRWXG
# define S_IRWXG (S_IRGRP|S_IWGRP|S_IXGRP)
#endif
#ifndef S_IRWXO
# define S_IRWXO (S_IROTH|S_IWOTH|S_IXOTH)
#endif
#ifndef S_IRUGO
# define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH)
#endif
#ifndef S_IWUGO
# define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH)
#endif
#ifndef S_IXUGO
# define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
#endif
#ifndef HAVE_LSTAT
# define lstat stat
#endif
#ifndef HAVE_READLINK
# define readlink(PATH, BUF, BUFSZ) \
((void)(PATH), (void)(BUF), (void)(BUFSZ), errno = ENOSYS, -1)
#endif
#ifndef F_OK /* missing macros for access() */
# define F_OK 0
# define X_OK 1
# define W_OK 2
# define R_OK 4
#endif
#ifndef HAVE_LCHOWN
# define lchown chown
#endif
#ifndef HAVE_MEMCPY
# define memcpy memmove
#endif
#ifndef HAVE_MEMMOVE
# ifndef memmove
static char *zmmv;
# define memmove(dest, src, len) (bcopy((src), zmmv = (dest), (len)), zmmv)
# endif
#endif
#ifndef offsetof
# define offsetof(TYPE, MEM) ((char *)&((TYPE *)0)->MEM - (char *)(TYPE *)0)
#endif
extern char **environ;
/*
* We always need setenv and unsetenv in pairs, because
* we don't know how to do memory management on the values set.
*/
#if defined(HAVE_SETENV) && defined(HAVE_UNSETENV) && !defined(__APPLE__)
# define USE_SET_UNSET_ENV
#endif
/* These variables are sometimes defined in, *
* and needed by, the termcap library. */
#if MUST_DEFINE_OSPEED
extern char PC, *BC, *UP;
extern short ospeed;
#endif
#ifndef O_NOCTTY
# define O_NOCTTY 0
#endif
#ifdef _LARGEFILE_SOURCE
#ifdef HAVE_FSEEKO
#define fseek fseeko
#endif
#ifdef HAVE_FTELLO
#define ftell ftello
#endif
#endif
/* Can't support job control without working tcsetgrp() */
#ifdef BROKEN_TCSETPGRP
#undef JOB_CONTROL
#endif /* BROKEN_TCSETPGRP */
#ifdef BROKEN_KILL_ESRCH
#undef ESRCH
#define ESRCH EINVAL
#endif /* BROKEN_KILL_ESRCH */
/* Can we do locale stuff? */
#undef USE_LOCALE
#if defined(CONFIG_LOCALE) && defined(HAVE_SETLOCALE) && defined(LC_ALL)
# define USE_LOCALE 1
#endif /* CONFIG_LOCALE && HAVE_SETLOCALE && LC_ALL */
#ifndef MAILDIR_SUPPORT
#define mailstat(X,Y) stat(X,Y)
#endif
#ifdef __CYGWIN__
# include <sys/cygwin.h>
# define IS_DIRSEP(c) ((c) == '/' || (c) == '\\')
#else
# define IS_DIRSEP(c) ((c) == '/')
#endif
#if defined(__GNUC__) && (!defined(__APPLE__) || defined(__clang__))
/* Does the OS X port of gcc still gag on __attribute__? */
#define UNUSED(x) x __attribute__((__unused__))
#else
#define UNUSED(x) x
#endif
/*
* The MULTIBYTE_SUPPORT configure-define specifies that we want to enable
* complete Unicode conversion between wide characters and multibyte strings.
*/
#if defined MULTIBYTE_SUPPORT \
|| (defined HAVE_WCHAR_H && defined HAVE_WCTOMB && defined __STDC_ISO_10646__)
/*
* If MULTIBYTE_SUPPORT is not defined, these includes provide a subset of
* Unicode support that makes the \u and \U printf escape sequences work.
*/
#if defined(__hpux) && !defined(_INCLUDE__STDC_A1_SOURCE)
#define _INCLUDE__STDC_A1_SOURCE
#endif
# include <wchar.h>
# include <wctype.h>
#endif
#ifdef HAVE_LANGINFO_H
# include <langinfo.h>
# ifdef HAVE_ICONV
# include <iconv.h>
# endif
#endif
#if defined(HAVE_INITGROUPS) && !defined(DISABLE_DYNAMIC_NSS)
# define USE_INITGROUPS
#endif
#if defined(HAVE_GETGRGID) && !defined(DISABLE_DYNAMIC_NSS)
# define USE_GETGRGID
#endif
#if defined(HAVE_GETGRNAM) && !defined(DISABLE_DYNAMIC_NSS)
# define USE_GETGRNAM
#endif
#if defined(HAVE_GETPWENT) && !defined(DISABLE_DYNAMIC_NSS)
# define USE_GETPWENT
#endif
#if defined(HAVE_GETPWNAM) && !defined(DISABLE_DYNAMIC_NSS)
# define USE_GETPWNAM
#endif
#if defined(HAVE_GETPWUID) && !defined(DISABLE_DYNAMIC_NSS)
# define USE_GETPWUID
#endif
#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
# define GET_ST_ATIME_NSEC(st) (st).st_atim.tv_nsec
#elif HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
# define GET_ST_ATIME_NSEC(st) (st).st_atimespec.tv_nsec
#elif HAVE_STRUCT_STAT_ST_ATIMENSEC
# define GET_ST_ATIME_NSEC(st) (st).st_atimensec
#endif
#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
# define GET_ST_MTIME_NSEC(st) (st).st_mtim.tv_nsec
#elif HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
# define GET_ST_MTIME_NSEC(st) (st).st_mtimespec.tv_nsec
#elif HAVE_STRUCT_STAT_ST_MTIMENSEC
# define GET_ST_MTIME_NSEC(st) (st).st_mtimensec
#endif
#ifdef HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC
# define GET_ST_CTIME_NSEC(st) (st).st_ctim.tv_nsec
#elif HAVE_STRUCT_STAT_ST_CTIMESPEC_TV_NSEC
# define GET_ST_CTIME_NSEC(st) (st).st_ctimespec.tv_nsec
#elif HAVE_STRUCT_STAT_ST_CTIMENSEC
# define GET_ST_CTIME_NSEC(st) (st).st_ctimensec
#endif
#if defined(HAVE_TGETENT) && !defined(ZSH_NO_TERM_HANDLING)
# if defined(ZSH_HAVE_CURSES_H) && defined(ZSH_HAVE_TERM_H)
# define USES_TERM_H 1
# else
# ifdef HAVE_TERMCAP_H
# define USES_TERMCAP_H 1
# endif
# endif
# ifdef USES_TERM_H
# ifdef HAVE_TERMIO_H
# include <termio.h>
# endif
# ifdef ZSH_HAVE_CURSES_H
# include "zshcurses.h"
# endif
# include "zshterm.h"
# else
# ifdef USES_TERMCAP_H
# include <termcap.h>
# endif
# endif
#endif
#ifdef HAVE_SRAND_DETERMINISTIC
# define srand srand_deterministic
#endif
#ifdef ZSH_VALGRIND
# include "valgrind/valgrind.h"
# include "valgrind/memcheck.h"
#endif

View File

@ -1,89 +0,0 @@
/*
* ztype.h - character classification macros
*
* This file is part of zsh, the Z shell.
*
* Copyright (c) 1992-1997 Paul Falstad
* All rights reserved.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and to distribute modified versions of this software for any
* purpose, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* In no event shall Paul Falstad or the Zsh Development Group be liable
* to any party for direct, indirect, special, incidental, or consequential
* damages arising out of the use of this software and its documentation,
* even if Paul Falstad and the Zsh Development Group have been advised of
* the possibility of such damage.
*
* Paul Falstad and the Zsh Development Group specifically disclaim any
* warranties, including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose. The software
* provided hereunder is on an "as is" basis, and Paul Falstad and the
* Zsh Development Group have no obligation to provide maintenance,
* support, updates, enhancements, or modifications.
*
*/
#define IDIGIT (1 << 0)
#define IALNUM (1 << 1)
#define IBLANK (1 << 2)
#define INBLANK (1 << 3)
#define ITOK (1 << 4)
#define ISEP (1 << 5)
#define IALPHA (1 << 6)
#define IIDENT (1 << 7)
#define IUSER (1 << 8)
#define ICNTRL (1 << 9)
#define IWORD (1 << 10)
#define ISPECIAL (1 << 11)
#define IMETA (1 << 12)
#define IWSEP (1 << 13)
#define INULL (1 << 14)
#define IPATTERN (1 << 15)
#define zistype(X,Y) (typtab[STOUC(X)] & Y)
#define idigit(X) zistype(X,IDIGIT)
#define ialnum(X) zistype(X,IALNUM)
#define iblank(X) zistype(X,IBLANK) /* blank, not including \n */
#define inblank(X) zistype(X,INBLANK) /* blank or \n */
#define itok(X) zistype(X,ITOK)
#define isep(X) zistype(X,ISEP)
#define ialpha(X) zistype(X,IALPHA)
#define iident(X) zistype(X,IIDENT)
#define iuser(X) zistype(X,IUSER) /* username char */
#define icntrl(X) zistype(X,ICNTRL)
#define iword(X) zistype(X,IWORD)
#define ispecial(X) zistype(X,ISPECIAL)
#define imeta(X) zistype(X,IMETA)
#define iwsep(X) zistype(X,IWSEP)
#define inull(X) zistype(X,INULL)
#define ipattern(X) zistype(X,IPATTERN)
/*
* Bit flags for typtab_flags --- preserved after
* shell initialisation.
*/
#define ZTF_INIT (0x0001) /* One-off initialisation done */
#define ZTF_INTERACT (0x0002) /* Shell interative and reading from stdin */
#define ZTF_SP_COMMA (0x0004) /* Treat comma as a special characters */
#define ZTF_BANGCHAR (0x0008) /* Treat bangchar as a special character */
#ifdef MULTIBYTE_SUPPORT
#define WC_ZISTYPE(X,Y) wcsitype((X),(Y))
# ifdef ENABLE_UNICODE9
# define WC_ISPRINT(X) u9_iswprint(X)
# else
# define WC_ISPRINT(X) iswprint(X)
# endif
#else
#define WC_ZISTYPE(X,Y) zistype((X),(Y))
#define WC_ISPRINT(X) isprint(X)
#endif
#if defined(__APPLE__) && defined(BROKEN_ISPRINT)
#define ZISPRINT(c) isprint_ascii(c)
#else
#define ZISPRINT(c) isprint(c)
#endif

View File

@ -1,3 +0,0 @@
Makefile
*.tmp
*.swp

View File

@ -1,2 +0,0 @@
DISTFILES_SRC='
'

View File

@ -1,790 +0,0 @@
#
# This file contains tests corresponding to the `Shell Grammar' texinfo node.
#
%prep
mkdir basic.tmp && cd basic.tmp
touch foo bar
echo "'" >unmatched_quote.txt
%test
#
# Tests for `Simple Commands and Pipelines'
#
# Test skipping early to ensure we run the remainder...
if [[ -n $ZTST_test_skip ]]; then
ZTST_skip="Test system verification for skipping"
else
print "This is standard output"
print "This is standard error" >&2
false
fi
1:Test skipping if ZTST_test_skip is set
>This is standard output
?This is standard error
echo foo | cat | sed 's/foo/bar/'
0:Basic pipeline handling
>bar
false | true
0:Exit status of pipeline with builtins (true)
true | false
1:Exit status of pipeline with builtins (false)
false
$nonexistent_variable
0:Executing command that evaluates to empty resets status
false
sleep 1 &
print $?
# a tidy test is a happy test
wait $!
0:Starting background command resets status
>0
false
. /dev/null
0:Sourcing empty file resets status
fn() { local foo; read foo; print $foo; }
coproc fn
print -p coproc test output
read -p bar
print $bar
0:Basic coprocess handling
>coproc test output
true | false && print true || print false
0:Basic sublist (i)
>false
false | true && print true || print false
0:Basic sublist (ii)
>true
(cd /NonExistentDirectory >&/dev/null) || print false
0:Basic subshell list with error
>false
{ cd /NonExistentDirectory >&/dev/null } || print false
0:Basic current shell list with error
>false
#
# Tests for `Precommand Modifiers'
#
- $ZTST_testdir/../Src/zsh -fc "[[ \$0 = \"-$ZTST_testdir/../Src/zsh\" ]]"
0:`-' precommand modifier
echo f*
noglob echo f*
0:`noglob' precommand modifier
>foo
>f*
(exec /bin/sh; echo bar)
0:`exec' precommand modifier
(exec -l $ZTST_testdir/../Src/zsh -fc 'echo $0' | sed 's%/.*/%%' )
0:`exec' with -l option
>-zsh
(exec -a /bin/SPLATTER /bin/sh -c 'echo $0')
0:`exec' with -a option
>/bin/SPLATTER
(exec -a/bin/SPLOOSH /bin/sh -c 'echo $0')
0:`exec' with -a option, no space
>/bin/SPLOOSH
(export FOO=bar; exec -c /bin/sh -c 'echo x${FOO}x')
0:`exec' with -c option
>xx
cat() { echo Function cat executed; }
command cat && unfunction cat
0:`command' precommand modifier
<External command cat executed
>External command cat executed
command -pv cat
command -pv echo
command -p -V cat
command -p -V -- echo
0:command -p in combination
*>*/cat
>echo
>cat is /*/cat
>echo is a shell builtin
cd() { echo Not cd at all; }
builtin cd . && unfunction cd
0:`builtin' precommand modifier
#
# Tests for `Complex Commands'
#
if true; then
print true-1
elif true; then
print true-2
else
print false
fi
0:`if ...' (i)
>true-1
if false; then
print true-1
elif true; then
print true-2
else
print false
fi
0:`if ...' (ii)
>true-2
if false; then
print true-1
elif false; then
print true-2
else
print false
fi
0:`if ...' (iii)
>false
if true;
:
fi
1d:`if ...' (iv)
?(eval):3: parse error near `fi'
for name in word to term; do
print $name
done
0:`for' loop
>word
>to
>term
for name
in word to term; do
print $name
done
0:`for' loop with newline before in keyword
>word
>to
>term
for (( name = 0; name < 3; name++ )); do
print $name
done
0:arithmetic `for' loop
>0
>1
>2
for (( $(true); ; )); do break; done
for (( ; $(true); )); do break; done
for (( ; ; $(true) )); do break; done
for (( ; $((1)); )); do break; done
0:regression test, nested cmdsubst in arithmetic `for' loop
for keyvar valvar in key1 val1 key2 val2; do
print key=$keyvar val=$valvar
done
0:enhanced `for' syntax with two loop variables
>key=key1 val=val1
>key=key2 val=val2
for keyvar valvar stuffvar in keyA valA stuffA keyB valB stuffB; do
print key=$keyvar val=$valvar stuff=$stuffvar
done
0:enhanced `for' syntax with three loop variables
>key=keyA val=valA stuff=stuffA
>key=keyB val=valB stuff=stuffB
for in in in in in stop; do
print in=$in
done
0:compatibility of enhanced `for' syntax with standard syntax
>in=in
>in=in
>in=in
>in=stop
name=0
while (( name < 3 )); do
print $name
(( name++ ))
done
0:`while' loop
>0
>1
>2
name=0
until (( name == 3 )); do
print $name
(( name++ ))
done
0:`until' loop
>0
>1
>2
repeat 3 do
echo over and over
done
0:`repeat' loop
>over and over
>over and over
>over and over
word=Trinity
case $word in
Michaelmas) print 0
;;
Hilary) print 1
;;
Trinity) print 2
;;
*) print 3
;;
esac
0:`case', old syntax
>2
word=Trinity
case $word in
(Michaelmas) print 0
;;
(Hilary) print 1
;;
(Trinity) print 2
;;
(*) print 3
;;
esac
0:`case', new syntax
>2
word=Hilary
case $word in
(Michaelmas) print 0
;;
(Hilary) print 1
;&
(Trinity) print 2
;&
(*) print 3
;;
esac
0:`case', new syntax, cascaded
>1
>2
>3
case whatever in
(*) print yeah, right ;&
esac
print but well
0:'case', redundant final ";&"
>yeah, right
>but well
## Select now reads from stdin if the shell is not interactive.
## Its own output goes to stderr.
(COLUMNS=80 LINES=3
PS3="input> "
select name in one two three; do
print $name
done)
0:`select' loop
<2
?1) one 2) two 3) three
?input> input>
>two
function name1 name2 () { print This is $0; }
name2
name1 name2() { print This is still $0; }
name2
0:`function' keyword
>This is name2
>This is still name2
(time cat) >&/dev/null
0:`time' keyword (status only)
if [[ -f foo && -d . && -n $ZTST_testdir ]]; then
true
else
false
fi
0:basic [[ ... ]] test
#
# Current shell execution with try/always form.
# We put those with errors in subshells so that any unhandled error doesn't
# propagate.
#
{
print The try block.
} always {
print The always block.
}
print After the always block.
0:Basic `always' syntax
>The try block.
>The always block.
>After the always block.
({
print Position one.
print ${*this is an error*}
print Position two.
} always {
if (( TRY_BLOCK_ERROR )); then
print An error occurred.
else
print No error occurred.
fi
}
print Position three)
1:Always block with error not reset
>Position one.
>An error occurred.
?(eval):3: bad substitution
({
print Stelle eins.
print ${*voici une erreur}
print Posizione due.
} always {
if (( TRY_BLOCK_ERROR )); then
print Erratum factum est. Retro ponetur.
(( TRY_BLOCK_ERROR = 0 ))
else
print unray touay foay anguageslay
fi
}
print Status after always block is $?.)
0:Always block with error reset
>Stelle eins.
>Erratum factum est. Retro ponetur.
>Status after always block is 1.
?(eval):3: bad substitution
fn() { { return } always { echo always 1 }; echo not executed }
fn
fn() { { echo try 2 } always { return }; echo not executed }
fn
0:Always block interaction with return
>always 1
>try 2
# Outputting of structures from the wordcode is distinctly non-trivial,
# we probably ought to have more like the following...
fn1() { { echo foo; } }
fn2() { { echo foo; } always { echo bar; } }
fn3() { ( echo foo; ) }
functions fn1 fn2 fn3
0:Output of syntactic structures with and without always blocks
>fn1 () {
> {
> echo foo
> }
>}
>fn2 () {
> {
> echo foo
> } always {
> echo bar
> }
>}
>fn3 () {
> (
> echo foo
> )
>}
#
# Tests for `Alternate Forms For Complex Commands'
#
if (true) { print true-1 } elif (true) { print true-2 } else { print false }
if (false) { print true-1 } elif (true) { print true-2 } else { print false }
if (false) { print true-1 } elif (false) { print true-2 } else { print false }
0:Alternate `if' with braces
>true-1
>true-2
>false
if { true } print true
if { false } print false
0:Short form of `if'
>true
eval "if"
1:Short form of `if' can't be too short
?(eval):1: parse error near `if'
for name ( word1 word2 word3 ) print $name
0:Form of `for' with parentheses.
>word1
>word2
>word3
for name in alpha beta gamma; print $name
0:Short form of `for'
>alpha
>beta
>gamma
for (( val = 2; val < 10; val *= val )) print $val
0:Short arithmetic `for'
>2
>4
foreach name ( verbiage words periphrasis )
print $name
end
0:Csh-like `for'
>verbiage
>words
>periphrasis
# see comment with braces used in if loops
val=0;
while (( val < 2 )) { print $((val++)); }
0:Alternative `while'
>0
>1
val=2;
until (( val == 0 )) { print $((val--)); }
0:Alternative `until'
>2
>1
repeat 3 print Hip hip hooray
0:Short `repeat'
>Hip hip hooray
>Hip hip hooray
>Hip hip hooray
case bravo {
(alpha) print schmalpha
;;
(bravo) print schmavo
;;
(charlie) print schmarlie
;;
}
0:`case' with braces
>schmavo
for word in artichoke bladderwort chrysanthemum Zanzibar
case $word in
(*der*) print $word contains the forbidden incantation der
;;
(a*) print $word begins with a
;&
([[:upper:]]*) print $word either begins with a or an upper case letter
;|
([[:lower:]]*) print $word begins with a lower case letter
;|
(*e*) print $word contains an e
;;
esac
0:`case' with mixed ;& and ;|
>artichoke begins with a
>artichoke either begins with a or an upper case letter
>artichoke begins with a lower case letter
>artichoke contains an e
>bladderwort contains the forbidden incantation der
>chrysanthemum begins with a lower case letter
>chrysanthemum contains an e
>Zanzibar either begins with a or an upper case letter
print -u $ZTST_fd 'This test hangs the shell when it fails...'
name=0
# The number 4375 here is chosen to produce more than 16384 bytes of output
while (( name < 4375 )); do
print -n $name
(( name++ ))
done < /dev/null | { read name; print done }
0:Bug regression: `while' loop with redirection and pipeline
>done
# This used to be buggy and print X at the end of each iteration.
for f in 1 2 3 4; do
print $f || break
done && print X
0:Handling of ||'s and &&'s with a for loop in between
>1
>2
>3
>4
>X
# Same bug for &&, used to print `no' at the end of each iteration
for f in 1 2 3 4; do
false && print strange
done || print no
0:Handling of &&'s and ||'s with a for loop in between
>no
$ZTST_testdir/../Src/zsh -f unmatched_quote.txt
1:Parse error with file causes non-zero exit status
?unmatched_quote.txt:2: unmatched '
$ZTST_testdir/../Src/zsh -f <unmatched_quote.txt
1:Parse error on standard input causes non-zero exit status
?zsh: unmatched '
$ZTST_testdir/../Src/zsh -f -c "'"
1:Parse error on inline command causes non-zero exit status
?zsh:1: unmatched '
$ZTST_testdir/../Src/zsh -f NonExistentScript
127q:Non-existent script causes exit status 127
?$ZTST_testdir/../Src/zsh: can't open input file: NonExistentScript
(setopt nonomatch
# use this to get stuff at start of line
contents=$'# comment \'\necho value #with " stuff\n# comment\n#comment
echo not#comment\n'
eval 'VAR=$('"$contents"')'
print -l $VAR)
0:comments within $(...)
>value
>not#comment
. ./nonexistent
127: Attempt to "." non-existent file.
?(eval):.:1: no such file or directory: ./nonexistent
echo '[[' >bad_syntax
. ./bad_syntax
126: Attempt to "." file with bad syntax.
?./bad_syntax:2: parse error near `\n'
# `
echo 'false' >dot_false
. ./dot_false
print $?
echo 'true' >dot_true
. ./dot_true
print $?
0:Last status of successfully executed "." file is retained
>1
>0
echo 'echo $?' >dot_status
false
. ./dot_status
0:"." file sees status from previous command
>1
mkdir test_path_script
print "#!/bin/sh\necho Found the script." >test_path_script/myscript
chmod u+x test_path_script/myscript
path=($PWD/test_path_script $path)
export PATH
$ZTST_testdir/../Src/zsh -f -o pathscript myscript
0:PATHSCRIPT option
>Found the script.
$ZTST_testdir/../Src/zsh -f myscript
127q:PATHSCRIPT option not used.
?$ZTST_testdir/../Src/zsh: can't open input file: myscript
# '
$ZTST_testdir/../Src/zsh -fc 'echo $0; echo $1' myargzero myargone
0:$0 is traditionally if bizarrely set to the first argument with -c
>myargzero
>myargone
(setopt shglob
eval '
if ! (echo success1); then echo failure1; fi
if !(echo success2); then echo failure2; fi
print -l one two | while(read foo)do(print read it)done
')
0:Parentheses in shglob
>success1
>success2
>read it
>read it
(
mywrap() { echo BEGIN; true; echo END }
mytest() { { exit 3 } always { mywrap }; print Exited before this }
mytest
print Exited before this, too
)
3:Exit and always block with functions: simple
>BEGIN
>END
(
mytrue() { echo mytrue; return 0 }
mywrap() { echo BEGIN; mytrue; echo END }
mytest() { { exit 4 } always { mywrap }; print Exited before this }
mytest
print Exited before this, too
)
4:Exit and always block with functions: nested
>BEGIN
>mytrue
>END
(emulate sh -c '
fn() {
case $1 in
( one | two | three )
print Matched $1
;;
( fo* | fi* | si* )
print Pattern matched $1
;;
( []x | a[b]* )
print Character class matched $1
;;
esac
}
'
which fn
fn one
fn two
fn three
fn four
fn five
fn six
fn abecedinarian
fn xylophone)
0: case word handling in sh emulation (SH_GLOB parentheses)
>fn () {
> case $1 in
> (one | two | three) print Matched $1 ;;
> (fo* | fi* | si*) print Pattern matched $1 ;;
> ([]x | a[b]*) print Character class matched $1 ;;
> esac
>}
>Matched one
>Matched two
>Matched three
>Pattern matched four
>Pattern matched five
>Pattern matched six
>Character class matched abecedinarian
case grumph in
( no | (grumph) )
print 1 OK
;;
esac
case snruf in
( fleer | (|snr(|[au]f)) )
print 2 OK
;;
esac
0: case patterns within words
>1 OK
>2 OK
case horrible in
([a-m])(|[n-z])rr(|ib(um|le|ah)))
print It worked
;;
esac
case "a string with separate words" in
(*with separate*))
print That worked, too
;;
esac
0:Unbalanced parentheses and spaces with zsh pattern
>It worked
>That worked, too
case horrible in
(([a-m])(|[n-z])rr(|ib(um|le|ah)))
print It worked
;;
esac
case "a string with separate words" in
(*with separate*)
print That worked, too
;;
esac
0:Balanced parentheses and spaces with zsh pattern
>It worked
>That worked, too
fn() {
typeset ac_file="the else branch"
case $ac_file in
*.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
*.* ) break;;
*)
;;
esac
print Stuff here
}
which fn
fn
0:Long case with parsed alternatives turned back into text
>fn () {
> typeset ac_file="the else branch"
> case $ac_file in
> (*.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj) ;;
> (*.*) break ;;
> (*) ;;
> esac
> print Stuff here
>}
>Stuff here
(exit 37)
case $? in
(37) echo $?
;;
esac
0:case retains exit status for execution of cases
>37
false
case stuff in
(nomatch) foo
;;
esac
echo $?
0:case sets exit status to zero if no patterns are matched
>0
case match in
(match) true; false; (exit 37)
;;
esac
echo $?
0:case keeps exit status of last command executed in compound-list
>37
x=1
x=2 | echo $x
echo $x
0:Assignment-only current shell commands in LHS of pipelin
>1
>1

View File

@ -1,139 +0,0 @@
# To get the "command not found" message when aliasing is suppressed
# we need, er, a command that isn't found.
# The other aliases are only ever used as aliases.
%prep
alias ThisCommandDefinitelyDoesNotExist=echo
alias -g bar=echo
alias '\bar=echo'
%test
ThisCommandDefinitelyDoesNotExist ThisCommandDefinitelyDoesNotExist
0:Basic aliasing
>ThisCommandDefinitelyDoesNotExist
bar bar
0:Global aliasing
>echo
\ThisCommandDefinitelyDoesNotExist ThisCommandDefinitelyDoesNotExist
127:Not aliasing
?(eval):1: command not found: ThisCommandDefinitelyDoesNotExist
\bar \bar
0:Aliasing with a backslash
>bar
(alias '!=echo This command has the argument'
eval 'print Without
! true'
setopt posixaliases
eval 'print With
! true')
1:POSIX_ALIASES option
>Without
>This command has the argument true
>With
print -u $ZTST_fd 'This test hangs the shell when it fails...'
alias cat='LC_ALL=C cat'
cat <(echo foo | cat)
0:Alias expansion works at the end of parsed strings
>foo
alias -g '&&=(){ return $?; } && '
alias not_the_print_command=print
eval 'print This is output
&& print And so is this
&& { print And this too; false; }
&& print But not this
&& print Nor this
true
&& not_the_print_command And aliases are expanded'
0:We can now alias special tokens. Woo hoo.
>This is output
>And so is this
>And this too
>And aliases are expanded
$ZTST_testdir/../Src/zsh -fis <<<'
unsetopt PROMPT_SP
PROMPT="" PS2="" PS3="" PS4="" RPS1="" RPS2=""
exec 2>&1
alias \{=echo
{ begin
{end
fc -l -2' 2>/dev/null
0:Aliasing reserved tokens
>begin
>end
*>*5*{ begin
*>*6*{end
$ZTST_testdir/../Src/zsh -fis <<<'
unsetopt PROMPT_SP
PROMPT="" PS2="" PS3="" PS4="" RPS1="" RPS2=""
exec 2>&1
alias -g S=\"
echo S a string S "
fc -l -1' 2>/dev/null
0:Global aliasing quotes
> a string S
*>*5*echo S a string S "
# "
# Note there is a trailing space on the "> a string S " line
(
unalias -a
alias
)
0:unalias -a
alias -s foo=print
type bar.foo; type -w bar.foo
unalias -as
0:unalias -as
>foo is a suffix alias for print
>foo: suffix alias
aliases[x=y]=z
alias -L | grep x=y
echo $pipestatus[1]
0:printing invalid aliases warns
>0
?(eval):2: invalid alias 'x=y' encountered while printing aliases
# Currently, 'alias -L' returns 0 in this case. Perhaps it should return 1.
alias -s mysuff='print -r "You said it.";'
eval 'thingummy.mysuff'
127:No endless loop with suffix alias in command position
>You said it.
?(eval):1: command not found: thingummy.mysuff
alias +x; alias -z
1:error message has the correct sign
?(eval):alias:1: bad option: +x
?(eval):alias:1: bad option: -z
# Usual issue that aliases aren't expanded until we
# trigger a new parse...
(alias badalias=notacommand
eval 'badalias() { print does not work; }')
1:ALIAS_FUNC_DEF off by default.
?(eval):1: defining function based on alias `badalias'
?(eval):1: parse error near `()'
(alias goodalias=isafunc
setopt ALIAS_FUNC_DEF
eval 'goodalias() { print does now work; }'
isafunc)
0:ALIAS_FUNC_DEF causes the icky behaviour to be avaliable
>does now work
(alias thisisokthough='thisworks() { print That worked; }'
eval thisisokthough
thisworks)
0:NO_ALIAS_FUNC_DEF works if the alias is a complete definition
>That worked

View File

@ -1,80 +0,0 @@
%test
print 'single quotes' "double quotes" `echo backquotes`
0:Simple use of quotes
>single quotes double quotes backquotes
foo=text
print -r '$foo\\\' "$foo\$foo\\\"\``echo bar`\`\"" `print -r $foo\\\``
0:Quoting inside quotes
>$foo\\\ text$foo\"`bar`" text`
print -r $'\'ut queant laxis\'\n"resonare fibris"'
0:$'-style quotes
>'ut queant laxis'
>"resonare fibris"
print -r $'\'a \\\' is \'a backslash\' is \'a \\\''
0:$'-style quotes with backslashed backslashes
>'a \' is 'a backslash' is 'a \'
chars=$(print -r $'BS\\MBS\M-\\')
for (( i = 1; i <= $#chars; i++ )); do
char=$chars[$i]
print $(( [#16] #char ))
done
0:$'-style quote with metafied backslash
>16#42
>16#53
>16#5C
>16#4D
>16#42
>16#53
>16#DC
print -r ''''
setopt rcquotes
# We need to set rcquotes here for the next example since it is
# needed while parsing.
0:No RC_QUOTES with single quotes
>
print -r ''''
unsetopt rcquotes
0:Yes RC_QUOTES with single quotes
>'
# ' Deconfuse Emacs quoting rules
print '<\u0041>'
printf '%s\n' $'<\u0042>'
print '<\u0043>'
printf '%s\n' $'<\u0044>'
0:\u in both print and printf
><A>
><B>
><C>
><D>
null1="$(print -r a$'b\0c'd)"
null2="$(setopt posixstrings; print -r a$'b\0c'd)"
for string in $null1 $null2; do
print ":"
for (( i = 1; i <= $#string; i++ )); do
char=$string[$i]
print $(( [#16] #char ))
done
done
0:Embedded null characters in $'...' strings.
>:
>16#61
>16#62
>16#0
>16#63
>16#64
>:
>16#61
>16#62
>16#64
() { print $# } '' "" $''
0:$'' should not be elided, in common with other empty quotes
>3

View File

@ -1,588 +0,0 @@
# Tests corresponding to the `Redirection' texinfo node.
%prep
mkdir redir.tmp && cd redir.tmp
myfd=99
(echo >&$myfd) 2>msg
bad_fd_msg="${$(<msg)##*:}"
%test
print 'This is file redir' >redir && cat redir
0:'>' and '<' redirection
>This is file redir
rm -f redir
print 'This is still file redir' <>redir >&0 && cat <>redir
0:'<>' redirection
>This is still file redir
rm -f redir
print 'With a bar' >|redir && cat redir
0:'>|' redirection
>With a bar
rm -f redir
print 'With a bang' >!redir && cat redir
0:'>!' redirection
>With a bang
rm -f redir
print 'Line 1' >>redir && print 'Line 2' >>redir && cat redir
0:'>>' redirection
>Line 1
>Line 2
rm -f redir
print 'Line a' >>|redir && print 'Line b' >>!redir
0:'>>|' and '>>!' redirection
foo=bar
cat <<' HERE'
$foo
HERE
eval "$(print 'cat <<HERE\n$foo\nHERE')"
0:Here-documents
> $foo
>bar
cat <<-HERE
# note tabs at the start of the following lines
$foo$foo
HERE
0:Here-documents stripping tabs
>barbar
cat <<-$'$HERE '`$(THERE) `'$((AND)) '"\EVERYWHERE" #
# tabs again. sorry about the max miller.
Here's a funny thing. Here is a funny thing.
I went home last night. There's a funny thing.
Man walks into a $foo. Ouch, it's an iron $foo.
$HERE `$(THERE) `$((AND)) \EVERYWHERE
0:Here-documents don't perform shell expansion on the initial word
>Here's a funny thing. Here is a funny thing.
>I went home last night. There's a funny thing.
>Man walks into a $foo. Ouch, it's an iron $foo.
cat <<-$'\x45\x4e\x44\t\x44\x4f\x43'
# tabs again
This message is unfathomable.
END DOC
0:Here-documents do perform $'...' expansion on the initial word
>This message is unfathomable.
cat <<<"This is a line with a $foo in it"
0:'<<<' redirection
>This is a line with a bar in it
cat <<<$'a\nb\nc'
0:here-strings with $'...' quoting
>a
>b
>c
# The following tests check that output of parsed here-documents works.
# This isn't completely trivial because we convert the here-documents
# internally to here-strings. So we check again that we can output
# the reevaluated here-strings correctly. Hence there are three slightly
# different stages. We don't care how the output actually looks, so
# we don't test that.
heretest() {
print First line
cat <<-HERE
$foo$foo met celeste 'but with extra' "stuff to test quoting"
HERE
print Last line
}
heretest
eval "$(functions heretest)"
heretest
eval "$(functions heretest)"
heretest
0:Re-evaluation of function output with here document, unquoted
>First line
>barbar met celeste 'but with extra' "stuff to test quoting"
>Last line
>First line
>barbar met celeste 'but with extra' "stuff to test quoting"
>Last line
>First line
>barbar met celeste 'but with extra' "stuff to test quoting"
>Last line
heretest() {
print First line
cat <<' HERE'
$foo$foo met celeste 'but with extra' "stuff to test quoting"
HERE
print Last line
}
heretest
eval "$(functions heretest)"
heretest
eval "$(functions heretest)"
heretest
0:Re-evaluation of function output with here document, quoted
>First line
> $foo$foo met celeste 'but with extra' "stuff to test quoting"
>Last line
>First line
> $foo$foo met celeste 'but with extra' "stuff to test quoting"
>Last line
>First line
> $foo$foo met celeste 'but with extra' "stuff to test quoting"
>Last line
read -r line <<' HERE'
HERE
1:No input, not even newline, from empty here document.
#
# exec tests: perform these in subshells so if they fail the
# shell won't exit.
#
(exec 3>redir && print hello >&3 && print goodbye >&3 && cat redir)
0:'>&' redirection
>hello
>goodbye
(exec 3<redir && read foo <&3 && print $foo && read foo <&3 && print $foo)
0:'<&' redirection
>hello
>goodbye
({exec 3<&- } 2>/dev/null
exec 3<&-
read foo <&-)
1:'<&-' redirection with numeric fd (no error message on failure)
(exec {varid}<&0
exec {varid}<&-
print About to close a second time >&2
read {varid}<&-)
1:'<&-' redirection with fd in variable (error message on failure)
?About to close a second time
*?\(eval\):*: failed to close file descriptor *
print foo >&-
0:'>&-' redirection
(exec >&-
print foo)
0:'>&-' with attempt to use closed fd
*?\(eval\):2: write error:*
fn() { local foo; read foo; print $foo; }
coproc fn
print test output >&p
read bar <&p
print $bar
0:'>&p' and '<&p' redirection
>test output
( print Output; print Error >& 2 ) >&errout && cat errout
0:'>&FILE' handling
>Output
>Error
rm -f errout
( print Output2; print Error2 >& 2 ) &>errout && cat errout
0:'&>FILE' handling
>Output2
>Error2
rm -f errout
( print Output3; print Error3 >& 2 ) >&|errout && cat errout
( print Output4; print Error4 >& 2 ) >&!errout && cat errout
( print Output5; print Error5 >& 2 ) &>|errout && cat errout
( print Output6; print Error6 >& 2 ) &>!errout &&
( print Output7; print Error7 >& 2 ) >>&errout &&
( print Output8; print Error8 >& 2 ) &>>errout &&
( print Output9; print Error9 >& 2 ) >>&|errout &&
( print Output10; print Error10 >& 2 ) &>>|errout &&
( print Output11; print Error11 >& 2 ) >>&!errout &&
( print Output12; print Error12 >& 2 ) &>>!errout && cat errout
0:'>&|', '>&!', '&>|', '&>!' redirection
>Output3
>Error3
>Output4
>Error4
>Output5
>Error5
>Output6
>Error6
>Output7
>Error7
>Output8
>Error8
>Output9
>Error9
>Output10
>Error10
>Output11
>Error11
>Output12
>Error12
rm -f errout
( print Output; print Error 1>&2 ) 1>errout 2>&1 && cat errout
0:'Combining > with >& (1)'
>Output
>Error
rm -f errout
( print Output; print Error 1>&2 ) 2>&1 1>errout && print errout: &&
cat errout
0:'Combining > with >& (2)'
>Error
>errout:
>Output
rm -f errout
print doo be doo be doo >foo >bar
print "foo: $(<foo)\nbar: $(<bar)"
0:2-file multio
>foo: doo be doo be doo
>bar: doo be doo be doo
rm -f foo bar
print dont be dont be dont >foo | sed 's/dont/wont/g' >bar
0:setup file+pipe multio
print "foo: $(<foo)\nbar: $(<bar)"
0:read file+pipe multio
>foo: dont be dont be dont
>bar: wont be wont be wont
rm -f *
touch out1 out2
print All files >*
print *
print "out1: $(<out1)\nout2: $(<out2)"
0:multio with globbing
>out1 out2
>out1: All files
>out2: All files
print This is out1 >out1
print This is out2 >out2
0:setup multio for input
# Currently, <out{1,2} doesn't work: this is a bug.
cat <out*
0:read multio input
>This is out1
>This is out2
cat out1 | sed s/out/bout/ <out2
0:read multio input with pipe
>This is bout1
>This is bout2
unset NULLCMD
>out1
1:null redir with NULLCMD unset
?(eval):2: redirection with no command
echo this should still work >out1
print "$(<out1)"
0:null redir in $(...) with NULLCMD unset
>this should still work
READNULLCMD=cat
print cat input >out1
<out1
1:READNULLCMD with NULLCMD unset
?(eval):3: redirection with no command
NULLCMD=:
>out1
[[ ! -s out1 ]] || print out1 is not empty
0:null redir with NULLCMD=:
<input
print cat input >out1
<out1
0:READNULLCMD
>cat input
NULLCMD=cat
>out1
cat out1
0:null redir with NULLCMD=cat
<input
>input
(myfd=
exec {myfd}>logfile
if [[ -z $myfd ]]; then
print "Ooops, failed to set myfd to a file descriptor." >&2
else
print This is my logfile. >&$myfd
print Examining contents of logfile...
cat logfile
fi)
0:Using {fdvar}> syntax to open a new file descriptor
>Examining contents of logfile...
>This is my logfile.
(setopt noclobber
exec {myfd}>logfile2
echo $myfd
exec {myfd}>logfile3) | read myfd
(( ! ${pipestatus[1]} ))
1q:NO_CLOBBER prevents overwriting parameter with allocated fd
?(eval):4: can't clobber parameter myfd containing file descriptor $myfd
(setopt noclobber
exec {myfd}>logfile2b
print First open >&$myfd
rm -f logfile2b # prevent normal file no_clobberation
myotherfd="${myfd}+0"
exec {myotherfd}>logfile2b
print Overwritten >&$myotherfd)
cat logfile2b
0:NO_CLOBBER doesn't complain about any other expression
>Overwritten
(exec {myfd}>logfile4
echo $myfd
exec {myfd}>&-
print This message should disappear >&$myfd) | read myfd
(( ! ${pipestatus[1]} ))
1q:Closing file descriptor using brace syntax
?(eval):4: $myfd:$bad_fd_msg
typeset -r myfd
echo This should not appear {myfd}>nologfile
1:Error opening file descriptor using readonly variable
?(eval):2: can't allocate file descriptor to readonly parameter myfd
(typeset +r myfd
exec {myfd}>newlogfile
typeset -r myfd
exec {myfd}>&-)
1:Error closing file descriptor using readonly variable
?(eval):4: can't close file descriptor from readonly parameter myfd
# This tests the here-string to filename optimisation; we can't
# test that it's actually being optimised, but we can test that it
# still works.
cat =(<<<$'This string has been replaced\nby a file containing it.\n')
0:Optimised here-string to filename
>This string has been replaced
>by a file containing it.
print This f$'\x69'le contains d$'\x61'ta. >redirfile
print redirection:
cat<redirfile>outfile
print output:
cat outfile
print append:
cat>>outfile<redirfile
print more output:
cat outfile
0:Parsing of redirection operators (no space required before operators)
>redirection:
>output:
>This file contains data.
>append:
>more output:
>This file contains data.
>This file contains data.
$ZTST_testdir/../Src/zsh -fc 'exec >/nonexistent/nonexistent
echo output'
0:failed exec redir, no POSIX_BUILTINS
>output
?zsh:1: no such file or directory: /nonexistent/nonexistent
$ZTST_testdir/../Src/zsh -f -o POSIX_BUILTINS -c '
exec >/nonexistent/nonexistent
echo output'
1:failed exec redir, POSIX_BUILTINS
?zsh:2: no such file or directory: /nonexistent/nonexistent
$ZTST_testdir/../Src/zsh -f -o POSIX_BUILTINS -c '
set >/nonexistent/nonexistent
echo output'
1:failed special builtin redir, POSIX_BUILTINS
?zsh:2: no such file or directory: /nonexistent/nonexistent
$ZTST_testdir/../Src/zsh -f -o POSIX_BUILTINS -c '
command set >/nonexistent/nonexistent
echo output'
0:failed special builtin redir with command prefix, POSIX_BUILTINS
>output
?zsh:2: no such file or directory: /nonexistent/nonexistent
$ZTST_testdir/../Src/zsh -f -o POSIX_BUILTINS -c '
echo >/nonexistent/nonexistent
echo output'
0:failed unspecial builtin redir, POSIX_BUILTINS
>output
?zsh:2: no such file or directory: /nonexistent/nonexistent
$ZTST_testdir/../Src/zsh -f -o POSIX_BUILTINS -c '
. /nonexistent/nonexistent
echo output'
1:failed dot, POSIX_BUILTINS
?zsh:.:2: no such file or directory: /nonexistent/nonexistent
$ZTST_testdir/../Src/zsh -f -c '
. /nonexistent/nonexistent
echo output'
0:failed dot, NO_POSIX_BUILTINS
>output
?zsh:.:2: no such file or directory: /nonexistent/nonexistent
$ZTST_testdir/../Src/zsh -f -o CONTINUE_ON_ERROR <<<'
readonly foo
foo=bar set output
echo output'
0:failed assignment on posix special, CONTINUE_ON_ERROR
>output
?zsh: read-only variable: foo
$ZTST_testdir/../Src/zsh -f <<<'
readonly foo
foo=bar set output
echo output'
1:failed assignment on posix special, NO_CONTINUE_ON_ERROR
?zsh: read-only variable: foo
$ZTST_testdir/../Src/zsh -f -o CONTINUE_ON_ERROR <<<'
readonly foo
foo=bar echo output
echo output'
0:failed assignment on non-posix-special, CONTINUE_ON_ERROR
>output
?zsh: read-only variable: foo
[</dev/null ]
1:check behaviour with square brackets
print any old rubbish >input1
() {
local var
read var
print I just read $var
} <input1 >output1
print Nothing output yet
cat output1
0:anonymous function redirections are applied immediately
>Nothing output yet
>I just read any old rubbish
redirfn() {
local var
read var
print I want to tell you about $var
print Also, this might be an error >&2
} <input2 >output2 2>&1
print something I heard on the radio >input2
redirfn
print No output until after this
cat output2
0:redirections with normal function definition
>No output until after this
>I want to tell you about something I heard on the radio
>Also, this might be an error
which redirfn
0:text output of function with redirections
>redirfn () {
> local var
> read var
> print I want to tell you about $var
> print Also, this might be an error >&2
>} < input2 > output2 2>&1
1func 2func 3func() { print Ich heisse $0 } >output3
for i in 1 2 3; do
f=${i}func
print Running $f
$f
cat output3
unfunction $f
done
0:multiply named functions with redirection
>Running 1func
>Ich heisse 1func
>Running 2func
>Ich heisse 2func
>Running 3func
>Ich heisse 3func
redirfn2() { print The latest output; } >&3
redirfn2 3>output4
print No output yet
cat output4
0:Redirections in both function definition and command line
>No output yet
>The latest output
# This relies on the fact that the test harness always loads
# the zsh/parameter module.
print $functions[redirfn]
0:Output from $functions[] for definition with redirection
>{
> local var
> read var
> print I want to tell you about $var
> print Also, this might be an error >&2
>} < input2 > output2 2>&1
noredirfn() { print This rather boring function has no redirection.; }
print $functions[noredirfn]
0:Output from $functions[] for definition with no redirection
> print This rather boring function has no redirection.
(x=43
x=$(print This should appear, really >&2; print Not used) exec >test.log
print x=$x)
cat test.log
0:Assignment with exec used for redirection: no POSIX_BUILTINS
>x=43
?This should appear, really
(setopt POSIX_BUILTINS
x=45
x=$(print This should appear, too >&2; print And this) exec >test.log
print x=$x)
cat test.log
0:Assignment with exec used for redirection: POSIX_BUILTINS
>x=And this
?This should appear, too
fn-two-heres() {
# tabs below
cat <<-x <<-y
foo
x
bar
y
}
which -x2 fn-two-heres
fn-two-heres
eval "$(which -x2 fn-two-heres)"
fn-two-heres
print $functions[fn-two-heres]
0:Two here-documents in a line are shown correctly.
>fn-two-heres () {
> cat <<x <<y
>foo
>x
>bar
>y
>}
>foo
>bar
>foo
>bar
> cat <<x <<y
>foo
>x
>bar
>y

View File

@ -1,312 +0,0 @@
%prep
storepath=($path)
mkdir command.tmp command.tmp/dir1 command.tmp/dir2
cd command.tmp
print '#!/bin/sh\necho This is top' >tstcmd
print '#!/bin/sh\necho This is dir1' >dir1/tstcmd
print '#!/bin/sh\necho This is dir2' >dir2/tstcmd
chmod 755 tstcmd dir1/tstcmd dir2/tstcmd
%test
./tstcmd
0:./prog execution
>This is top
path=($ZTST_testdir/command.tmp/dir1
$ZTST_testdir/command.tmp/dir2
.)
tstcmd
path=($storepath)
0:path (1)
>This is dir1
path=(. command.tmp/dir{1,2})
tstcmd
path=($storepath)
0:path (2)
>This is top
functst() { print $# arguments:; print -l $*; }
functst "Eines Morgens" "als Gregor Samsa"
functst ""
functst "aus unrühigen Träumen erwachte"
foo="fand er sich in seinem Bett"
bar=
rod="zu einem ungeheuren Ungeziefer verwandelt."
functst $foo $bar $rod
# set up alias for next test
alias foo='print This is alias one'
0:function argument passing
>2 arguments:
>Eines Morgens
>als Gregor Samsa
>1 arguments:
>
>1 arguments:
>aus unrühigen Träumen erwachte
>2 arguments:
>fand er sich in seinem Bett
>zu einem ungeheuren Ungeziefer verwandelt.
alias foo='print This is alias two'
fn() { foo; }
fn
0:Aliases in functions
>This is alias one
foo='Global foo'
traptst() { local foo="Local foo"; trap 'print $foo' EXIT; }
traptst
0:EXIT trap environment
>Global foo
functst() { return 0; print Ha ha; return 1; }
functst
0:return (1)
functst() { return 1; print Ho ho; return 0; }
functst
1:return (2)
unfunction functst
fpath=(.)
print "print This is functst." >functst
autoload functst
functst
0:autoloading (1)
>This is functst.
unfunction functst
print "functst() { print This, too, is functst; }; print Hello." >functst
typeset -fu functst
functst
functst
0:autoloading with initialization
>Hello.
>This, too, is functst
unfunction functst
print "print Yet another version" >functst
functst() { autoload -X; }
functst
0:autoloading via -X
>Yet another version
chpwd() { print Changed to $PWD; }
cd .
unfunction chpwd
0q:chpwd
>Changed to $ZTST_testdir/command.tmp
chpwd() { print chpwd: changed to $PWD; }
chpwdfn1() { print chpwdfn1: changed to $PWD; }
chpwdfn2() { print chpwdfn2: changed to $PWD; }
chpwd_functions=(chpwdfn1 '' chpwdnonexistentfn chpwdfn2)
cd .
unfunction chpwd
unset chpwd_functions
0q:chpwd_functions
>chpwd: changed to $ZTST_testdir/command.tmp
>chpwdfn1: changed to $ZTST_testdir/command.tmp
>chpwdfn2: changed to $ZTST_testdir/command.tmp
# Hard to test periodic, precmd and preexec non-interactively.
fn() { TRAPEXIT() { print Exit; }; }
fn
0:TRAPEXIT
>Exit
unsetopt DEBUG_BEFORE_CMD
unfunction fn
print 'TRAPDEBUG() {
print Line $LINENO
}
:
unfunction TRAPDEBUG
' > fn
autoload fn
fn
rm fn
0:TRAPDEBUG
>Line 1
>Line 1
unsetopt DEBUG_BEFORE_CMD
unfunction fn
print 'trap '\''print Line $LINENO'\'' DEBUG
:
trap - DEBUG
' > fn
autoload fn
fn
rm fn
0:trap DEBUG
>Line 1
>Line 2
TRAPZERR() { print Command failed; }
true
false
true
false
unfunction TRAPZERR
0:TRAPZERR
>Command failed
>Command failed
trap 'print Command failed again.' ZERR
true
false
true
false
trap - ZERR
0:trap ZERR
>Command failed again.
>Command failed again.
false
sleep 1000 &
print $?
kill $!
0:Status reset by starting a backgrounded command
>0
{ setopt MONITOR } 2>/dev/null
[[ -o MONITOR ]] || print -u $ZTST_fd 'Unable to change MONITOR option'
repeat 2048; do (return 2 |
return 1 |
while true; do
false
break
done;
print "${pipestatus[@]}")
ZTST_hashmark
done | sort | uniq -c | sed 's/^ *//'
0:Check whether '$pipestatus[]' behaves.
>2048 2 1 0
F:This test checks for a bug in '$pipestatus[]' handling. If it breaks then
F:the bug is still there or it reappeared. See workers-29973 for details.
{ setopt MONITOR } 2>/dev/null
externFunc() { awk >/dev/null 2>&1; true; }
false | true | false | true | externFunc
echo $pipestatus
0:Check $pipestatus with a known difficult case
>1 0 1 0 0
F:This similar test was triggering a reproducible failure with pipestatus.
{ unsetopt MONITOR } 2>/dev/null
coproc { read -et 5 || { print -u $ZTST_fd KILLED; kill -HUP -$$ } }
print -u $ZTST_fd 'This test takes 5 seconds to fail...'
{ printf "%d\n" {1..20000} } 2>/dev/null | ( read -e )
hang(){ printf "%d\n" {2..20000} | cat }; hang 2>/dev/null | ( read -e )
print -p done
read -et 6 -p
0:Bug regression: piping a shell construct to an external process may hang
>1
>2
>done
F:This test checks for a file descriptor leak that could cause the left
F:side of a pipe to block on write after the right side has exited
{ setopt MONITOR } 2>/dev/null
if [[ -o MONITOR ]]
then
( while :; do print "This is a line"; done ) | () : &
sleep 1
jobs -l
else
print -u $ZTST_fd "Skipping pipe leak test, requires MONITOR option"
print "[0] 0 0"
fi
0:Bug regression: piping to anonymous function; piping to backround function
*>\[<->\] <-> <->
F:This test checks for two different bugs, a parser segfault piping to an
F:anonymous function, and a descriptor leak when backgrounding a pipeline
print "autoload_redir() { print Autoloaded ksh style; } >autoload.log" >autoload_redir
autoload -Uk autoload_redir
autoload_redir
print No output yet
cat autoload.log
functions autoload_redir
0:
>No output yet
>Autoloaded ksh style
>autoload_redir () {
> print Autoloaded ksh style
>} > autoload.log
# This tests that we record the status of processes that have already exited
# for when we wait for them.
#
# Actually, we don't guarantee here that the jobs have already exited, but
# the order of the waits means it's highly likely we do need to recall a
# previous status, barring accidents which shouldn't happen very often. In
# other words, we rely on the test working repeatedly rather than just
# once. The monitor option is irrelevant to the logic, so we'll make
# our job easier by turning it off.
{ unsetopt MONITOR } 2>/dev/null
(exit 1) &
one=$!
(exit 2) &
two=$!
(exit 3) &
three=$!
wait $three
print $?
wait $two
print $?
wait $one
print $?
0:The status of recently exited background jobs is recorded
>3
>2
>1
# Regression test for workers/34060 (patch in 34065)
setopt ERR_EXIT NULL_GLOB
if false; then :; else echo if:$?; fi
if false; then :; else for x in _*_; do :; done; echo for:$?; fi
0:False "if" condition handled correctly by "for" loops with ERR_EXIT
>if:1
>for:0
# Regression test for workers/34065 (uses setopt from preceding test)
select x; do :; done; echo $?
select x in; do :; done; echo $?
select x in _*_; do :; done; echo $?
unsetopt ERR_EXIT NULL_GLOB
0:The status of "select" is zero when the loop body does not execute
>0
>0
>0
# Regression test for workers/36392
print -u $ZTST_fd 'This test takes 3 seconds and hangs the shell when it fails...'
callfromchld() { true && { print CHLD } }
TRAPCHLD() { callfromchld }
sleep 2 & sleep 3; print OK
0:Background job exit does not affect reaping foreground job
>CHLD
>OK
# Regression test for workers/39839 and workers/39844
() { if return 11; then :; fi }; echo $?
() { while return 13; do :; done }; echo $?
() { until return 17; do :; done }; echo $?
() { until false; do return 19; done }; echo $?
0:"return" in "if" or "while" conditional
>11
>13
>17
>19

View File

@ -1,631 +0,0 @@
# Tests of parameter assignments
%prep
mkdir assign.tmp && cd assign.tmp
touch tmpfile1 tmpfile2
%test
typeset -A assoc
assoc=(one 1 two 2 odd)
1:assign to association with odd no. of values
?(eval):2: bad set of key/value pairs for associative array
# tests of array element assignment
array=(1 2 3 4 5)
array[1]=42
print $array
0:Replacement of array element
>42 2 3 4 5
array=(1 2 3 4 5)
array[1]=(42 43)
print $array
0:Replacement of array element with array
>42 43 2 3 4 5
array=(1 2 3 4 5)
array[1,2]=(42 43)
print $array
0:Replacement of start of array
>42 43 3 4 5
array=(1 2 3 4 5)
array[1,4]=(42 43)
print $array
0:Replacement of start of array with shorter slice
>42 43 5
array=(1 2 3 4 5)
array[1,6]=(42 43)
print $array
0:Replacement of array by extending slice
>42 43
array=(1 2 3 4 5)
array[3]=(42 43)
print $array
0:Replacement of middle element with array
>1 2 42 43 4 5
array=(1 2 3 4 5)
array[3,4]=(42 43 44)
print $array
0:Replacement of slice in middle
>1 2 42 43 44 5
array=(1 2 3 4 5)
array[7,8]=(42 43)
print $array
# check that [6] was left empty...
array[6]=41
print $array
0:Appending by replacing elements off the end
>1 2 3 4 5 42 43
>1 2 3 4 5 41 42 43
array=(1 2 3 4 5)
array[-1]=42
print $array
0:Replacement of last element of array, negative indices
>1 2 3 4 42
array=(1 2 3 4 5)
array[-1]=(42 43)
print $array
0:Replacement of last element of array with array, negative indices
>1 2 3 4 42 43
array=(1 2 3 4 5)
array[-3,-2]=(42 43 44)
print $array
0:Replacement of middle of array, negative indices
>1 2 42 43 44 5
array=(1 2 3 4 5)
array[-5,-1]=(42 43)
print $array
0:Replacement of entire array, negative indices
>42 43
array=(1 2 3 4 5)
array[-7,-1]=(42 43)
print $array
0:Replacement of more than entire array, negative indices
>42 43
array=(1 2 3 4 5)
array[-7]=42
print $array
0:Replacement of element off start of array.
>42 1 2 3 4 5
array=(1 2 3 4 5)
array[-7]=42
array[-6]=43
print $array
0:Replacement off start doesn't leave gaps. Hope this is right.
>43 1 2 3 4 5
array=(1 2 3 4 5)
array[1,-1]=(42 43)
print $array
array[-3,3]=(1 2 3 4 5)
print $array
0:Replacement of entire array, mixed indices
>42 43
>1 2 3 4 5
array=(1 2 3 4 5)
array[-7,7]=(42 43)
print $array
0:Replacement of more than entire array, mixed indices
>42 43
array=(1 2 3 4 5)
array[3,-2]=(42 43 44)
print $array
array[-3,5]=(100 99)
print $array
0:Replacement of slice in middle, mixed indices
>1 2 42 43 44 5
>1 2 42 100 99 5
# tests of var+=scalar
s+=foo
echo $s
0:append scalar to unset scalar
>foo
s=foo
s+=bar
echo $s
0:append to scalar
>foobar
set -- a b c
2+=end
echo $2
0:append to positional parameter
>bend
a=(first second)
a+=last
print -l $a
0:add scalar to array
>first
>second
>last
setopt ksharrays
a=(first second)
a+=last
print -l $a
unsetopt ksharrays
0:add scalar to array with ksharrays set
>firstlast
a=(1 2)
a[@]+=3
print -l $a
0:add scalar to array with alternate syntax
>1
>2
>3
integer i=10
i+=20
(( i == 30 ))
0:add to integer
float f=3.4
f+=2.3
printf "%g\n" f
0:add to float
>5.7
typeset -A hash
hash=(one 1)
hash+=string
[[ $hash[@] == string ]]
0:add scalar to association
# tests of var+=(array)
unset a
a+=(1 2 3)
print -l $a
0:add array to unset parameter
>1
>2
>3
a=(a)
a+=(b)
print -l $a
0:add array to existing array
>a
>b
s=foo
s+=(bar)
print -l $s
0:add array to scalar
>foo
>bar
integer i=1
i+=(2 3)
print -l $i
0:add array to integer
>1
>2
>3
float f=2.5
f+=(3.5 4.5)
printf '%g\n' $f
0:add array to float
>2.5
>3.5
>4.5
typeset -A h
h+=(a 1 b 2)
print -l $h
0:add to empty association
>1
>2
typeset -A h
h=(a 1)
h+=(b 2 c 3)
print -l $h
0:add to association
>1
>2
>3
typeset -A h
h=(a 1 b 2)
h+=()
print -l $h
0:add empty array to association
>1
>2
# tests of var[range]+=scalar
s=sting
s[2]+=art
echo $s
0:insert scalar inside another
>starting
s=inert
s[-4]+=s
echo $s
0:insert scalar inside another with negative index
>insert
s=append
s[2,6]+=age
echo $s
0:append scalar to scalar using a range
>appendage
s=123456789
s[3,-5]+=X
echo $s
0:insert scalar inside another, specifying a slice
>12345X6789
a=(a b c)
a[2]+=oo
echo $a
0:append to array element
>a boo c
a=(a b c d)
a[-2]+=ool
echo $a
0:append to array element with negative index
>a b cool d
a=(a b c d)
a[2,-1]+=oom
echo $a
0:append to array element, specifying a slice
>a b c doom
setopt ksharrays
a=(a b c d)
a[0]+=0
echo $a
unsetopt ksharrays
0:append to array element with ksharrays set
>a0
typeset -A h
h=(one foo)
h[one]+=bar
echo $h
0:append to association element
>foobar
typeset -A h
h[foo]+=bar
echo ${(kv)h}
0:append to non-existent association element
>foo bar
typeset -A h
h=(one a two b three c four d)
h[(I)*o*]+=append
1:attempt to append to slice of association
?(eval):3: h: attempt to set slice of associative array
integer i=123
i[2]+=6
1:attempt to add to indexed integer variable
?(eval):2: attempt to add to slice of a numeric variable
float f=1234.5
f[2,4]+=3
1:attempt to add to slice of float variable
?(eval):2: attempt to add to slice of a numeric variable
unset u
u[3]+=third
echo $u[1]:$u[3]
0:append to unset variable with index
>:third
# tests of var[range]+=(array)
a=(1 2 3)
a[2]+=(a b)
echo $a
0:insert array inside another
>1 2 a b 3
a=(a b c)
a[-1]+=(d)
echo $a
0:append to array using negative index
>a b c d
a=(1 2 3 4)
a[-1,-3]+=(x)
echo $a
0:insert array using negative range
>1 2 x 3 4
s=string
s[2]+=(a b)
1:attempt to insert array into string
?(eval):2: s: attempt to assign array value to non-array
integer i=365
i[2]+=(1 2)
1:attempt to insert array into string
?(eval):2: i: attempt to assign array value to non-array
typeset -A h
h=(a 1)
h[a]+=(b 2)
1:attempt to append array to hash element
?(eval):3: h: attempt to set slice of associative array
unset u
u[-34,-2]+=(a z)
echo $u
0:add array to indexed unset variable
>a z
repeat 10 PATH=. echo hello
0:saving and restoring of exported special parameters
>hello
>hello
>hello
>hello
>hello
>hello
>hello
>hello
>hello
>hello
repeat 10 FOO=BAR BAR=FOO echo $FOO $BAR
0:save and restore multiple variables around builtin
>
>
>
>
>
>
>
>
>
>
call() { print $HELLO; }
export HELLO=world
call
HELLO=universe call
call
HELLO=${HELLO}liness call
call
unset HELLO
0:save and restore when using original value in temporary
>world
>universe
>world
>worldliness
>world
(integer i n x
float f
setopt globassign
i=tmpfile1
n=tmpf*
x=*2
f=2+2
typeset -p i n x f)
0:GLOB_ASSIGN with numeric types
>typeset -i i=0
>typeset -a n=( tmpfile1 tmpfile2 )
>typeset x=tmpfile2
>typeset -E f=4.000000000e+00
setopt globassign
foo=tmpf*
print $foo
unsetopt globassign
foo=tmpf*
print $foo
0:GLOB_ASSIGN option
>tmpfile1 tmpfile2
>tmpf*
(setopt globassign
typeset -A foo
touch gatest1 gatest2
foo=(gatest*)
print ${(t)foo}
rm -rf gatest*)
0:GLOB_ASSIGN doesn't monkey with type if not scalar assignment.
>association-local
A=(first second)
A="${A[*]}" /bin/sh -c 'echo $A'
print -l "${A[@]}"
0:command execution with assignments shadowing array parameter
>first second
>first
>second
setopt ksharrays
A=(first second)
A="${A[*]}" /bin/sh -c 'echo $A'
print -l "${A[@]}"
unsetopt ksharrays
0:command execution with assignments shadowing array parameter with ksharrays
>first second
>first
>second
typeset -aU unique_array=(first second)
unique_array[1]=second
print $unique_array
0:assignment to unique array
>second
typeset -a array=(first)
array[1,3]=(FIRST)
print $array
0:slice beyond length of array
>FIRST
# tests of string assignments
a="abc"
a[1]=x
print $a
0:overwrite first character in string
>xbc
a="abc"
a[2]="x"
print $a
0:overwrite middle character in string
>axc
a="abc"
a[3]="x"
print $a
0:overwrite last character in string
>abx
a="abc"
a[-1]="x"
print $a
0:overwrite -1 character in string
>abx
a="abc"
a[-2]="x"
print $a
0:overwrite -2 character (middle) in string
>axc
a="ab"
a[-2]="x"
print $a
0:overwrite -2 character (first) in string
>xb
a="abc"
a[-3]="x"
print $a
0:overwrite -3 character (first) in string
>xbc
a="abc"
a[-4]="x"
print $a
0:overwrite -4 character (before first) in string
>xabc
a="abc"
a[-5]="x"
print $a
0:overwrite -5 character (before-before first) in string
>xabc
a="abc"
a[-4,0]="x"
print $a
0:overwrite [-4,0] characters (before first) in string
>xabc
a="abc"
a[-4,-4]="x"
print $a
0:overwrite [-4,-4] character (before first) in string
>xabc
a="abc"
a[-40,-30]="x"
print $a
0:overwrite [-40,-30] characters (far before first) in string
>xabc
a="abc"
a[-40,1]="x"
print $a
0:overwrite [-40,1] characters in short string
>xbc
a="abc"
a[-40,40]="x"
print $a
0:overwrite [-40,40] characters in short string
>x
a="abc"
a[2,40]="x"
print $a
0:overwrite [2,40] characters in short string
>ax
a="abc"
a[2,-1]="x"
print $a
0:overwrite [2,-1] characters in short string
>ax
a="abc"
a[-2,-1]="x"
print $a
0:overwrite [-2,-1] characters in short string
>ax
a="a"
a[-1]="xx"
print $a
0:overwrite [-1] character with "xx"
>xx
a="a"
a[-2]="xx"
print $a
0:overwrite [-2] character (before first) with "xx"
>xxa
a="a"
a[2]="xx"
print $a
0:overwrite [2] character (after last) with "xx"
>axx
a=""
a[1]="xx"
print $a
0:overwrite [1] character (string: "") with "xx"
>xx
a=""
a[-1]="xx"
print $a
0:overwrite [-1] character (string: "") with "xx"
>xx
a=""
a[2]="xx"
print $a
0:overwrite [2] character (string: "") with "xx"
>xx

View File

@ -1,165 +0,0 @@
# Test control commands for loops and functions.
%test
fn3() { return $1; print Error }
fn2() { fn3 $1 }
fn() {
print start $1
fn2 $1
return
print Error
}
for val in -1 0 1 255; do
fn $val; print $?
done
0:Passing of return values back through functions
>start -1
>-1
>start 0
>0
>start 1
>1
>start 255
>255
$ZTST_testdir/../Src/zsh -fc 'fn() {
continue
}
fn'
1:continue outside loop
?fn:continue:1: not in while, until, select, or repeat loop
for outer in 0 1 2 3; do
print outer $outer
for inner in 0 1 2 3; do
print inner $inner
continue $(( (outer & 1) ? 2 : 1 ))
print error
done
print outer end
done
0:continue with valid argument
>outer 0
>inner 0
>inner 1
>inner 2
>inner 3
>outer end
>outer 1
>inner 0
>outer 2
>inner 0
>inner 1
>inner 2
>inner 3
>outer end
>outer 3
>inner 0
for outer in 0 1; do
continue 0
print -- $outer got here, status $?
done
1:continue error case 0
?(eval):continue:2: argument is not positive: 0
for outer in 0 1; do
continue -1
print -- $outer got here, status $?
done
1:continue error case -1
?(eval):continue:2: argument is not positive: -1
fn() {
break
}
for outer in 0 1; do
print $outer
fn
done
0:break from within function (this is a feature, I disovered)
>0
for outer in 0 1 2 3; do
print outer $outer
for inner in 0 1 2 3; do
print inner $inner
break $(( (outer & 1) ? 2 : 1 ))
print error
done
print outer end
done
0:break with valid argument
>outer 0
>inner 0
>outer end
>outer 1
>inner 0
for outer in 0 1; do
break 0
print -- $outer got here, status $?
done
1:break error case 0
?(eval):break:2: argument is not positive: 0
for outer in 0 1; do
break -1
print -- $outer got here, status $?
done
1:break error case -1
?(eval):break:2: argument is not positive: -1
false
for x in; do
print nothing executed
done
0:Status 0 from for with explicit empty list
set --
false
for x; do
print nothing executed
done
0:Status 0 from for with implicit empty list
(exit 2)
for x in 1 2; do
print $?
done
0:Status from previous command propagated into for loop
>2
>0
false
for x in $(echo 1 2; (exit 3)); do
print $?
done
0:Status from expansion propagated into for loop
>3
>0
false
for x in $(exit 4); do
print not executed
done
0:Status from expansion not propagated after unexecuted for loop
false
for x in NonExistentFilePrefix*(N); do
print not executed, either
done
0:Status from before for loop not propagated if empty after expansion
for x in $(echo 1; false); do
done
0:Status reset by empty list in for loop
false
for x in $(echo 1; false); do
echo $?
(exit 4)
done
4:Last status from loop body is kept even with other funny business going on
>1

View File

@ -1,144 +0,0 @@
# This file serves as a model for how to write tests, so is more heavily
# commented than the others. All tests are run in the Test subdirectory
# of the distribution, which must be writable. They should end with
# the suffix `.ztst': this is not required by the test harness itself,
# but it is needed by the Makefile to run all the tests.
# Blank lines with no other special meaning (e.g. separating chunks of
# code) and all those with a `#' in the first column are ignored.
# All section names start with a % in the first column. The names
# must be in the expected order, though not all sections are required.
# The sections are %prep (preparatory setup: code executed should return
# status 0, but no other tests are performed), %test (the main tests), and
# %clean (to cleanup: the code is simply unconditionally executed).
#
# Literal shell code to be evaluated must be indented with any number
# of spaces and/or tabs, to differentiate it from tags with a special
# meaning to the test harness. Note that this is true even in sections
# where there are no such tags. Also note that file descriptor 9
# is reserved for input from the test script, and file descriptor 8
# preserves the original stdout. Option settings are preserved between the
# execution of different code chunks; initially, all standard zsh options
# (the effect of `emulate -R zsh') are set.
%prep
# This optional section prepares the test, creating directories and files
# and so on. Chunks of code are separated by blank lines (which is not
# necessary before the end of the section); each chunk of code is evaluated
# in one go and must return status 0, or the preparation is deemed to have
# failed and the test ends with an appropriate error message. Standard
# output from this section is redirected to /dev/null, but standard error
# is not redirected.
#
# Tests should use subdirectories ending in `.tmp'. These will be
# removed with all the contents even if the test is aborted.
mkdir cdtst.tmp cdtst.tmp/real cdtst.tmp/sub
ln -s ../real cdtst.tmp/sub/fake
setopt chaselinks
cd .
unsetopt chaselinks
mydir=$PWD
%test
# This is where the tests are run. It consists of blocks separated
# by blank lines. Each block has the same format and there may be any
# number of them. It consists of indented code, plus optional sets of lines
# beginning '<', '>' and '?' which may appear in any order. These correspond
# to stdin (fed to the code), stdout (compared with code output) and
# stderr (compared with code error output) respectively. These subblocks
# may occur in any order, but the natural one is: code, stdin, stdout,
# stderr.
#
# The rules for '<', '>' and '?' lines are the same: only the first
# character is stripped (with the excpetion for '*' noted below), with
# subsequent whitespace being significant; lines are not subject to any
# substitution unless the `q' flag (see below) is set.
#
# Each line of a '>' and '?' chunk may be preceded by a '*', so the line
# starts '*>' or '*?'. This signifies that for any line with '*' in front
# the actual output should be pattern matched against the corresponding
# lines in the test output. Each line following '>' or '?' must be a
# valid pattern, so characters special to patterns such as parentheses
# must be quoted with a backslash. The EXTENDED_GLOB option is used for
# all such patterns.
#
# Each chunk of indented code is to be evaluated in one go and is to
# be followed by a line starting (in the first column) with
# the expected status returned by the code when run, or - if it is
# irrelevant. An optional set of single-letter flags follows the status
# or -. The following are understood:
# . d Don't diff stdout against the expected stdout.
# D Don't diff stderr against the expected stderr.
# q All redirection lines given in the test script (not the lines
# actually produced by the test) are subject to ordinary quoted shell
# expansion (i.e. not globbing).
# This can be followed by a `:' and a message describing the
# test, which will be printed if the test fails, along with a
# description of the failure that occurred. The `:' and message are
# optional, but highly recommended.
# Hence a complete status line looks something like:
# 0dDq:Checking whether the world will end with a bang or a whimper
#
# If either or both of the '>' and '?' sets of lines is absent, it is
# assumed the corresponding output should be empty and it is an error if it
# is not. If '<' is empty, stdin is an empty (but opened) file.
#
# It is also possible to add lines in the redirection section beginning
# with `F:'. The remaining text on all such lines will be concatenated
# (with newlines in between) and displayed in the event of an error.
# This text is useful for explaining certain frequent errors, for example
# ones which may arise from the environment rather than from the shell
# itself. (The example below isn't particularly useful as errors with
# `cd' are unusual.)
#
# A couple of features aren't used in this file, but are usefuil in cases
# where features may not be available so should not be tested. They boh
# take the form of variables. Note that to keep the test framework simple
# there is no magic in setting the variables: the chunk of code being
# executed needs to avoid executing any test code by appropriate structure
# (typically "if"). In both cases, the value of the variable is output
# as a warning that the test was skipped.
# ZTST_unimplemented: Set this in the %prep phase if the entire test file
# is to be skipped.
# ZTST_skip: Set this in any test case if that single test case is to be
# skipped. Testing resumes at the next test case in the same file.
cd cdtst.tmp/sub/fake &&
pwd &&
print $PWD
0q:Preserving symbolic links in the current directory string
>$mydir/cdtst.tmp/sub/fake
>$mydir/cdtst.tmp/sub/fake
F:This test shouldn't really fail. The fact that it has indicates
F:something is broken. But you already knew that.
cd ../../.. &&
pwd &&
print $PWD
0q:Changing directory up through symbolic links without following them
>$mydir
>$mydir
setopt chaselinks
cd cdtst.tmp/sub/fake &&
pwd &&
print $PWD
0q:Resolving symbolic links with chaselinks set
>$mydir/cdtst.tmp/real
>$mydir/cdtst.tmp/real
ln -s nonexistent link_to_nonexistent
pwd1=$(pwd -P)
cd -s link_to_nonexistent
pwd2=$(pwd -P)
[[ $pwd1 = $pwd2 ]] || print "Ooops, changed to directory '$pwd2'"
0:
?(eval):cd:3: not a directory: link_to_nonexistent
%clean
# This optional section cleans up after the test, if necessary,
# e.g. killing processes etc. This is in addition to the removal of *.tmp
# subdirectories. This is essentially like %prep, except that status
# return values are ignored.

View File

@ -1,723 +0,0 @@
# There are certain usages of typeset and its synonyms that it is not
# possible to test here, because they must appear at the top level and
# everything that follows is processed by an "eval" within a function.
# Equivalences:
# declare typeset
# export typeset -xg
# float typeset -E
# functions typeset -f
# integer typeset -i
# local typeset +g -m approximately
# readonly typeset -r
# Tested elsewhere:
# Equivalence of autoload and typeset -fu A05execution
# Associative array creation & assignment D04parameter, D06subscript
# Effects of GLOBAL_EXPORT E01options
# Function tracing (typeset -ft) E02xtrace
# Not yet tested:
# Assorted illegal flag combinations
%prep
## Do not remove the next line, it's used by V10private.ztst
# test_zsh_param_private
mkdir typeset.tmp && cd typeset.tmp
setopt noglob
scalar=scalar
array=(a r r a y)
scope00() {
typeset scalar
scalar=local
typeset -a array
array=(l o c a l)
print $scalar $array
}
scope01() {
local scalar
scalar=local
local -a array
array=(l o c a l)
print $scalar $array
}
scope02() {
declare scalar
scalar=local
declare -a array
array=(l o c a l)
print $scalar $array
}
scope10() {
export outer=outer
/bin/sh -fc 'echo $outer'
}
scope11() {
typeset -x outer=outer
/bin/sh -fc 'echo $outer'
}
scope12() {
local -x outer=inner
/bin/sh -fc 'echo $outer'
}
scope13() {
local -xT OUTER outer
outer=(i n n e r)
/bin/sh -fc 'echo $OUTER'
}
# Bug? `typeset -h' complains that ! # $ * - ? @ are not identifiers.
stress00() {
typeset -h +g -m [[:alpha:]_]*
unset -m [[:alpha:]_]*
typeset +m [[:alpha:]_]*
}
%test
typeset +m scalar array
0:Report types of parameters with typeset +m
>scalar
>array array
scope00
print $scalar $array
0:Simple local declarations
>local l o c a l
>scalar a r r a y
scope01
print $scalar $array
0:Equivalence of local and typeset in functions
>local l o c a l
>scalar a r r a y
scope02
print $scalar $array
0:Basic equivalence of declare and typeset
>local l o c a l
>scalar a r r a y
declare +m scalar
0:declare previously lacked -m/+m options
>scalar
scope10
print $outer
0:Global export
>outer
>outer
scope11
print $outer
0:Equivalence of export and typeset -x
>outer
>outer
scope12
print $outer
0:Local export
>inner
>outer
float f=3.14159
typeset +m f
float -E3 f
print $f
float -F f
print $f
0:Floating point, adding a precision, and fixed point
>float local f
>3.14e+00
>3.142
integer i=3.141
typeset +m i
integer -i2 i
print $i
0:Integer and changing the base
>integer local i
>2#11
float -E3 f=3.141
typeset +m f
integer -i2 f
typeset +m f
print $f
0:Conversion of floating point to integer
>float local f
>integer 2 local f
>2#11
typeset -f
0q:Equivalence of functions and typeset -f
>$(functions)
readonly r=success
print $r
r=failure
1:Readonly declaration
>success
?(eval):3: read-only variable: r
typeset r=success
readonly r
print $r
r=failure
1:Convert to readonly
>success
?(eval):4: read-only variable: r
typeset -gU array
print $array
0:Uniquified arrays and non-local scope
>a r y
typeset -T SCALAR=l:o:c:a:l array
print $array
typeset -U SCALAR
print $SCALAR $array
0:Tied parameters and uniquified colon-arrays
>l o c a l
>l:o:c:a l o c a
(setopt NO_multibyte cbases
LC_ALL=C 2>/dev/null
typeset -T SCALAR=$'l\x83o\x83c\x83a\x83l' array $'\x83'
print $array
typeset -U SCALAR
for (( i = 1; i <= ${#SCALAR}; i++ )); do
char=$SCALAR[i]
print $(( [#16] #char ))
done
print $array)
0:Tied parameters and uniquified arrays with meta-character as separator
>l o c a l
>0x6C
>0x83
>0x6F
>0x83
>0x63
>0x83
>0x61
>l o c a
typeset -T SCALAR=$'l\000o\000c\000a\000l' array $'\000'
typeset -U SCALAR
print $array
[[ $SCALAR == $'l\000o\000c\000a' ]]
0:Tied parameters and uniquified arrays with NUL-character as separator
>l o c a
typeset -T SCALAR array
typeset +T SCALAR
1:Untying is prohibited
?(eval):typeset:2: use unset to remove tied variables
OUTER=outer
scope13
print $OUTER
0:Export of tied parameters
>i:n:n:e:r
>outer
typeset -TU MORESTUFF=here-we-go-go-again morestuff '-'
print -l $morestuff
0:Tied arrays with separator specified
>here
>we
>go
>again
typeset -T THIS will not work
1:Tied array syntax
?(eval):typeset:1: too many arguments for -T
local array[2]=x
1:Illegal local array element assignment
?(eval):local:1: array[2]: can't create local array elements
local -a array
typeset array[1]=a array[2]=b array[3]=c
print $array
0:Legal local array element assignment
>a b c
local -A assoc
local b=1 ;: to stomp assoc[1] if assoc[b] is broken
typeset assoc[1]=a assoc[b]=2 assoc[3]=c
print $assoc[1] $assoc[b] $assoc[3]
0:Legal local associative array element assignment
>a 2 c
local scalar scalar[1]=a scalar[2]=b scalar[3]=c
print $scalar
0:Local scalar subscript assignment
>abc
typeset -L 10 fools
for fools in " once" "twice" " thrice" " oops too long here"; do
print "'$fools'"
done
0:Left justification of scalars
>'once '
>'twice '
>'thrice '
>'oops too l'
typeset -L 10 -F 3 foolf
for foolf in 1.3 4.6 -2.987 -4.91031; do
print "'$foolf'"
done
0:Left justification of floating point
>'1.300 '
>'4.600 '
>'-2.987 '
>'-4.910 '
typeset -L 10 -Z foolzs
for foolzs in 001.3 04.6 -2.987 -04.91231; do
print "'$foolzs'"
done
0:Left justification of scalars with zero suppression
>'1.3 '
>'4.6 '
>'-2.987 '
>'-04.91231 '
typeset -R 10 foors
for foors in short longer even-longer; do
print "'$foors'"
done
0:Right justification of scalars
>' short'
>' longer'
>'ven-longer'
typeset -Z 10 foozs
for foozs in 42 -42 " 43" " -43"; do
print "'$foozs'"
done
0:Right justification of scalars with zeroes
>'0000000042'
>' -42'
>' 000000043'
>' -43'
integer -Z 10 foozi
for foozi in 42 -42 " 43" " -43"; do
print "'$foozi'"
done
0:Right justification of integers with zero, no initial base
>'0000000042'
>'-000000042'
>'0000000043'
>'-000000043'
# In case you hadn't twigged, the spaces are absorbed in the initial
# math evaluation, so don't get through.
unsetopt cbases
integer -Z 10 -i 16 foozi16
for foozi16 in 42 -42 " 43" " -43"; do
print "'$foozi16'"
done
0:Right justification of integers with zero, base 16, C_BASES off
>'16#000002A'
>'-16#00002A'
>'16#000002B'
>'-16#00002B'
setopt cbases
integer -Z 10 -i 16 foozi16c
for foozi16c in 42 -42 " 43" " -43"; do
print "'$foozi16c'"
done
0:Right justification of integers with zero, base 16, C_BASES on
>'0x0000002A'
>'-0x000002A'
>'0x0000002B'
>'-0x000002B'
setopt cbases
integer -Z 10 -i 16 foozi16c
for foozi16c in 0x1234 -0x1234; do
for (( i = 1; i <= 5; i++ )); do
print "'${foozi16c[i,11-i]}'"
done
print "'${foozi16c[-2]}'"
done
0:Extracting substrings from padded integers
>'0x00001234'
>'x0000123'
>'000012'
>'0001'
>'00'
>'3'
>'-0x0001234'
>'0x000123'
>'x00012'
>'0001'
>'00'
>'3'
typeset -F 3 -Z 10 foozf
for foozf in 3.14159 -3.14159 4 -4; do
print "'$foozf'"
done
0:Right justification of fixed point numbers with zero
>'000003.142'
>'-00003.142'
>'000004.000'
>'-00004.000'
stress00
print $scalar $array
0q:Stress test: all parameters are local and unset, using -m
>scalar a r y
local parentenv=preserved
fn() {
typeset -h +g -m \*
unset -m \*
integer i=9
float -H f=9
declare -t scalar
declare -H -a array
typeset
typeset +
}
fn
echo $parentenv
0:Parameter hiding and tagging, printing types and values
>array local array
>float local f
>integer local i=9
>local tagged scalar=''
>array local array
>float local f
>integer local i
>local tagged scalar
>preserved
export ENVFOO=bar
print ENVFOO in environment
env | grep '^ENVFOO'
print Changing ENVFOO
ENVFOO="not bar any more"
env | grep '^ENVFOO'
unset ENVFOO
print ENVFOO no longer in environment
env | grep '^ENVFOO'
1:Adding and removing values to and from the environment
>ENVFOO in environment
>ENVFOO=bar
>Changing ENVFOO
>ENVFOO=not bar any more
>ENVFOO no longer in environment
(export FOOENV=BAR
env | grep '^FOOENV'
print Exec
exec $ZTST_testdir/../Src/zsh -fc '
print Unset
unset FOOENV
env | grep "^FOOENV"')
1:Can unset environment variables after exec
>FOOENV=BAR
>Exec
>Unset
local case1=upper
typeset -u case1
print $case1
upper="VALUE OF \$UPPER"
print ${(P)case1}
0:Upper case conversion, does not apply to values used internally
>UPPER
>VALUE OF $UPPER
local case2=LOWER
typeset -l case2
print $case2
LOWER="value of \$lower"
print ${(P)case2}
0:Lower case conversion, does not apply to values used internally
>lower
>value of $lower
typeset -a array
array=(foo bar)
fn() { typeset -p array nonexistent; }
fn
1:declare -p shouldn't create scoped values
>typeset -g -a array=( foo bar )
?fn:typeset: no such variable: nonexistent
unsetopt typesetsilent
silent1(){ typeset -g silence; }
silent2(){ local silence; silent1; }
silent2
0:typeset -g should be silent even without TYPESET_SILENT
typeset -T TIED_SCALAR tied_array
TIED_SCALAR=foo:bar
print $tied_array
typeset -T TIED_SCALAR=goo:car tied_array
print $tied_array
typeset -T TIED_SCALAR tied_array=(poo par)
print $TIED_SCALAR
0:retying arrays to same array works
>foo bar
>goo car
>poo:par
(
setopt POSIXBUILTINS
readonly pbro
print ${+pbro} >&2
(typeset -g pbro=3)
(pbro=4)
readonly -p pbro >&2 # shows up as "readonly" although unset
typeset -gr pbro # idempotent (no error)...
print ${+pbro} >&2 # ...so still readonly...
typeset -g +r pbro # ...can't turn it off
)
1:readonly with POSIX_BUILTINS
?0
?(eval):5: read-only variable: pbro
?(eval):6: read-only variable: pbro
?typeset -g -r pbro
?0
?(eval):10: read-only variable: pbro
readonly foo=bar novalue
readonly -p
0:readonly -p output (no readonly specials)
>typeset -r foo=bar
>typeset -r novalue=''
local -a a1 a2
local -r r1=yes r2=no
a1=(one two) a2=(three four)
readonly a1
typeset -pm 'a[12]'
typeset -pm 'r[12]'
0:readonly -p output
>typeset -ar a1=( one two )
>typeset -a a2=( three four )
>typeset -r r1=yes
>typeset -r r2=no
one=hidden two=hidden three=hidden four=hidden five=hidden
fn() {
local bleugh="four=vier"
typeset -R10 one=eins two=(zwei dio) three $bleugh five=(cinq cinque)
three=drei
print -l $one $two $three $four $five
}
fn
print -l $one $two $three $four $five
0:typeset reserved word interface: basic
> eins
>zwei
>dio
> drei
> vier
>cinq
>cinque
>hidden
>hidden
>hidden
>hidden
>hidden
(
setopt glob
mkdir -p arrayglob
touch arrayglob/{one,two,three,four,five,six,seven}
fn() {
typeset array=(arrayglob/[tf]*)
print -l ${array:t}
#
typeset {first,second,third}=the_same_value array=(
extends
over
multiple
lines
)
print -l $first $second $third "$array"
#
integer i=$(echo 1 + 2 + 3 + 4)
print $i
#
# only noted by accident this was broken..
# we need to turn off special recognition
# of assignments within assignments...
typeset careful=( i=1 j=2 k=3 )
print -l $careful
}
fn
)
0:typeset reserved word, more complicated cases
>five
>four
>three
>two
>the_same_value
>the_same_value
>the_same_value
>extends over multiple lines
>10
>i=1
>j=2
>k=3
(
# reserved word is recognised at parsing.
# yes, this is documented.
# anyway, that means we need to
# re-eval the function...
fn='
fn() {
typeset foo=`echo one word=two`
print $foo
print $word
}
'
print reserved
eval $fn; fn
print builtin
disable -r typeset
eval $fn; fn
enable -r typeset
disable typeset
print reserved
eval $fn; fn
)
0:reserved word and builtin interfaces
>reserved
>one word=two
>
>builtin
>one
>two
>reserved
>one word=two
>
fn() {
emulate -L zsh
setopt typeset_silent
local k
typeset -A hash=(k1 v1 k2 v2)
typeset foo=word array=(more than one word)
for k in ${(ko)hash}; do
print $k $hash[$k]
done
print -l $foo $array
typeset -A hash
typeset foo array
for k in ${(ko)hash}; do
print $k $hash[$k]
done
print -l $foo $array
typeset hash=(k3 v3 k4 v4) array=(odd number here)
for k in ${(ko)hash}; do
print $k $hash[$k]
done
print -l $array
}
fn
0:typeset preserves existing variable types
>k1 v1
>k2 v2
>word
>more
>than
>one
>word
>k1 v1
>k2 v2
>word
>more
>than
>one
>word
>k3 v3
>k4 v4
>odd
>number
>here
fn() { typeset foo bar thing=this stuff=(that other) more=woevva; }
which -x2 fn
fn2() { typeset assignfirst=(why not); }
which -x2 fn2
0:text output from typeset
>fn () {
> typeset foo bar thing=this stuff=(that other) more=woevva
>}
>fn2 () {
> typeset assignfirst=(why not)
>}
fn() {
typeset array=()
print ${(t)array} ${#array}
typeset gnothergarray=() gnothergarray[1]=yes gnothergarray[2]=no
print -l ${(t)gnothergarray} $gnothergarray
}
fn
0:can set empty array
>array-local 0
>array-local
>yes
>no
array=(nothing to see here)
fn() {
typeset array=(one two three four five)
typeset array[2,4]=(umm er)
print ${#array} $array
typeset array[2,3]=()
print ${#array} $array
}
fn
print ${#array} $array
0:can update array slices in typeset
>4 one umm er five
>2 one five
>4 nothing to see here
array=(no really nothing here)
fn() {
typeset array=() array[2]=two array[4]=four
typeset -p array
typeset array=() array[3]=three array[1]=one
typeset -p array
}
fn
print $array
0:setting empty array in typeset
>typeset -a array=( '' two '' four )
>typeset -a array=( one '' three )
>no really nothing here
readonly isreadonly=yes
typeset isreadonly=still
1:typeset returns status 1 if setting readonly variable
?(eval):2: read-only variable: isreadonly
if (( UID )); then
UID=$((UID+1)) date; echo "Status is printed, $?"
else
ZTST_skip="cannot test setuid error when tests run as superuser"
fi
0:when cannot change UID, the command isn't run
# 'date' did not run.
>Status is printed, 1
*?*: failed to change user ID: *

View File

@ -1,336 +0,0 @@
# Tests for the echo, print, printf and pushln builtins
# Tested elsewhere:
# Use of print -p to output to coprocess A01grammar
# Prompt expansion with print -P D01prompt
# -l, -r, -R and -n indirectly tested in various places
# Not yet tested:
# echo and pushln
# print's -b -c -s -z -N options
%test
print -D "${HOME:-~}"
0:replace directory name
>~
print -u2 'error message'
0:output to file-descriptor
?error message
print -o foo bar Baz
0:argument sorting
>Baz bar foo
print -f
1:print -f needs a format specified
?(eval):print:1: argument expected: -f
print -Of '%s\n' foo bar baz
0:reverse argument sorting
>foo
>baz
>bar
# some locales force case-insensitive sorting
(LC_ALL=C; print -o a B c)
0:case-sensitive argument sorting
>B a c
(LC_ALL=C; print -io a B c)
0:case-insensitive argument sorting
>a B c
print -m '[0-9]' one 2 three 4 five 6
0:removal of non-matching arguments
>2 4 6
printf '%s\n' string
0:test s format specifier
>string
printf '%b' '\t\\\n'
0:test b format specifier
> \
printf '%q\n' '=a=b \ c!'
0: test q format specifier
>\=a=b\ \\\ c!
printf '%c\n' char
0:test c format specifier
>c
printf '%.10e%n\n' 1 count >/dev/null
printf '%d\n' $count
0:test n format specifier
>16
printf '%5b%n\n' abc count >/dev/null; echo $count
0:check count of width-specified %b
>5
printf '%s!%5b!\n' abc
0:ensure width is applied to empty param
>abc! !
printf '%d %d\n' 123.45 678 90.1
0:test d format specifier
>123 678
>90 0
printf '%g %g\n' 123.45 678 90.1
0:test g format specifier
>123.45 678
>90.1 0
print -f 'arg: %b\n' -C2 '\x41' '\x42' '\x43'
0:override -C when -f was given
>arg: A
>arg: B
>arg: C
# Is anyone not using ASCII
printf '%d\n' \'A
0:initial quote to get numeric value of character with int
>65
printf '%.1E\n' \'B
0:initial quote to get numeric value of character with double
>6.6E+01
printf '%x\n' $(printf '"\xf0')
0:numeric value of high numbered character
>f0
printf '\x25s\n' arg
0:using \x25 to print a literal % in format
>%s
printf '%3c\n' c
0:width specified in format specifier
> c
printf '%.4s\n' chopped
0:precision specified in format specifier
>chop
printf '%*.*f\n' 6 2 10.2
0:width/precision specified in arguments
> 10.20
printf '%z'
1:use of invalid directive
?(eval):printf:1: %z: invalid directive
printf '%d\n' 3a
1:bad arithmetic expression
?(eval):1: bad math expression: operator expected at `a'
>0
printf '%12$s' 1 2 3
1:out of range argument specifier
?(eval):printf:1: 12: argument specifier out of range
printf '%2$s\n' 1 2 3
1:out of range argument specifier on format reuse
?(eval):printf:1: 2: argument specifier out of range
>2
printf '%*0$d'
1:out of range argument specifier on width
?(eval):printf:1: 0: argument specifier out of range
print -m -f 'format - %s.\n' 'z' a b c
0:format not printed if no arguments left after -m removal
print -f 'format - %s%b.\n'
0:format printed despite lack of arguments
>format - .
printf 'x%4sx\n'
0:with no arguments empty string where string needed
>x x
printf '%d\n'
0:with no arguments, zero used where number needed
>0
printf '%s\t%c:%#x%%\n' one a 1 two b 2 three c 3
0:multiple arguments with format reused
>one a:0x1%
>two b:0x2%
>three c:0x3%
printf '%d%n' 123 val val val > /dev/null
printf '%d\n' val
0:%n count zeroed on format reuse
>1
# this may fill spec string with '%0'+- #*.*lld\0' - 14 characters
printf '%1$0'"'+- #-08.5dx\n" 123
0:maximal length format specification
>+00123 x
printf "x:%-20s:y\n" fubar
0:left-justification of string
>x:fubar :y
printf '%*smorning\n' -5 good
0:negative width specified
>good morning
printf '%.*g\n' -1 .1
0:negative precision specified
>0.1
printf '%2$s %1$d\n' 1 2
0:specify argument to output explicitly
>2 1
printf '%3$.*1$d\n' 4 0 3
0:specify output and precision arguments explicitly
>0003
printf '%2$d%1$d\n' 1 2 3 4
0:reuse format where arguments are explicitly specified
>21
>43
printf '%1$*2$d' 1 2 3 4 5 6 7 8 9 10; echo .EoL.
0:reuse of specified arguments
> 1 3 5 7 9.EoL.
echo -n 'Now is the time'; echo .EoL.
0:testing -n with echo
>Now is the time.EoL.
printf '%1$0+.3d\n' 3
0:flags mixed with specified argument
>+003
# Test the parsing of the \c escape.
echo '1 2!\c3 4' a b c d; echo .EoL.
0:Truncating first echo arg using backslash-c
>1 2!.EoL.
echo a b '1 2?\c5 6' c d; echo .EoL.
0:Truncating third echo arg using backslash-c
>a b 1 2?.EoL.
printf '1 2!\c3 4'; echo .EoL.
0:Truncating printf literal using backslash-c
>1 2!.EoL.
printf '%s %b!\c%s %s' 1 2 3 4 5 6 7 8 9; echo .EoL.
0:Truncating printf format using backslash-c
>1 2!.EoL.
printf '%s %b!\c%s %s' '1\c' '2\n\c' 3 4 5 6 7 8 9
0:Truncating printf early %b arg using backslash-c
>1\c 2
printf '%b %b\n' 1 2 3 4 '5\c' 6 7 8 9; echo .EoL.
0:Truncating printf late %b arg using backslash-c
>1 2
>3 4
>5.EoL.
# The following usage, as stated in the manual, is not recommended and the
# results are undefined. Tests are here anyway to ensure some form of
# half-sane behaviour.
printf '%2$s %s %3$s\n' Morning Good World
0:mixed style of argument selection
>Good Morning World
printf '%*1$.*d\n' 1 2
0:argument specified for width only
>00
print -f '%*.*1$d\n' 1 2 3
0:argument specified for precision only
>2
>000
printf -- '%s\n' str
0:initial `--' ignored to satisfy POSIX
>str
printf '%'
1:nothing after % in format specifier
?(eval):printf:1: %: invalid directive
printf $'%\0'
1:explicit null after % in format specifier
?(eval):printf:1: %: invalid directive
printf '%b\n' '\0123'
0:printf handles \0... octal escapes in replacement text
>S
print -lO $'a' $'a\0' $'a\0b' $'a\0b\0' $'a\0b\0a' $'a\0b\0b' $'a\0c' |
while read -r line; do
for (( i = 1; i <= ${#line}; i++ )); do
foo=$line[i]
printf "%02x" $(( #foo ))
done
print
done
0:sorting with embedded nulls
>610063
>6100620062
>6100620061
>61006200
>610062
>6100
>61
foo=$'one\ttwo\tthree\tfour\n'
foo+=$'\tone\ttwo\tthree\tfour\n'
foo+=$'\t\tone\t\ttwo\t\tthree\t\tfour'
print -x4 $foo
print -X4 $foo
0:Tab expansion by print
>one two three four
> one two three four
> one two three four
>one two three four
> one two three four
> one two three four
unset foo
print -v foo once more
typeset -p foo
printf -v foo "%s\0%s-" into the breach
typeset -p foo
0:print and printf into a variable
>typeset -g foo='once more'
>typeset -g foo=$'into\C-@the-breach\C-@-'
typeset -a foo
print -f '%2$d %4s' -v foo one 1 two 2 three 3
typeset -p foo
0:printf into an array variable
>typeset -a foo=( '1 one' '2 two' '3 three' )
typeset -a foo
print -f '%s' -v foo string
typeset -p foo
0:printf to an array variable without format string reuse
>typeset foo=string
printf -
printf - -
printf --
printf -- -
printf -- --
printf -x -v foo
# Final print for newline on stdout
print
0:regression test of printf with assorted ambiguous options or formats
>------x
?(eval):printf:3: not enough arguments

View File

@ -1,112 +0,0 @@
# Tests for the read builtin
# Tested elsewhere:
# reading from a coprocess A01grammar, A04redirect
# Not tested:
# -c/-l/-n (options for compctl functions)
# -q/-s (needs a tty)
%test
read <<<'hello world'
print $REPLY
0:basic read command
>hello world
read -A <<<'hello world'
print $reply[2]
0:array read
>world
read -k3 -u0 <<<foo:bar
print $REPLY
0:read specified number of chars
>foo
for char in y Y n N X $'\n'; do
read -q -u0 <<<$char
print $?
done
0:read yes or no, default no
>0
>0
>1
>1
>1
>1
read -d: <<<foo:bar
print $REPLY
0:read up to delimiter
>foo
print foo:bar|IFS=: read -A
print $reply
0:use different, IFS separator to array
>foo bar
print -z hello world; read -z
print $REPLY
0:read from editor buffer stack
>hello world
unset REPLY
read -E <<<hello
print $REPLY
0:read with echoing and assigning
>hello
>hello
unset REPLY
read -e <<<hello
print $REPLY
0:read with echoing but assigning disabled
>hello
>
read -e -t <<<hello
0:read with test first
>hello
SECONDS=0
read -e -t 5 <<<hello
print $SECONDS
0:read with timeout (no waiting should occur)
>hello
>0
print -n 'Testing the\0null hypothesis\0' |
while read -d $'\0' line; do print $line; done
0:read with null delimiter
>Testing the
>null hypothesis
# Note that trailing NULLs are not stripped even if they are in
# $IFS; only whitespace characters contained in $IFS are stripped.
print -n $'Aaargh, I hate nulls.\0\0\0' | read line
print ${#line}
0:read with trailing metafied characters
>24
(typeset -r foo
read foo) <<<bar
1:return status on failing to set parameter
?(eval):2: read-only variable: foo
read -AE array <<<'one two three'
print ${(j.:.)array}
0:Behaviour of -A and -E combination
>one
>two
>three
>one:two:three
array=()
read -Ae array <<<'four five six'
print ${(j.:.)array}
0:Behaviour of -A and -e combination
>four
>five
>six
>

View File

@ -1,34 +0,0 @@
# Tests for the eval builtin.
# This is quite short; eval is widely tested throughout the test suite
# and its basic behaviour is fairly straightforward.
%prep
cmd='print $?'
%test
false
eval $cmd
0:eval retains value of $?
>1
# no point getting worked up over what the error message is...
./command_not_found 2>/dev/null
eval $cmd
0:eval after command not found
>127
# trick the test system
sp=
false
eval "
$sp
$sp
$sp
"
0:eval with empty command resets the status
false
eval
0:eval with empty command resets the status

View File

@ -1,25 +0,0 @@
# Tests of fc command
%prep
mkdir fc.tmp
cd fc.tmp
print 'fc -l foo' >fcl
%test
$ZTST_testdir/../Src/zsh -f ./fcl
1:Checking that fc -l foo doesn't core dump when history is empty
?./fcl:fc:1: event not found: foo
PS1='%% ' $ZTST_testdir/../Src/zsh +Z -fsi <<< $'fc -p /dev/null 0 0\n:'
0:Checking that fc -p doesn't core dump when history size is zero
*?*%*
PS1='%% ' $ZTST_testdir/../Src/zsh +Z -fsi <<< 'fc -p /dev/null a 0'
1:Checking that fc -p rejects non-integer history size
*?*% fc: HISTSIZE must be an integer
*?*%*
PS1='%% ' $ZTST_testdir/../Src/zsh +Z -fsi <<< 'fc -p /dev/null 0 a'
1:Checking that fc -p rejects non-integer history save size
*?*% fc: SAVEHIST must be an integer
*?*%*

View File

@ -1,253 +0,0 @@
# Test the "emulate" builtin and related functions.
%prep
isset() {
print -n "${1}: "
if [[ -o $1 ]]; then print yes; else print no; fi
}
showopts() {
# Set for Bourne shell emulation
isset shwordsplit
# Set in native mode and unless "emulate -R" is in use
isset banghist
}
cshowopts() {
showopts
# Show a csh option, too
isset cshnullglob
}
%test
(print Before
showopts
fn() {
emulate sh
}
fn
print After
showopts)
0:Basic use of emulate
>Before
>shwordsplit: no
>banghist: yes
>After
>shwordsplit: yes
>banghist: yes
fn() {
emulate -L sh
print During
showopts
}
print Before
showopts
fn
print After
showopts
0:Use of emulate -L
>Before
>shwordsplit: no
>banghist: yes
>During
>shwordsplit: yes
>banghist: yes
>After
>shwordsplit: no
>banghist: yes
(print Before
showopts
emulate -R sh
print After
showopts)
0:Use of emulate -R
>Before
>shwordsplit: no
>banghist: yes
>After
>shwordsplit: yes
>banghist: no
print Before
showopts
emulate sh -c 'print During; showopts'
print After
showopts
0:Use of emulate -c
>Before
>shwordsplit: no
>banghist: yes
>During
>shwordsplit: yes
>banghist: yes
>After
>shwordsplit: no
>banghist: yes
print Before
showopts
emulate -R sh -c 'print During; showopts'
print After
showopts
0:Use of emulate -R -c
>Before
>shwordsplit: no
>banghist: yes
>During
>shwordsplit: yes
>banghist: no
>After
>shwordsplit: no
>banghist: yes
print Before
showopts
emulate -R sh -c 'shshowopts() { showopts; }'
print After definition
showopts
print In sticky emulation
shshowopts
print After sticky emulation
showopts
0:Basic sticky function emulation
>Before
>shwordsplit: no
>banghist: yes
>After definition
>shwordsplit: no
>banghist: yes
>In sticky emulation
>shwordsplit: yes
>banghist: no
>After sticky emulation
>shwordsplit: no
>banghist: yes
print Before
cshowopts
emulate -R sh -c 'shshowopts() { cshowopts; }'
emulate csh -c 'cshshowopts() {
cshowopts
print In nested sh emulation
shshowopts
}'
print After definition
cshowopts
print In sticky csh emulation
cshshowopts
print After sticky emulation
cshowopts
0:Basic sticky function emulation
>Before
>shwordsplit: no
>banghist: yes
>cshnullglob: no
>After definition
>shwordsplit: no
>banghist: yes
>cshnullglob: no
>In sticky csh emulation
>shwordsplit: no
>banghist: yes
>cshnullglob: yes
>In nested sh emulation
>shwordsplit: yes
>banghist: no
>cshnullglob: no
>After sticky emulation
>shwordsplit: no
>banghist: yes
>cshnullglob: no
isalp() { if [[ -o alwayslastprompt ]]; then print on; else print off; fi; }
emulate sh -c 'shfunc_inner() { setopt alwayslastprompt; }'
emulate csh -c 'cshfunc_inner() { setopt alwayslastprompt; }'
emulate sh -c 'shfunc_outer() {
unsetopt alwayslastprompt;
shfunc_inner;
isalp
unsetopt alwayslastprompt
cshfunc_inner
isalp
}'
shfunc_outer
0:Sticky emulation not triggered if sticky emulation unchanged
>on
>off
(
setopt ignorebraces
emulate zsh -o extendedglob -c '
[[ -o ignorebraces ]] || print "Yay, ignorebraces was reset"
[[ -o extendedglob ]] && print "Yay, extendedglob is set"
'
)
0:emulate -c with options
>Yay, ignorebraces was reset
>Yay, extendedglob is set
(
setopt ignorebraces
emulate zsh -o extendedglob
[[ -o ignorebraces ]] || print "Yay, ignorebraces is no longer set"
[[ -o extendedglob ]] && print "Yay, extendedglob is set"
)
0:emulate with options but no -c
>Yay, ignorebraces is no longer set
>Yay, extendedglob is set
emulate zsh -o fixallmybugs 'print This was executed, bad'
1:emulate -c with incorrect options
?(eval):emulate:1: no such option: fixallmybugs
emulate zsh -c '
func() { [[ -o extendedglob ]] || print extendedglob is off }
'
func
emulate zsh -o extendedglob -c '
func() { [[ -o extendedglob ]] && print extendedglob is on }
'
func
0:options specified alongside emulation are also sticky
>extendedglob is off
>extendedglob is on
emulate zsh -o extendedglob -c '
func_inner() { setopt nobareglobqual }
'
emulate zsh -o extendedglob -c '
func_outer() {
func_inner
[[ -o bareglobqual ]] || print bareglobqual was turned off
[[ -o extendedglob ]] && print extendedglob is on, though
}
'
[[ -o extendedglob ]] || print extendedglob is initially off
func_outer
0:options propagate between identical emulations
>extendedglob is initially off
>bareglobqual was turned off
>extendedglob is on, though
emulate zsh -o extendedglob -c '
func_inner() { setopt nobareglobqual }
'
emulate zsh -o extendedglob -o cbases -c '
func_outer() {
func_inner
[[ -o bareglobqual ]] && print bareglobqual is still on
[[ -o extendedglob ]] && print extendedglob is on, too
}
'
[[ -o extendedglob ]] || print extendedglob is initially off
func_outer
0:options do not propagate between different emulations
>extendedglob is initially off
>bareglobqual is still on
>extendedglob is on, too
emulate sh -c '[[ a == a ]]'
0:regression test for POSIX_ALIASES reserved words
F:Some reserved tokens are handled in alias expansion

Some files were not shown because too many files have changed in this diff Show More