gboolean ok;
gboolean ok = TRUE;
xpidl_process_idl(char *filename, IncludePathEntry *include_path,                  char *file_basename, ModeData *mode){    char *tmp, *outname, *real_outname = NULL;    IDL_tree top;    TreeState state;    int rv;    input_callback_state callback_state;    gboolean ok;    backend *emitter;    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 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;#if defined(XP_UNIX)        const char os_separator = '/';#elif defined(XP_WIN)        const char os_separator = '\\';#endif#if defined(XP_UNIX) || defined(XP_WIN)        tmp = strrchr(outname, os_separator);        if (!file_basename && tmp) {            real_outname = g_strdup_printf("%s.%s", tmp + 1, mode->suffix);        } else {            real_outname = g_strdup_printf("%s.%s", outname, mode->suffix);        }#else        real_outname = g_strdup_printf("%s.%s", outname, mode->suffix);#endif        /* 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 (state.file != stdout)        fclose(state.file);    free(state.basename);    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        free(real_outname);    }    return ok;}