/* exported interface documented in nsgenbind-ast.h */ struct genbind_node * genbind_node_find_method(struct genbind_node *node, struct genbind_node *prev, enum genbind_method_type methodtype) { struct genbind_node *res_node; res_node = genbind_node_find_type( genbind_node_getnode(node), prev, GENBIND_NODE_TYPE_METHOD); while (res_node != NULL) { struct genbind_node *type_node; enum genbind_method_type *type; type_node = genbind_node_find_type( genbind_node_getnode(res_node), NULL, GENBIND_NODE_TYPE_METHOD_TYPE); type = (enum genbind_method_type *)genbind_node_getint(type_node); if (*type == methodtype) { break; } res_node = genbind_node_find_type( genbind_node_getnode(node), res_node, GENBIND_NODE_TYPE_METHOD); } return res_node; }
/* exported interface documented in nsgenbind-ast.h */ struct genbind_node * genbind_node_find_type_type(struct genbind_node *node, struct genbind_node *prev, enum genbind_node_type type, const char *ident) { struct genbind_node *found_node; struct genbind_node *ident_node; found_node = genbind_node_find_type(node, prev, type); while (found_node != NULL) { /* look for a type node */ ident_node = genbind_node_find_type(genbind_node_getnode(found_node), NULL, GENBIND_NODE_TYPE_TYPE); if (ident_node != NULL) { if (strcmp(ident_node->r.text, ident) == 0) break; } /* look for next matching node */ found_node = genbind_node_find_type(node, found_node, type); } return found_node; }
/** dump ast node to file at indent level */ static int genbind_ast_dump(FILE *dfile, struct genbind_node *node, int indent) { const char *SPACES=" "; char *txt; int *val; while (node != NULL) { fprintf(dfile, "%.*s%s", indent, SPACES, genbind_node_type_to_str(node->type)); txt = genbind_node_gettext(node); if (txt == NULL) { val = genbind_node_getint(node); if (val == NULL) { fprintf(dfile, "\n"); genbind_ast_dump(dfile, genbind_node_getnode(node), indent + 2); } else { fprintf(dfile, ": %d\n", *val); } } else { fprintf(dfile, ": \"%.*s\"\n", 75 - indent, txt); } node = node->l; } return 0; }
/* exported interface documented in nsgenbind-ast.h */ struct genbind_node * genbind_node_find_method_ident(struct genbind_node *node, struct genbind_node *prev, enum genbind_method_type nodetype, const char *ident) { struct genbind_node *res_node; char *method_ident; res_node = genbind_node_find_method(node, prev, nodetype); while (res_node != NULL) { method_ident = genbind_node_gettext( genbind_node_find_type( genbind_node_getnode(res_node), NULL, GENBIND_NODE_TYPE_IDENT)); if ((ident != NULL) && (method_ident != NULL) && strcmp(ident, method_ident) == 0) { break; } res_node = genbind_node_find_method(node, res_node, nodetype); } return res_node; }
/** * get the type of binding */ static enum bindingtype_e genbind_get_type(struct genbind_node *node) { struct genbind_node *binding_node; const char *binding_type; binding_node = genbind_node_find_type(node, NULL, GENBIND_NODE_TYPE_BINDING); if (binding_node == NULL) { /* binding entry is missing which is invalid */ return BINDINGTYPE_UNKNOWN; } binding_type = genbind_node_gettext( genbind_node_find_type( genbind_node_getnode(binding_node), NULL, GENBIND_NODE_TYPE_NAME)); if (binding_type == NULL) { fprintf(stderr, "Error: missing binding type\n"); return BINDINGTYPE_UNKNOWN; } if (strcmp(binding_type, "jsapi_libdom") == 0) { return BINDINGTYPE_JSAPI_LIBDOM; } if (strcmp(binding_type, "duk_libdom") == 0) { return BINDINGTYPE_DUK_LIBDOM; } fprintf(stderr, "Error: unsupported binding type \"%s\"\n", binding_type); return BINDINGTYPE_UNKNOWN; }
static int genbind_load_idl(struct genbind_node *genbind, struct webidl_node **webidl_out) { int res; struct genbind_node *binding_node; binding_node = genbind_node_find_type(genbind, NULL, GENBIND_NODE_TYPE_BINDING); /* walk AST and load any web IDL files required */ res = genbind_node_foreach_type( genbind_node_getnode(binding_node), GENBIND_NODE_TYPE_WEBIDL, webidl_file_cb, webidl_out); if (res != 0) { fprintf(stderr, "Error: failed reading Web IDL\n"); return -1; } /* implements are implemented as mixins so intercalate them */ res = webidl_intercalate_implements(*webidl_out); if (res != 0) { fprintf(stderr, "Error: Failed to intercalate implements\n"); return -1; } return 0; }
/* exported interface documented in nsgenbind-ast.h */ struct genbind_node * genbind_node_find_type_ident(struct genbind_node *node, struct genbind_node *prev, enum genbind_node_type type, const char *ident) { struct genbind_node *found_node; struct genbind_node *ident_node; if (ident == NULL) { return NULL; } found_node = genbind_node_find_type(node, prev, type); while (found_node != NULL) { /* look for an ident node */ ident_node = genbind_node_find_type( genbind_node_getnode(found_node), NULL, GENBIND_NODE_TYPE_IDENT); while (ident_node != NULL) { /* check for matching text */ if (strcmp(ident_node->r.text, ident) == 0) { return found_node; } ident_node = genbind_node_find_type( genbind_node_getnode(found_node), ident_node, GENBIND_NODE_TYPE_IDENT); } /* look for next matching node */ found_node = genbind_node_find_type(node, found_node, type); } return found_node; }
int genbind_ast_dump(struct genbind_node *node, int indent) { const char *SPACES=" "; char *txt; while (node != NULL) { printf("%.*s%s", indent, SPACES, genbind_node_type_to_str(node->type)); txt = genbind_node_gettext(node); if (txt == NULL) { printf("\n"); genbind_ast_dump(genbind_node_getnode(node), indent + 2); } else { printf(": \"%.*s\"\n", 75 - indent, txt); } node = node->l; } return 0; }
/** generate class initialisers * * Generates function to create the javascript class prototypes for * each interface in the binding. * */ int output_class_init(struct binding *binding) { int res = 0; struct genbind_node *api_node; int inf; /* class Initialisor declaration */ if (binding->hdrfile) { if (binding->interfacec > 1) { fprintf(binding->hdrfile, "\n#define %s_INTERFACE_COUNT %d", binding->name, binding->interfacec); } fprintf(binding->hdrfile, "\nint jsapi_InitClass_%s(JSContext *cx, JSObject *parent, JSObject **prototypes);\n\n", binding->name); } /* class Initialisor definition */ fprintf(binding->outfile, "int\n" "jsapi_InitClass_%s(JSContext *cx, " "JSObject *parent, " "JSObject **prototypes)\n" "{\n" "\tJSObject *prototype;\n", binding->name); /* check for the binding having an init override */ api_node = genbind_node_find_type_ident(binding->gb_ast, NULL, GENBIND_NODE_TYPE_API, "init"); if (api_node != NULL) { output_code_block(binding, genbind_node_getnode(api_node)); } else { /* generate interface init for each class in binding */ for (inf = 0; inf < binding->interfacec; inf++) { /* skip generating javascript class * initialisation for interfaces not in binding */ if (binding->interfaces[inf].node != NULL) { generate_prototype_init(binding, inf); } } fprintf(binding->outfile, "\n\treturn %d;\n", inf); } fprintf(binding->outfile, "}\n\n"); return res; }