-
Notifications
You must be signed in to change notification settings - Fork 0
/
bottom
executable file
Β·106 lines (84 loc) Β· 2.05 KB
/
bottom
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
#!/usr/bin/env bash
valueCharacters=(
[200]="π«"
[50]="π"
[10]="β¨"
[5]="π₯Ί"
[1]=","
[0]="β€οΈ"
)
separator="ππ"
fatal() {
echo "$@" 1>&2
exit 1
}
main() {
case "$1" in
d) decode;;
*) encode;;
esac
}
encode() {
# C is needed to force read to use ASCII codepoints.
local LANG=C
# Use a special delimited read to account for NUL characters not being
# handled properly.
while IFS= read -d '' -n 1 -r char; do
printf -v codepoint %d "'$char"
(( codepoint == 0 )) && {
echo -n "${valueCharacters[0]}$separator"
continue
}
while (( codepoint > 0 )); do
for v in 200 50 10 5 1; do
(( codepoint >= v )) && {
(( codepoint -= v ))
echo -n "${valueCharacters[$v]}"
break
}
done
done
echo -n "$separator"
done
return 0
}
decode() {
[[ $LANG =~ (UTF|utf)-?8$ ]] || {
fatal "Error: Locale is not of UTF-8; unable to decode."
}
# buf will be used to seek until the section separator.
buf=""
# sumChar is used to calculate the summation of bytes so far.
sumChar=$[0]
while read -N1 -r char; do
case "$char" in
# Check if this is the separator character.
"${separator:0:1}" | "${separator:1:1}")
# Append the character and pop the last one out if it's full.
buf+="$char"
(( ${#buf} > ${#separator} )) && buf="${buf: -${#separator}}"
[[ "$buf" == "$separator" ]] && {
# New section; decode the sum.
printf -v codepoint "%03o" $[sumChar]
# We need LANG=C here specifically for this printf because we're
# outputting possibly partial Unicode bytes, so the terminal
# must treat it as such.
LANG=C printf "\\$codepoint"
# Reset the sum.
(( sumChar = 0 ))
}
;;
"π«") (( sumChar += 200 )) ;;
"π") (( sumChar += 50 )) ;;
"β¨") (( sumChar += 10 )) ;;
"π₯Ί") (( sumChar += 5 )) ;;
"," ) (( sumChar += 1 )) ;;
$'\u2764') (( sumChar += 0 )) ;;
$'\uFE0F') ;; # Ignore the trailing special character.
$'\n') return ;; # Treat a new line as EOF.
*) fatal "Error: invalid character $char."
esac
done
return 0
}
main "$@"