static gboolean header_epilog(TreeState *state) { const char *define = xpidl_basename(state->basename); fprintf(state->file, "\n#endif /* __gen_%s_h__ */\n", define); return TRUE; }
static gboolean header_prolog(TreeState *state) { char *define = xpidl_basename(state->basename); fprintf(state->file, "/*\n * DO NOT EDIT. THIS FILE IS GENERATED FROM" " %s.idl\n */\n", state->basename); fprintf(state->file, "\n#ifndef __gen_%s_h__\n" "#define __gen_%s_h__\n", define, define); g_free(define); if (state->base_includes != NULL) { guint len = g_slist_length(state->base_includes); guint i; fputc('\n', state->file); for (i = 0; i < len; i++) { char *ident, *dot; ident = (char *)g_slist_nth_data(state->base_includes, i); /* suppress any trailing .extension */ /* XXX use g_basename instead ? ? */ dot = strrchr(ident, '.'); if (dot != NULL) *dot = '\0'; /* begin include guard */ fprintf(state->file, "\n#ifndef __gen_%s_h__\n", ident); fprintf(state->file, "#include \"%s.h\"\n", (char *)g_slist_nth_data(state->base_includes, i)); fprintf(state->file, "#endif\n"); } if (i > 0) fputc('\n', state->file); } /* * Support IDL files that don't include a root IDL file that defines * NS_NO_VTABLE. */ fprintf(state->file, "/* For IDL files that don't want to include root IDL files. */\n" "#ifndef NS_NO_VTABLE\n" "#define NS_NO_VTABLE\n" "#endif\n"); return TRUE; }
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; }