1## vim:ft=zsh:foldmethod=marker
2
3function VCS_INFO_quilt-match() {
4    emulate -L zsh
5    setopt extendedglob
6    local d mode="$1" param="$2"
7    local -a list
8
9    case ${mode} in
10        (assoc) list=( ${(kOP)param} );;
11        (array) : "${foo[@]}" ${(t)foo}; list=( ${(OP)param} );;
12        (*) return 1;;
13    esac
14    for d in "${list[@]}"; do
15        if [[ ${PWD} == ${d%/##}(|/*) ]]; then
16            print "$d"
17            return 0
18        fi
19    done
20    return 1
21}
22
23function VCS_INFO_quilt-standalone-detect() {
24    emulate -L zsh
25    setopt extendedglob
26    local param
27    local -i ret
28
29    zstyle -s "${context}" quilt-standalone param || return 1
30    [[ "${param}" == 'never' ]] && return 1
31    [[ "${param}" == 'always' ]] && return 0
32
33    if (( ${+functions[$param]} )); then
34        ${param}
35        return $?
36    fi
37
38    case ${(Pt)param} in
39    *association*)
40        local m
41        local -A A
42        m="$(VCS_INFO_quilt-match assoc ${param})"
43        A=(${(kvP)param})
44        (( $? == 0 )) && [[ ${A[$m]} == "true" ]] && return 0
45        return 1
46        ;;
47    *array*)
48        typeset -gU ${param}
49        VCS_INFO_quilt-match array ${param} > /dev/null
50        return $?
51        ;;
52    *scalar*)
53        [[ "${(P)param}" == 'always' ]] && return 0
54        [[ "${(P)param}" == 'never' ]] && return 1
55        ;;
56    esac
57    # If nothing hit yet, it just wasn't meant to be.
58    return 1
59}
60
61function VCS_INFO_quilt-dirfind() {
62    # This is a wrapper around VCS_INFO_bydir_detect(). It makes sure
63    # that $vcs_comm[] is unchanged. Currently, changing anything in it
64    # should not be an issue, but this makes sure the code can safely
65    # be called elsewhere, too - if needed.
66    emulate -L zsh
67    setopt extendedglob
68    local dir="$1" file="$2"; shift $#
69    local ret oldfile olddir
70
71    olddir=${vcs_comm[basedir]}
72    vcs_comm[basedir]=''
73    if [[ -n "${file}" ]]; then
74        oldfile=${vcs_comm[detect_need_file]}
75        vcs_comm[detect_need_file]=${file}
76    fi
77    VCS_INFO_bydir_detect ${dir}
78    ret=$?
79    [[ -n "${file}" ]] && vcs_comm[detect_need_file]=${oldfile}
80    printf '%s' ${vcs_comm[basedir]}
81    vcs_comm[basedir]="${olddir}"
82    return ${ret}
83}
84
85function VCS_INFO_quilt() {
86    emulate -L zsh
87    setopt extendedglob
88    local mode="$1"
89    local patches pc tmp qstring root
90    local -i ret
91    local -x context
92    local -a applied unapplied all applied_string unapplied_string quiltcommand
93    local -Ax hook_com
94
95    context=":vcs_info:${vcs}.quilt-${mode}:${usercontext}:${rrn}"
96    zstyle -t "${context}" use-quilt || return 1
97
98    case ${mode} in
99    (standalone)
100        VCS_INFO_quilt-standalone-detect || return 1
101        ;;
102    (addon)
103        ;;
104    (*)
105        printf 'Invalid mode: `%s'\''\n' "$1"
106        return 2
107        ;;
108    esac
109
110    zstyle -s "${context}" quilt-patch-dir patches || patches="${QUILT_PATCHES}"
111    if [[ "${patches}" != /* ]]; then
112        tmp=${patches:-patches}
113        patches="$(VCS_INFO_quilt-dirfind "${tmp}")"
114        ret=$?
115        (( ret )) && return ${ret}
116        patches=${patches}/${tmp}
117    else
118        [[ -d ${patches} ]] || return 1
119    fi
120
121    pc="$(VCS_INFO_quilt-dirfind .pc .version)"
122    ret=$?
123    if (( ret == 0 )); then
124        [[ ${quiltmode} == 'standalone' ]] && root=${pc}
125        pc=${pc}/.pc
126        if [[ -e ${pc}/applied-patches ]]; then
127            applied=( ${(f)"$(<$pc/applied-patches)"} )
128            # throw away empty entries
129            applied=( ${applied:#} )
130            applied=( ${(Oa)applied} )
131        else
132            applied=()
133        fi
134    fi
135    if zstyle -t "${context}" get-unapplied; then
136        # This zstyle call needs to be moved further up if `quilt' needs
137        # to be run in more places than this one.
138        zstyle -s "${context}" quiltcommand quiltcommand || quiltcommand='quilt'
139        unapplied=( ${(f)"$(QUILT_PATCHES=$patches $quiltcommand --quiltrc /dev/null unapplied 2> /dev/null)"} )
140        unapplied=( ${unapplied:#} )
141    else
142        unapplied=()
143    fi
144
145    all=( ${(Oa)applied} ${unapplied} )
146
147    if VCS_INFO_hook 'gen-applied-string' "${applied[@]}"; then
148        if (( ${#applied} )); then
149            applied_string=${applied[1]}
150        else
151            applied_string=""
152        fi
153    else
154        applied_string=${hook_com[applied-string]}
155    fi
156    hook_com=()
157    if VCS_INFO_hook 'gen-unapplied-string' "${unapplied[@]}"; then
158        unapplied_string="${#unapplied}"
159    else
160        unapplied_string=${hook_com[unapplied-string]}
161    fi
162
163    if (( ${#applied} )); then
164        zstyle -s "${context}" patch-format qstring || qstring="%p (%n applied)"
165    else
166        zstyle -s "${context}" nopatch-format qstring || qstring="no patch applied"
167    fi
168    hook_com=( applied "${applied_string}" unapplied "${unapplied_string}"
169               applied-n ${#applied}       unapplied-n ${#unapplied}       all-n ${#all} )
170    if VCS_INFO_hook 'set-patch-format' ${qstring}; then
171        zformat -f qstring "${qstring}" "p:${hook_com[applied]}" "u:${hook_com[unapplied]}" \
172                                        "n:${#applied}" "c:${#unapplied}" "a:${#all}"
173    else
174        qstring=${hook_com[patch-replace]}
175    fi
176    hook_com=()
177
178    case ${mode} in
179    (standalone)
180        VCS_INFO_formats '' '' "${root}" '' '' '' "${qstring}"
181        VCS_INFO_set
182        ;;
183    (addon)
184        # When VCS_INFO_quilt() is called with "addon" a "local -x REPLY" variable
185        # should be in place. That variable can be unset after it's being used.
186        REPLY="${qstring}"
187        ;;
188    esac
189
190    VCS_INFO_hook 'post-quilt' ${mode} ${patches} ${pc:-\\-nopc-}
191}
192VCS_INFO_quilt "$@"
193