File: INIT

package info (click to toggle)
yash 2.60-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,152 kB
  • sloc: ansic: 34,578; makefile: 851; sh: 808; sed: 16
file content (677 lines) | stat: -rw-r--r-- 30,869 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
# (C) 2010-2019 magicant

# This file is autoloaded when completion is first performed by the shell.
# This file contains utility functions that are commonly used by many
# completion functions.


# This is the function that is called when completing a command argument.
if ! command -vf completion//argument >/dev/null 2>&1; then
        function completion//argument {
                command -f completion//reexecute -f
        }
fi


# This function parses array $WORDS and variable $TARGETWORD according to array
# $OPTIONS and modifies $WORDS so that the caller can easily parse $WORDS.
#
# $WORDS is an array containing command line words that have been already
# entered by the user before the word being completed. The first word of $WORDS
# is considered the command name and ignored. The other words are considered
# arguments to the command and parsed.
#
# $TARGETWORD is a variable containing the word being completed.
#
# $OPTIONS is an array containing data about parsed options. The value of each
# element must follow the following syntax.
#   element     := optionlist
#                | optionlist ";" description
#   optionlist  := option
#                | optionlist " " option
#   option      := optionvalue
#                | optionvalue ":"
#                | optionvalue "::"
#   optionvalue := character
#                | "-" characters
# An element value consists of an option list that is possibly followed by a
# description of the options. The option list and the description is separated
# by a semicolon and the description may contain any characters.
# The option list consists of any number of options separated by whitespaces.
# An option is an option value possibly followed by one or two colons.
# An option that takes no, mandatory, and optional argument should be specified
# with zero, one, and two colons, respectively.
# The option value may be either a single character or a character string
# preceded by one or more hyphens. Note that a single-character option must be
# specified without a hyphen though it is preceded by a hyphen on the command
# line. Also note that multiple single-character options can be combined
# together after one hyphen on the command line. Long options, on the other
# hand, must be specified including their preceding hyphen(s).
#
# The following options can be specified to this function:
#   -e  Without -e, options are parsed only before the first operand word in
#       $WORDS. Words after the first operand word are all considered operands.
#       With -e, options are parsed for any words in $WORDS (except after
#       "--"). Options and operands can be intermixed.
#   -n  Without -n, array $WORDS is updated to reflect the parse result.
#       Multiple single-character options after one hyphen are separated and
#       separate option arguments are combined with the options so that the
#       option and its argument are in the same command line word. When -s is
#       specified or -e is not specified, options and operands in $WORDS are
#       separated by "--".
#       With -n, $WORDS is left intact.
#   -s  Only meaningful when with -e and without -n.
#       Without -s, words in $WORDS are not reordered.
#       With -s, words in $WORDS are reordered so that all options come
#       before operands.
#
# After words in $WORDS are parsed, $TARGETWORD is parsed as well and it is
# determined how $TARGETWORD should be completed. The results are returned as
# two variables $ARGOPT and $PREFIX.
# If $TARGETWORD is an operand to the command, $ARGOPT and $PREFIX are empty
# strings. If $TARGETWORD is one or more single-character option, $ARGOPT is
# "-" and $PREFIX is $TARGETWORD. If $TARGETWORD is a long option or "-",
# $ARGOPT is "-" and $PREFIX is an empty string. If $TARGETWORD is an option
# followed by an argument to that option or a separate option argument (in
# which case $TARGETWORD should be completed as an option argument), $ARGOPT
# is the name of that option (as specified by "optionvalue" in the syntax
# above) and $PREFIX is the part of $TARGETWORD that is not the argument.
#
# Note:
# Single-hyphened long options cannot be abbreviated.
# Optional option arguments are not supported for single-hyphened long options.
# Ambiguous options, invalid options, etc. are silently ignored.
function completion//parseoptions {

        # parse options to this function itself
        typeset opt= OPTIND=1
        typeset extension=false update=true sort=false
        while getopts :ens opt; do
                case $opt in
                        (e) extension=true;;
                        (n) update=false;;
                        (s) sort=true;;
                esac
        done

        if [ "${WORDS+set}" != "set" ] ||
                        [ ${WORDS[#]} -le 0 ] ||
                        [ "${OPTIONS+set}" != "set" ] ||
                        [ "${TARGETWORD+set}" != "set" ]; then
                return 1
        fi

        # results
        typeset result options operands
        result=() options=() operands=()

        # parse $WORDS
        typeset index=1 nomoreoptions=false
        typeset matches
        ARGOPT= PREFIX=
        while index=$((index+1)); [ $index -le ${WORDS[#]} ]; do
                typeset word="${WORDS[index]}"
                case $word in
                (--)
                        result=("$result" "${WORDS[index,-1]}")
                        operands=("$operands" "${WORDS[index+1,-1]}")
                        nomoreoptions=true
                        break
                        ;;
                (--?*=*) # double-hyphened long option with argument
                        matches=()
                        for opt in ${OPTIONS%%;*}; do
                                case ${${opt%:}%:} in
                                ("${word%%=*}")
                                        matches=("$opt")
                                        break
                                        ;;
                                ("${word%%=*}"*)
                                        matches=("$matches" "$opt")
                                        ;;
                                esac
                        done
                        if [ ${matches[#]} -eq 1 ]; then
                                opt=${matches[1]}
                                case $opt in (*:) # option argument allowed
                                        opt=${${opt%:}%:} word=${word#*=}
                                        result=("$result" "$opt=$word")
                                        options=("$options" "$opt=$word")
                                esac
                        fi
                        ;;
                (--?*) # double-hyphened long option without argument
                        matches=()
                        for opt in ${OPTIONS%%;*}; do
                                case ${${opt%:}%:} in
                                ("$word")
                                        matches=("$opt")
                                        break
                                        ;;
                                ("$word"*)
                                        matches=("$matches" "$opt")
                                        ;;
                                esac
                        done
                        if [ ${matches[#]} -eq 1 ]; then
                                opt=${matches[1]}
                                case $opt in
                                (*[!:]:) # option argument required
                                        if [ $index -eq ${WORDS[#]} ]; then
                                                # $TARGETWORD is argument
                                                ARGOPT=${opt%:} # PREFIX=
                                                break
                                        else
                                                index=$((index+1))
                                                # ${WORDS[index]} is argument
                                                result=("$result" "${opt%:}=${WORDS[index]}")
                                                options=("$options" "${opt%:}=${WORDS[index]}")
                                        fi
                                        ;;
                                (*) # no option argument
                                        result=("$result" "${opt%::}")
                                        options=("$options" "${opt%::}")
                                        ;;
                                esac
                        fi
                        ;;
                (-?*) # single-hyphened option
                        # first check for single-hyphened long option
                        for opt in ${OPTIONS%%;*}; do
                                case ${${opt%:}%:} in ("${word%%=*}")
                                        case $opt in
                                        (*::) # optional argument not supported
                                                ;;
                                        (*:) # requires option argument
                                                case $word in
                                                (*=*)
                                                        result=("$result" "$word")
                                                        options=("$options" "$word")
                                                        ;;
                                                (*) # argument is next word
                                                        if [ $index -eq ${WORDS[#]} ]; then
                                                                # $TARGETWORD is argument
                                                                ARGOPT=${opt%:} # PREFIX=
                                                                break 2
                                                        else
                                                                index=$((index+1))
                                                                # ${WORDS[index]} is argument
                                                                result=("$result" "${opt%:}=${WORDS[index]}")
                                                                options=("$options" "${opt%:}=${WORDS[index]}")
                                                        fi
                                                        ;;
                                                esac
                                                ;;
                                        (*) # no option argument
                                                case $word in
                                                (*=*) # Bad!
                                                        ;;
                                                (*) # OK!
                                                        result=("$result" "$opt")
                                                        options=("$options" "$opt")
                                                        ;;
                                                esac
                                                ;;
                                        esac
                                        continue 2
                                esac
                        done
                        # Next, check for single-character options
                        while word=${word#?}; [ "$word" ]; do
                                for opt in ${OPTIONS%%;*}; do
                                        case $opt in
                                        ("${word[1]}") # no option argument
                                                result=("$result" "-$opt")
                                                options=("$options" "-$opt")
                                                ;;
                                        ("${word[1]}":) # requires option argument
                                                if [ "${word#?}" ]; then
                                                        # rest of $word is argument
                                                        result=("$result" "-$word")
                                                        options=("$options" "-$word")
                                                elif [ $index -eq ${WORDS[#]} ]; then
                                                        # $TARGETWORD is argument
                                                        ARGOPT=${opt%:} # PREFIX
                                                        break 3
                                                else
                                                        index=$((index+1))
                                                        # ${WORDS[index]} is argument
                                                        result=("$result" "-${opt%:}${WORDS[index]}")
                                                        options=("$options" "-${opt%:}${WORDS[index]}")
                                                fi
                                                break 2
                                                ;;
                                        ("${word[1]}"::) # optional option argument
                                                result=("$result" "-$word")
                                                options=("$options" "-$word")
                                                break 2
                                                ;;
                                        esac
                                done
                        done
                        ;;
                (*) # operand
                        if $extension; then
                                result=("$result" "$word")
                                operands=("$operands" "$word")
                        else
                                result=("$result" "${WORDS[index,-1]}")
                                operands=("$operands" "${WORDS[index,-1]}")
                                nomoreoptions=true
                                break
                        fi
                        ;;
                esac
        done

        # determine if $TARGETWORD should be completed as an option
        if ! $nomoreoptions && [ -z "$ARGOPT" ]; then
                case $TARGETWORD in
                (--*=*)
                        matches=()
                        for opt in ${OPTIONS%%;*}; do
                                case ${${opt%:}%:} in
                                ("${TARGETWORD%%=*}")
                                        matches=("$opt")
                                        break
                                        ;;
                                ("${TARGETWORD%%=*}"*)
                                        matches=("$matches" "$opt")
                                        ;;
                                esac
                        done
                        if [ ${matches[#]} -eq 1 ]; then
                                opt=${matches[1]}
                                case $opt in (*:) # option argument allowed
                                        ARGOPT=${${opt%:}%:}
                                        PREFIX=${TARGETWORD%%=*}=
                                esac
                        fi
                        ;;
                (-|--*)
                        ARGOPT=- # PREFIX=
                        ;;
                (-*)
                        ARGOPT=- # PREFIX=
                        # first check for single-hyphened long option
                        typeset long=false
                        for opt in ${OPTIONS%%;*}; do
                                case ${opt%:} in ("${TARGETWORD%%=*}"*)
                                        long=true
                                        case $TARGETWORD in (*=*)
                                                if [ "${TARGETWORD%%=*}" = "${opt%:}" ]; then
                                                        ARGOPT=${opt%:}
                                                        PREFIX=${TARGETWORD%%=*}=
                                                        break
                                                fi
                                        esac
                                esac
                        done
                        # Next, check for single-character options
                        if ! $long; then
                                typeset word="$TARGETWORD"
                                while word=${word#?}; [ "$word" ]; do
                                        for opt in ${OPTIONS%%;*}; do
                                                case $opt in
                                                ("${word[1]}")
                                                        result=("$result" "-$opt")
                                                        options=("$options" "-$opt")
                                                        ;;
                                                ("${word[1]}":|"${word[1]}"::)
                                                        ARGOPT=${${opt%:}%:}
                                                        PREFIX=${TARGETWORD%${word#?}}
                                                        break 2
                                                        ;;
                                                esac
                                        done
                                done
                                if [ -z "$word" ]; then
                                        PREFIX=$TARGETWORD
                                fi
                        fi
                        ;;
                esac
        fi

        # update $WORDS
        if $update; then
                if ! $extension || $sort; then
                        WORDS=("${WORDS[1]}" "$options" -- "$operands")
                else
                        WORDS=("${WORDS[1]}" "$result")
                fi
        fi

}


# This function calls the "complete" built-in to generate candidates to
# complete $TARGETWORD as an option. Candidates are generated according to
# array $OPTIONS specifying options in the same syntax as the
# "completion//parseoptions" function above. If more than one option matches
# $TARGETWORD, only the first match is used to generate the candidate.
#
# This function accepts either of the -s and -S options. With -s, this function
# completes single-character options only (in which case $TARGETWORD may have
# other single-character options already entered). With -S, $TARGETWORD is
# completed as a single option. These options are mutually exclusive. If
# specified both, the last specified one is effective. If specified neither,
# it defaults to whether $PREFIX is empty or not.
#
# Normally, a long option that takes an argument is completed with an `=' sign.
# But if you specify the -e option, the option is completed with a space like a
# normal word.
#
# The exit status of this function is 0 if at least one candidate was
# generated. Otherwise, the exit status is 1.
#
# If variable $ARGOPT is defined but its value is not "-" or if $TARGETWORD
# does not start with a hyphen, this function does nothing but returning the
# exit status of 2 unless the -f option is specified.
function completion//completeoptions {

        # check $PREFIX
        if [ "${PREFIX-}" ]; then
                typeset single=true
        else
                typeset single=false
        fi

        # parse options to this function itself
        typeset opt= OPTIND=1 longargeq=true force=false
        while getopts :efsS opt; do
                case $opt in
                        (e) longargeq=;;
                        (f) force=true;;
                        (s) single=true;;
                        (S) single=false;;
                esac
        done

        if ! $force; then
                if [ "${OPTIONS+set}" != "set" ] ||
                                [ "${TARGETWORD+set}" != "set" ] ||
                                [ "${ARGOPT--}" != "-" ]; then
                        return 2
                fi
                case $TARGETWORD in
                        (-*) ;;
                        (*)  return 2 ;;
                esac
        fi

        # generate candidates
        typeset opts desc
        typeset generated=false
        for opts in "$OPTIONS"; do

                # get description
                case $opts in
                (*\;*)
                        desc=${opts#*;}
                        while true; do  # trim surrounding spaces
                                case $desc in
                                ([[:space:]]*) desc=${desc#[[:space:]]} ;;
                                (*[[:space:]]) desc=${desc%[[:space:]]} ;;
                                (*)            break ;;
                                esac
                        done
                        ;;
                (*)
                        desc=
                        ;;
                esac

                if $single; then
                        # generate single-character option
                        for opt in ${opts%%;*}; do
                                case $opt in
                                ([!-]|[!-]:)
                                        complete -O -P "$TARGETWORD" ${desc:+-D "$desc"} "${opt%:}" &&
                                        generated=true
                                        break
                                        ;;
                                ([!-]::)
                                        complete -OT -P "$TARGETWORD" ${desc:+-D "$desc"} "${opt%::}" &&
                                        generated=true
                                        break
                                        ;;
                                esac
                        done
                else
                        # generate candidate for first match
                        for opt in ${opts%%;*}; do
                                case $opt in
                                (-*:) # long option that takes argument
                                        case ${${opt%:}%:} in ("$TARGETWORD"*)
                                                complete ${desc:+-D "$desc"} ${longargeq:+-T -S =} -O -- "${${opt%:}%:}" &&
                                                generated=true
                                                break
                                        esac
                                        ;;
                                (-*) # long option that does not take argument
                                        case $opt in ("$TARGETWORD"*)
                                                complete ${desc:+-D "$desc"} -O -- "$opt" &&
                                                generated=true
                                                break
                                        esac
                                        ;;
                                (?::) # single-char option w/ optional argument
                                        if [ "$TARGETWORD" = "-" ]; then
                                                complete ${desc:+-D "$desc"} -OT -- "-${opt%::}" &&
                                                generated=true
                                                break
                                        fi
                                        ;;
                                (?|?:) # other single-char option
                                        if [ "$TARGETWORD" = "-" ]; then
                                                complete ${desc:+-D "$desc"} -O -- "-${opt%:}" &&
                                                generated=true
                                                break
                                        fi
                                        ;;
                                esac
                        done
                fi
        done

        # return 0 if at least one candidate was generated
        $generated

}


# This function removes one or more elements from the $WORDS array.
# When this function is called, the array is supposed to contain the following
# elements (in this order):
#  * a command name word
#  * any number of options that start with a hyphen
#  * a "--" separator (optional)
#  * any number of operands
# This function removes any words other than operands.
function completion//getoperands {

        typeset i=2
        while [ $i -le ${WORDS[#]} ]; do
                case ${WORDS[i]} in
                (--)
                        i=$((i+1))
                        break
                        ;;
                (-?*)
                        i=$((i+1))
                        ;;
                (*)
                        break
                        ;;
                esac
        done
        WORDS=("${WORDS[i,-1]}")

}


# This function re-executes the completion function using the current $WORDS.
# If the -e option is specified, only external commands are completed as the
# command name.
# If the -f option is specified, the following fall-back functions are not used:
#   * completion//command
#   * completion//argument
# If an operand is given to this function, it is used as the command name
# instead of ${WORDS[1]} and the -f option is assumed.
# This function does not change $WORDS (but the completion function may do).
function completion//reexecute {

        # parse options
        typeset opt= OPTIND=1 extonly=false fallback=true
        while getopts :ef opt; do
                case $opt in
                        (e) extonly=true;;
                        (f) fallback=false;;
                esac
        done

        # if there's no words, complete the command name
        if [ ${WORDS[#]} -le 0 ]; then
                if $fallback && command -vf completion//command >/dev/null 2>&1; then
                        unset opt OPTIND extonly fallback
                        command -f completion//command
                else
                        complete -P "${PREFIX-}" -T -S / -d
                        case ${TARGETWORD#"${PREFIX-}"} in
                        (*/*)
                                complete -P "${PREFIX-}" --executable-file
                                ;;
                        (*)
                                if $extonly; then
                                        complete -P "${PREFIX-}" --external-command
                                else
                                        complete -P "${PREFIX-}" -R '*/*' -ck --normal-alias
                                fi
                                ;;
                        esac
                fi
                return
        fi

        if [ $OPTIND -le $# ]; then
                set -- "${@[OPTIND]}"
                fallback=false
        else
                set -- "${WORDS[1]}"
        fi

        if $fallback && command -vf completion//argument >/dev/null 2>&1; then
                unset opt OPTIND extonly fallback
                command -f completion//argument
                return
        fi

        typeset compfunc= cmdbase
        if ! command -f completion//findcompfunc "$1"; then
                cmdbase="${1%.*}"
                if [ "$cmdbase" != "$1" ] && [ "${PATHEXT:+set}" = set ] &&
                        grep -iqx "${{PATHEXT//';'/'\|'}//'.'/'\.'}" <<< "${1#"$cmdbase"}" &&
                        command -f completion//findcompfunc "$cmdbase" &&
                        [ $OPTIND -gt $# ]; then
                        WORDS=("$cmdbase" "${WORDS[2,-1]}")
                fi
        fi
        set -- "$compfunc"
        unset opt OPTIND extonly fallback compfunc cmdbase

        if [ "$1" ]; then
                command -f "$1"
        else
                complete -P "${PREFIX-}" -f
        fi

}

# $1 = command name
# The result is set to the "compfunc" variable
function completion//findcompfunc
        if command -vf "completion/$1" >/dev/null 2>&1; then
                compfunc="completion/$1"
        elif command -vf "completion/${1##*/}" >/dev/null 2>&1; then
                compfunc="completion/${1##*/}"
        elif . -AL "completion/$1" 2>/dev/null
                        command -vf "completion/$1" >/dev/null 2>&1; then
                compfunc="completion/$1"
        elif command -vf "completion/${1##*/}" >/dev/null 2>&1; then
                compfunc="completion/${1##*/}"
        elif . -AL "completion/${1##*/}" 2>/dev/null
                        command -vf "completion/$1" >/dev/null 2>&1; then
                compfunc="completion/$1"
        elif command -vf "completion/${1##*/}" >/dev/null 2>&1; then
                compfunc="completion/${1##*/}"
        else
                compfunc=
                false
        fi


# Prints all commands in $PATH.
# Given an argument, it is treated as a pattern that filters results.
function completion//allcommands {
        typeset IFS

        # check if $PATH is an array
        case $(typeset -p PATH 2>/dev/null) in
        (PATH=\(*)
                ;;
        ('')
                typeset PATH
                PATH=()
                ;;
        (*)
                # re-define $PATH as local array
                typeset IFS=: savepath="$PATH"
                typeset PATH
                PATH=($savepath)
                ;;
        esac
        IFS=' '

        # use "find" if it supports "-min/maxdepth"
        if find -L . -mindepth 0 -maxdepth 0 -prune >&2; then
                find -L "$PATH" -mindepth 1 -maxdepth 1 \
                        ${1+-name "$1"} -type f -perm -u+x
                return
        fi 2>/dev/null

        typeset dir file pat="${1-*}" oldopt="$(set +o)"
        set -o glob -o dotglob -o nullglob -o caseglob -o markdirs
        for dir in "$PATH"; do
                case $dir in
                        (*/)
                                ;;
                        (*)
                                dir=$dir/ ;;
                esac
                for file in "$dir"*; do
                        case $file in
                                (*/.|*/..|*/)
                                        ;;
                                (*/$pat)
                                        if [ -x "$file" ]; then
                                                printf '%s\n' "$file"
                                        fi
                                        ;;
                        esac
                done
        done
        eval "$oldopt"
}


# The completion function for the "." built-in
if ! command -vf completion/. >/dev/null 2>&1; then
        function completion/. {
        # load the "_dot" file and call the "completion/." function in it
                . -AL completion/_dot && command -f completion/. "$@"
        }
fi


# vim: set ft=sh ts=8 sts=8 sw=8 et: