char* subscriptMethodName(TreeState *state, char *str) { char *sstr = NULL; if (strcmp(str, "toString") && strcmp(str, "clone") && strcmp(str, "finalize") && strcmp(str, "equals") && strcmp(str, "hashCode")) { return subscriptIdentifier(state, str); } sstr = g_strdup_printf("%s_", str); return sstr; }
static gboolean xpcom_to_java_param(TreeState *state) { IDL_tree param = state->tree; /* * Put in type of parameter */ if (!xpcom_to_java_type(state, IDL_PARAM_DCL(param).param_type_spec)) { return FALSE; } /* * If the parameter is out or inout, make it a Java array of the * appropriate type */ if (IDL_PARAM_DCL(param).attr != IDL_PARAM_IN) { fputs("[]", state->file); } /* * If the parameter is an array make it a Java array */ if (IDL_tree_property_get(IDL_PARAM_DCL(param).simple_declarator, "array")) fputs("[]", state->file); /* * Put in name of parameter */ fputc(' ', state->file); fputs(subscriptIdentifier(state, IDL_IDENT(IDL_PARAM_DCL(param).simple_declarator).str), state->file); return TRUE; }
static gboolean constant_declaration(TreeState *state) { /* * The C++ header XPIDL module only allows for shorts and longs (ints) * to be constants, so we will follow the same convention */ struct _IDL_CONST_DCL *declaration = &IDL_CONST_DCL(state->tree); const char *name = IDL_IDENT(declaration->ident).str; IDL_tree real_type; gboolean success; gboolean isshort = FALSE; if (!verify_const_declaration(state->tree)) return FALSE; /* Could be a typedef; try to map it to the real type. */ real_type = find_underlying_type(declaration->const_type); real_type = real_type ? real_type : declaration->const_type; /* * Consts must be in an interface */ if (!IDL_NODE_UP(IDL_NODE_UP(state->tree)) || IDL_NODE_TYPE(IDL_NODE_UP(IDL_NODE_UP(state->tree))) != IDLN_INTERFACE) { XPIDL_WARNING((state->tree, IDL_WARNING1, "A constant \"%s\" was declared outside an interface." " It was ignored.", name)); return TRUE; } /* * Make sure this is a numeric short or long constant. */ success = (IDLN_TYPE_INTEGER == IDL_NODE_TYPE(real_type)); if (success) { /* * We aren't successful yet, we know it's an integer, but what *kind* * of integer? */ switch(IDL_TYPE_INTEGER(real_type).f_type) { case IDL_INTEGER_TYPE_SHORT: /* * We're OK */ isshort = TRUE; break; case IDL_INTEGER_TYPE_LONG: /* * We're OK */ break; default: /* * Whoops, it's some other kind of number */ success = FALSE; } } else { IDL_tree_error(state->tree, "const declaration \'%s\' must be of type short or long", name); return FALSE; } /* if (doc_comments != NULL) { fputs(" ", state->file); printlist(state->file, doc_comments); } */ if (success) { /* Since Java does not have any concept of 'unsigned short', we need * to check that the value is in the proper range. If not, promote * it to an 'int'. */ int value = (int) IDL_INTEGER(declaration->const_exp).value; if (isshort && (value < -32768 || value > 32767)) isshort = FALSE; fputc('\n', state->file); xpidl_write_comment(state, 4); /* write_comment(state); */ fprintf(state->file, " public static final %s %s = %d;\n", (isshort ? "short" : "int"), subscriptIdentifier(state, (char*) name), (int) IDL_INTEGER(declaration->const_exp).value); } else { XPIDL_WARNING((state->tree, IDL_WARNING1, "A constant \"%s\" was not of type short or long." " It was ignored.", name)); } return TRUE; }
static gboolean method_declaration(TreeState *state) { const char* array = NULL; struct _IDL_OP_DCL *method = &IDL_OP_DCL(state->tree); gboolean method_notxpcom = (IDL_tree_property_get(method->ident, "notxpcom") != NULL); gboolean method_noscript = (IDL_tree_property_get(method->ident, "noscript") != NULL); IDL_tree iterator = NULL; IDL_tree retval_param = NULL; char *method_name = g_strdup_printf("%c%s", tolower(IDL_IDENT(method->ident).str[0]), IDL_IDENT(method->ident).str + 1); if (!verify_method_declaration(state->tree)) return FALSE; fputc('\n', state->file); xpidl_write_comment(state, 4); #if 1 /* do not write non-xpcom methods */ if (method_notxpcom) { return TRUE; } /* * Write beginning of method declaration */ fputs(" public ", state->file); #else /* do not write nonscriptable methods */ if (method_notxpcom || method_noscript) { return TRUE; } /* * Write beginning of method declaration */ fputs(" ", state->file); if (!method_noscript) { /* Nonscriptable methods become package-protected */ fputs("public ", state->file); } #endif /* * Write return type * Unlike C++ headers, Java interfaces return the declared * return value; an exception indicates XPCOM method failure. */ if (method->op_type_spec) { state->tree = method->op_type_spec; if (!xpcom_to_java_type(state, method->op_type_spec)) { return FALSE; } } else { /* Check for retval attribute */ for (iterator = method->parameter_dcls; iterator != NULL; iterator = IDL_LIST(iterator).next) { IDL_tree original_tree = state->tree; state->tree = IDL_LIST(iterator).data; if (IDL_tree_property_get(IDL_PARAM_DCL(state->tree).simple_declarator, "retval")) { retval_param = iterator; array = IDL_tree_property_get(IDL_PARAM_DCL(state->tree).simple_declarator, "array"); /* * Put in type of parameter */ if (!xpcom_to_java_type(state, IDL_PARAM_DCL(state->tree).param_type_spec)) { return FALSE; } if (array) fputs("[]", state->file); } state->tree = original_tree; } if (retval_param == NULL) { fputs("void", state->file); } } /* * Write method name */ fprintf(state->file, " %s(", subscriptIdentifier(state, method_name)); /* * Write parameters */ for (iterator = method->parameter_dcls; iterator != NULL; iterator = IDL_LIST(iterator).next) { /* Skip "retval" */ if (iterator == retval_param) { continue; } if (iterator != method->parameter_dcls) { fputs(", ", state->file); } state->tree = IDL_LIST(iterator).data; if (!xpcom_to_java_param(state)) { return FALSE; } } fputs(")", state->file); /* XXX Disable this for now. How do we specify exceptions? if (method->raises_expr) { IDL_tree iter = method->raises_expr; IDL_tree dataNode = IDL_LIST(iter).data; fputs(" throws ", state->file); fputs(IDL_IDENT(dataNode).str, state->file); iter = IDL_LIST(iter).next; while (iter) { dataNode = IDL_LIST(iter).data; fprintf(state->file, ", %s", IDL_IDENT(dataNode).str); iter = IDL_LIST(iter).next; } } */ fputs(";\n", state->file); return TRUE; }
static gboolean interface_declaration(TreeState *state) { char outname[PATH_MAX]; char* p; IDL_tree interface = state->tree; IDL_tree iterator = NULL; char *interface_name = subscriptIdentifier(state, IDL_IDENT(IDL_INTERFACE(interface).ident).str); const char *iid = NULL; char iid_parsed[UUID_LENGTH]; if (!verify_interface_declaration(interface)) return FALSE; /* * Each interface decl is a single file */ p = strrchr(state->filename, '/'); if (p) { strncpy(outname, state->filename, p + 1 - state->filename); outname[p + 1 - state->filename] = '\0'; } strcat(outname, interface_name); strcat(outname, ".java"); state->file = fopen(outname, "w"); if (!state->file) { perror("error opening output file"); return FALSE; } fputs("/*\n * ************* DO NOT EDIT THIS FILE ***********\n", state->file); fprintf(state->file, " *\n * This file was automatically generated from %s.idl.\n", state->basename); fputs(" */\n\n", state->file); if (state->package) fprintf(state->file, "\npackage %s;\n\n", state->package); if (!state->package || strcmp(state->package, "org.mozilla.xpcom") != 0) fputs("import org.mozilla.xpcom.*;\n", state->file); fputs("\n", state->file); #ifndef LIBIDL_MAJOR_VERSION iid = IDL_tree_property_get(interface, "uuid"); #else iid = IDL_tree_property_get(IDL_INTERFACE(interface).ident, "uuid"); #endif if (iid) { struct nsID id; /* Redundant, but a better error than 'cannot parse.' */ if (strlen(iid) != 36) { IDL_tree_error(state->tree, "IID %s is the wrong length\n", iid); return FALSE; } /* * Parse uuid and then output resulting nsID to string, to validate * uuid and normalize resulting .h files. */ if (!xpidl_parse_iid(&id, iid)) { IDL_tree_error(state->tree, "cannot parse IID %s\n", iid); return FALSE; } if (!xpidl_sprint_iid(&id, iid_parsed)) { IDL_tree_error(state->tree, "error formatting IID %s\n", iid); return FALSE; } } else { IDL_tree_error(state->tree, "interface %s lacks a uuid attribute\n", interface_name); return FALSE; } /* * Write out JavaDoc comment */ fprintf(state->file, "\n/**\n * Interface %s\n", interface_name); if (iid != NULL) { fprintf(state->file, " *\n * IID: 0x%s\n */\n\n", iid_parsed); } else { fputs(" */\n\n", state->file); } /* * Write "public interface <foo>" */ fprintf(state->file, "public interface %s", interface_name); /* * Check for inheritence, and iterator over the inherited names, * if any. */ if ((iterator = IDL_INTERFACE(interface).inheritance_spec)) { fputs(" extends ", state->file); do { fprintf(state->file, "%s", IDL_IDENT(IDL_LIST(iterator).data).str); if (IDL_LIST(iterator).next) { fputs(", ", state->file); } } while ((iterator = IDL_LIST(iterator).next)); } fputs("\n{\n", state->file); /* * Write interface constants for IID */ if (iid) { /* public static final String NS_ISUPPORTS_IID = "00000000-0000-0000-c000-000000000046" */ fputs(" public static final String ", state->file); write_classname_iid_define(state->file, interface_name); fprintf(state->file, " =\n \"{%s}\";\n\n", iid_parsed); } /* * Advance the state of the tree, go on to process more */ state->tree = IDL_INTERFACE(interface).body; PRIVDATA(state)->bCountingMethods = FALSE; PRIVDATA(state)->numMethods = 0; if (state->tree && !xpidl_process_node(state)) { return FALSE; } fputs("\n}\n", state->file); fprintf(state->file, "\n/*\n * end\n */\n"); fclose(state->file); return TRUE; }
static gboolean xpcom_to_java_type (TreeState *state) { IDL_tree real_type; if (!state->tree) { fputs("Object", FILENAME(state)); return TRUE; } /* Could be a typedef; try to map it to the real type */ real_type = find_underlying_type(state->tree); state->tree = real_type ? real_type : state->tree; switch(IDL_NODE_TYPE(state->tree)) { case IDLN_TYPE_INTEGER: { switch(IDL_TYPE_INTEGER(state->tree).f_type) { case IDL_INTEGER_TYPE_SHORT: fputs("short", FILENAME(state)); break; case IDL_INTEGER_TYPE_LONG: fputs("int", FILENAME(state)); break; case IDL_INTEGER_TYPE_LONGLONG: fputs("long", FILENAME(state)); break; default: g_error(" Unknown integer type: %d\n", IDL_TYPE_INTEGER(state->tree).f_type); return FALSE; } break; } case IDLN_TYPE_CHAR: case IDLN_TYPE_WIDE_CHAR: fputs("char", FILENAME(state)); break; case IDLN_TYPE_WIDE_STRING: case IDLN_TYPE_STRING: fputs("String", FILENAME(state)); break; case IDLN_TYPE_BOOLEAN: fputs("boolean", FILENAME(state)); break; case IDLN_TYPE_OCTET: fputs("byte", FILENAME(state)); break; case IDLN_TYPE_FLOAT: switch(IDL_TYPE_FLOAT(state->tree).f_type) { case IDL_FLOAT_TYPE_FLOAT: fputs("float", FILENAME(state)); break; case IDL_FLOAT_TYPE_DOUBLE: fputs("double", FILENAME(state)); break; default: g_error(" Unknown floating point typ: %d\n", IDL_NODE_TYPE(state->tree)); break; } break; case IDLN_IDENT: if (IDL_NODE_UP(state->tree) && IDL_NODE_TYPE(IDL_NODE_UP(state->tree)) == IDLN_NATIVE) { const char *user_type = IDL_NATIVE(IDL_NODE_UP(state->tree)).user_type; const char *ident_str = IDL_IDENT(IDL_NATIVE(IDL_NODE_UP(state->tree)).ident).str; if (strcmp(user_type, "void") == 0) { /*it should not happend for scriptable methods*/ fputs("Object", FILENAME(state)); } /* XXX: s.b test for "id" attribute */ /* XXX: special class for nsIDs */ else if (strcmp(user_type, "nsID") == 0) { fputs("ID", FILENAME(state)); } else if (strcmp(user_type, "nsIID") == 0) { fputs("IID", FILENAME(state)); } else if (strcmp(user_type, "nsCID") == 0) { fputs("CID", FILENAME(state)); } else { /* XXX: special class for opaque types */ /*it should not happend for scriptable methods*/ fputs("OpaqueValue", FILENAME(state)); } } else { const char *ident_str = IDL_IDENT(state->tree).str; /* XXX: big kludge; s.b. way to match to typedefs */ if (strcmp(ident_str, "PRInt8") == 0 || strcmp(ident_str, "PRUint8") == 0) { fputs("byte", FILENAME(state)); } else if (strcmp(ident_str, "PRInt16") == 0 || strcmp(ident_str, "PRUint16") == 0) { fputs("short", FILENAME(state)); } else if (strcmp(ident_str, "PRInt32") == 0 || strcmp(ident_str, "PRUint32") == 0) { fputs("int", FILENAME(state)); } else if (strcmp(ident_str, "PRInt64") == 0 || strcmp(ident_str, "PRUint64") == 0) { fputs("long", FILENAME(state)); } else if (strcmp(ident_str, "PRBool") == 0) { fputs("boolean", FILENAME(state)); } else if (strcmp(ident_str, "nsrefcnt") == 0) { fputs("int", FILENAME(state)); } else { IDL_tree real_type = g_hash_table_lookup(TYPEDEFS(state), ident_str); if (real_type) { IDL_tree orig_tree = state->tree; state->tree = real_type; xpcom_to_java_type(state); state->tree = orig_tree; } else { fputs(subscriptIdentifier(state, (char*) ident_str), FILENAME(state)); } } } break; case IDLN_TYPE_ENUM: case IDLN_TYPE_OBJECT: default: g_error(" Unknown type: %d\n", IDL_TYPE_FLOAT(state->tree).f_type); break; } return TRUE; }
static gboolean interface_declaration(TreeState *state) { char *outname; IDL_tree interface = state->tree; IDL_tree iterator = NULL; char *interface_name = subscriptIdentifier(state, IDL_IDENT(IDL_INTERFACE(interface).ident).str); const char *iid = NULL; GSList *doc_comments = IDL_IDENT(IDL_INTERFACE(interface).ident).comments; char *prefix = IDL_GENTREE(IDL_NS(state->ns).current)._cur_prefix; /* * Each interface decl is a single file */ outname = g_strdup_printf("%s.%s", interface_name, "java"); FILENAME(state) = fopen(outname, "w"); if (!FILENAME(state)) { perror("error opening output file"); return FALSE; } fputs("/*\n * ************* DO NOT EDIT THIS FILE ***********\n", FILENAME(state)); fprintf(FILENAME(state), " *\n * This file was automatically generated from %s.idl.\n", state->basename); fputs(" */\n\n", FILENAME(state)); if (prefix) { if (strlen(prefix)) fprintf(FILENAME(state), "\npackage %s;\n\n", prefix); fputs("import org.mozilla.xpcom.*;\n\n", FILENAME(state)); } else { fputs("\npackage org.mozilla.xpcom;\n\n", FILENAME(state)); } /* * Write out JavaDoc comment */ fprintf(FILENAME(state), "\n/**\n * Interface %s\n", interface_name); #ifndef LIBIDL_MAJOR_VERSION iid = IDL_tree_property_get(interface, "uuid"); #else iid = IDL_tree_property_get(IDL_INTERFACE(interface).ident, "uuid"); #endif if (iid != NULL) { fprintf(FILENAME(state), " *\n * IID: 0x%s\n */\n\n", iid); } else { fputs(" */\n\n", FILENAME(state)); } if (doc_comments != NULL) printlist(FILENAME(state), doc_comments); /* * Write "public interface <foo>" */ fprintf(FILENAME(state), "public interface %s ", interface_name); /* * Check for inheritence, and iterator over the inherited names, * if any. */ if ((iterator = IDL_INTERFACE(interface).inheritance_spec)) { fputs("extends ", FILENAME(state)); do { fprintf(FILENAME(state), "%s", IDL_IDENT(IDL_LIST(iterator).data).str); if (IDL_LIST(iterator).next) { fputs(", ", FILENAME(state)); } } while ((iterator = IDL_LIST(iterator).next)); } fputs("\n{\n", FILENAME(state)); if (iid) { /* * Write interface constants for IID */ /* fputs(" public static final String ", FILENAME(state)); */ /* XXX s.b just "IID" ? */ /* if (!write_classname_iid_define(FILENAME(state), interface_name)) { */ /* return FALSE; */ /* } */ /* fprintf(FILENAME(state), "_STRING =\n \"%s\";\n\n", iid); */ /* fputs(" public static final nsID ", FILENAME(state)); */ /* XXX s.b just "IID" ? */ /* if (!write_classname_iid_define(FILENAME(state), interface_name)) { */ /* return FALSE; */ /* } */ /* fprintf(FILENAME(state), " =\n new nsID(\"%s\");\n\n", iid); */ fprintf(FILENAME(state), " public static final IID IID =\n new IID(\"%s\");\n\n", iid); } /* * Advance the state of the tree, go on to process more */ state->tree = IDL_INTERFACE(interface).body; if (state->tree && !xpidl_process_node(state)) { return FALSE; } fputs("\n}\n", FILENAME(state)); fprintf(FILENAME(state), "\n/*\n * end\n */\n"); fclose(FILENAME(state)); free(outname); return TRUE; }