mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-27 16:50:58 +01:00
zsh-workers/10106
This commit is contained in:
parent
b1fcad6a63
commit
16ea1f357d
4 changed files with 241 additions and 5 deletions
226
Functions/Misc/zrecompile
Normal file
226
Functions/Misc/zrecompile
Normal file
|
|
@ -0,0 +1,226 @@
|
||||||
|
# This tries to find wordcode files and automatically re-compile them if
|
||||||
|
# at least one of the original files is newer than the wordcode file.
|
||||||
|
# This will only work if the original files were added with their full
|
||||||
|
# paths or if the names stored in the wordcode files are relative to the
|
||||||
|
# directory where the wordcode file is.
|
||||||
|
#
|
||||||
|
# Arguments are the names of wordcode files and directories containing
|
||||||
|
# wordcode files that should be checked. If no arguments are given, the
|
||||||
|
# directories and wordcode files in $fpath are used.
|
||||||
|
#
|
||||||
|
# And then there are two options:
|
||||||
|
# -t: Only check if there are wordcode files that have to be
|
||||||
|
# re-compiled. The return status is zero if there are files
|
||||||
|
# that need to be re-compiled and non-zero otherwise.
|
||||||
|
# -q: Be quiet, i.e.: only set the return status.
|
||||||
|
# -p: If this is given, the arguments are interpreted differently:
|
||||||
|
# they should form one or more sets of arguments for zcompile,
|
||||||
|
# seperated by `--'. For example:
|
||||||
|
#
|
||||||
|
# zrecompile -p \
|
||||||
|
# -r ~/.zshrc -- \
|
||||||
|
# -m ~/.zcompdump -- \
|
||||||
|
# ~/zsh/comp.zwc ~/zsh/Completion/*/_* \
|
||||||
|
#
|
||||||
|
# This makes ~/.zshrc be compiled into ~/.zshrc.zwc if that doesn't
|
||||||
|
# exist or if it is older than ~/.zshrc. The wordcode file will be
|
||||||
|
# marked for reading instead of mapping. The same is done for
|
||||||
|
# ~/.zcompdump and ~/.zcompdump.zwc, but the wordcode file is marked
|
||||||
|
# for mapping. The last line re-creates the file ~/zsh/comp.zwc if
|
||||||
|
# any of the files matching the given pattern is newer than it.
|
||||||
|
#
|
||||||
|
# Without the -t option, the return status is zero if all wordcode files
|
||||||
|
# that needed re-compilation could be compiled and non-zero if compilation
|
||||||
|
# for at least one of the files failed.
|
||||||
|
|
||||||
|
emulate -L zsh
|
||||||
|
setopt extendedglob
|
||||||
|
|
||||||
|
local opt check quiet zwc files re file pre ret map tmp mesg pats
|
||||||
|
|
||||||
|
while getopts "tqp" opt; do
|
||||||
|
case $opt in
|
||||||
|
t) check=yes ;;
|
||||||
|
q) quiet=yes ;;
|
||||||
|
p) pats=yes ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift OPTIND-1
|
||||||
|
|
||||||
|
if [[ -n $check ]]; then
|
||||||
|
ret=1
|
||||||
|
else
|
||||||
|
ret=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n $pats ]]; then
|
||||||
|
local end
|
||||||
|
|
||||||
|
while (( $# )); do
|
||||||
|
end=$argv[(i)--]
|
||||||
|
|
||||||
|
if [[ end -le $# ]]; then
|
||||||
|
files=( $argv[1,end-1] )
|
||||||
|
shift end
|
||||||
|
else
|
||||||
|
files=( $argv )
|
||||||
|
argv=()
|
||||||
|
fi
|
||||||
|
|
||||||
|
files=( ${files:#*(.zwc|~)} )
|
||||||
|
if [[ $files[1] = -[rm] ]]; then
|
||||||
|
map=( $files[1] )
|
||||||
|
shift 1 files
|
||||||
|
else
|
||||||
|
map=()
|
||||||
|
fi
|
||||||
|
|
||||||
|
(( $#files )) || continue
|
||||||
|
|
||||||
|
zwc=${files[1]%.zwc}.zwc
|
||||||
|
shift 1 files
|
||||||
|
|
||||||
|
(( $#files )) || files=( ${zwc%.zwc} )
|
||||||
|
|
||||||
|
if [[ -f $zwc ]]; then
|
||||||
|
re=
|
||||||
|
for file in $files; do
|
||||||
|
if [[ $file -nt $zwc ]]; then
|
||||||
|
re=yes
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
re=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n $re ]]; then
|
||||||
|
if [[ -n $check ]]; then
|
||||||
|
|
||||||
|
# ... say so.
|
||||||
|
|
||||||
|
[[ -z $quiet ]] && print $zwc needs re-compilation
|
||||||
|
ret=0
|
||||||
|
else
|
||||||
|
|
||||||
|
# ... or do it.
|
||||||
|
|
||||||
|
[[ -z $quiet ]] && print -n "re-compiling ${zwc}: "
|
||||||
|
|
||||||
|
# If the file is mapped, it might be mapped right now, so keep the
|
||||||
|
# old file by renaming it.
|
||||||
|
|
||||||
|
if { [[ ! -f $zwc ]] || mv $zwc ${zwc}.old } &&
|
||||||
|
zcompile "$map[@]" $zwc $files 2> /dev/null; then
|
||||||
|
[[ -z $quiet ]] && print succeeded
|
||||||
|
else
|
||||||
|
[[ -z $quiet ]] && print failed
|
||||||
|
ret=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
return ret
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get the names of wordcode files.
|
||||||
|
|
||||||
|
if (( $# )); then
|
||||||
|
argv=( ${^argv}/*.zwc(ND) ${^argv}.zwc(ND) ${(M)argv:#*.zwc} )
|
||||||
|
else
|
||||||
|
argv=( ${^fpath}/*.zwc(ND) ${^fpath}.zwc(ND) ${(M)fpath:#*.zwc} )
|
||||||
|
fi
|
||||||
|
|
||||||
|
# We only handle *.zwc files. zcompile only handles *.zwc files. Everybody
|
||||||
|
# seems to handle only *.zwc files.
|
||||||
|
|
||||||
|
argv=( ${^argv%.zwc}.zwc )
|
||||||
|
|
||||||
|
for zwc; do
|
||||||
|
|
||||||
|
# Get the files in the wordcode file.
|
||||||
|
|
||||||
|
files=( ${(f)"$(zcompile -t $zwc)"} )
|
||||||
|
|
||||||
|
# See if the wordcode file will be mapped.
|
||||||
|
|
||||||
|
if [[ $files[1] = *\(mapped\)* ]]; then
|
||||||
|
map=-m
|
||||||
|
mesg='succeeded (old saved)'
|
||||||
|
else
|
||||||
|
map=-r
|
||||||
|
mesg=succeeded
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get the path prefix of the wordcode file to prepend it to names of
|
||||||
|
# original files that are relative pathnames.
|
||||||
|
|
||||||
|
if [[ $zwc = */* ]]; then
|
||||||
|
pre=${zwc%/*}/
|
||||||
|
else
|
||||||
|
pre=
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Maybe this is even for an older version of the shell?
|
||||||
|
|
||||||
|
if [[ $files[1] != *$ZSH_VERSION ]]; then
|
||||||
|
re=yes
|
||||||
|
else
|
||||||
|
re=
|
||||||
|
fi
|
||||||
|
|
||||||
|
files=( ${pre}${^files[2,-1]:#/*} ${(M)files[2,-1]:#/*} )
|
||||||
|
|
||||||
|
# If the version is correct, compare the age of every original file
|
||||||
|
# to the age of the wordcode file.
|
||||||
|
|
||||||
|
[[ -z $re ]] &&
|
||||||
|
for file in $files; do
|
||||||
|
if [[ $file -nt $zwc ]]; then
|
||||||
|
re=yes
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -n $re ]]; then
|
||||||
|
|
||||||
|
# The wordcode files needs re-compilation...
|
||||||
|
|
||||||
|
if [[ -n $check ]]; then
|
||||||
|
|
||||||
|
# ... say so.
|
||||||
|
|
||||||
|
[[ -z $quiet ]] && print $zwc needs re-compilation
|
||||||
|
ret=0
|
||||||
|
else
|
||||||
|
|
||||||
|
# ... or do it.
|
||||||
|
|
||||||
|
[[ -z $quiet ]] && print -n "re-compiling ${zwc}: "
|
||||||
|
|
||||||
|
tmp=( ${^files}(N) )
|
||||||
|
|
||||||
|
# Here is the call to zcompile, but if we can't find all the original
|
||||||
|
# files, we don't try compilation.
|
||||||
|
|
||||||
|
if [[ $#tmp -ne $#files ]]; then
|
||||||
|
[[ -z $quiet ]] && print 'failed (missing files)'
|
||||||
|
ret=1
|
||||||
|
else
|
||||||
|
|
||||||
|
# If the file is mapped, it might be mapped right now, so keep the
|
||||||
|
# old file by renaming it.
|
||||||
|
|
||||||
|
if mv $zwc ${zwc}.old && zcompile $map $zwc $files 2> /dev/null; then
|
||||||
|
[[ -z $quiet ]] && print $mesg
|
||||||
|
else
|
||||||
|
[[ -z $quiet ]] && print failed
|
||||||
|
ret=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
@ -315,12 +315,16 @@ static char list_pipe_text[JOBTEXTSIZE];
|
||||||
static int
|
static int
|
||||||
execcursh(Estate state, int do_exec)
|
execcursh(Estate state, int do_exec)
|
||||||
{
|
{
|
||||||
|
Wordcode end = state->pc + WC_CURSH_SKIP(state->pc[-1]);
|
||||||
|
|
||||||
if (!list_pipe && thisjob != list_pipe_job)
|
if (!list_pipe && thisjob != list_pipe_job)
|
||||||
deletejob(jobtab + thisjob);
|
deletejob(jobtab + thisjob);
|
||||||
cmdpush(CS_CURSH);
|
cmdpush(CS_CURSH);
|
||||||
execlist(state, 1, do_exec);
|
execlist(state, 1, do_exec);
|
||||||
cmdpop();
|
cmdpop();
|
||||||
|
|
||||||
|
state->pc = end;
|
||||||
|
|
||||||
return lastval;
|
return lastval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
10
Src/parse.c
10
Src/parse.c
|
|
@ -1264,13 +1264,16 @@ par_repeat(int *complex)
|
||||||
static void
|
static void
|
||||||
par_subsh(int *complex)
|
par_subsh(int *complex)
|
||||||
{
|
{
|
||||||
int oecused = ecused, otok = tok;
|
int oecused = ecused, otok = tok, p;
|
||||||
|
|
||||||
ecadd(tok == INPAR ? WCB_SUBSH() : WCB_CURSH());
|
p = ecadd(0);
|
||||||
yylex();
|
yylex();
|
||||||
par_save_list(complex);
|
par_list(complex);
|
||||||
|
ecadd(WCB_END());
|
||||||
if (tok != ((otok == INPAR) ? OUTPAR : OUTBRACE))
|
if (tok != ((otok == INPAR) ? OUTPAR : OUTBRACE))
|
||||||
YYERRORV(oecused);
|
YYERRORV(oecused);
|
||||||
|
ecbuf[p] = (otok == INPAR ? WCB_SUBSH(ecused - 1 - p) :
|
||||||
|
WCB_CURSH(ecused - 1 - p));
|
||||||
incmdpos = 1;
|
incmdpos = 1;
|
||||||
yylex();
|
yylex();
|
||||||
}
|
}
|
||||||
|
|
@ -2422,6 +2425,7 @@ build_dump(char *nam, char *dump, char **files, int ali, int map)
|
||||||
zfree(file, flen);
|
zfree(file, flen);
|
||||||
zerrnam(nam, "can't read file: %s", *files, 0);
|
zerrnam(nam, "can't read file: %s", *files, 0);
|
||||||
noaliases = ona;
|
noaliases = ona;
|
||||||
|
errflag = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
zfree(file, flen);
|
zfree(file, flen);
|
||||||
|
|
|
||||||
|
|
@ -596,9 +596,11 @@ struct eccstr {
|
||||||
#define WC_SIMPLE_ARGC(C) wc_data(C)
|
#define WC_SIMPLE_ARGC(C) wc_data(C)
|
||||||
#define WCB_SIMPLE(N) wc_bld(WC_SIMPLE, (N))
|
#define WCB_SIMPLE(N) wc_bld(WC_SIMPLE, (N))
|
||||||
|
|
||||||
#define WCB_SUBSH() wc_bld(WC_SUBSH, 0)
|
#define WC_SUBSH_SKIP(C) wc_data(C)
|
||||||
|
#define WCB_SUBSH(O) wc_bld(WC_SUBSH, (O))
|
||||||
|
|
||||||
#define WCB_CURSH() wc_bld(WC_CURSH, 0)
|
#define WC_CURSH_SKIP(C) wc_data(C)
|
||||||
|
#define WCB_CURSH(O) wc_bld(WC_CURSH, (O))
|
||||||
|
|
||||||
#define WC_TIMED_TYPE(C) wc_data(C)
|
#define WC_TIMED_TYPE(C) wc_data(C)
|
||||||
#define WC_TIMED_EMPTY 0
|
#define WC_TIMED_EMPTY 0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue