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
|
#
# This script parses a command_table file into something which is a bit
# easier for an awk script to understand.
#
# Input syntax: a .ct file
#
# Output syntax:
# (for the command_table line)
# command_table <command_table>
#
#(for each request definition)
# BOR
# sub: <subroutine name>
# hlp: <help text>
# cmd: <command>
# opt: <option>
# EOR
# (there may be more than one 'cmd' or 'opt' line
#
# A number sent to the output represents a parse error --- it will be
# followed by the next line which will have the form:
# ERROR: <error text>
#
# The design of this output syntax is such that it should be easy for
# an awk script to parse.
#
# The first section of this script is just to canonicalize the file.
# It removes comments, and puts each command_table request onto a single
# line
#
:FIRST
y/ / /
s/^ *//
s/#.*$//
/; *$/!{
N
y/ / /
s/\n */ /
bFIRST
}
s/, */, /g
#
# Now we take care of some syntactic sugar.....
#
/^unimplemented/ {
s/^unimplemented [A-Za-z_0-9]*/request ss_unimplemented/
s/;/, (dont_list, dont_summarize);/
}
/^unknown/ {
s/^unknown /request ss_unknown, "", /
}
#
# Dispatch based on the keyword.... illegal keywords are prefixed by ERROR:
# and are handled by the awk script.
#
/^command_table /bCMD
/^request /bREQUEST
/^end;/bEND
s/ .*//
s/^/ERROR: unknown keyword: /
=
b
#
# Handle the command_table keyword
#
:CMD
s/;$//
p
d
b
#
# Handle the request keyword --- this is the heart of the sed script.
#
:REQUEST
s/^request *//
h
i\
BOR
# First, parse out the subroutine name
s/^/sub: /
s/,.*//
p
# Next, parse out the help message, being careful to handle a quoted string
g
s/^[^,]*, *//
h
/^"/ {
s/^"//
s/".*//
x
s/^"[^"]*", *//
x
b EMITHLP
}
s/[^a-zA-Z0-9].*//
x
s/[a-zA-Z0-9]*, *//
x
:EMITHLP
s/^/hlp: /
p
# Next take care of the command names
:CMDLIST
g
/^(/b OPTIONS
/^;/b EOR
/^"/ {
s/^"//
s/".*//
x
s/^"[^"]*"//
s/, *//
x
b EMITREQ
}
s/[^A-Za-z_0-9].*//
x
s/[A-Za-z_0-9]*//
s/, *//
x
:EMITREQ
s/^/cmd: /
p
b CMDLIST
#
# Here we parse the list of options.
#
: OPTIONS
g
s/^(//
h
: OPTLIST
/^)/ b EOR
/^[^A-Za-z_0-9]/ {
=
c\
ERROR: parse error in options list
}
s/[^A-Za-z_0-9].*//
x
s/[A-Za-z_0-9]*//
s/, *//
x
s/^/opt: /
p
g
b OPTLIST
: EOR
c\
EOR\
d
b
#
# Handle the end keyword --- it's basically ignored.
#
:END
d
b
|