/* * IDL Compiler * * Copyright 2002 Ove Kaaven * based on WRC code by Bertho Stultiens * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include #ifdef HAVE_UNISTD_H # include #endif #include #include #include #include #define WIDL_FULLVERSION "0.1" #include "widl.h" #include "utils.h" #include "parser.h" #include "proxy.h" #include "wine/wpp.h" /* future options to reserve characters for: */ /* a = alignment of structures */ /* A = ACF input filename */ /* c = client stub only? */ /* C = client stub filename */ /* J = do not search standard include path */ /* O = generate interpreted stubs */ /* p = proxy only? */ /* P = proxy filename */ /* s = server stub only? */ /* S = server stub filename */ /* u = UUID file only? */ /* U = UUID filename */ /* w = select win16/win32 output (?) */ static char usage[] = "Usage: widl [options...] infile.idl\n" " -d n Set debug level to 'n'\n" " -D id[=val] Define preprocessor identifier id=val\n" " -E Preprocess only\n" " -h Generate headers only\n" " -H file Name of header file (default is infile.h)\n" " -I path Set include search dir to path (multiple -I allowed)\n" " -N Do not preprocess input\n" " -t Generate typelib only\n" " -T file Name of typelib file (default is infile.tlb)\n" " -V Print version and exit\n" " -W Enable pedantic warnings\n" "Debug level 'n' is a bitmask with following meaning:\n" " * 0x01 Tell which resource is parsed (verbose mode)\n" " * 0x02 Dump internal structures\n" " * 0x04 Create a parser trace (yydebug=1)\n" " * 0x08 Preprocessor messages\n" " * 0x10 Preprocessor lex messages\n" " * 0x20 Preprocessor yacc trace\n" ; static const char version_string[] = "Wine IDL Compiler Version " WIDL_FULLVERSION "\n" "Copyright 2002 Ove Kaaven\n"; int win32 = 1; int debuglevel = DEBUGLEVEL_NONE; int pedantic = 0; int do_everything = 1; int preprocess_only = 0; int header_only = 0; int typelib_only = 0; int no_preprocess = 0; char *input_name; char *header_name; char *header_token; char *typelib_name; char *proxy_name; char *proxy_token; char *temp_name; int line_number = 1; FILE *header; FILE *proxy; time_t now; int getopt (int argc, char *const *argv, const char *optstring); static void rm_tempfile(void); static void segvhandler(int sig); static char *make_token(const char *name) { char *token; char *slash; int i; slash = strrchr(name, '/'); if (slash) name = slash + 1; token = xstrdup(name); for (i=0; token[i]; i++) { if (!isalnum(token[i])) token[i] = '_'; else token[i] = toupper(token[i]); } return token; } int main(int argc,char *argv[]) { extern char* optarg; extern int optind; int optc; int ret = 0; signal(SIGSEGV, segvhandler); now = time(NULL); while((optc = getopt(argc, argv, "d:D:EhH:I:NtT:VW")) != EOF) { switch(optc) { case 'd': debuglevel = strtol(optarg, NULL, 0); break; case 'D': wpp_add_cmdline_define(optarg); break; case 'E': do_everything = 0; preprocess_only = 1; break; case 'h': do_everything = 0; header_only = 1; break; case 'H': header_name = strdup(optarg); break; case 'I': wpp_add_include_path(optarg); break; case 'N': no_preprocess = 1; break; case 't': do_everything = 0; typelib_only = 1; break; case 'T': typelib_name = strdup(optarg); break; case 'V': printf(version_string); return 0; case 'W': pedantic = 1; break; default: fprintf(stderr, usage); return 1; } } if(optind < argc) { input_name = xstrdup(argv[optind]); } else { fprintf(stderr, usage); return 1; } if(debuglevel) { setbuf(stdout,0); setbuf(stderr,0); } yydebug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0; yy_flex_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0; wpp_set_debug( (debuglevel & DEBUGLEVEL_PPLEX) != 0, (debuglevel & DEBUGLEVEL_PPTRACE) != 0, (debuglevel & DEBUGLEVEL_PPMSG) != 0 ); if (!header_name && (do_everything || header_only)) { header_name = dup_basename(input_name, ".idl"); strcat(header_name, ".h"); } if (!typelib_name && (do_everything || typelib_only)) { typelib_name = dup_basename(input_name, ".idl"); strcat(typelib_name, ".tlb"); } if (!proxy_name && do_everything) { proxy_name = dup_basename(input_name, ".idl"); proxy_token = xstrdup(proxy_name); strcat(proxy_name, "_p.c"); } wpp_add_cmdline_define("__WIDL__"); atexit(rm_tempfile); if (!no_preprocess) { chat("Starting preprocess"); if (!preprocess_only) { ret = wpp_parse_temp( input_name, header_name, &temp_name ); } else { ret = wpp_parse( input_name, stdout ); } if(ret) exit(1); if(preprocess_only) exit(0); if(!(yyin = fopen(temp_name, "r"))) { fprintf(stderr, "Could not open %s for input\n", temp_name); return 1; } } else { if(!(yyin = fopen(input_name, "r"))) { fprintf(stderr, "Could not open %s for input\n", input_name); return 1; } } if(do_everything || header_only) { header_token = make_token(header_name); if(!(header = fopen(header_name, "w"))) { fprintf(stderr, "Could not open %s for output\n", header_name); return 1; } fprintf(header, "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", WIDL_FULLVERSION, input_name); fprintf(header, "#include \n" ); fprintf(header, "#include \n\n" ); fprintf(header, "#ifndef __WIDL_%s\n", header_token); fprintf(header, "#define __WIDL_%s\n", header_token); fprintf(header, "#ifdef __cplusplus\n"); fprintf(header, "extern \"C\" {\n"); fprintf(header, "#endif\n"); ret = yyparse(); fprintf(header, "#ifdef __cplusplus\n"); fprintf(header, "}\n"); fprintf(header, "#endif\n"); fprintf(header, "#endif /* __WIDL_%s */\n", header_token); fclose(header); } fclose(yyin); if(ret) { exit(1); } header_name = NULL; return 0; } static void rm_tempfile(void) { abort_import(); if(temp_name) unlink(temp_name); if (header_name) unlink( header_name ); } static void segvhandler(int sig) { fprintf(stderr, "\n%s:%d: Oops, segment violation\n", input_name, line_number); fflush(stdout); fflush(stderr); abort(); }