static input_data * new_input_data(const char *filename, IncludePathEntry *include_path) { input_data *new_data; FILE *inputfile; char *buffer = NULL; size_t offset = 0; size_t buffer_size; #ifdef XP_MAC size_t i; #endif #if defined(XP_MAC) && defined(XPIDL_PLUGIN) /* on Mac, fopen knows how to find files. */ inputfile = fopen(filename, "r"); #elif defined(XP_OS2) || defined(XP_WIN32) /* * if filename is fully qualified (starts with driver letter), then * just call fopen(); else, go with fopen_from_includes() */ if( filename[1] == ':' ) inputfile = fopen(filename, "r"); else inputfile = fopen_from_includes(filename, "r", include_path); #else inputfile = fopen_from_includes(filename, "r", include_path); #endif if (!inputfile) return NULL; #ifdef XP_MAC { struct stat input_stat; if (fstat(fileno(inputfile), &input_stat)) return NULL; buffer = malloc(input_stat.st_size + 1); if (!buffer) return NULL; offset = fread(buffer, 1, input_stat.st_size, inputfile); if (ferror(inputfile)) return NULL; } #else /* * Rather than try to keep track of many different varieties of state * around the boundaries of a circular buffer, we just read in the entire * file. * * We iteratively grow the buffer here; an alternative would be to use * stat to find the exact buffer size we need, as xpt_dump does. */ for (buffer_size = 8191; ; buffer_size *= 2) { size_t just_read; buffer = realloc(buffer, buffer_size + 1); /* +1 for trailing nul */ just_read = fread(buffer + offset, 1, buffer_size - offset, inputfile); if (ferror(inputfile)) return NULL; if (just_read < buffer_size - offset || just_read == 0) { /* Done reading. */ offset += just_read; break; } offset += just_read; } #endif fclose(inputfile); #ifdef XP_MAC /* * libIDL doesn't speak '\r' properly - always make sure lines end with * '\n'. */ for (i = 0; i < offset; i++) { if (buffer[i] == '\r') buffer[i] = '\n'; } #endif new_data = xpidl_malloc(sizeof (struct input_data)); new_data->point = new_data->buf = buffer; new_data->max = buffer + offset; *new_data->max = '\0'; new_data->filename = xpidl_strdup(filename); /* libIDL expects the line number to be that of the *next* line */ new_data->lineno = 2; new_data->next = NULL; return new_data; }
int main(int argc, char *argv[]) { int i; IncludePathEntry *inc, *inc_head, **inc_tail; char *file_basename = NULL; ModeData *mode = NULL; gboolean create_old_typelib = FALSE; /* turn this on for extra checking of our code */ /* IDL_check_cast_enable(TRUE); */ inc_head = xpidl_malloc(sizeof *inc); #ifndef XP_MAC inc_head->directory = "."; #else inc_head->directory = ""; #endif inc_head->next = NULL; inc_tail = &inc_head->next; for (i = 1; i < argc; i++) { if (argv[i][0] != '-') break; switch (argv[i][1]) { case '-': argc++; /* pretend we didn't see this */ /* fall through */ case 0: /* - is a legal input filename (stdin) */ goto done_options; case 'a': emit_typelib_annotations = TRUE; break; case 'w': enable_warnings = TRUE; break; case 'v': verbose_mode = TRUE; break; case 't': { /* Parse for "-t version number" and store it into global boolean * and string variables. */ const gchar* typelib_version_string = NULL; /* * If -t is the last argument on the command line, we have a problem */ if (i + 1 == argc) { fprintf(stderr, "ERROR: missing version number after -t\n"); xpidl_usage(argc, argv); return 1; } /* Do not allow more than one "-t" definition */ if (create_old_typelib) { fprintf(stderr, "ERROR: -t argument used twice. " "Cannot specify more than one version\n"); xpidl_usage(argc, argv); return 1; } /* * Assume that the argument after "-t" is the version number string * and search for it in our internal list of acceptable version * numbers. */ switch (XPT_ParseVersionString(argv[++i], &major_version, &minor_version)) { case XPT_VERSION_CURRENT: break; case XPT_VERSION_OLD: create_old_typelib = TRUE; break; case XPT_VERSION_UNSUPPORTED: fprintf(stderr, "ERROR: version \"%s\" not supported.\n", argv[i]); xpidl_usage(argc, argv); return 1; case XPT_VERSION_UNKNOWN: default: fprintf(stderr, "ERROR: version \"%s\" not recognised.\n", argv[i]); xpidl_usage(argc, argv); return 1; } break; } case 'I': if (argv[i][2] == '\0' && i == argc) { fputs("ERROR: missing path after -I\n", stderr); xpidl_usage(argc, argv); return 1; } inc = xpidl_malloc(sizeof *inc); if (argv[i][2] == '\0') { /* is it the -I foo form? */ inc->directory = argv[++i]; } else { /* must be the -Ifoo form. Don't preincrement i. */ inc->directory = argv[i] + 2; } #ifdef DEBUG_shaver_includes fprintf(stderr, "adding %s to include path\n", inc->directory); #endif inc->next = NULL; *inc_tail = inc; inc_tail = &inc->next; break; case 'o': if (i == argc) { fprintf(stderr, "ERROR: missing basename after -o\n"); xpidl_usage(argc, argv); return 1; } file_basename = argv[++i]; explicit_output_filename = FALSE; break; case 'e': if (i == argc) { fprintf(stderr, "ERROR: missing basename after -e\n"); xpidl_usage(argc, argv); return 1; } file_basename = argv[++i]; explicit_output_filename = TRUE; break; case 'm': if (i + 1 == argc) { fprintf(stderr, "ERROR: missing modename after -m\n"); xpidl_usage(argc, argv); return 1; } if (mode) { fprintf(stderr, "ERROR: must specify exactly one mode " "(first \"%s\", now \"%s\")\n", mode->mode, argv[i + 1]); xpidl_usage(argc, argv); return 1; } mode = FindMode(argv[++i]); if (!mode) { fprintf(stderr, "ERROR: unknown mode \"%s\"\n", argv[i]); xpidl_usage(argc, argv); return 1; } break; default: fprintf(stderr, "unknown option %s\n", argv[i]); xpidl_usage(argc, argv); return 1; } } done_options: if (!mode) { fprintf(stderr, "ERROR: must specify output mode\n"); xpidl_usage(argc, argv); return 1; } if (argc != i + 1) { fprintf(stderr, "ERROR: extra arguments after input file\n"); } /* * Don't try to process multiple files, given that we don't handle -o * multiply. */ if (xpidl_process_idl(argv[i], inc_head, file_basename, mode)) return 0; return 1; }
static input_data * new_input_data(char **filename, IncludePathEntry *include_path) { input_data *new_data; FILE *inputfile; char *buffer = NULL; size_t offset = 0; size_t buffer_size; #if defined(XP_OS2) || defined(XP_WIN32) /* * if filename is fully qualified (starts with driver letter), then * just call fopen(); else, go with fopen_from_includes() */ if( (*filename)[1] == ':' ) inputfile = fopen(*filename, "r"); else inputfile = fopen_from_includes(filename, "r", include_path); #else inputfile = fopen_from_includes(filename, "r", include_path); #endif if (!inputfile) return NULL; /* * Rather than try to keep track of many different varieties of state * around the boundaries of a circular buffer, we just read in the entire * file. * * We iteratively grow the buffer here; an alternative would be to use * stat to find the exact buffer size we need, as xpt_dump does. */ for (buffer_size = 8191; ; buffer_size *= 2) { size_t just_read; buffer = realloc(buffer, buffer_size + 1); /* +1 for trailing nul */ just_read = fread(buffer + offset, 1, buffer_size - offset, inputfile); if (ferror(inputfile)) return NULL; if (just_read < buffer_size - offset || just_read == 0) { /* Done reading. */ offset += just_read; break; } offset += just_read; } fclose(inputfile); new_data = xpidl_malloc(sizeof (struct input_data)); new_data->point = new_data->buf = buffer; new_data->max = buffer + offset; *new_data->max = '\0'; new_data->filename = *filename; /* libIDL expects the line number to be that of the *next* line */ new_data->lineno = 2; new_data->next = NULL; if (deps) fprintf(deps, " \\\n\t%s", *filename); return new_data; }