ofp-util: Fix inconsistencies in table features type.
[sliver-openvswitch.git] / ofproto / ipfix-gen-entities
1 #!/usr/bin/python
2 #
3 # Copyright (C) 2012 Nicira, Inc.
4 #
5 # Copying and distribution of this file, with or without modification,
6 # are permitted in any medium without royalty provided the copyright
7 # notice and this notice are preserved.  This file is offered as-is,
8 # without warranty of any kind.
9
10 import getopt
11 import re
12 import sys
13 import xml.sax
14 import xml.sax.handler
15
16 class IpfixEntityHandler(xml.sax.handler.ContentHandler):
17
18     RECORD_FIELDS = ['name', 'dataType', 'elementId', 'status']
19
20     # Cf. RFC 5101, Section 6.
21     DATA_TYPE_SIZE = {
22         'unsigned8': 1,
23         'unsigned16': 2,
24         'unsigned32': 4,
25         'unsigned64': 8,
26         'signed8': 1,
27         'signed16': 2,
28         'signed32': 4,
29         'signed64': 8,
30         'float32': 4,
31         'float64': 8,
32         'boolean': 1,  # Not clear.
33         'macAddress': 6,
34         'octetArray': 0,  # Not clear.
35         'string': 0,  # Not clear.
36         'dateTimeSeconds': 4,
37         'dateTimeMilliseconds': 8,
38         'dateTimeMicroseconds': 8,
39         'dateTimeNanoseconds': 8,
40         'ipv4Address': 4,
41         'ipv6Address': 16,
42         }
43
44     def __init__(self):
45         self.current_field_name = None
46         self.current_field_value = []
47         self.current_record = dict()
48
49     def startDocument(self):
50         print """\
51 /* IPFIX entities. */
52 #ifndef IPFIX_ENTITY
53 #define IPFIX_ENTITY(ENUM, ID, SIZE, NAME)
54 #endif
55 """
56
57     def endDocument(self):
58         print """
59 #undef IPFIX_ENTITY"""
60
61     def startElement(self, name, attrs):
62         if name in self.RECORD_FIELDS:
63             self.current_field_name = name
64         else:
65             self.current_field_name = None
66         self.current_field_value = []
67
68     @staticmethod
69     def camelcase_to_uppercase(s):
70         return re.sub('(.)([A-Z]+)', r'\1_\2', s).upper()
71
72     def endElement(self, name):
73         if self.current_field_name is not None:
74             self.current_record[self.current_field_name] = ''.join(
75                 self.current_field_value).strip()
76         elif (name == 'record'
77               and self.current_record.get('status') == 'current'
78               and 'dataType' in self.current_record):
79
80             self.current_record['enumName'] = self.camelcase_to_uppercase(
81                 self.current_record['name'])
82             self.current_record['dataTypeSize'] = self.DATA_TYPE_SIZE.get(
83                 self.current_record['dataType'], 0)
84
85             print 'IPFIX_ENTITY(%(enumName)s, %(elementId)s, ' \
86                   '%(dataTypeSize)i, %(name)s)' % self.current_record
87             self.current_record.clear()
88
89     def characters(self, content):
90         if self.current_field_name is not None:
91             self.current_field_value.append(content)
92
93 def print_ipfix_entity_macros(xml_file):
94     xml.sax.parse(xml_file, IpfixEntityHandler())
95
96 def usage(name):
97     print """\
98 %(name)s: IPFIX entity definition generator
99 Prints C macros defining IPFIX entities from the standard IANA file at
100 <http://www.iana.org/assignments/ipfix/ipfix.xml>
101 usage: %(name)s [OPTIONS] XML
102 where XML is the standard IANA XML file defining IPFIX entities
103
104 The following options are also available:
105   -h, --help                  display this help message
106   -V, --version               display version information\
107 """ % {'name': name}
108     sys.exit(0)
109
110 if __name__ == '__main__':
111 #    try:
112         try:
113             options, args = getopt.gnu_getopt(sys.argv[1:], 'hV',
114                                               ['help', 'version'])
115         except getopt.GetoptError, geo:
116             sys.stderr.write('%s: %s\n' % (sys.argv[0], geo.msg))
117             sys.exit(1)
118
119         for key, value in options:
120             if key in ['-h', '--help']:
121                 usage()
122             elif key in ['-V', '--version']:
123                 print 'ipfix-gen-entities (Open vSwitch)'
124             else:
125                 sys.exit(0)
126
127         if len(args) != 1:
128             sys.stderr.write('%s: exactly 1 non-option arguments required '
129                              '(use --help for help)\n' % sys.argv[0])
130             sys.exit(1)
131
132         print_ipfix_entity_macros(args[0])
133
134 #    except Exception, e:
135 #        sys.stderr.write('%s: %s\n' % (sys.argv[0], e))
136 #        sys.exit(1)
137
138 # Local variables:
139 # mode: python
140 # End: