refactor: remove for submodule
This commit is contained in:
parent
dadf0d19c3
commit
f1c424a9ec
@ -1,2 +0,0 @@
|
||||
modules/** linguist-vendored
|
||||
modules/Src/aloxaf/*.c -linguist-vendored
|
@ -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).
|
@ -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.
|
@ -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.
|
@ -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
|
||||
|
@ -1 +0,0 @@
|
||||
*.zwc
|
@ -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.
|
@ -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)
|
@ -1,3 +0,0 @@
|
||||
0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
|
||||
0="${${(M)0:#/*}:-$PWD/$0}"
|
||||
source "${0:A:h}/fzf-tab.zsh"
|
@ -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'
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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.
|
@ -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
|
||||
|
||||
...
|
||||
}
|
||||
```
|
||||
|
@ -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
|
||||
|
@ -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:
|
@ -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
|
@ -1,4 +0,0 @@
|
||||
DISTFILES_SRC='
|
||||
META-FAQ
|
||||
configure config.h.in stamp-h.in
|
||||
'
|
@ -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
|
@ -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
|
@ -1,7 +0,0 @@
|
||||
#! /bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
autoconf
|
||||
autoheader
|
||||
echo > stamp-h.in
|
@ -1,2 +0,0 @@
|
||||
defs.mk
|
||||
*.swp
|
@ -1,2 +0,0 @@
|
||||
DISTFILES_SRC='
|
||||
'
|
@ -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])
|
||||
])
|
@ -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
|
@ -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
|
@ -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:
|
@ -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
|
@ -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
|
@ -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'
|
@ -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.
|
@ -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:
|
@ -1 +0,0 @@
|
||||
1580588806
|
@ -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
|
@ -1,2 +0,0 @@
|
||||
DISTFILES_SRC='
|
||||
'
|
@ -1,2 +0,0 @@
|
||||
set ai
|
||||
set sw=4
|
@ -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
|
@ -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
|
@ -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)
|
||||
|
@ -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
|
@ -1,2 +0,0 @@
|
||||
DISTFILES_SRC='
|
||||
'
|
@ -1,2 +0,0 @@
|
||||
set ai
|
||||
set sw=4
|
@ -1,8 +0,0 @@
|
||||
Makefile.in
|
||||
*.epro
|
||||
*.export
|
||||
*.mdh
|
||||
*.mdhi
|
||||
*.mdhs
|
||||
*.pro
|
||||
*.syms
|
@ -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;
|
||||
}
|
@ -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
@ -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
@ -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
@ -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
@ -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;
|
||||
}
|
@ -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
@ -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
|
@ -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
@ -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
@ -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
@ -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));
|
@ -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)
|
||||
}
|
@ -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 "};"
|
||||
}
|
@ -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
@ -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
|
@ -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"
|
@ -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
|
@ -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
|
@ -1,3 +0,0 @@
|
||||
Makefile
|
||||
*.tmp
|
||||
*.swp
|
@ -1,2 +0,0 @@
|
||||
DISTFILES_SRC='
|
||||
'
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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.
|
@ -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: *
|
@ -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
|
@ -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
|
||||
>
|
@ -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
|
@ -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
|
||||
*?*%*
|
@ -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
Loading…
Reference in New Issue
Block a user