1#!/usr/bin/python 2 3import sys 4import re 5 6import idl 7 8def libxl_C_instance_of(ty, instancename): 9 if isinstance(ty, idl.Aggregate) and ty.typename is None: 10 if instancename is None: 11 return libxl_C_type_define(ty) 12 else: 13 return libxl_C_type_define(ty) + " " + instancename 14 15 s = "" 16 if isinstance(ty, idl.Array): 17 s += libxl_C_instance_of(ty.lenvar.type, ty.lenvar.name) + ";\n" 18 19 return s + ty.typename + " " + instancename 20 21def libxl_C_type_define(ty, indent = ""): 22 s = "" 23 if isinstance(ty, idl.Enumeration): 24 if ty.typename is None: 25 s += "enum {\n" 26 else: 27 s += "typedef enum %s {\n" % ty.typename 28 29 for v in ty.values: 30 x = "%s = %d" % (v.name, v.value) 31 x = x.replace("\n", "\n ") 32 s += " " + x + ",\n" 33 if ty.typename is None: 34 s += "}" 35 else: 36 s += "} %s" % ty.typename 37 38 elif isinstance(ty, idl.Aggregate): 39 if isinstance(ty, idl.KeyedUnion): 40 s += libxl_C_instance_of(ty.keyvar.type, ty.keyvar.name) + ";\n" 41 42 if ty.typename is None: 43 s += "%s {\n" % ty.kind 44 else: 45 s += "typedef %s %s {\n" % (ty.kind, ty.typename) 46 47 for f in ty.fields: 48 if isinstance(ty, idl.KeyedUnion) and f.type is None: continue 49 50 x = libxl_C_instance_of(f.type, f.name) 51 if f.const: 52 x = "const " + x 53 x = x.replace("\n", "\n ") 54 s += " " + x + ";\n" 55 if ty.typename is None: 56 s += "}" 57 else: 58 s += "} %s" % ty.typename 59 else: 60 raise NotImplementedError("%s" % type(ty)) 61 return s.replace("\n", "\n%s" % indent) 62 63def libxl_C_type_dispose(ty, v, indent = " ", parent = None): 64 s = "" 65 if isinstance(ty, idl.KeyedUnion): 66 if parent is None: 67 raise Exception("KeyedUnion type must have a parent") 68 s += "switch (%s) {\n" % (parent + ty.keyvar.name) 69 for f in ty.fields: 70 (nparent,fexpr) = ty.member(v, f, parent is None) 71 s += "case %s:\n" % f.enumname 72 if f.type is not None: 73 s += libxl_C_type_dispose(f.type, fexpr, indent + " ", nparent) 74 s += " break;\n" 75 s += "}\n" 76 elif isinstance(ty, idl.Array): 77 if parent is None: 78 raise Exception("Array type must have a parent") 79 if ty.elem_type.dispose_fn is not None: 80 s += "{\n" 81 s += " int i;\n" 82 s += " for (i=0; i<%s; i++)\n" % (parent + ty.lenvar.name) 83 s += libxl_C_type_dispose(ty.elem_type, v+"[i]", 84 indent + " ", parent) 85 if ty.dispose_fn is not None: 86 if ty.elem_type.dispose_fn is not None: 87 s += " " 88 s += "%s(%s);\n" % (ty.dispose_fn, ty.pass_arg(v, parent is None)) 89 if ty.elem_type.dispose_fn is not None: 90 s += "}\n" 91 elif isinstance(ty, idl.Struct) and (parent is None or ty.dispose_fn is None): 92 for f in [f for f in ty.fields if not f.const]: 93 (nparent,fexpr) = ty.member(v, f, parent is None) 94 s += libxl_C_type_dispose(f.type, fexpr, "", nparent) 95 else: 96 if ty.dispose_fn is not None: 97 s += "%s(%s);\n" % (ty.dispose_fn, ty.pass_arg(v, parent is None)) 98 99 if s != "": 100 s = indent + s 101 return s.replace("\n", "\n%s" % indent).rstrip(indent) 102 103def libxl_C_type_copy(ty, v, w, indent = " ", vparent = None, wparent = None): 104 s = "" 105 106 if vparent is None: 107 s += "GC_INIT(ctx);\n"; 108 109 if isinstance(ty, idl.KeyedUnion): 110 if vparent is None or wparent is None: 111 raise Exception("KeyedUnion type must have a parent") 112 s += "%s = %s;\n" % ((vparent + ty.keyvar.name), (wparent + ty.keyvar.name)) 113 s += "switch (%s) {\n" % (wparent + ty.keyvar.name) 114 for f in ty.fields: 115 (vnparent,vfexpr) = ty.member(v, f, vparent is None) 116 (wnparent,wfexpr) = ty.member(w, f, wparent is None) 117 s += "case %s:\n" % f.enumname 118 if f.type is not None: 119 s += libxl_C_type_copy(f.type, vfexpr, wfexpr, indent + " ", 120 vnparent, wnparent) 121 s += " break;\n" 122 s += "}\n" 123 elif isinstance(ty, idl.Array): 124 if vparent is None or wparent is None: 125 raise Exception("Array type must have a parent") 126 s += "%s = libxl__calloc(NOGC, %s, sizeof(*%s));\n" % (ty.pass_arg(v, vparent is None), 127 (wparent + ty.lenvar.name), 128 ty.pass_arg(w, wparent is None)) 129 s += "%s = %s;\n" % ((vparent + ty.lenvar.name), (wparent + ty.lenvar.name)) 130 s += "{\n" 131 s += " int i;\n" 132 s += " for (i=0; i<%s; i++)\n" % (wparent + ty.lenvar.name) 133 s += libxl_C_type_copy(ty.elem_type, v+"[i]", w+"[i]", 134 indent + " ", vparent, wparent) 135 s += "}\n" 136 elif isinstance(ty, idl.Struct) and ((vparent is None and wparent is None) or ty.copy_fn is None): 137 for f in [f for f in ty.fields if not f.const and not f.type.private]: 138 (vnparent,vfexpr) = ty.member(v, f, vparent is None) 139 (wnparent,wfexpr) = ty.member(w, f, wparent is None) 140 s += libxl_C_type_copy(f.type, vfexpr, wfexpr, "", vnparent, wnparent) 141 else: 142 if ty.copy_fn is not None: 143 s += "%s(ctx, %s, %s);\n" % (ty.copy_fn, 144 ty.pass_arg(v, vparent is None, passby=idl.PASS_BY_REFERENCE), 145 ty.pass_arg(w, wparent is None, passby=idl.PASS_BY_REFERENCE)) 146 147 else: 148 s += "%s = %s;\n" % (ty.pass_arg(v, vparent is None, passby=idl.PASS_BY_VALUE), 149 ty.pass_arg(w, wparent is None, passby=idl.PASS_BY_VALUE)) 150 151 if vparent is None: 152 s += "GC_FREE;\n" 153 154 if s != "": 155 s = indent + s 156 return s.replace("\n", "\n%s" % indent).rstrip(indent) 157 158def libxl_init_members(ty, nesting = 0): 159 """Returns a list of members of ty which require a separate init""" 160 161 if isinstance(ty, idl.Aggregate): 162 return [f for f in ty.fields if not f.const and isinstance(f.type,idl.KeyedUnion)] 163 else: 164 return [] 165 166def _libxl_C_type_init(ty, v, indent = " ", parent = None, subinit=False): 167 s = "" 168 if isinstance(ty, idl.KeyedUnion): 169 if parent is None: 170 raise Exception("KeyedUnion type must have a parent") 171 if subinit: 172 s += "switch (%s) {\n" % (parent + ty.keyvar.name) 173 for f in ty.fields: 174 (nparent,fexpr) = ty.member(v, f, parent is None) 175 s += "case %s:\n" % f.enumname 176 if f.type is not None: 177 s += _libxl_C_type_init(f.type, fexpr, " ", nparent) 178 s += " break;\n" 179 s += "}\n" 180 else: 181 if ty.keyvar.init_val: 182 s += "%s = %s;\n" % (parent + ty.keyvar.name, ty.keyvar.init_val) 183 elif ty.keyvar.type.init_val: 184 s += "%s = %s;\n" % (parent + ty.keyvar.name, ty.keyvar.type.init_val) 185 elif isinstance(ty, idl.Struct) and (parent is None or ty.init_fn is None): 186 for f in [f for f in ty.fields if not f.const]: 187 (nparent,fexpr) = ty.member(v, f, parent is None) 188 if f.init_val is not None: 189 s += "%s = %s;\n" % (fexpr, f.init_val) 190 else: 191 s += _libxl_C_type_init(f.type, fexpr, "", nparent) 192 else: 193 if ty.init_val is not None: 194 s += "%s = %s;\n" % (ty.pass_arg(v, parent is None), ty.init_val) 195 elif ty.init_fn is not None: 196 s += "%s(%s);\n" % (ty.init_fn, ty.pass_arg(v, parent is None)) 197 198 if s != "": 199 s = indent + s 200 return s.replace("\n", "\n%s" % indent).rstrip(indent) 201 202def libxl_C_type_init(ty): 203 s = "" 204 s += "void %s(%s)\n" % (ty.init_fn, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE)) 205 s += "{\n" 206 s += " memset(p, '\\0', sizeof(*p));\n" 207 s += _libxl_C_type_init(ty, "p") 208 s += "}\n" 209 s += "\n" 210 return s 211 212def libxl_C_type_member_init(ty, field): 213 if not isinstance(field.type, idl.KeyedUnion): 214 raise Exception("Only KeyedUnion is supported for member init") 215 216 ku = field.type 217 218 s = "" 219 s += "void %s(%s, %s)\n" % (ty.init_fn + "_" + ku.keyvar.name, 220 ty.make_arg("p", passby=idl.PASS_BY_REFERENCE), 221 ku.keyvar.type.make_arg(ku.keyvar.name)) 222 s += "{\n" 223 224 if ku.keyvar.init_val is not None: 225 init_val = ku.keyvar.init_val 226 elif ku.keyvar.type.init_val is not None: 227 init_val = ku.keyvar.type.init_val 228 else: 229 init_val = None 230 231 (nparent,fexpr) = ty.member(ty.pass_arg("p"), ku.keyvar, isref=True) 232 if init_val is not None: 233 s += " assert(%s == %s);\n" % (fexpr, init_val) 234 else: 235 s += " assert(!%s);\n" % (fexpr) 236 s += " %s = %s;\n" % (fexpr, ku.keyvar.name) 237 238 (nparent,fexpr) = ty.member(ty.pass_arg("p"), field, isref=True) 239 s += _libxl_C_type_init(ku, fexpr, parent=nparent, subinit=True) 240 s += "}\n" 241 s += "\n" 242 return s 243 244def libxl_C_type_gen_map_key(f, parent, indent = ""): 245 s = "" 246 if isinstance(f.type, idl.KeyedUnion): 247 s += "switch (%s) {\n" % (parent + f.type.keyvar.name) 248 for x in f.type.fields: 249 v = f.type.keyvar.name + "." + x.name 250 s += "case %s:\n" % x.enumname 251 s += " s = yajl_gen_string(hand, (const unsigned char *)\"%s\", sizeof(\"%s\")-1);\n" % (v, v) 252 s += " if (s != yajl_gen_status_ok)\n" 253 s += " goto out;\n" 254 s += " break;\n" 255 s += "}\n" 256 else: 257 s += "s = yajl_gen_string(hand, (const unsigned char *)\"%s\", sizeof(\"%s\")-1);\n" % (f.name, f.name) 258 s += "if (s != yajl_gen_status_ok)\n" 259 s += " goto out;\n" 260 if s != "": 261 s = indent + s 262 return s.replace("\n", "\n%s" % indent).rstrip(indent) 263 264def libxl_C_type_copy_deprecated(field, v, indent = " ", vparent = None): 265 s = "" 266 267 if isinstance(field.type, idl.KeyedUnion): 268 if vparent is None: 269 raise Exception("KeyedUnion type must have a parent") 270 s += "switch (%s) {\n" % (vparent + field.type.keyvar.name) 271 for f in [f for f in field.type.fields if not f.const]: 272 (vnparent,vfexpr) = ty.member(v, f, vparent is None) 273 s += "case %s:\n" % f.enumname 274 if f.type is not None: 275 s += libxl_C_type_copy_deprecated(f, vfexpr, indent, vnparent) 276 s+= " break;\n" 277 s+="}\n"; 278 elif isinstance(field.type, idl.Array) and field.deprecated_by: 279 raise Exception("Array type is not supported for deprecation") 280 elif isinstance(field.type, idl.Struct) and field.type.copy_fn is None: 281 for f in [f for f in field.type.fields if not f.const]: 282 (vnparent,vfexpr) = ty.member(v, f, vparent is None) 283 s += libxl_C_type_copy_deprecated(f, vfexpr, "", vnparent) 284 elif field.deprecated_by is not None: 285 if field.type.check_default_fn is None: 286 raise Exception( 287"Deprecated field %s type doesn't have a default value checker" % field.name) 288 field_val = field.type.pass_arg(v, vparent is None, 289 passby=idl.PASS_BY_VALUE) 290 field_ptr = field.type.pass_arg(v, vparent is None, 291 passby=idl.PASS_BY_REFERENCE) 292 s+= "if (!%s(&p->%s) && !%s(%s))\n" % (field.type.check_default_fn, 293 field.deprecated_by, 294 field.type.check_default_fn, 295 field_ptr) 296 s+= " return -EINVAL;\n" 297 s+="(void) (&p->%s == %s);\n" % (field.deprecated_by, field_ptr) 298 s+= "if (%s(&p->%s)) {\n" % (field.type.check_default_fn, 299 field.deprecated_by) 300 s+= " " 301 if field.type.copy_fn is not None: 302 s+= "%s(ctx, &p->%s, %s);\n" % (field.type.copy_fn, 303 field.deprecated_by, field_ptr) 304 else: 305 s+= "p->%s = %s;\n" % (field.deprecated_by, field_val) 306 307 if field.type.dispose_fn is not None: 308 s+= " %s(%s);\n" % (field.type.dispose_fn, 309 field.type.pass_arg(v, vparent is None)) 310 311 s+= " " 312 if field.type.init_fn is not None: 313 s+= "%s(%s);\n" % (field.type.init_fn, field_ptr) 314 elif field.type.init_val is not None: 315 s+= "%s = %s;\n" % (field_val, field.type.init_val) 316 else: 317 s+= "memset(%s, 0, sizeof(*%s));\n" % (field_ptr, field_ptr) 318 319 s+= "}\n" 320 321 if s != "": 322 s = indent + s 323 return s.replace("\n", "\n%s" % indent).rstrip(indent) 324 325def get_init_val(f): 326 if f.init_val is not None: 327 return f.init_val 328 elif f.type.init_val is not None: 329 return f.type.init_val 330 return None 331 332def get_default_expr(f, nparent, fexpr): 333 if isinstance(f.type, idl.Aggregate): 334 return "1 /* always generate JSON output for aggregate type */" 335 336 if isinstance(f.type, idl.Array): 337 return "%s && %s" % (fexpr, nparent + f.type.lenvar.name) 338 339 init_val = get_init_val(f) 340 if init_val is not None: 341 return "%s != %s" % (fexpr, init_val) 342 343 if f.type.check_default_fn: 344 return "!%s(&%s)" % (f.type.check_default_fn, fexpr) 345 346 return "%s" % fexpr 347 348def libxl_C_type_gen_json(ty, v, indent = " ", parent = None): 349 s = "" 350 if parent is None: 351 s += "yajl_gen_status s;\n" 352 353 if isinstance(ty, idl.Array): 354 if parent is None: 355 raise Exception("Array type must have a parent") 356 s += "{\n" 357 s += " int i;\n" 358 s += " s = yajl_gen_array_open(hand);\n" 359 s += " if (s != yajl_gen_status_ok)\n" 360 s += " goto out;\n" 361 s += " for (i=0; i<%s; i++) {\n" % (parent + ty.lenvar.name) 362 s += libxl_C_type_gen_json(ty.elem_type, v+"[i]", 363 indent + " ", parent) 364 s += " }\n" 365 s += " s = yajl_gen_array_close(hand);\n" 366 s += " if (s != yajl_gen_status_ok)\n" 367 s += " goto out;\n" 368 s += "}\n" 369 elif isinstance(ty, idl.Enumeration): 370 s += "s = libxl__yajl_gen_enum(hand, %s_to_string(%s));\n" % (ty.typename, ty.pass_arg(v, parent is None)) 371 s += "if (s != yajl_gen_status_ok)\n" 372 s += " goto out;\n" 373 elif isinstance(ty, idl.KeyedUnion): 374 if parent is None: 375 raise Exception("KeyedUnion type must have a parent") 376 s += "switch (%s) {\n" % (parent + ty.keyvar.name) 377 for f in ty.fields: 378 (nparent,fexpr) = ty.member(v, f, parent is None) 379 s += "case %s:\n" % f.enumname 380 if f.type is not None: 381 s += libxl_C_type_gen_json(f.type, fexpr, indent + " ", nparent) 382 else: 383 s += " s = yajl_gen_map_open(hand);\n" 384 s += " if (s != yajl_gen_status_ok)\n" 385 s += " goto out;\n" 386 s += " s = yajl_gen_map_close(hand);\n" 387 s += " if (s != yajl_gen_status_ok)\n" 388 s += " goto out;\n" 389 s += " break;\n" 390 s += "}\n" 391 elif isinstance(ty, idl.Struct) and (parent is None or ty.json_gen_fn is None): 392 s += "s = yajl_gen_map_open(hand);\n" 393 s += "if (s != yajl_gen_status_ok)\n" 394 s += " goto out;\n" 395 for f in [f for f in ty.fields if not f.const and not f.type.private]: 396 (nparent,fexpr) = ty.member(v, f, parent is None) 397 default_expr = get_default_expr(f, nparent, fexpr) 398 s += "if (%s) {\n" % default_expr 399 400 s += libxl_C_type_gen_map_key(f, nparent, " ") 401 s += libxl_C_type_gen_json(f.type, fexpr, " ", nparent) 402 403 s += "}\n" 404 405 s += "s = yajl_gen_map_close(hand);\n" 406 s += "if (s != yajl_gen_status_ok)\n" 407 s += " goto out;\n" 408 else: 409 if ty.json_gen_fn is not None: 410 s += "s = %s(hand, %s);\n" % (ty.json_gen_fn, ty.pass_arg(v, parent is None)) 411 s += "if (s != yajl_gen_status_ok)\n" 412 s += " goto out;\n" 413 414 if parent is None: 415 s += "out:\n" 416 s += "return s;\n" 417 418 if s != "": 419 s = indent + s 420 return s.replace("\n", "\n%s" % indent).rstrip(indent) 421 422def libxl_C_type_to_json(ty, v, indent = " "): 423 s = "" 424 gen = "(libxl__gen_json_callback)&%s_gen_json" % ty.typename 425 s += "return libxl__object_to_json(ctx, \"%s\", %s, (void *)%s);\n" % (ty.typename, gen, ty.pass_arg(v, passby=idl.PASS_BY_REFERENCE)) 426 427 if s != "": 428 s = indent + s 429 return s.replace("\n", "\n%s" % indent).rstrip(indent) 430 431def libxl_C_type_parse_json(ty, w, v, indent = " ", parent = None, discriminator = None): 432 s = "" 433 if parent is None: 434 s += "int rc = 0;\n" 435 s += "const libxl__json_object *x __attribute__((__unused__)) = o;\n" 436 437 if isinstance(ty, idl.Array): 438 if parent is None: 439 raise Exception("Array type must have a parent") 440 if discriminator is not None: 441 raise Exception("Only KeyedUnion can have discriminator") 442 lenvar = parent + ty.lenvar.name 443 s += "{\n" 444 s += " libxl__json_object *t;\n" 445 s += " int i;\n" 446 s += " if (!libxl__json_object_is_array(x)) {\n" 447 s += " rc = -1;\n" 448 s += " goto out;\n" 449 s += " }\n" 450 s += " %s = x->u.array->count;\n" % lenvar 451 s += " %s = libxl__calloc(NOGC, %s, sizeof(*%s));\n" % (v, lenvar, v) 452 s += " if (!%s && %s != 0) {\n" % (v, lenvar) 453 s += " rc = -1;\n" 454 s += " goto out;\n" 455 s += " }\n" 456 s += " for (i=0; (t=libxl__json_array_get(x,i)); i++) {\n" 457 s += libxl_C_type_parse_json(ty.elem_type, "t", v+"[i]", 458 indent + " ", parent) 459 s += " }\n" 460 s += " if (i != %s) {\n" % lenvar 461 s += " rc = -1;\n" 462 s += " goto out;\n" 463 s += " }\n" 464 s += "}\n" 465 elif isinstance(ty, idl.Enumeration): 466 if discriminator is not None: 467 raise Exception("Only KeyedUnion can have discriminator") 468 s += "{\n" 469 s += " const char *enum_str;\n" 470 s += " if (!libxl__json_object_is_string(%s)) {\n" % w 471 s += " rc = -1;\n" 472 s += " goto out;\n" 473 s += " }\n" 474 s += " enum_str = libxl__json_object_get_string(%s);\n" % w 475 s += " rc = %s_from_string(enum_str, %s);\n" % (ty.typename, ty.pass_arg(v, parent is None, idl.PASS_BY_REFERENCE)) 476 s += " if (rc)\n" 477 s += " goto out;\n" 478 s += "}\n" 479 elif isinstance(ty, idl.KeyedUnion): 480 if parent is None: 481 raise Exception("KeyedUnion type must have a parent") 482 if discriminator is None: 483 raise Excpetion("KeyedUnion type must have a discriminator") 484 for f in ty.fields: 485 if f.enumname != discriminator: 486 continue 487 (nparent,fexpr) = ty.member(v, f, parent is None) 488 if f.type is not None: 489 s += libxl_C_type_parse_json(f.type, w, fexpr, indent + " ", nparent) 490 elif isinstance(ty, idl.Struct) and (parent is None or ty.json_parse_fn is None): 491 if discriminator is not None: 492 raise Exception("Only KeyedUnion can have discriminator") 493 for f in [f for f in ty.fields if not f.const and not f.type.private]: 494 saved_var_name = "saved_%s" % f.name 495 s += "{\n" 496 s += " const libxl__json_object *%s = x;\n" % saved_var_name 497 if isinstance(f.type, idl.KeyedUnion): 498 for x in f.type.fields: 499 s += " x = libxl__json_map_get(\"%s\", %s, JSON_MAP);\n" % \ 500 (f.type.keyvar.name + "." + x.name, w) 501 s += " if (x) {\n" 502 (nparent, fexpr) = ty.member(v, f.type.keyvar, parent is None) 503 s += " %s_init_%s(%s, %s);\n" % (ty.typename, f.type.keyvar.name, v, x.enumname) 504 (nparent,fexpr) = ty.member(v, f, parent is None) 505 s += libxl_C_type_parse_json(f.type, "x", fexpr, " ", nparent, x.enumname) 506 s += " }\n" 507 else: 508 s += " x = libxl__json_map_get(\"%s\", %s, %s);\n" % (f.name, w, f.type.json_parse_type) 509 s += " if (x) {\n" 510 (nparent,fexpr) = ty.member(v, f, parent is None) 511 s += libxl_C_type_parse_json(f.type, "x", fexpr, " ", nparent) 512 s += " }\n" 513 s += " x = %s;\n" % saved_var_name 514 s += "}\n" 515 else: 516 if discriminator is not None: 517 raise Exception("Only KeyedUnion can have discriminator") 518 if ty.json_parse_fn is not None: 519 s += "rc = %s(gc, %s, &%s);\n" % (ty.json_parse_fn, w, v) 520 s += "if (rc)\n" 521 s += " goto out;\n" 522 523 if parent is None: 524 s += "out:\n" 525 s += "return rc;\n" 526 527 if s != "": 528 s = indent +s 529 return s.replace("\n", "\n%s" % indent).rstrip(indent) 530 531def libxl_C_type_from_json(ty, v, w, indent = " "): 532 s = "" 533 parse = "(libxl__json_parse_callback)&%s_parse_json" % (ty.namespace + "_" + ty.rawname) 534 s += "return libxl__object_from_json(ctx, \"%s\", %s, %s, %s);\n" % (ty.typename, parse, v, w) 535 536 if s != "": 537 s = indent + s 538 return s.replace("\n", "\n%s" % indent).rstrip(indent) 539 540def libxl_C_enum_to_string(ty, e, indent = " "): 541 s = "" 542 s += "switch(%s) {\n" % e 543 for v in ty.values: 544 s += " case %s:\n" % (v.name) 545 s += " return \"%s\";\n" % (v.valuename.lower()) 546 s += " default:\n " 547 s += " return NULL;\n" 548 s += "}\n" 549 550 if s != "": 551 s = indent + s 552 return s.replace("\n", "\n%s" % indent).rstrip(indent) 553 554def libxl_C_enum_strings(ty, indent=""): 555 s = "" 556 s += "libxl_enum_string_table %s_string_table[] = {\n" % (ty.typename) 557 for v in ty.values: 558 s += " { .s = \"%s\", .v = %s },\n" % (v.valuename.lower(), v.name) 559 s += " { NULL, -1 },\n" 560 s += "};\n" 561 s += "\n" 562 563 if s != "": 564 s = indent + s 565 return s.replace("\n", "\n%s" % indent).rstrip(indent) 566 567def libxl_C_enum_from_string(ty, str, e, indent = " "): 568 s = "" 569 s += "return libxl__enum_from_string(%s_string_table,\n" % ty.typename 570 s += " %s, (int *)%s);\n" % (str, e) 571 572 if s != "": 573 s = indent + s 574 return s.replace("\n", "\n%s" % indent).rstrip(indent) 575 576 577if __name__ == '__main__': 578 if len(sys.argv) != 6: 579 print >>sys.stderr, "Usage: gentypes.py <idl> <header> <header-private> <header-json> <implementation>" 580 sys.exit(1) 581 582 (_, idlname, header, header_private, header_json, impl) = sys.argv 583 584 (builtins,types) = idl.parse(idlname) 585 586 print "outputting libxl type definitions to %s" % header 587 588 f = open(header, "w") 589 590 header_define = header.upper().replace('.','_') 591 f.write("""#ifndef %s 592#define %s 593 594/* 595 * DO NOT EDIT. 596 * 597 * This file is autogenerated by 598 * "%s" 599 */ 600 601""" % (header_define, header_define, " ".join(sys.argv))) 602 603 for ty in types: 604 f.write(libxl_C_type_define(ty) + ";\n") 605 if ty.dispose_fn is not None: 606 f.write("%svoid %s(%s);\n" % (ty.hidden(), ty.dispose_fn, ty.make_arg("p"))) 607 if ty.copy_deprecated_fn is not None: 608 f.write("%sint %s(libxl_ctx *ctx, %s);\n" % (ty.hidden(), 609 ty.copy_deprecated_fn, 610 ty.make_arg("p"))) 611 if ty.copy_fn is not None: 612 f.write("%svoid %s(libxl_ctx *ctx, %s, const %s);\n" % (ty.hidden(), ty.copy_fn, 613 ty.make_arg("dst"), ty.make_arg("src"))) 614 if ty.init_fn is not None: 615 f.write("%svoid %s(%s);\n" % (ty.hidden(), ty.init_fn, ty.make_arg("p"))) 616 for field in libxl_init_members(ty): 617 if not isinstance(field.type, idl.KeyedUnion): 618 raise Exception("Only KeyedUnion is supported for member init") 619 ku = field.type 620 f.write("%svoid %s(%s, %s);\n" % (ty.hidden(), ty.init_fn + "_" + ku.keyvar.name, 621 ty.make_arg("p"), 622 ku.keyvar.type.make_arg(ku.keyvar.name))) 623 if ty.json_gen_fn is not None: 624 f.write("%schar *%s_to_json(libxl_ctx *ctx, %s);\n" % (ty.hidden(), ty.typename, ty.make_arg("p"))) 625 if ty.json_parse_fn is not None: 626 f.write("%sint %s_from_json(libxl_ctx *ctx, %s, const char *s);\n" % (ty.hidden(), ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE))) 627 if isinstance(ty, idl.Enumeration): 628 f.write("%sconst char *%s_to_string(%s);\n" % (ty.hidden(), ty.typename, ty.make_arg("p"))) 629 f.write("%sint %s_from_string(const char *s, %s);\n" % (ty.hidden(), ty.typename, ty.make_arg("e", passby=idl.PASS_BY_REFERENCE))) 630 f.write("%sextern libxl_enum_string_table %s_string_table[];\n" % (ty.hidden(), ty.typename)) 631 f.write("\n") 632 633 f.write("""#endif /* %s */\n""" % (header_define)) 634 f.close() 635 636 print "outputting libxl JSON definitions to %s" % header_json 637 638 f = open(header_json, "w") 639 640 header_json_define = header_json.upper().replace('.','_') 641 f.write("""#ifndef %s 642#define %s 643 644/* 645 * DO NOT EDIT. 646 * 647 * This file is autogenerated by 648 * "%s" 649 */ 650 651""" % (header_json_define, header_json_define, " ".join(sys.argv))) 652 653 for ty in [ty for ty in types if ty.json_gen_fn is not None]: 654 f.write("%syajl_gen_status %s_gen_json(yajl_gen hand, %s);\n" % (ty.hidden(), ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE))) 655 656 f.write("\n") 657 f.write("""#endif /* %s */\n""" % header_json_define) 658 f.close() 659 660 print "outputting libxl type internal definitions to %s" % header_private 661 662 f = open(header_private, "w") 663 664 header_private_define = header_private.upper().replace('.','_') 665 f.write("""#ifndef %s 666#define %s 667 668/* 669 * DO NOT EDIT. 670 * 671 * This file is autogenerated by 672 * "%s" 673 */ 674 675""" % (header_private_define, header_private_define, " ".join(sys.argv))) 676 677 for ty in [ty for ty in types if ty.json_parse_fn is not None]: 678 f.write("%sint %s_parse_json(libxl__gc *gc, const libxl__json_object *o, %s);\n" % \ 679 (ty.hidden(), ty.namespace + "_" + ty.rawname, 680 ty.make_arg("p", passby=idl.PASS_BY_REFERENCE))) 681 682 f.write("\n") 683 f.write("""#endif /* %s */\n""" % header_json_define) 684 f.close() 685 686 print "outputting libxl type implementations to %s" % impl 687 688 f = open(impl, "w") 689 f.write(""" 690/* DO NOT EDIT. 691 * 692 * This file is autogenerated by 693 * "%s" 694 */ 695 696#include "libxl_osdeps.h" 697 698#include <stdint.h> 699#include <stdlib.h> 700#include <string.h> 701 702#include "libxl_internal.h" 703 704 705""" % " ".join(sys.argv)) 706 707 for ty in [t for t in types if t.dispose_fn is not None and t.autogenerate_dispose_fn]: 708 f.write("void %s(%s)\n" % (ty.dispose_fn, ty.make_arg("p"))) 709 f.write("{\n") 710 f.write(" if (!p) return;\n") 711 f.write(libxl_C_type_dispose(ty, "p")) 712 f.write(" memset(p, 0, sizeof(*p));\n") 713 f.write("}\n") 714 f.write("\n") 715 716 for ty in [t for t in types if t.copy_fn and t.autogenerate_copy_fn]: 717 f.write("void %s(libxl_ctx *ctx, %s, const %s)\n" % (ty.copy_fn, 718 ty.make_arg("dst", passby=idl.PASS_BY_REFERENCE), 719 ty.make_arg("src", passby=idl.PASS_BY_REFERENCE))) 720 f.write("{\n") 721 f.write(libxl_C_type_copy(ty, "dst", "src")) 722 f.write("}\n") 723 f.write("\n") 724 725 for ty in [t for t in types if t.copy_deprecated_fn]: 726 f.write("int %s(libxl_ctx *ctx, %s)\n" % (ty.copy_deprecated_fn, 727 ty.make_arg("p", passby=idl.PASS_BY_REFERENCE))) 728 f.write("{\n") 729 for field in [field for field in ty.fields if not field.const]: 730 (vnparent,vfexpr) = ty.member("p", field, True) 731 f.write(libxl_C_type_copy_deprecated(field, vfexpr, 732 vparent = vnparent)) 733 f.write(" return 0;\n") 734 f.write("}\n") 735 f.write("\n") 736 737 for ty in [t for t in types if t.init_fn is not None and t.autogenerate_init_fn]: 738 f.write(libxl_C_type_init(ty)) 739 for field in libxl_init_members(ty): 740 f.write(libxl_C_type_member_init(ty, field)) 741 742 for ty in [t for t in types if isinstance(t,idl.Enumeration)]: 743 f.write("const char *%s_to_string(%s e)\n" % (ty.typename, ty.typename)) 744 f.write("{\n") 745 f.write(libxl_C_enum_to_string(ty, "e")) 746 f.write("}\n") 747 f.write("\n") 748 749 f.write(libxl_C_enum_strings(ty)) 750 751 f.write("int %s_from_string(const char *s, %s *e)\n" % (ty.typename, ty.typename)) 752 f.write("{\n") 753 f.write(libxl_C_enum_from_string(ty, "s", "e")) 754 f.write("}\n") 755 f.write("\n") 756 757 for ty in [t for t in types if t.json_gen_fn is not None]: 758 f.write("yajl_gen_status %s_gen_json(yajl_gen hand, %s)\n" % (ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE))) 759 f.write("{\n") 760 f.write(libxl_C_type_gen_json(ty, "p")) 761 f.write("}\n") 762 f.write("\n") 763 764 f.write("char *%s_to_json(libxl_ctx *ctx, %s)\n" % (ty.typename, ty.make_arg("p"))) 765 f.write("{\n") 766 f.write(libxl_C_type_to_json(ty, "p")) 767 f.write("}\n") 768 f.write("\n") 769 770 for ty in [t for t in types if t.json_parse_fn is not None]: 771 f.write("int %s_parse_json(libxl__gc *gc, const libxl__json_object *%s, %s)\n" % \ 772 (ty.namespace + "_" + ty.rawname,"o",ty.make_arg("p", passby=idl.PASS_BY_REFERENCE))) 773 f.write("{\n") 774 f.write(libxl_C_type_parse_json(ty, "o", "p")) 775 f.write("}\n") 776 f.write("\n") 777 778 f.write("int %s_from_json(libxl_ctx *ctx, %s, const char *s)\n" % (ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE))) 779 f.write("{\n") 780 if not isinstance(ty, idl.Enumeration): 781 f.write(" %s_init(p);\n" % ty.typename) 782 f.write(libxl_C_type_from_json(ty, "p", "s")) 783 f.write("}\n") 784 f.write("\n") 785 786 f.close() 787