Exemplo n.º 1
0
static gboolean
typelib_list(TreeState *state)
{
    IDL_tree iter;
    for (iter = state->tree; iter; iter = IDL_LIST(iter).next) {
        state->tree = IDL_LIST(iter).data;
        if (!xpidl_process_node(state))
            return FALSE;
    }
    return TRUE;
}
Exemplo n.º 2
0
static gboolean
process_list(TreeState *state)
{
    IDL_tree iter;
    gint type;
    for (iter = state->tree; iter; iter = IDL_LIST(iter).next) {
        state->tree = IDL_LIST(iter).data;
        type = IDL_NODE_TYPE(state->tree);
        if (!xpidl_process_node(state))
            return FALSE;
    }
    return TRUE;
}
Exemplo n.º 3
0
static gboolean
typelib_interface(TreeState *state)
{
    IDL_tree iface = state->tree, iter;
    char *name = IDL_IDENT(IDL_INTERFACE(iface).ident).str;
    XPTInterfaceDirectoryEntry *ide;
    XPTInterfaceDescriptor *id;
    uint16 parent_id = 0;
    PRUint8 interface_flags = 0;

    if (!verify_interface_declaration(iface))
        return FALSE;

    if (IDL_tree_property_get(IDL_INTERFACE(iface).ident, "scriptable"))
        interface_flags |= XPT_ID_SCRIPTABLE;

    if (IDL_tree_property_get(IDL_INTERFACE(iface).ident, "function"))
        interface_flags |= XPT_ID_FUNCTION;

    ide = FindInterfaceByName(HEADER(state)->interface_directory,
                              HEADER(state)->num_interfaces, name);
    if (!ide) {
        IDL_tree_error(iface, "ERROR: didn't find interface %s in "
                       "IDE block. Giving up.\n", name);
        return FALSE;
    }

    if ((iter = IDL_INTERFACE(iface).inheritance_spec)) {
        char *parent;
        if (IDL_LIST(iter).next) {
            IDL_tree_error(iface,
                           "ERROR: more than one parent interface for %s\n",
                           name);
            return FALSE;
        }
        parent = IDL_IDENT(IDL_LIST(iter).data).str;
        parent_id = (uint16)(uint32)g_hash_table_lookup(IFACE_MAP(state),
                                                        parent);
        if (!parent_id) {
            IDL_tree_error(iface,
                           "ERROR: no index found for %s. Giving up.\n",
                           parent);
            return FALSE;
        }
    }

    id = XPT_NewInterfaceDescriptor(ARENA(state), parent_id, 0, 0, 
                                    interface_flags);
    if (!id)
        return FALSE;

    CURRENT(state) = ide->interface_descriptor = id;
#ifdef DEBUG_shaver_ifaces
    fprintf(stderr, "DBG: starting interface %s @ %p\n", name, id);
#endif

    NEXT_METH(state) = 0;
    NEXT_CONST(state) = 0;
    NEXT_TYPE(state) = 0;

    state->tree = IDL_INTERFACE(iface).body;
    if (state->tree && !xpidl_process_node(state))
        return FALSE;
#ifdef DEBUG_shaver_ifaces
    fprintf(stderr, "DBG: ending interface %s\n", name);
#endif
    return TRUE;
}
static gboolean
interface(TreeState *state)
{
    IDL_tree iface = state->tree, iter, orig;
    char *className = IDL_IDENT(IDL_INTERFACE(iface).ident).str;
    char *classNameUpper = NULL;
    char *classNameImpl = NULL;
    char *cp;
    gboolean ok = TRUE;
    gboolean keepvtable;
    const char *iid;
    const char *name_space;
    struct nsID id;
    char iid_parsed[UUID_LENGTH];
    GSList *doc_comments = IDL_IDENT(IDL_INTERFACE(iface).ident).comments;

    if (!verify_interface_declaration(iface))
        return FALSE;

#define FAIL    do {ok = FALSE; goto out;} while(0)

    fprintf(state->file,   "\n/* starting interface:    %s */\n",
            className);

    name_space = IDL_tree_property_get(IDL_INTERFACE(iface).ident, "namespace");
    if (name_space) {
        fprintf(state->file, "/* namespace:             %s */\n",
                name_space);
        fprintf(state->file, "/* fully qualified name:  %s.%s */\n",
                name_space,className);
    }

    iid = IDL_tree_property_get(IDL_INTERFACE(iface).ident, "uuid");
    if (iid) {
        /* 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);
            FAIL;
        }

        /*
         * 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);
            FAIL;
        }
        if (!xpidl_sprint_iid(&id, iid_parsed)) {
            IDL_tree_error(state->tree, "error formatting IID %s\n", iid);
            FAIL;
        }

        /* #define NS_ISUPPORTS_IID_STR "00000000-0000-0000-c000-000000000046" */
        fputs("#define ", state->file);
        write_classname_iid_define(state->file, className);
        fprintf(state->file, "_STR \"%s\"\n", iid_parsed);
        fputc('\n', state->file);

        /* #define NS_ISUPPORTS_IID { {0x00000000 .... 0x46 }} */
        fprintf(state->file, "#define ");
        write_classname_iid_define(state->file, className);
        fprintf(state->file, " \\\n"
                "  {0x%.8x, 0x%.4x, 0x%.4x, \\\n"
                "    { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, "
                "0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }}\n",
                id.m0, id.m1, id.m2,
                id.m3[0], id.m3[1], id.m3[2], id.m3[3],
                id.m3[4], id.m3[5], id.m3[6], id.m3[7]);
        fputc('\n', state->file);
    } else {
        IDL_tree_error(state->tree, "interface %s lacks a uuid attribute\n", 
            className);
        FAIL;
    }

    if (doc_comments != NULL)
        printlist(state->file, doc_comments);

    /*
     * NS_NO_VTABLE is defined in nsISupportsUtils.h, and defined on windows
     * to __declspec(novtable) on windows.  This optimization is safe
     * whenever the constructor calls no virtual methods.  Writing in IDL
     * almost guarantees this, except for the case when a %{C++ block occurs in
     * the interface.  We detect that case, and emit a macro call that disables
     * the optimization.
     */
    keepvtable = FALSE;
    for (iter = IDL_INTERFACE(state->tree).body;
         iter != NULL;
         iter = IDL_LIST(iter).next)
    {
        IDL_tree data = IDL_LIST(iter).data;
        if (IDL_NODE_TYPE(data) == IDLN_CODEFRAG)
            keepvtable = TRUE;
    }
    
    /* The interface declaration itself. */
    fprintf(state->file,
            "class %s%s",
            (keepvtable ? "" : "NS_NO_VTABLE "), className);
    
    if ((iter = IDL_INTERFACE(iface).inheritance_spec)) {
        fputs(" : ", state->file);
        if (IDL_LIST(iter).next != NULL) {
            IDL_tree_error(iter,
                           "multiple inheritance is not supported by xpidl");
            FAIL;
        }
        fprintf(state->file, "public %s", IDL_IDENT(IDL_LIST(iter).data).str);
    }
    fputs(" {\n"
          " public: \n\n", state->file);
    if (iid) {
        fputs("  NS_DEFINE_STATIC_IID_ACCESSOR(", state->file);
        write_classname_iid_define(state->file, className);
        fputs(")\n\n", state->file);
    }

    orig = state->tree; /* It would be nice to remove this state-twiddling. */

    state->tree = IDL_INTERFACE(iface).body;

    if (state->tree && !xpidl_process_node(state))
        FAIL;

    fputs("};\n", state->file);
    fputc('\n', state->file);

    /*
     * #define NS_DECL_NSIFOO - create method prototypes that can be used in
     * class definitions that support this interface.
     *
     * Walk the tree explicitly to prototype a reworking of xpidl to get rid of
     * the callback mechanism.
     */
    state->tree = orig;
    fputs("/* Use this macro when declaring classes that implement this "
          "interface. */\n", state->file);
    fputs("#define NS_DECL_", state->file);
    classNameUpper = xpidl_strdup(className);
    for (cp = classNameUpper; *cp != '\0'; cp++)
        *cp = toupper(*cp);
    fprintf(state->file, "%s \\\n", classNameUpper);
    if (IDL_INTERFACE(state->tree).body == NULL) {
        write_indent(state->file);
        fputs("/* no methods! */\n", state->file);
    }

    for (iter = IDL_INTERFACE(state->tree).body;
         iter != NULL;
         iter = IDL_LIST(iter).next)
    {
        IDL_tree data = IDL_LIST(iter).data;

        switch(IDL_NODE_TYPE(data)) {
          case IDLN_OP_DCL:
            write_indent(state->file);
            write_method_signature(data, state->file, AS_DECL, NULL);
            break;

          case IDLN_ATTR_DCL:
            write_indent(state->file);
            if (!write_attr_accessor(data, state->file, TRUE, AS_DECL, NULL))
                FAIL;
            if (!IDL_ATTR_DCL(data).f_readonly) {
                fputs("; \\\n", state->file); /* Terminate the previous one. */
                write_indent(state->file);
                if (!write_attr_accessor(data, state->file,
                                         FALSE, AS_DECL, NULL))
                    FAIL;
                /* '; \n' at end will clean up. */
            }
            break;

          case IDLN_CONST_DCL:
            /* ignore it here; it doesn't contribute to the macro. */
            continue;

          case IDLN_CODEFRAG:
            XPIDL_WARNING((iter, IDL_WARNING1,
                           "%%{ .. %%} code fragment within interface "
                           "ignored when generating NS_DECL_%s macro; "
                           "if the code fragment contains method "
                           "declarations, the macro probably isn't "
                           "complete.", classNameUpper));
            continue;

          default:
            IDL_tree_error(iter,
                           "unexpected node type %d! "
                           "Please file a bug against the xpidl component.",
                           IDL_NODE_TYPE(data));
            FAIL;
        }

        if (IDL_LIST(iter).next != NULL) {
            fprintf(state->file, "; \\\n");
        } else {
            fprintf(state->file, "; \n");
        }
    }
    fputc('\n', state->file);

    /* XXX abstract above and below into one function? */
    /*
     * #define NS_FORWARD_NSIFOO - create forwarding methods that can delegate
     * behavior from in implementation to another object.  As generated by
     * idlc.
     */
    fprintf(state->file,
            "/* Use this macro to declare functions that forward the "
            "behavior of this interface to another object. */\n"
            "#define NS_FORWARD_%s(_to) \\\n",
            classNameUpper);
    if (IDL_INTERFACE(state->tree).body == NULL) {
        write_indent(state->file);
        fputs("/* no methods! */\n", state->file);
    }

    for (iter = IDL_INTERFACE(state->tree).body;
         iter != NULL;
         iter = IDL_LIST(iter).next)
    {
        IDL_tree data = IDL_LIST(iter).data;

        switch(IDL_NODE_TYPE(data)) {
          case IDLN_OP_DCL:
            write_indent(state->file);
            write_method_signature(data, state->file, AS_DECL, NULL);
            fputs(" { return _to ", state->file);
            write_method_signature(data, state->file, AS_CALL, NULL);
            break;

          case IDLN_ATTR_DCL:
            write_indent(state->file);
            if (!write_attr_accessor(data, state->file, TRUE, AS_DECL, NULL))
                FAIL;
            fputs(" { return _to ", state->file);
            if (!write_attr_accessor(data, state->file, TRUE, AS_CALL, NULL))
                FAIL;
            if (!IDL_ATTR_DCL(data).f_readonly) {
                fputs("; } \\\n", state->file); /* Terminate the previous one. */
                write_indent(state->file);
                if (!write_attr_accessor(data, state->file,
                                         FALSE, AS_DECL, NULL))
                    FAIL;
                fputs(" { return _to ", state->file);
                if (!write_attr_accessor(data, state->file,
                                         FALSE, AS_CALL, NULL))
                    FAIL;
                /* '; } \n' at end will clean up. */
            }
            break;

          case IDLN_CONST_DCL:
          case IDLN_CODEFRAG:
              continue;

          default:
            FAIL;
        }

        if (IDL_LIST(iter).next != NULL) {
            fprintf(state->file, "; } \\\n");
        } else {
            fprintf(state->file, "; } \n");
        }
    }
    fputc('\n', state->file);


    /* XXX abstract above and below into one function? */
    /*
     * #define NS_FORWARD_SAFE_NSIFOO - create forwarding methods that can delegate
     * behavior from in implementation to another object.  As generated by
     * idlc.
     */
    fprintf(state->file,
            "/* Use this macro to declare functions that forward the "
            "behavior of this interface to another object in a safe way. */\n"
            "#define NS_FORWARD_SAFE_%s(_to) \\\n",
            classNameUpper);
    if (IDL_INTERFACE(state->tree).body == NULL) {
        write_indent(state->file);
        fputs("/* no methods! */\n", state->file);
    }

    for (iter = IDL_INTERFACE(state->tree).body;
         iter != NULL;
         iter = IDL_LIST(iter).next)
    {
        IDL_tree data = IDL_LIST(iter).data;

        switch(IDL_NODE_TYPE(data)) {
          case IDLN_OP_DCL:
            write_indent(state->file);
            write_method_signature(data, state->file, AS_DECL, NULL);
            fputs(" { return !_to ? NS_ERROR_NULL_POINTER : _to->", state->file);
            write_method_signature(data, state->file, AS_CALL, NULL);
            break;

          case IDLN_ATTR_DCL:
            write_indent(state->file);
            if (!write_attr_accessor(data, state->file, TRUE, AS_DECL, NULL))
                FAIL;
            fputs(" { return !_to ? NS_ERROR_NULL_POINTER : _to->", state->file);
            if (!write_attr_accessor(data, state->file, TRUE, AS_CALL, NULL))
                FAIL;
            if (!IDL_ATTR_DCL(data).f_readonly) {
                fputs("; } \\\n", state->file); /* Terminate the previous one. */
                write_indent(state->file);
                if (!write_attr_accessor(data, state->file,
                                         FALSE, AS_DECL, NULL))
                    FAIL;
                fputs(" { return !_to ? NS_ERROR_NULL_POINTER : _to->", state->file);
                if (!write_attr_accessor(data, state->file,
                                         FALSE, AS_CALL, NULL))
                    FAIL;
                /* '; } \n' at end will clean up. */
            }
            break;

          case IDLN_CONST_DCL:
          case IDLN_CODEFRAG:
              continue;

          default:
            FAIL;
        }

        if (IDL_LIST(iter).next != NULL) {
            fprintf(state->file, "; } \\\n");
        } else {
            fprintf(state->file, "; } \n");
        }
    }
    fputc('\n', state->file);

    /*
     * Build a sample implementation template.
     */
    if (strlen(className) >= 3 && className[2] == 'I') {
        classNameImpl = xpidl_strdup(className);
        if (!classNameImpl)
            FAIL;
        memmove(&classNameImpl[2], &classNameImpl[3], strlen(classNameImpl) - 2);
    } else {
        classNameImpl = xpidl_strdup("_MYCLASS_");
        if (!classNameImpl)
            FAIL;
    }

    fputs("#if 0\n"
          "/* Use the code below as a template for the "
          "implementation class for this interface. */\n"
          "\n"
          "/* Header file */"
          "\n",
          state->file);
    fprintf(state->file, "class %s : public %s\n", classNameImpl, className);
    fputs("{\n"
          "public:\n", state->file);
    write_indent(state->file);
    fputs("NS_DECL_ISUPPORTS\n", state->file);
    write_indent(state->file);
    fprintf(state->file, "NS_DECL_%s\n", classNameUpper);
    fputs("\n", state->file);
    write_indent(state->file);
    fprintf(state->file, "%s();\n", classNameImpl);
    fputs("\n"
          "private:\n", state->file);
    write_indent(state->file);
    fprintf(state->file, "~%s();\n", classNameImpl);
    fputs("\n"
          "protected:\n", state->file);
    write_indent(state->file);
    fputs("/* additional members */\n", state->file);
    fputs("};\n\n", state->file);

    fputs("/* Implementation file */\n", state->file);

    fprintf(state->file, 
            "NS_IMPL_ISUPPORTS1(%s, %s)\n", classNameImpl, className);
    fputs("\n", state->file);
    
    fprintf(state->file, "%s::%s()\n", classNameImpl, classNameImpl);
    fputs("{\n", state->file);
    write_indent(state->file);
    fputs("/* member initializers and constructor code */\n", state->file);
    fputs("}\n\n", state->file);
    
    fprintf(state->file, "%s::~%s()\n", classNameImpl, classNameImpl);
    fputs("{\n", state->file);
    write_indent(state->file);
    fputs("/* destructor code */\n", state->file);
    fputs("}\n\n", state->file);

    for (iter = IDL_INTERFACE(state->tree).body;
         iter != NULL;
         iter = IDL_LIST(iter).next)
    {
        IDL_tree data = IDL_LIST(iter).data;

        switch(IDL_NODE_TYPE(data)) {
          case IDLN_OP_DCL:
            /* It would be nice to remove this state-twiddling. */
            orig = state->tree; 
            state->tree = data;
            xpidl_write_comment(state, 0);
            state->tree = orig;

            write_method_signature(data, state->file, AS_IMPL, classNameImpl);
            fputs("\n{\n", state->file);
            write_indent(state->file);
            write_indent(state->file);
            fputs("return NS_ERROR_NOT_IMPLEMENTED;\n"
                  "}\n"
                  "\n", state->file);
            break;

          case IDLN_ATTR_DCL:
            /* It would be nice to remove this state-twiddling. */
            orig = state->tree; 
            state->tree = data;
            xpidl_write_comment(state, 0);
            state->tree = orig;
            
            if (!write_attr_accessor(data, state->file, TRUE, 
                                     AS_IMPL, classNameImpl))
                FAIL;
            fputs("\n{\n", state->file);
            write_indent(state->file);
            write_indent(state->file);
            fputs("return NS_ERROR_NOT_IMPLEMENTED;\n"
                  "}\n", state->file);

            if (!IDL_ATTR_DCL(data).f_readonly) {
                if (!write_attr_accessor(data, state->file, FALSE, 
                                         AS_IMPL, classNameImpl))
                    FAIL;
                fputs("\n{\n", state->file);
                write_indent(state->file);
                write_indent(state->file);
                fputs("return NS_ERROR_NOT_IMPLEMENTED;\n"
                      "}\n", state->file);
            }
            fputs("\n", state->file);
            break;

          case IDLN_CONST_DCL:
          case IDLN_CODEFRAG:
              continue;

          default:
            FAIL;
        }
    }

    fputs("/* End of implementation class template. */\n"
          "#endif\n"
          "\n", state->file);

#undef FAIL

out:
    if (classNameUpper)
        free(classNameUpper);
    if (classNameImpl)
        free(classNameImpl);
    return ok;
}
Exemplo n.º 5
0
int
xpidl_process_idl(char *filename, IncludePathEntry *include_path,
                  char *file_basename, char* package, ModeData *mode)
{
    char *tmp, *outname, *real_outname = NULL;
    IDL_tree top;
    TreeState state;
    int rv;
    input_callback_state callback_state;
    gboolean ok = TRUE;
    backend *emitter;

    memset(&state, 0, sizeof(state));

    callback_state.input_stack = NULL;
    callback_state.base_includes = NULL;
    callback_state.include_path = include_path;
    callback_state.already_included = g_hash_table_new(g_str_hash, g_str_equal);

    if (!callback_state.already_included) {
        fprintf(stderr, "failed to create hashtable.  out of memory?\n");
        return 0;
    }

    state.basename = xpidl_strdup(filename);
    if (package)
      state.package = xpidl_strdup(package);

    /* if basename has an .extension, truncate it. */
    tmp = strrchr(state.basename, '.');
    if (tmp)
        *tmp = '\0';

    if (!file_basename)
        outname = xpidl_strdup(state.basename);
    else
        outname = xpidl_strdup(file_basename);

    /* so we don't include it again! */
    g_hash_table_insert(callback_state.already_included,
                        xpidl_strdup(filename), (void *)TRUE);

    parsed_empty_file = FALSE;

    rv = IDL_parse_filename_with_input(filename, input_callback, &callback_state,
                                       msg_callback, &top,
                                       &state.ns,
                                       IDLF_IGNORE_FORWARDS |
                                       IDLF_XPIDL,
                                       enable_warnings ? IDL_WARNING1 :
                                       IDL_ERROR);
    if (parsed_empty_file) {
        /*
         * If we've detected (via hack in msg_callback) that libIDL returned
         * failure because it found a file with no IDL, set the parse tree to
         * null and proceed.  Allowing this is useful to permit .idl files that
         * collect #includes.
         */
        top = NULL;
        state.ns = NULL;
    } else if (rv != IDL_SUCCESS) {
        if (rv == -1) {
            g_warning("Parse of %s failed: %s", filename, g_strerror(errno));
        } else {
            g_warning("Parse of %s failed", filename);
        }
        return 0;
    }

    state.basename = xpidl_strdup(filename);
    tmp = strrchr(state.basename, '.');
    if (tmp)
        *tmp = '\0';

    /* so xpidl_header.c can use it to generate a list of #include directives */
    state.base_includes = callback_state.base_includes;

    emitter = mode->factory();
    state.dispatch = emitter->dispatch_table;

    if (strcmp(outname, "-")) {
        const char *fopen_mode;
        const char *out_basename;

        /* explicit_output_filename can't be true without a filename */
        if (explicit_output_filename) {
            real_outname = g_strdup(outname);
        } else {
/* 
 *This combination seems a little strange, what about OS/2?
 * Assume it's some build issue
 */
#if defined(XP_UNIX) || defined(XP_WIN)
            if (!file_basename) {
                out_basename = xpidl_basename(outname);
            } else {
                out_basename = outname;
            }
#else
            out_basename = outname;
#endif
            real_outname = g_strdup_printf("%s.%s", out_basename, mode->suffix);
        }

        /* don't create/open file here for Java */
        if (strcmp(mode->mode, "java") == 0)
        {
            state.filename = real_outname;
        } else {
            /* Use binary write for typelib mode */
            fopen_mode = (strcmp(mode->mode, "typelib")) ? "w" : "wb";
            state.file = fopen(real_outname, fopen_mode);
            if (!state.file) {
                perror("error opening output file");
                return 0;
            }
        }
    } else {
        state.file = stdout;
    }
    state.tree = top;

    if (emitter->emit_prolog)
        emitter->emit_prolog(&state);
    if (state.tree) /* Only if we have a tree to process. */
        ok = xpidl_process_node(&state);
    if (emitter->emit_epilog)
        emitter->emit_epilog(&state);

    if (strcmp(mode->mode, "java") != 0)
    {
        if (state.file != stdout)
            fclose(state.file);
    }

    free(state.basename);
    free(state.package);
    free(outname);
    g_hash_table_foreach(callback_state.already_included, free_ghash_key, NULL);
    g_hash_table_destroy(callback_state.already_included);
    g_slist_foreach(callback_state.base_includes, free_gslist_data, NULL);

    if (state.ns)
        IDL_ns_free(state.ns);
    if (top)
        IDL_tree_free(top);

    if (real_outname != NULL) {
        /*
         * Delete partial output file on failure.  (Mac does this in the plugin
         * driver code, if the compiler returns failure.)
         */
#if defined(XP_UNIX) || defined(XP_WIN)
        if (!ok)
            unlink(real_outname);
#endif
        g_free(real_outname);
    }

    return ok;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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;
}