]>
git.proxmox.com Git - ovs.git/blob - build-aux/extract-ofp-msgs
15 NX_VENDOR_ID
= 0x00002320
18 OFPT10_STATS_REQUEST
= 16
19 OFPT10_STATS_REPLY
= 17
20 OFPT11_STATS_REQUEST
= 18
21 OFPT11_STATS_REPLY
= 19
24 version_map
= {"1.0": (OFP10_VERSION
, OFP10_VERSION
),
25 "1.1": (OFP11_VERSION
, OFP11_VERSION
),
26 "1.2": (OFP12_VERSION
, OFP12_VERSION
),
27 "1.3": (OFP13_VERSION
, OFP13_VERSION
),
28 "1.4": (OFP14_VERSION
, OFP14_VERSION
),
29 "1.0+": (OFP10_VERSION
, OFP14_VERSION
),
30 "1.1+": (OFP11_VERSION
, OFP14_VERSION
),
31 "1.2+": (OFP12_VERSION
, OFP14_VERSION
),
32 "1.3+": (OFP13_VERSION
, OFP14_VERSION
),
33 "1.4+": (OFP14_VERSION
, OFP14_VERSION
),
34 "1.0-1.1": (OFP10_VERSION
, OFP11_VERSION
),
35 "1.0-1.2": (OFP10_VERSION
, OFP12_VERSION
),
36 "1.1-1.2": (OFP11_VERSION
, OFP12_VERSION
),
37 "<all>": (0x01, 0xff)}
42 line
= input_file
.readline()
45 fatal("unexpected end of input")
50 sys
.stderr
.write("%s:%d: %s\n" % (file_name
, line_number
, msg
))
58 argv0
= os
.path
.basename(sys
.argv
[0])
60 %(argv0)s, for extracting OpenFlow message types from header files
61 usage: %(argv0)s INPUT OUTPUT
62 where INPUT is the name of the input header file
63 and OUTPUT is the output file name.
64 Despite OUTPUT, the output is written to stdout, and the OUTPUT argument
65 only controls #line directives in the output.\
66 ''' % {"argv0": argv0
}
70 m
= re
.match(r
'(.*) up to (.*)', s
)
72 struct
, member
= m
.groups()
73 return "offsetof(%s, %s)" % (struct
, member
)
75 return "sizeof(%s)" % s
77 def extract_ofp_msgs(output_file_name
):
86 if re
.match('enum ofpraw', line
):
91 first_line_number
= line_number
92 here
= '%s:%d' % (file_name
, line_number
)
93 if (line
.startswith('/*')
94 or line
.startswith(' *')
98 elif re
.match('}', line
):
101 if not line
.lstrip().startswith('/*'):
102 fatal("unexpected syntax between ofpraw types")
104 comment
= line
.lstrip()[2:].strip()
105 while not comment
.endswith('*/'):
107 if line
.startswith('/*') or not line
or line
.isspace():
108 fatal("unexpected syntax within error")
109 comment
+= ' %s' % line
.lstrip('* \t').rstrip(' \t\r\n')
110 comment
= comment
[:-2].rstrip()
112 m
= re
.match(r
'([A-Z]+) ([-.+\d]+|<all>) \((\d+)\): ([^.]+)\.$', comment
)
114 fatal("unexpected syntax between messages")
115 type_
, versions
, number
, contents
= m
.groups()
119 m
= re
.match('\s+(?:OFPRAW_%s)(\d*)_([A-Z0-9_]+),?$' % type_
,
122 fatal("syntax error expecting OFPRAW_ enum")
123 vinfix
, name
= m
.groups()
124 rawname
= 'OFPRAW_%s%s_%s' % (type_
, vinfix
, name
)
126 min_version
, max_version
= version_map
[versions
]
128 human_name
= '%s_%s' % (type_
, name
)
129 if type_
.endswith('ST'):
130 if rawname
.endswith('_REQUEST'):
131 human_name
= human_name
[:-8] + " request"
132 elif rawname
.endswith('_REPLY'):
133 human_name
= human_name
[:-6] + " reply"
135 fatal("%s messages are statistics but %s doesn't end "
136 "in _REQUEST or _REPLY" % (type_
, rawname
))
139 for version
in range(min_version
, max_version
+ 1):
141 if number
== OFPT_VENDOR
:
142 fatal("OFPT (%d) is used for vendor extensions"
144 elif (version
== OFP10_VERSION
145 and (number
== OFPT10_STATS_REQUEST
146 or number
== OFPT10_STATS_REPLY
)):
147 fatal("OFPT 1.0 (%d) is used for stats messages"
149 elif (version
!= OFP10_VERSION
150 and (number
== OFPT11_STATS_REQUEST
151 or number
== OFPT11_STATS_REPLY
)):
152 fatal("OFPT 1.1+ (%d) is used for stats messages"
154 hdrs
= (version
, number
, 0, 0, 0)
155 elif type_
== 'OFPST' and name
.endswith('_REQUEST'):
156 if version
== OFP10_VERSION
:
157 hdrs
= (version
, OFPT10_STATS_REQUEST
, number
, 0, 0)
159 hdrs
= (version
, OFPT11_STATS_REQUEST
, number
, 0, 0)
160 elif type_
== 'OFPST' and name
.endswith('_REPLY'):
161 if version
== OFP10_VERSION
:
162 hdrs
= (version
, OFPT10_STATS_REPLY
, number
, 0, 0)
164 hdrs
= (version
, OFPT11_STATS_REPLY
, number
, 0, 0)
166 hdrs
= (version
, OFPT_VENDOR
, 0, NX_VENDOR_ID
, number
)
167 elif type_
== 'NXST' and name
.endswith('_REQUEST'):
168 if version
== OFP10_VERSION
:
169 hdrs
= (version
, OFPT10_STATS_REQUEST
, OFPST_VENDOR
,
170 NX_VENDOR_ID
, number
)
172 hdrs
= (version
, OFPT11_STATS_REQUEST
, OFPST_VENDOR
,
173 NX_VENDOR_ID
, number
)
174 elif type_
== 'NXST' and name
.endswith('_REPLY'):
175 if version
== OFP10_VERSION
:
176 hdrs
= (version
, OFPT10_STATS_REPLY
, OFPST_VENDOR
,
177 NX_VENDOR_ID
, number
)
179 hdrs
= (version
, OFPT11_STATS_REPLY
, OFPST_VENDOR
,
180 NX_VENDOR_ID
, number
)
182 fatal("type '%s' unknown" % type_
)
185 error("Duplicate message definition for %s." % str(hdrs
))
186 sys
.stderr
.write("%s: Here is the location "
187 "of the previous definition.\n"
189 all_hdrs
[hdrs
] = here
190 these_hdrs
.append(hdrs
)
193 if contents
== 'void':
197 for c
in [s
.strip() for s
in contents
.split(",")]:
199 if extra_multiple
== '0':
200 extra_multiple
= make_sizeof(c
[:-2])
202 error("Cannot have multiple [] elements")
204 min_body_elem
.append(c
)
207 min_body
= " + ".join([make_sizeof(s
)
208 for s
in min_body_elem
])
210 if extra_multiple
== '0':
211 error("Must specify contents (use 'void' if empty)")
214 if rawname
in all_raws
:
215 fatal("%s: Duplicate name" % rawname
)
217 all_raws
[rawname
] = {"hdrs": these_hdrs
,
218 "min_version": min_version
,
219 "max_version": max_version
,
220 "min_body": min_body
,
221 "extra_multiple": extra_multiple
,
223 "human_name": human_name
,
224 "line": first_line_number
}
225 all_raws_order
.append(rawname
)
231 if re
.match('enum ofptype', line
):
236 if re
.match(r
'\s*/?\*', line
) or line
.isspace():
238 elif re
.match('}', line
):
241 if not re
.match(r
'\s*OFPTYPE_.*/\*', line
):
242 fatal("unexpected syntax between OFPTYPE_ definitions")
244 syntax
= line
.strip()
245 while not syntax
.endswith('*/'):
247 if not line
.strip().startswith('*'):
248 fatal("unexpected syntax within OFPTYPE_ definition")
249 syntax
+= ' %s' % line
.strip().lstrip('* \t')
250 syntax
= syntax
.strip()
252 m
= re
.match(r
'(OFPTYPE_[A-Z0-9_]+),\s*/\* (.*) \*/', syntax
)
254 fatal("syntax error in OFPTYPE_ definition")
256 ofptype
, raws_
= m
.groups()
257 raws
= [s
.rstrip('.') for s
in raws_
.split()]
259 if not re
.match('OFPRAW_[A-Z0-9_]+$', raw
):
260 fatal("%s: invalid OFPRAW_* name syntax" % raw
)
261 if raw
not in all_raws
:
262 fatal("%s: not a declared OFPRAW_* name" % raw
)
263 if "ofptype" in all_raws
[raw
]:
264 fatal("%s: already part of %s"
265 % (raw
, all_raws
[raw
]["ofptype"]))
266 all_raws
[raw
]["ofptype"] = ofptype
274 output
.append("/* Generated automatically; do not modify! "
275 "-*- buffer-read-only: t -*- */")
278 for raw
in all_raws_order
:
280 output
.append("static struct raw_instance %s_instances[] = {"
282 for hdrs
in r
['hdrs']:
283 output
.append(" { {0, NULL}, {%d, %d, %d, 0x%x, %d}, %s, 0 },"
290 output
.append("static struct raw_info raw_infos[] = {")
291 for raw
in all_raws_order
:
293 if "ofptype" not in r
:
294 error("%s: no defined OFPTYPE_" % raw
)
297 output
.append(" %s_instances," % raw
.lower())
298 output
.append(" %d, %d," % (r
["min_version"], r
["max_version"]))
299 output
.append("#line %s \"%s\"" % (r
["line"], file_name
))
300 output
.append(" %s," % r
["min_body"])
301 output
.append("#line %s \"%s\"" % (r
["line"], file_name
))
302 output
.append(" %s," % r
["extra_multiple"])
303 output
.append("#line %s \"%s\"" % (len(output
) + 2, output_file_name
))
304 output
.append(" %s," % r
["ofptype"])
305 output
.append(" \"%s\"," % r
["human_name"])
308 if r
['type'].endswith("ST"):
309 for hdrs
in r
['hdrs']:
311 if hdrs
[0] == OFP10_VERSION
:
312 if hdrs
[1] == OFPT10_STATS_REQUEST
:
313 op_hdrs
[1] = OFPT10_STATS_REPLY
314 elif hdrs
[1] == OFPT10_STATS_REPLY
:
315 op_hdrs
[1] = OFPT10_STATS_REQUEST
319 if hdrs
[1] == OFPT11_STATS_REQUEST
:
320 op_hdrs
[1] = OFPT11_STATS_REPLY
321 elif hdrs
[1] == OFPT11_STATS_REPLY
:
322 op_hdrs
[1] = OFPT11_STATS_REQUEST
325 if tuple(op_hdrs
) not in all_hdrs
:
326 if r
["human_name"].endswith("request"):
327 fatal("%s has no corresponding reply"
330 fatal("%s has no corresponding request"
340 if __name__
== '__main__':
341 if '--help' in sys
.argv
:
343 elif len(sys
.argv
) != 3:
344 sys
.stderr
.write("exactly one non-option arguments required; "
345 "use --help for help\n")
351 file_name
= sys
.argv
[1]
352 input_file
= open(file_name
)
355 for line
in extract_ofp_msgs(sys
.argv
[2]):