chiark / gitweb /
server/: Post-merge fixup.
[tripe] / maint-utils / keysubst
CommitLineData
44e29279
MW
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.
23keysubst='
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
84sed "$keysubst"