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