server/admin.c: Remove spurious `ping' in usage message.
[tripe] / maint-utils / keysubst
1 #! /bin/sh
2
3 ## This sed(1) script takes key/value pairs in tripe-admin(5) format as
4 ## input; it writes sh(1) variable assignments as output. The idea is that
5 ## you can say
6 ##
7 ## eval $(tripectl algs | sed "$keysubst")
8 ##
9 ## and have shell variables set from the output of the command. The shell
10 ## variable names are worked out from the key names, with sequences of
11 ## nonalphanumerics replaced by single underscores. Quoting is handled
12 ## correctly, both on input and output.
13 ##
14 ## Theory of operation: firstly, ! and @ characters in the input are replaced
15 ## by !e and !a respectively; this is a reversible transformation, which we
16 ## undo at the end. We now know that the input does not contain @. We use a
17 ## string of the form [lr][nqQ]@ as a cursor to move across the input from
18 ## left to right. The letters on the left of the @ are state markers: l
19 ## means left of =, r means right; n means not in quotes; q means single-
20 ## quoted; Q means double-quoted.
21 ##
22 ## This is a particularly awful hack. I'm so sorry.
23 keysubst='
24 ## Initial transformation.
25 s/!/!e/g'$p'
26 s/@/!a/g'$p'
27
28 ## Initial state: left-hand side, not quoted
29 s/^/ln@/'$p'
30
31 :loop
32 ## Reached the end: exit.
33 /@$/ b end
34
35 ## Enter or leave quoted state as necessary.
36 s/\(.\)n@'\''/\1q@/'$p'
37 s/\(.\)n@"/\1Q@/'$p'
38 s/\(.\)q@'\''/\1n@/'$p'
39 s/\(.\)Q@"/\1n@/'$p'
40 t loop
41
42 ## Leave backslashed things alone.
43 /\(..\)@\\/ {
44 s//\1@/
45 b lit
46 }
47
48 ## Unquotes spaces delimit key/value pairs.
49 s/\(rn\)@[ ]\+/'\'' ln@/'$p'
50
51 ## An = sign separates left and right sides.
52 s/l\(.\)@=/='\''r\1@/'$p'
53
54 ## Single quotes on the right-hand side need special care.
55 t loop
56 s/r\(.\)@'\'/\''\\'\'\''r\1@/'$p'
57
58 ## Sequences of alphanumerics are always easy.
59 s/\(..\)@\([[:alnum:]]\+\)/\2\1@/'$p'
60
61 :lit
62 ## Convert bad left-hand-side characters to underscores.
63 t loop
64 s/l\(.\)@\(!.\|[^=![:alnum:]]\)\+/_l\1@/'$p'
65
66 ## Convert sequences of nonproblematic right-hand-side characters.
67 t loop
68 s/\(r.\)@\([^ '\''"`]\+\)/\2\1@/'$p'
69
70 ## And anything else is probably OK.
71 s/\(..\)@\(.\)/\2\1@/'$p'
72 b loop
73
74 :end
75 ## Unquote the end appropriately.
76 s/r.@/'\''/'$p'
77 s/..@//'$p'
78
79 ## And undo the initial transformation.
80 s/!a/@/g'$p'
81 s/!e/!/g'$p'
82 '
83
84 sed "$keysubst"