* _make-expandVars() broken? (was Re: Makefile completion with wildcard targets)
@ 2015-07-28 13:20 Jun T.
2015-07-28 19:26 ` Bart Schaefer
2015-07-30 16:26 ` Jun T.
0 siblings, 2 replies; 4+ messages in thread
From: Jun T. @ 2015-07-28 13:20 UTC (permalink / raw)
To: zsh-workers
Continued form zsh-users (20348, 20349, 20352).
Currently _make recognizes the target by the the following
pattern (line 87 of _make):
[[:alnum:]][^$TAB:=]#:[^=]*
i.e., the first character must be an alnum. This means if a target
start with a meta character, for example,
*.c: dependencies
then *.c is not recognized as a target. If we are going to add -Q
to compadd, then it would be better to use a pattern something like
[[*?[:alnum:]$][^$TAB:=%]#:[^=]*
But when I tried this pattern I noticed that the function
_make-expandVars() was not working at all.
# I've looked into the function but couldn't understand what
# the variables $front, $ret and $tmp were supposed to do.
I think this function must be fixed irrespective of what pattern
to use at line 87, and add -Q to compadd or not.
I tried to rewrite the function as in the patch below.
It seems to work at least with the zsh's top-level Makefile
and several of my own small Makefiles, but may be far from
complete. Please improve if someone has a spare time.
In _make-expandVars() below, the input is divided into $front$rest,
where in $front all the make variables have already been replaced
with their values, while in $rest there remains one or more variables.
I also changed the $TARGETS from an associative to an ordinary
array, because only its keys were used.
diff --git a/Completion/Unix/Command/_make b/Completion/Unix/Command/_make
index c14a34c..64c91cd 100644
--- a/Completion/Unix/Command/_make
+++ b/Completion/Unix/Command/_make
@@ -4,58 +4,57 @@
# are used in those targets and their dependencies.
_make-expandVars() {
- local open close var val front ret tmp=$1
+ local open close var val front='' rest=$1
- front=${tmp%%\$*}
- case $tmp in
- (\(*) # Variable of the form $(foobar)
- open='('
- close=')'
- ;;
-
- ({*) # ${foobar}
- open='{'
- close='}'
- ;;
-
- ([[:alpha:]]*) # $foobar. This is exactly $(f)oobar.
- open=''
- close=''
- var=${(s::)var[1]}
- ;;
-
- (\$*) # Escaped $.
- print -- "${front}\$$(_make-expandVars ${tmp#\$})"
- return
- ;;
-
- (*) # Nothing left to substitute.
- print -- $tmp
- return
- ;;
- esac
+ while [[ $rest = (#b)[^$]#($)* ]]; do
+ front=$front${rest[1,$mbegin[1]-1]}
+ rest=${rest[$mbegin[1],-1]}
- if [[ -n $open ]]
- then
- var=${tmp#$open}
- var=${var%%$close*}
- fi
+ case $rest[2] in
+ ($) # '$$'. may not appear in target and variable's value
+ front=$front\$ # or $front\$\$ ?
+ rest=${rest[3,-1]}
+ continue
+ ;;
+ (\() # Variable of the form $(foobar)
+ open='('
+ close=')'
+ ;;
+ ({) # ${foobar}
+ open='{'
+ close='}'
+ ;;
+ ([[:alpha:]]) # $foobar. This is exactly $(f)oobar.
+ open=''
+ close=''
+ var=$rest[2]
+ ;;
+ (*) # bad parameter name
+ print -- $front$rest
+ return
+ ;;
+ esac
- case $var in
- ([[:alnum:]_]#)
- val=${VARIABLES[$var]}
- ret=${ret//\$$open$var$close/$val}
- ;;
+ if [[ -n $open ]]; then
+ if [[ $rest = \$$open(#b)([[:alnum:]_]##)(#B)$close* ]]; then
+ var=$match
+ else # unmatched () or {}, or bad parameter name
+ print -- $front$rest
+ return
+ fi
+ fi
- (*)
- # Improper variable name. No replacement.
- # I'm not sure if this is desired behavior.
- front+="\$$open$var$close"
- ret=${ret/\$$open$var$close/}
- ;;
- esac
+ if [[ -n ${VARIABLES[(i)$var]} ]]; then
+ rest=${rest//\$$open$var$close/${VARIABLES[$var]}}
+ else
+ # if $var is not defined, just leave it as is.
+ # (or better to replace by a null string?)
+ front=$front\$$open$var$close
+ rest=${rest#\$$open$var$close}
+ fi
+ done
- print -- "${front}$(_make-expandVars ${ret})"
+ print -- ${front}${rest}
}
_make-parseMakefile () {
@@ -84,16 +83,9 @@ _make-parseMakefile () {
# TARGET: dependencies
# TARGET1 TARGET2 TARGET3: dependencies
- ([[:alnum:]][^$TAB:=]#:[^=]*)
- input=$(_make-expandVars $input)
- target=${input%%:*}
- dep=${input#*:}
- dep=${(z)dep}
- dep="$dep"
- for tmp in ${(z)target}
- do
- TARGETS[$tmp]=$dep
- done
+ ([[*?[:alnum:]$][^$TAB:=%]#:[^=]*)
+ target=$(_make-expandVars ${input%%:*})
+ TARGETS+=( ${(z)target} )
;;
# Include another makefile
@@ -150,7 +142,8 @@ _make() {
local prev="$words[CURRENT-1]" file expl tmp is_gnu dir incl match
local context state state_descr line
local -a option_specs
- local -A TARGETS VARIABLES opt_args
+ local -A VARIABLES opt_args
+ local -aU TARGETS
local ret=1
_pick_variant -r is_gnu gnu=GNU unix -v -f
@@ -275,7 +268,7 @@ _make() {
while _tags
do
_requested targets expl 'make targets' \
- compadd -- ${(k)TARGETS} && ret=0
+ compadd -Q -- ${TARGETS} && ret=0
_requested variables expl 'make variables' \
compadd -S '=' -- ${(k)VARIABLES} && ret=0
done
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: _make-expandVars() broken? (was Re: Makefile completion with wildcard targets)
2015-07-28 13:20 _make-expandVars() broken? (was Re: Makefile completion with wildcard targets) Jun T.
@ 2015-07-28 19:26 ` Bart Schaefer
2015-07-30 16:26 ` Jun T.
1 sibling, 0 replies; 4+ messages in thread
From: Bart Schaefer @ 2015-07-28 19:26 UTC (permalink / raw)
To: zsh-workers
On Jul 28, 10:20pm, Jun T. wrote:
}
} I think this function must be fixed irrespective of what pattern
} to use at line 87, and add -Q to compadd or not.
I agree. I see you've replaced recursive calls with a loop, that's
probably a good thing.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: _make-expandVars() broken? (was Re: Makefile completion with wildcard targets)
2015-07-28 13:20 _make-expandVars() broken? (was Re: Makefile completion with wildcard targets) Jun T.
2015-07-28 19:26 ` Bart Schaefer
@ 2015-07-30 16:26 ` Jun T.
2015-07-31 2:14 ` Bart Schaefer
1 sibling, 1 reply; 4+ messages in thread
From: Jun T. @ 2015-07-30 16:26 UTC (permalink / raw)
To: zsh-workers
Here is a slightly updated _make.
(1)(2)(3) were already in the previous patch.
(4)(5) are new.
(1) fix the broken make-expandVars()
(2) allow * ? and $ as the first character of the target.
(3) add an option -Q to compadd for targets.
(4) If 'VAR=VAL' is on the current command line,
% make VAR=VAL <TAB>
then use it in make-expandVars(). Also do not offer VAR for
completion if VAR=VAL is already on the command line (compadd -F).
(5) If the variable is not defined in Makefile nor on the command
line, then look it up in the environment.
The option --environment-overrides is respected.
It doesn't support $(SRCS:.c=.o) etc., but if a user need these
then he/she can set call-command style to true to use the
output from 'make -nsp'.
Any comment?
# The reason that make-expandVars() has been broken for a long time
# may be that most of the users are setting call-command style?
diff --git a/Completion/Unix/Command/_make b/Completion/Unix/Command/_make
index c14a34c..48befa7 100644
--- a/Completion/Unix/Command/_make
+++ b/Completion/Unix/Command/_make
@@ -4,58 +4,68 @@
# are used in those targets and their dependencies.
_make-expandVars() {
- local open close var val front ret tmp=$1
+ local open close var val front='' rest=$1
- front=${tmp%%\$*}
- case $tmp in
- (\(*) # Variable of the form $(foobar)
- open='('
- close=')'
- ;;
-
- ({*) # ${foobar}
- open='{'
- close='}'
- ;;
-
- ([[:alpha:]]*) # $foobar. This is exactly $(f)oobar.
- open=''
- close=''
- var=${(s::)var[1]}
- ;;
-
- (\$*) # Escaped $.
- print -- "${front}\$$(_make-expandVars ${tmp#\$})"
- return
- ;;
+ while [[ $rest == (#b)[^$]#($)* ]]; do
+ front=$front${rest[1,$mbegin[1]-1]}
+ rest=${rest[$mbegin[1],-1]}
- (*) # Nothing left to substitute.
- print -- $tmp
- return
- ;;
- esac
-
- if [[ -n $open ]]
- then
- var=${tmp#$open}
- var=${var%%$close*}
- fi
+ case $rest[2] in
+ ($) # '$$'. may not appear in target and variable's value
+ front=$front\$\$
+ rest=${rest[3,-1]}
+ continue
+ ;;
+ (\() # Variable of the form $(foobar)
+ open='('
+ close=')'
+ ;;
+ ({) # ${foobar}
+ open='{'
+ close='}'
+ ;;
+ ([[:alpha:]]) # $foobar. This is exactly $(f)oobar.
+ open=''
+ close=''
+ var=$rest[2]
+ ;;
+ (*) # bad parameter name
+ print -- $front$rest
+ return 1
+ ;;
+ esac
- case $var in
- ([[:alnum:]_]#)
- val=${VARIABLES[$var]}
- ret=${ret//\$$open$var$close/$val}
- ;;
+ if [[ -n $open ]]; then
+ if [[ $rest == \$$open(#b)([[:alnum:]_]##)(#B)$close* ]]; then
+ var=$match
+ else # unmatched () or {}, or bad parameter name
+ print -- $front$rest
+ return 1
+ fi
+ fi
- (*)
- # Improper variable name. No replacement.
- # I'm not sure if this is desired behavior.
- front+="\$$open$var$close"
- ret=${ret/\$$open$var$close/}
- ;;
- esac
+ val=''
+ if [[ -n ${VAR_ARGS[(i)$var]} ]]; then
+ val=${VAR_ARGS[$var]}
+ else
+ if [[ -n $opt_args[(I)(-e|--environment-overrides)] ]]; then
+ if [[ $parameters[$var] == scalar-export* ]]; then
+ val=${(P)var}
+ elif [[ -n ${VARIABLES[(i)$var]} ]]; then
+ val=${VARIABLES[$var]}
+ fi
+ else
+ if [[ -n ${VARIABLES[(i)$var]} ]]; then
+ val=${VARIABLES[$var]}
+ elif [[ $parameters[$var] == scalar-export* ]]; then
+ val=${(P)var}
+ fi
+ fi
+ fi
+ rest=${rest//\$$open$var$close/$val}
+ done
- print -- "${front}$(_make-expandVars ${ret})"
+ print -- ${front}${rest}
}
_make-parseMakefile () {
@@ -84,16 +94,9 @@ _make-parseMakefile () {
# TARGET: dependencies
# TARGET1 TARGET2 TARGET3: dependencies
- ([[:alnum:]][^$TAB:=]#:[^=]*)
- input=$(_make-expandVars $input)
- target=${input%%:*}
- dep=${input#*:}
- dep=${(z)dep}
- dep="$dep"
- for tmp in ${(z)target}
- do
- TARGETS[$tmp]=$dep
- done
+ ([[*?[:alnum:]$][^$TAB:=%]#:[^=]*)
+ target=$(_make-expandVars ${input%%:*})
+ TARGETS+=( ${(z)target} )
;;
# Include another makefile
@@ -150,9 +153,18 @@ _make() {
local prev="$words[CURRENT-1]" file expl tmp is_gnu dir incl match
local context state state_descr line
local -a option_specs
- local -A TARGETS VARIABLES opt_args
+ local -A VARIABLES VAR_ARGS opt_args
+ local -aU TARGETS keys
local ret=1
+ # VAR=VAL on the current command line
+ for tmp in $words; do
+ if [[ $tmp == (#b)([[:alnum:]_]##)=(*) ]]; then
+ VAR_ARGS[${tmp[$mbegin[1],$mend[1]]}]=${(e)tmp[$mbegin[2],$mend[2]]}
+ fi
+ done
+ keys=( ${(k)VAR_ARGS} ) # to be used in 'compadd -F keys'
+
_pick_variant -r is_gnu gnu=GNU unix -v -f
if [[ $is_gnu == gnu ]]
@@ -275,9 +287,9 @@ _make() {
while _tags
do
_requested targets expl 'make targets' \
- compadd -- ${(k)TARGETS} && ret=0
+ compadd -Q -- $TARGETS && ret=0
_requested variables expl 'make variables' \
- compadd -S '=' -- ${(k)VARIABLES} && ret=0
+ compadd -S '=' -F keys -- ${(k)VARIABLES} && ret=0
done
fi
esac
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: _make-expandVars() broken? (was Re: Makefile completion with wildcard targets)
2015-07-30 16:26 ` Jun T.
@ 2015-07-31 2:14 ` Bart Schaefer
0 siblings, 0 replies; 4+ messages in thread
From: Bart Schaefer @ 2015-07-31 2:14 UTC (permalink / raw)
To: zsh-workers
On Jul 31, 1:26am, Jun T. wrote:
}
} Any comment?
This all sounds good to me, thanks!
} # The reason that make-expandVars() has been broken for a long time
} # may be that most of the users are setting call-command style?
Or just not completing targets that depend on variable expansions, I
suppose.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-07-31 2:14 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-28 13:20 _make-expandVars() broken? (was Re: Makefile completion with wildcard targets) Jun T.
2015-07-28 19:26 ` Bart Schaefer
2015-07-30 16:26 ` Jun T.
2015-07-31 2:14 ` Bart Schaefer
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).