7 sys.path.insert(0, "@abs_top_srcdir@/ovsdb")
8 import simplejson as json
12 class Error(Exception):
13 def __init__(self, msg):
14 Exception.__init__(self)
17 def getMember(json, name, validTypes, description, default=None):
20 if type(member) not in validTypes:
21 raise Error("%s: type mismatch for '%s' member"
22 % (description, name))
26 def mustGetMember(json, name, expectedType, description):
27 member = getMember(json, name, expectedType, description)
29 raise Error("%s: missing '%s' member" % (description, name))
33 def __init__(self, name, comment, tables):
35 self.comment = comment
40 name = mustGetMember(json, 'name', [unicode], 'database')
41 comment = getMember(json, 'comment', [unicode], 'database')
42 tablesJson = mustGetMember(json, 'tables', [dict], 'database')
44 for name, json in tablesJson.iteritems():
45 tables[name] = TableSchema.fromJson(json, "%s table" % name)
46 return DbSchema(name, comment, tables)
49 d = {"name": self.name,
51 for name, table in self.tables.iteritems():
52 d["tables"][name] = table.toJson()
53 if self.comment != None:
54 d["comment"] = self.comment
58 def __init__(self, comment, columns):
59 self.comment = comment
60 self.columns = columns
63 def fromJson(json, description):
64 comment = getMember(json, 'comment', [unicode], description)
65 columnsJson = mustGetMember(json, 'columns', [dict], description)
67 for name, json in columnsJson.iteritems():
68 columns[name] = ColumnSchema.fromJson(
69 json, "column %s in %s" % (name, description))
70 return TableSchema(comment, columns)
74 for name, column in self.columns.iteritems():
75 d["columns"][name] = column.toJson()
76 if self.comment != None:
77 d["comment"] = self.comment
81 def __init__(self, comment, type, persistent):
82 self.comment = comment
84 self.persistent = persistent
87 def fromJson(json, description):
88 comment = getMember(json, 'comment', [unicode], description)
89 type = Type.fromJson(mustGetMember(json, 'type', [dict, unicode],
91 'type of %s' % description)
92 ephemeral = getMember(json, 'ephemeral', [True,False], description)
93 persistent = ephemeral != True
94 return ColumnSchema(comment, type, persistent)
97 d = {"type": self.type.toJson()}
98 if self.persistent == False:
100 if self.comment != None:
101 d["comment"] = self.comment
105 def __init__(self, key, keyRefTable=None, value=None, valueRefTable=None,
108 self.keyRefTable = keyRefTable
110 self.valueRefTable = valueRefTable
115 def fromJson(json, description):
116 if type(json) == unicode:
119 key = mustGetMember(json, 'key', [unicode], description)
120 keyRefTable = getMember(json, 'keyRefTable', [unicode], description)
121 value = getMember(json, 'value', [unicode], description)
122 valueRefTable = getMember(json, 'valueRefTable', [unicode], description)
123 min = getMember(json, 'min', [int], description, 1)
124 max = getMember(json, 'max', [int, unicode], description, 1)
125 return Type(key, keyRefTable, value, valueRefTable, min, max)
128 if self.value == None and self.min == 1 and self.max == 1:
131 d = {"key": self.key}
132 if self.value != None:
133 d["value"] = self.value
140 def parseSchema(filename):
141 file = open(filename, "r")
144 if not line.startswith('//'):
146 return DbSchema.fromJson(json.loads(s))
148 def cBaseType(prefix, type, refTable=None):
149 if type == 'uuid' and refTable:
150 return "struct %s%s *" % (prefix, refTable.lower())
152 return {'integer': 'int64_t ',
154 'uuid': 'struct uuid ',
156 'string': 'char *'}[type]
158 def printCIDLHeader(schema):
161 /* Generated automatically -- do not modify! -*- buffer-read-only: t -*- */
163 #ifndef %(prefix)sIDL_HEADER
164 #define %(prefix)sIDL_HEADER 1
169 #include "uuid.h"''' % {'prefix': prefix.upper()}
170 for tableName, table in schema.tables.iteritems():
172 if table.comment != None:
173 print "/* %s table (%s). */" % (tableName, table.comment)
175 print "/* %s table. */" % (tableName)
176 print "struct %s%s {" % (prefix, tableName.lower())
177 print "\t/* Columns automatically included in every table. */"
178 print "\tstruct uuid uuid_;"
179 print "\tstruct uuid version_;"
180 for columnName, column in table.columns.iteritems():
181 print "\n\t/* %s column. */" % columnName
183 if type.min == 1 and type.max == 1:
190 print "\tkey_%s%s%s;" % (cBaseType(prefix, type.key, type.keyRefTable), pointer, columnName)
191 print "\tvalue_%s%s%s;" % (cBaseType(prefix, type.value, type.valueRefTable), pointer, columnName)
193 print "\t%s%s%s;" % (cBaseType(prefix, type.key, type.keyRefTable), pointer, columnName)
195 print "\tsize_t n_%s;" % columnName
198 print "#endif /* %(prefix)sIDL_HEADER */" % {'prefix': prefix.upper()}
200 def ovsdb_escape(string):
204 raise Error("strings may not contain null bytes")
218 return '\\x%02x' % ord(c)
219 return re.sub(r'["\\\000-\037]', escape, string)
221 def printOVSDBSchema(schema):
222 json.dump(schema.toJson(), sys.stdout, sort_keys=True, indent=2)
226 %(argv0)s: ovsdb schema compiler
227 usage: %(argv0)s [OPTIONS] ACTION SCHEMA
228 where SCHEMA is the ovsdb schema to read (in JSON format).
230 One of the following actions must specified:
231 validate validate schema without taking any other action
232 c-idl-header print C header file for IDL
233 c-idl-source print C source file for IDL implementation
234 ovsdb-schema print ovsdb parseable schema
236 The following options are also available:
237 -h, --help display this help message
238 -V, --version display version information\
239 """ % {'argv0': argv0}
242 if __name__ == "__main__":
245 options, args = getopt.gnu_getopt(sys.argv[1:], 'hV',
248 except getopt.GetoptError, geo:
249 sys.stderr.write("%s: %s\n" % (argv0, geo.msg))
252 optKeys = [key for key, value in options]
253 if '-h' in optKeys or '--help' in optKeys:
255 elif '-V' in optKeys or '--version' in optKeys:
256 print "ovsdb-idlc (Open vSwitch) @VERSION@"
260 sys.stderr.write("%s: exactly two non-option arguments are "
261 "required (use --help for help)\n" % argv0)
264 action, inputFile = args
265 schema = parseSchema(inputFile)
266 if action == 'validate':
268 elif action == 'ovsdb-schema':
269 printOVSDBSchema(schema)
270 elif action == 'c-idl-header':
271 printCIDLHeader(schema)
272 elif action == 'c-idl-source':
273 printCIDLSource(schema)
276 "%s: unknown action '%s' (use --help for help)\n" %
280 sys.stderr.write("%s: %s\n" % (argv0, e.msg))