-
Notifications
You must be signed in to change notification settings - Fork 0
/
json2compound.ksh
161 lines (142 loc) · 2.72 KB
/
json2compound.ksh
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
function json2compound {
export libname="$0"
# Stringfy file
for (( ; ; )); do
if read -r line; then
fbuf+="$line "
else
break
fi
done < <(cat "${1:--}")
dotjson2compound "$fbuf"
}
function dotjson2compound {
# set -x
set -e
fbuf="$1"
# String length
strl=${#fbuf}
# Initialize declaration flag as false
fDeclaration=false
fIdentifierWithSpaces=false
fHitQuote=false
# Quote flag
# qflag
for ((c=0; c < strl; c++)); do
# Get current char from string.
cchr="${fbuf:c:1}"
# Check if the file starts as an object or array:
case $c in
0 | $strl)
case "$cchr" in
'{' | '}' | '[' | ']')
case "$cchr" in
'[')
arrayend=$(countto "$fbuf" ']')
arrayparse '' "${fbuf:$c:$arrayend}"
cchr=''
;;
']') cchr='' ;; # Fallthrough
'{') cchr='(' ;;
'}') cchr')' ;;
esac
;;
# *) panic 'Expected '\''{}'\'' or '\''[]'\'' characters at the %d position, found %c.' $c "$cchr";;
esac
;;
*) ;;
esac
case "$cchr" in
"'") panic 'Unexpected token "'\''": the JSON standard only accepts double quotes.' ;;
'"') if $fDeclaration; then
fHitQuote="true"
cchr="'"
else
fIdentifierWithSpaces='true'
cchr=""
fi ;;
':')
fIdentifierWithSpaces=false
fDeclaration=true
cchr='=' ;;
[[:space:]]) if ! $fDeclaration && $fIdentifierWithSpaces; then
cchr='_'
elif ! $fHitQuote; then
cchr=''
fi ;;
'[')
arrayend=$(countto "$fbuf" ']')
arrayparse "$id" "${fbuf:c:arrayend}"
;;
',')
fHitQuote=false
fDeclaration=false
cchr=" " ;;
*) if ! $fDeclaration; then
id+="$cchr"
fi ;;
esac
printf '%c' "$cchr"
done
unset fbuf dflag qflag
return 0
}
function arrayparse {
# set -x
id="$1"
array="$2"
arraylen=(start=$(($(countto '[' "$array") + 1))
end=$(($(countto ']' "$array") - 1)))
nelements=0
for ((i=${arraylen.start}; i < ${arraylen.end}; i++)); do
# Current character
cchr=${array:i:1}
case "$cchr" in
',')
nelements+=1
continue
;;
*) elements[$nelements]+="$cchr" ;;
esac
done
case "x$id" in
x)
printf '%c' '('
for ((j = 0; j <= nelements; j++)); do
printf ' %s ' \
"$(dotjson2compound "${elements[$j]}")"
done
printf '%c' ')'
;;
*) for ((j = 0; j <= nelements; j++)); do
printf '%s+=( %s ) ' \
$id "$(dotjson2compound "${elements[$j]}")"
done ;;
esac
unset id elements nelements
}
# Count character position from left to right
# countto char
function countto {
chr="$1"
str="$2"
strl=${#str}
for ((i = 0; i < strl; i++)); do
case $chr in
'\')
i+=1
continue
;;
esac
if [[ ${str:i:1} == "$chr" ]]; then
printf '%d' $i
break
fi
done
}
function panic {
msgbuf="$(printf "$@")"
printf 1>&2 '%s: panic: %s\n' \
"$libname" "$msgbuf"
return 1
}