-
Notifications
You must be signed in to change notification settings - Fork 5
/
whatlib.sh
145 lines (140 loc) · 3.38 KB
/
whatlib.sh
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
#!/bin/bash
# certainly useless stuffs
# Prototype!
_ancient_getlongopts(){
declare -A OPTLONG
OPTLONG[verbose]=v
OPTLONG[quiet]=q
OPTLONG[help]=H
OPTLONG[wait]=W:
OPTLONG['--']=--
local OPTIONS=("$@")
declare -p OPTIONS
while getopts 'vqhHW:-:' OPT; do
case "$OPT" in
(-) _ancient_longopt_handler;;
(*) _opt_handler_$OPT "$OPTARG";;
esac
done
}
_ancient_longopt_handler(){
local OPTEXPD="${OPTLONG[$OPTARG]}"
case "$OPTEXPD" in
(--) echo "Unrecognized longopt $OPTARG" >&2; return 1;;
(*::) echo "Unsupported argument count $OPTARG">&2; return 1;;
(*:) ((++OPTIND)); _opt_handler_${OPTEXPD::-1} "${OPTIONS[$OPTIND]}";;
(*) _opt_handler_$OPTEXPD;;
esac
}
# shsplit "str" -> _shsplit_out[]
# shlex.split()-like stuff
# what, implementing that 'disregard quotes mid-token'? No.\
# robustness note: many end-quote replacments should test for the existance of the pattern first,
# and return 42 if patt not present.
# fixme: backslash even-odd not checked in patterns! this is fatal.
# You will need to have an extra var to hold ${tmp##[!\\]} and count.
shsplit(){
_shsplit_out=()
shopt -s extglob
local _shsplit_ksh_cquote=1 _shsplit_bash_moquote=1
local i="$1" thisword='' tmp='' dquote_ret
# debug tip: set -xv freaks out for `[['.
while [[ $i ]]; do
case $i in
"'"*) # single quote, posix.1:2013v3c2s2.2.2
i=${i#\'}
# use till first "'"
tmp=${i%%\'*}
i=${i#"$tmp"\'}
thisword+=$tmp
;;
"\""*) # double quote, posix.1:2013v3c2s2.2.2
_shsplit_dquote
thisword+=$dquote_ret
;;
"$'"*) # bash s3.1.2.4
i=${i#'$'}
if ((_shsplit_ksh_cquote)); then
i=${i#\'}
# dquote & norm magic
tmp=${i%%!(!(\\)\\)\'*}
i=${i#"$tmp"}
tmp=${i:0:2}
i=${i:3}
# I am too lazy to play with you guys. Go get it, eval.
eval "thisword+=$'$tmp'"
else
thisword+=\$
fi
;;
'$"'*) # bash s3.1.2.5
i=${i#'$'}
if ((_shsplit_bash_moquote)); then
_shsplit_dquote
if ((_shsplit_bash_moquote == 2)); then
# re-escape. dirty, right?
# only do this when you fscking trust the input.
# no, I will not escape \$ and \` for you.
dquote_ret=${dquote_ret//\\/\\\\}
dquote_ret=${dquote_ret//\"/\\\"}
eval 'dquote_ret=$"'"$dquote_ret\""
# elif 3: gettext() .....
fi
thisword+=$dquote_ret
else
thisword+=\$
fi
;;
[[:space:]]*)
[[ $thisword ]] && _shsplit_out+=("$thisword")
thisword=''
i=${i##+([[:space:]])}
;;
*)
_shsplit_eat_till_special
;;
esac
done
[[ $thisword ]] && _shsplit_out+=("$thisword")
}
_shsplit_eat_till_special(){
local thisword2
tmp=${i%%!(\\)[\$\'\"[:space:]]*} # first non-escaped crap
i=${i#"$tmp"}
tmp=${i:0:1} # add back the extra !(\\) char killed
i=${i:1}
_shsplit_soft_backslash
thisword+=$thisword2
}
_shsplit_dquote(){
local thisword2
i=${i#\"}
tmp=${i%%!(!(\\)\\)\"*} # first non-escaped "
i=${i#"$tmp"}
tmp=${i:0:2} # add back the extra !(!(\\)\\) chars killed
i=${i:3} # kill three -- including "
_shsplit_soft_backslash
dquote_ret=$thisword2
}
_shsplit_soft_backslash(){
local tmp2
while [[ $tmp ]]; do
case $tmp in
'\\'*)
tmp=${tmp#'\\'}
thisword2+='\'
;;
'\'$'\n'*)
tmp=${tmp#'\'$'\n'}
;;
'\'*) # means nothing
tmp=${tmp#'\'}
;& # fallthru
*)
tmp2=${tmp%%\\*}
tmp=${tmp#"$tmp2"}
thisword2+=$tmp2
;;
esac
done
}