~ubuntu-branches/ubuntu/precise/zsh/precise

« back to all changes in this revision

Viewing changes to Completion/Unix/Command/_make

  • Committer: Bazaar Package Importer
  • Author(s): Angel Abad
  • Date: 2011-01-09 23:10:24 UTC
  • mfrom: (2.1.25 sid)
  • Revision ID: james.westby@ubuntu.com-20110109231024-7egfs040r26fq7fa
Tags: 4.3.11-1ubuntu1
* Merge from debian unstable. (LP: #700695) Remaining changes:
  - debian/zshrc: Enable completions by default, unless
    skip_global_compinit is set

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#compdef make gmake pmake dmake
2
2
 
3
 
local prev="$words[CURRENT-1]" file expl tmp is_gnu dir incl
 
3
# TODO: Based on targets given on the command line, show only variables that
 
4
# are used in those targets and their dependencies.
 
5
 
 
6
local prev="$words[CURRENT-1]" file expl tmp is_gnu dir incl match
 
7
local -A TARGETS VARIABLES
4
8
 
5
9
expandVars() {
6
 
    local open close var val tmp=$2 ret=$2
7
 
    if (( $1 == 0 )); then
8
 
        return
9
 
    fi
10
 
    while :; do
11
 
        var=${tmp#*\$}
12
 
        if [[ $var != $tmp ]]; then
13
 
            tmp=$var
14
 
            case $var in
15
 
            (\(*)
16
 
                open='('
17
 
                close=')'
18
 
                ;;
19
 
            ({*)
20
 
                open='{'
21
 
                close='}'
22
 
                ;;
23
 
            ([[:alpha:]]*)
24
 
                open=''
25
 
                close=''
26
 
                var=${(s::)var[1]}
27
 
                ;;
28
 
            (\$*)
29
 
                # avoid parsing second $ in $$
30
 
                tmp=${tmp#\$}
31
 
                ;&
32
 
            (*)
33
 
                continue
34
 
                ;;
35
 
            esac
36
 
            if [[ $open != '' ]]; then
37
 
                var=${var#$open}
38
 
                var=${var%%$close*}
39
 
            fi
40
 
            case $var in
41
 
            ([[:alnum:]_]#)
42
 
                val=${(P)var}
43
 
                val=$(expandVars $(($1 - 1)) $val)
44
 
                ret=${ret//\$$open$var$close/$val}
45
 
                ;;
46
 
            esac
47
 
        else
48
 
            print -- ${ret//\$\$/\$}
49
 
            return
50
 
        fi
51
 
    done
 
10
  local open close var val front ret tmp=$1
 
11
 
 
12
  front=${tmp%%\$*}
 
13
  case $tmp in
 
14
    (\(*) # Variable of the form $(foobar)
 
15
    open='('
 
16
    close=')'
 
17
    ;;
 
18
 
 
19
    ({*) # ${foobar}
 
20
    open='{'
 
21
    close='}'
 
22
    ;;
 
23
 
 
24
    ([[:alpha:]]*) # $foobar. This is exactly $(f)oobar.
 
25
    open=''
 
26
    close=''
 
27
    var=${(s::)var[1]}
 
28
    ;;
 
29
 
 
30
    (\$*) # Escaped $.
 
31
    print -- "${front}\$$(expandVars ${tmp#\$})"
 
32
    return
 
33
    ;;
 
34
 
 
35
    (*) # Nothing left to substitute.
 
36
    print -- $tmp
 
37
    return
 
38
    ;;
 
39
  esac
 
40
 
 
41
  if [[ -n $open ]]
 
42
  then
 
43
    var=${tmp#$open}
 
44
    var=${var%%$close*}
 
45
  fi
 
46
 
 
47
  case $var in
 
48
    ([[:alnum:]_]#)
 
49
    val=${VARIABLES[$var]}
 
50
    ret=${ret//\$$open$var$close/$val}
 
51
    ;;
 
52
 
 
53
    (*)
 
54
    # Improper variable name. No replacement.
 
55
    # I'm not sure if this is desired behavior.
 
56
    front+="\$$open$var$close"
 
57
    ret=${ret/\$$open$var$close/}
 
58
    ;;
 
59
  esac
 
60
 
 
61
  print -- "${front}$(expandVars ${ret})"
52
62
}
53
63
 
54
 
# parseMakefile only runs inside $(...), so it doesn't matter that
55
 
# it pollutes the global namespace, setting zsh variables to
56
 
# make variables.  The difficult case is where a make variable
57
 
# is special in zsh; we use local -h to hide those.  This
58
 
# isn't a complete solution since it means variables defined in
59
 
# included Makefiles are undefined before returning to the parent.
60
 
parseMakefile() {
61
 
    local input var val TAB=$'\t' dir=$1
62
 
 
63
 
    while read input; do
64
 
        case "$input " in
65
 
        ([[:alnum:]][[:alnum:]_]#[ $TAB]#=*)
66
 
            var=${input%%[ $TAB]#=*}
67
 
            val=${input#*=}
68
 
            val=${val##[ $TAB]#}
69
 
            [[ ${(tP)var} = *special ]] && local -h $var
70
 
            eval $var=\$val
71
 
            ;;
72
 
        ([[:alnum:]][[:alnum:]_]#[ $TAB]#:=*)
73
 
            var=${input%%[ $TAB]#:=*}
74
 
            val=${input#*=}
75
 
            val=${val##[ $TAB]#}
76
 
            val=$(expandVars 10 $val)
77
 
            [[ ${(tP)var} = *special ]] && local -h $var
78
 
            eval $var=\$val
79
 
            ;;
80
 
        ([[:alnum:]][^$TAB:=]#:[^=]*)
81
 
            input=${input%%:*}
82
 
            print $(expandVars 10 $input)
83
 
            ;;
84
 
        (${~incl} *)
85
 
            local f=${input##${~incl} ##}
86
 
            if [[ $incl = '.include' ]]; then
87
 
                f=${f#[\"<]}
88
 
                f=${f%[\">]}
89
 
            fi
90
 
            f=$(expandVars 10 $f)
91
 
            case $f in
92
 
            (/*) ;;
93
 
            (*)  f=$dir/$f ;;
94
 
            esac
95
 
            if [ -r $f ]; then
96
 
                parseMakefile ${f%%/[^/]##} < $f
97
 
            fi
98
 
            ;;
99
 
        esac
100
 
    done
 
64
parseMakefile () {
 
65
  local input var val target dep TAB=$'\t' dir=$1 tmp
 
66
 
 
67
  while read input
 
68
  do
 
69
    case "$input " in
 
70
      # VARIABLE = value
 
71
      ([[:alnum:]][[:alnum:]_]#[ $TAB]#=*)
 
72
      var=${input%%[ $TAB]#=*}
 
73
      val=${input#*=}
 
74
      val=${val##[ $TAB]#}
 
75
      VARIABLES[$var]=$val
 
76
      ;;
 
77
 
 
78
      # VARIABLE := value
 
79
      # Evaluated immediately
 
80
      ([[:alnum:]][[:alnum:]_]#[ $TAB]#:=*)
 
81
      var=${input%%[ $TAB]#:=*}
 
82
      val=${input#*=}
 
83
      val=${val##[ $TAB]#}
 
84
      val=$(expandVars $val)
 
85
      VARIABLES[$var]=$val
 
86
      ;;
 
87
 
 
88
      # TARGET: dependencies
 
89
      # TARGET1 TARGET2 TARGET3: dependencies
 
90
      ([[:alnum:]][^$TAB:=]#:[^=]*)
 
91
      input=$(expandVars $input)
 
92
      target=${input%%:*}
 
93
      dep=${input#*:}
 
94
      dep=${(z)dep}
 
95
      dep="$dep"
 
96
      for tmp in ${(z)target}
 
97
      do
 
98
        TARGETS[$tmp]=$dep
 
99
      done
 
100
      ;;
 
101
 
 
102
      # Include another makefile
 
103
      (${~incl} *)
 
104
      local f=${input##${~incl} ##}
 
105
      if [[ $incl == '.include' ]]
 
106
      then
 
107
        f=${f#[\"<]}
 
108
        f=${f%[\">]}
 
109
      fi
 
110
      f=$(expandVars $f)
 
111
      case $f in
 
112
        (/*) ;;
 
113
        (*) f=$dir/$f ;;
 
114
      esac
 
115
 
 
116
      if [[ -r $f ]]
 
117
      then
 
118
        parseMakefile ${f%%/[^/]##} < $f
 
119
      fi
 
120
      ;;
 
121
    esac
 
122
  done
101
123
}
102
124
 
103
125
findBasedir () {
104
126
  local file index basedir
105
127
  basedir=$PWD
106
 
  for ((index=0; index<$#@; index++)); do
107
 
    if [[ $@[index] = -C ]]; then
 
128
  for (( index=0; index < $#@; index++ ))
 
129
  do
 
130
    if [[ $@[index] == -C ]]
 
131
    then
108
132
      file=${~@[index+1]};
109
 
      if [[ -z $file ]]; then
110
 
        # make returns with an error if an empty arg is given
111
 
        # even if the concatenated path is a valid directory
112
 
        return
113
 
      elif [[ $file = /* ]]; then
114
 
        # Absolute path, replace base directory
115
 
        basedir=$file
 
133
      if [[ -z $file ]]
 
134
      then
 
135
        # make returns with an error if an empty arg is given
 
136
        # even if the concatenated path is a valid directory
 
137
        return
 
138
      elif [[ $file == /* ]]
 
139
      then
 
140
        # Absolute path, replace base directory
 
141
        basedir=$file
116
142
      else
117
 
        # Relative, concatenate path
118
 
        basedir=$basedir/$file
 
143
        # Relative, concatenate path
 
144
        basedir=$basedir/$file
119
145
      fi
120
146
    fi
121
147
  done
124
150
 
125
151
_pick_variant -r is_gnu gnu=GNU unix -v -f
126
152
 
127
 
if [[ $is_gnu = gnu ]]; then
128
 
    incl="(-|)include"
 
153
if [[ $is_gnu == gnu ]]
 
154
then
 
155
  incl="(-|)include"
129
156
else
130
 
    incl=.include
 
157
  incl=.include
131
158
fi
132
 
if [[ "$prev" = -[CI] ]]; then
 
159
 
 
160
if [[ "$prev" == -[CI] ]]
 
161
then
133
162
  _files -W ${(q)$(findBasedir ${words[1,CURRENT-1]})} -/
134
 
elif [[ "$prev" = -[foW] ]]; then
 
163
elif [[ "$prev" == -[foW] ]]
 
164
then
135
165
  _files -W ${(q)$(findBasedir $words)}
136
166
else
137
167
  file="$words[(I)-f]"
138
 
  if (( file )); then
 
168
  if (( file ))
 
169
  then
139
170
    file=${~words[file+1]}
140
 
    [[ $file = [^/]* ]] && file=${(q)$(findBasedir $words)}/$file
 
171
    [[ $file == [^/]* ]] && file=${(q)$(findBasedir $words)}/$file
141
172
    [[ -r $file ]] || file=
142
173
  else
143
174
    local basedir
144
175
    basedir=${(q)$(findBasedir $words)}
145
 
    if [[ $is_gnu = gnu && -r $basedir/GNUmakefile ]]; then
 
176
    if [[ $is_gnu == gnu && -r $basedir/GNUmakefile ]]
 
177
    then
146
178
      file=$basedir/GNUmakefile
147
 
    elif [[ -r $basedir/makefile ]]; then
 
179
    elif [[ -r $basedir/makefile ]]
 
180
    then
148
181
      file=$basedir/makefile
149
 
    elif [[ -r $basedir/Makefile ]]; then
 
182
    elif [[ -r $basedir/Makefile ]]
 
183
    then
150
184
      file=$basedir/Makefile
151
185
    else
152
186
      file=''
153
187
    fi
154
188
  fi
155
189
 
156
 
  if [[ -n "$file" ]] && _tags targets; then
157
 
    if [[ $is_gnu = gnu ]] &&
158
 
       zstyle -t ":completion:${curcontext}:targets" call-command; then
159
 
       tmp=( $(_call_program targets "$words[1]" -nsp --no-print-directory -f "$file" .PHONY 2> /dev/null | parseMakefile $PWD) )
 
190
  if [[ -n "$file" ]]
 
191
  then
 
192
    if [[ $is_gnu == gnu ]] && zstyle -t ":completion:${curcontext}:targets" call-command
 
193
    then
 
194
      parseMakefile $PWD < <(_call_program targets "$words[1]" -nsp --no-print-directory -f "$file" .PHONY 2> /dev/null)
160
195
    else
161
 
       tmp=( $(parseMakefile $PWD < $file) )
 
196
      case "$OSTYPE" in
 
197
        freebsd*)
 
198
        parseMakefile $PWD < <(_call_program targets "$words[1]" -nsp -f "$file" .PHONY 2> /dev/null)
 
199
        ;;
 
200
        *)
 
201
        parseMakefile $PWD < $file
 
202
      esac
162
203
    fi
163
 
    _wanted targets expl 'make target' compadd -a tmp && return 0
164
 
  fi
165
 
  compstate[parameter]="${PREFIX%%\=*}"
166
 
  compset -P 1 '*='
167
 
  _value "$@"
 
204
  fi
 
205
 
 
206
  if [[ $PREFIX == *'='* ]]
 
207
  then
 
208
    # Complete make variable as if shell variable
 
209
    compstate[parameter]="${PREFIX%%\=*}"
 
210
    compset -P 1 '*='
 
211
    _value "$@"
 
212
  else
 
213
    _tags targets variables
 
214
    while _tags
 
215
    do
 
216
      _requested targets expl 'make targets' \
 
217
        compadd -- ${(k)TARGETS}
 
218
      _requested variables expl 'make variables' \
 
219
        compadd -S '=' -- ${(k)VARIABLES}
 
220
    done
 
221
  fi
168
222
fi