ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

widl.c
Go to the documentation of this file.
00001 /*
00002  * IDL Compiler
00003  *
00004  * Copyright 2002 Ove Kaaven
00005  * based on WRC code by Bertho Stultiens
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  */
00021 
00022 #include "config.h"
00023 #include "wine/port.h"
00024 
00025 #include <errno.h>
00026 #include <limits.h>
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #ifdef HAVE_UNISTD_H
00030 # include <unistd.h>
00031 #endif
00032 #include <string.h>
00033 #include <assert.h>
00034 #include <ctype.h>
00035 #include <signal.h>
00036 #ifdef HAVE_GETOPT_H
00037 # include <getopt.h>
00038 #endif
00039 
00040 #include "widl.h"
00041 #include "utils.h"
00042 #include "parser.h"
00043 #include "wine/wpp.h"
00044 #include "header.h"
00045 
00046 /* future options to reserve characters for: */
00047 /* A = ACF input filename */
00048 /* J = do not search standard include path */
00049 /* w = select win16/win32 output (?) */
00050 
00051 static const char usage[] =
00052 "Usage: widl [options...] infile.idl\n"
00053 "   or: widl [options...] --dlldata-only name1 [name2...]\n"
00054 "   -b arch            Set the target architecture\n"
00055 "   -c                 Generate client stub\n"
00056 "   -d n               Set debug level to 'n'\n"
00057 "   -D id[=val]        Define preprocessor identifier id=val\n"
00058 "   -E                 Preprocess only\n"
00059 "   -h                 Generate headers\n"
00060 "   -H file            Name of header file (default is infile.h)\n"
00061 "   -I path            Set include search dir to path (multiple -I allowed)\n"
00062 "   --local-stubs=file Write empty stubs for call_as/local methods to file\n"
00063 "   -m32, -m64         Set the kind of typelib to build (Win32 or Win64)\n"
00064 "   -N                 Do not preprocess input\n"
00065 "   --oldnames         Use old naming conventions\n"
00066 "   -o, --output=NAME  Set the output file name\n"
00067 "   -Otype             Type of stubs to generate (-Os, -Oi, -Oif)\n"
00068 "   -p                 Generate proxy\n"
00069 "   --prefix-all=p     Prefix names of client stubs / server functions with 'p'\n"
00070 "   --prefix-client=p  Prefix names of client stubs with 'p'\n"
00071 "   --prefix-server=p  Prefix names of server functions with 'p'\n"
00072 "   -r                 Generate registration script\n"
00073 "   -s                 Generate server stub\n"
00074 "   -t                 Generate typelib\n"
00075 "   -u                 Generate interface identifiers file\n"
00076 "   -V                 Print version and exit\n"
00077 "   -W                 Enable pedantic warnings\n"
00078 "   --win32            Only generate 32-bit code\n"
00079 "   --win64            Only generate 64-bit code\n"
00080 "   --win32-align n    Set win32 structure alignment to 'n'\n"
00081 "   --win64-align n    Set win64 structure alignment to 'n'\n"
00082 "Debug level 'n' is a bitmask with following meaning:\n"
00083 "    * 0x01 Tell which resource is parsed (verbose mode)\n"
00084 "    * 0x02 Dump internal structures\n"
00085 "    * 0x04 Create a parser trace (yydebug=1)\n"
00086 "    * 0x08 Preprocessor messages\n"
00087 "    * 0x10 Preprocessor lex messages\n"
00088 "    * 0x20 Preprocessor yacc trace\n"
00089 ;
00090 
00091 static const char version_string[] = "Wine IDL Compiler version " PACKAGE_VERSION "\n"
00092             "Copyright 2002 Ove Kaaven\n";
00093 
00094 int debuglevel = DEBUGLEVEL_NONE;
00095 int parser_debug, yy_flex_debug;
00096 
00097 int pedantic = 0;
00098 int do_everything = 1;
00099 static int preprocess_only = 0;
00100 int do_header = 0;
00101 int do_typelib = 0;
00102 int do_proxies = 0;
00103 int do_client = 0;
00104 int do_server = 0;
00105 int do_regscript = 0;
00106 int do_idfile = 0;
00107 int do_dlldata = 0;
00108 static int no_preprocess = 0;
00109 int old_names = 0;
00110 int do_win32 = 1;
00111 int do_win64 = 1;
00112 int win32_packing = 8;
00113 int win64_packing = 8;
00114 static enum stub_mode stub_mode = MODE_Os;
00115 
00116 char *input_name;
00117 char *header_name;
00118 char *local_stubs_name;
00119 char *header_token;
00120 char *typelib_name;
00121 char *dlldata_name;
00122 char *proxy_name;
00123 char *proxy_token;
00124 char *client_name;
00125 char *client_token;
00126 char *server_name;
00127 char *server_token;
00128 char *regscript_name;
00129 char *regscript_token;
00130 static char *idfile_name;
00131 static char *idfile_token;
00132 char *temp_name;
00133 const char *prefix_client = "";
00134 const char *prefix_server = "";
00135 
00136 int line_number = 1;
00137 
00138 static FILE *idfile;
00139 
00140 unsigned int pointer_size = 0;
00141 syskind_t typelib_kind = sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32;
00142 
00143 time_t now;
00144 
00145 enum {
00146     OLDNAMES_OPTION = CHAR_MAX + 1,
00147     DLLDATA_OPTION,
00148     DLLDATA_ONLY_OPTION,
00149     LOCAL_STUBS_OPTION,
00150     PREFIX_ALL_OPTION,
00151     PREFIX_CLIENT_OPTION,
00152     PREFIX_SERVER_OPTION,
00153     WIN32_OPTION,
00154     WIN64_OPTION,
00155     WIN32_ALIGN_OPTION,
00156     WIN64_ALIGN_OPTION
00157 };
00158 
00159 static const char short_options[] =
00160     "b:cC:d:D:EhH:I:m:No:O:pP:rsS:tT:uU:VW";
00161 static const struct option long_options[] = {
00162     { "dlldata", 1, NULL, DLLDATA_OPTION },
00163     { "dlldata-only", 0, NULL, DLLDATA_ONLY_OPTION },
00164     { "local-stubs", 1, NULL, LOCAL_STUBS_OPTION },
00165     { "oldnames", 0, NULL, OLDNAMES_OPTION },
00166     { "output", 0, NULL, 'o' },
00167     { "prefix-all", 1, NULL, PREFIX_ALL_OPTION },
00168     { "prefix-client", 1, NULL, PREFIX_CLIENT_OPTION },
00169     { "prefix-server", 1, NULL, PREFIX_SERVER_OPTION },
00170     { "win32", 0, NULL, WIN32_OPTION },
00171     { "win64", 0, NULL, WIN64_OPTION },
00172     { "win32-align", 1, NULL, WIN32_ALIGN_OPTION },
00173     { "win64-align", 1, NULL, WIN64_ALIGN_OPTION },
00174     { NULL, 0, NULL, 0 }
00175 };
00176 
00177 static void rm_tempfile(void);
00178 
00179 enum stub_mode get_stub_mode(void)
00180 {
00181     /* old-style interpreted stubs are not supported on 64-bit */
00182     if (stub_mode == MODE_Oi && pointer_size == 8) return MODE_Oif;
00183     return stub_mode;
00184 }
00185 
00186 static char *make_token(const char *name)
00187 {
00188   char *token;
00189   char *slash;
00190   int i;
00191 
00192   slash = strrchr(name, '/');
00193   if(!slash)
00194     slash = strrchr(name, '\\');
00195 
00196   if (slash) name = slash + 1;
00197 
00198   token = xstrdup(name);
00199   for (i=0; token[i]; i++) {
00200     if (!isalnum(token[i])) token[i] = '_';
00201     else token[i] = toupper(token[i]);
00202   }
00203   return token;
00204 }
00205 
00206 /* duplicate a basename into a valid C token */
00207 static char *dup_basename_token(const char *name, const char *ext)
00208 {
00209     char *p, *ret = dup_basename( name, ext );
00210     /* map invalid characters to '_' */
00211     for (p = ret; *p; p++) if (!isalnum(*p)) *p = '_';
00212     return ret;
00213 }
00214 
00215 static void add_widl_version_define(void)
00216 {
00217     unsigned int version;
00218     const char *p = PACKAGE_VERSION;
00219 
00220     /* major */
00221     version = atoi(p) * 0x10000;
00222     p = strchr(p, '.');
00223 
00224     /* minor */
00225     if (p)
00226     {
00227         version += atoi(p + 1) * 0x100;
00228         p = strchr(p + 1, '.');
00229     }
00230 
00231     /* build */
00232     if (p)
00233         version += atoi(p + 1);
00234 
00235     if (version != 0)
00236     {
00237         char version_str[11];
00238         snprintf(version_str, sizeof(version_str), "0x%x", version);
00239         wpp_add_define("__WIDL__", version_str);
00240     }
00241     else
00242         wpp_add_define("__WIDL__", NULL);
00243 }
00244 
00245 /* set the target platform */
00246 static void set_target( const char *target )
00247 {
00248     static const struct
00249     {
00250         const char *name;
00251         syskind_t   kind;
00252     } cpu_names[] =
00253     {
00254         { "i386",    SYS_WIN32 },
00255         { "i486",    SYS_WIN32 },
00256         { "i586",    SYS_WIN32 },
00257         { "i686",    SYS_WIN32 },
00258         { "i786",    SYS_WIN32 },
00259         { "amd64",   SYS_WIN64 },
00260         { "x86_64",  SYS_WIN64 },
00261         { "sparc",   SYS_WIN32 },
00262         { "alpha",   SYS_WIN32 },
00263         { "powerpc", SYS_WIN32 },
00264         { "arm",     SYS_WIN32 }
00265     };
00266 
00267     unsigned int i;
00268     char *p, *spec = xstrdup( target );
00269 
00270     /* target specification is in the form CPU-MANUFACTURER-OS or CPU-MANUFACTURER-KERNEL-OS */
00271 
00272     if (!(p = strchr( spec, '-' ))) error( "Invalid target specification '%s'\n", target );
00273     *p++ = 0;
00274     for (i = 0; i < sizeof(cpu_names)/sizeof(cpu_names[0]); i++)
00275     {
00276         if (!strcmp( cpu_names[i].name, spec ))
00277         {
00278             typelib_kind = cpu_names[i].kind;
00279             free( spec );
00280             return;
00281         }
00282     }
00283     error( "Unrecognized CPU '%s'\n", spec );
00284 }
00285 
00286 /* clean things up when aborting on a signal */
00287 static void exit_on_signal( int sig )
00288 {
00289     exit(1);  /* this will call the atexit functions */
00290 }
00291 
00292 static void set_everything(int x)
00293 {
00294   do_header = x;
00295   do_typelib = x;
00296   do_proxies = x;
00297   do_client = x;
00298   do_server = x;
00299   do_regscript = x;
00300   do_idfile = x;
00301   do_dlldata = x;
00302 }
00303 
00304 void start_cplusplus_guard(FILE *fp)
00305 {
00306   fprintf(fp, "#ifdef __cplusplus\n");
00307   fprintf(fp, "extern \"C\" {\n");
00308   fprintf(fp, "#endif\n\n");
00309 }
00310 
00311 void end_cplusplus_guard(FILE *fp)
00312 {
00313   fprintf(fp, "#ifdef __cplusplus\n");
00314   fprintf(fp, "}\n");
00315   fprintf(fp, "#endif\n\n");
00316 }
00317 
00318 typedef struct
00319 {
00320   char *filename;
00321   struct list link;
00322 } filename_node_t;
00323 
00324 static void add_filename_node(struct list *list, const char *name)
00325 {
00326   filename_node_t *node = xmalloc(sizeof *node);
00327   node->filename = dup_basename( name, ".idl" );
00328   list_add_tail(list, &node->link);
00329 }
00330 
00331 static void free_filename_nodes(struct list *list)
00332 {
00333   filename_node_t *node, *next;
00334   LIST_FOR_EACH_ENTRY_SAFE(node, next, list, filename_node_t, link) {
00335     list_remove(&node->link);
00336     free(node->filename);
00337     free(node);
00338   }
00339 }
00340 
00341 static void write_dlldata_list(struct list *filenames)
00342 {
00343   FILE *dlldata;
00344   filename_node_t *node;
00345 
00346   dlldata = fopen(dlldata_name, "w");
00347   if (!dlldata)
00348     error("couldn't open %s: %s\n", dlldata_name, strerror(errno));
00349 
00350   fprintf(dlldata, "/*** Autogenerated by WIDL %s ", PACKAGE_VERSION);
00351   fprintf(dlldata, "- Do not edit ***/\n\n");
00352   fprintf(dlldata, "#include <objbase.h>\n");
00353   fprintf(dlldata, "#include <rpcproxy.h>\n\n");
00354   start_cplusplus_guard(dlldata);
00355 
00356   LIST_FOR_EACH_ENTRY(node, filenames, filename_node_t, link)
00357     fprintf(dlldata, "EXTERN_PROXY_FILE(%s)\n", node->filename);
00358 
00359   fprintf(dlldata, "\nPROXYFILE_LIST_START\n");
00360   fprintf(dlldata, "/* Start of list */\n");
00361   LIST_FOR_EACH_ENTRY(node, filenames, filename_node_t, link)
00362     fprintf(dlldata, "  REFERENCE_PROXY_FILE(%s),\n", node->filename);
00363   fprintf(dlldata, "/* End of list */\n");
00364   fprintf(dlldata, "PROXYFILE_LIST_END\n\n");
00365 
00366   fprintf(dlldata, "DLLDATA_ROUTINES(aProxyFileList, GET_DLL_CLSID)\n\n");
00367   end_cplusplus_guard(dlldata);
00368   fclose(dlldata);
00369 }
00370 
00371 static char *eat_space(char *s)
00372 {
00373   while (isspace((unsigned char) *s))
00374     ++s;
00375   return s;
00376 }
00377 
00378 void write_dlldata(const statement_list_t *stmts)
00379 {
00380   struct list filenames = LIST_INIT(filenames);
00381   filename_node_t *node;
00382   FILE *dlldata;
00383 
00384   if (!do_dlldata || !need_proxy_file(stmts))
00385     return;
00386 
00387   dlldata = fopen(dlldata_name, "r");
00388   if (dlldata) {
00389     static char marker[] = "REFERENCE_PROXY_FILE";
00390     char *line = NULL;
00391     size_t len = 0;
00392 
00393     while (widl_getline(&line, &len, dlldata)) {
00394       char *start, *end;
00395       start = eat_space(line);
00396       if (strncmp(start, marker, sizeof marker - 1) == 0) {
00397         start = eat_space(start + sizeof marker - 1);
00398         if (*start != '(')
00399           continue;
00400         end = start = eat_space(start + 1);
00401         while (*end && *end != ')')
00402           ++end;
00403         if (*end != ')')
00404           continue;
00405         while (isspace((unsigned char) end[-1]))
00406           --end;
00407         *end = '\0';
00408         if (start < end)
00409           add_filename_node(&filenames, start);
00410       }
00411     }
00412 
00413     if (ferror(dlldata))
00414       error("couldn't read from %s: %s\n", dlldata_name, strerror(errno));
00415 
00416     free(line);
00417     fclose(dlldata);
00418   }
00419 
00420   LIST_FOR_EACH_ENTRY(node, &filenames, filename_node_t, link)
00421     if (strcmp(proxy_token, node->filename) == 0) {
00422       /* We're already in the list, no need to regenerate this file.  */
00423       free_filename_nodes(&filenames);
00424       return;
00425     }
00426 
00427   add_filename_node(&filenames, proxy_token);
00428   write_dlldata_list(&filenames);
00429   free_filename_nodes(&filenames);
00430 }
00431 
00432 static void write_id_data_stmts(const statement_list_t *stmts)
00433 {
00434   const statement_t *stmt;
00435   if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
00436   {
00437     if (stmt->type == STMT_TYPE)
00438     {
00439       const type_t *type = stmt->u.type;
00440       if (type_get_type(type) == TYPE_INTERFACE)
00441       {
00442         const UUID *uuid;
00443         if (!is_object(type) && !is_attr(type->attrs, ATTR_DISPINTERFACE))
00444           continue;
00445         uuid = get_attrp(type->attrs, ATTR_UUID);
00446         write_guid(idfile, is_attr(type->attrs, ATTR_DISPINTERFACE) ? "DIID" : "IID",
00447                    type->name, uuid);
00448       }
00449       else if (type_get_type(type) == TYPE_COCLASS)
00450       {
00451         const UUID *uuid = get_attrp(type->attrs, ATTR_UUID);
00452         write_guid(idfile, "CLSID", type->name, uuid);
00453       }
00454     }
00455     else if (stmt->type == STMT_LIBRARY)
00456     {
00457       const UUID *uuid = get_attrp(stmt->u.lib->attrs, ATTR_UUID);
00458       write_guid(idfile, "LIBID", stmt->u.lib->name, uuid);
00459       write_id_data_stmts(stmt->u.lib->stmts);
00460     }
00461   }
00462 }
00463 
00464 void write_id_data(const statement_list_t *stmts)
00465 {
00466   if (!do_idfile) return;
00467 
00468   idfile_token = make_token(idfile_name);
00469 
00470   idfile = fopen(idfile_name, "w");
00471   if (! idfile) {
00472     error("Could not open %s for output\n", idfile_name);
00473     return;
00474   }
00475 
00476   fprintf(idfile, "/*** Autogenerated by WIDL %s ", PACKAGE_VERSION);
00477   fprintf(idfile, "from %s - Do not edit ***/\n\n", input_name);
00478   fprintf(idfile, "#include <rpc.h>\n");
00479   fprintf(idfile, "#include <rpcndr.h>\n\n");
00480   fprintf(idfile, "#include <initguid.h>\n\n");
00481   start_cplusplus_guard(idfile);
00482 
00483   write_id_data_stmts(stmts);
00484 
00485   fprintf(idfile, "\n");
00486   end_cplusplus_guard(idfile);
00487 
00488   fclose(idfile);
00489 }
00490 
00491 int main(int argc,char *argv[])
00492 {
00493   int optc;
00494   int ret = 0;
00495   int opti = 0;
00496   char *output_name = NULL;
00497 
00498   signal( SIGTERM, exit_on_signal );
00499   signal( SIGINT, exit_on_signal );
00500 #ifdef SIGHUP
00501   signal( SIGHUP, exit_on_signal );
00502 #endif
00503 
00504   now = time(NULL);
00505 
00506   while((optc = getopt_long(argc, argv, short_options, long_options, &opti)) != EOF) {
00507     switch(optc) {
00508     case DLLDATA_OPTION:
00509       dlldata_name = xstrdup(optarg);
00510       break;
00511     case DLLDATA_ONLY_OPTION:
00512       do_everything = 0;
00513       do_dlldata = 1;
00514       break;
00515     case LOCAL_STUBS_OPTION:
00516       do_everything = 0;
00517       local_stubs_name = xstrdup(optarg);
00518       break;
00519     case OLDNAMES_OPTION:
00520       old_names = 1;
00521       break;
00522     case PREFIX_ALL_OPTION:
00523       prefix_client = xstrdup(optarg);
00524       prefix_server = xstrdup(optarg);
00525       break;
00526     case PREFIX_CLIENT_OPTION:
00527       prefix_client = xstrdup(optarg);
00528       break;
00529     case PREFIX_SERVER_OPTION:
00530       prefix_server = xstrdup(optarg);
00531       break;
00532     case WIN32_OPTION:
00533       do_win32 = 1;
00534       do_win64 = 0;
00535       break;
00536     case WIN64_OPTION:
00537       do_win32 = 0;
00538       do_win64 = 1;
00539       break;
00540     case WIN32_ALIGN_OPTION:
00541       win32_packing = strtol(optarg, NULL, 0);
00542       if(win32_packing != 2 && win32_packing != 4 && win32_packing != 8)
00543           error("Packing must be one of 2, 4 or 8\n");
00544       break;
00545     case WIN64_ALIGN_OPTION:
00546       win64_packing = strtol(optarg, NULL, 0);
00547       if(win64_packing != 2 && win64_packing != 4 && win64_packing != 8)
00548           error("Packing must be one of 2, 4 or 8\n");
00549       break;
00550     case 'b':
00551       set_target( optarg );
00552       break;
00553     case 'c':
00554       do_everything = 0;
00555       do_client = 1;
00556       break;
00557     case 'C':
00558       client_name = xstrdup(optarg);
00559       break;
00560     case 'd':
00561       debuglevel = strtol(optarg, NULL, 0);
00562       break;
00563     case 'D':
00564       wpp_add_cmdline_define(optarg);
00565       break;
00566     case 'E':
00567       do_everything = 0;
00568       preprocess_only = 1;
00569       break;
00570     case 'h':
00571       do_everything = 0;
00572       do_header = 1;
00573       break;
00574     case 'H':
00575       header_name = xstrdup(optarg);
00576       break;
00577     case 'I':
00578       wpp_add_include_path(optarg);
00579       break;
00580     case 'm':
00581       if (!strcmp( optarg, "32" )) typelib_kind = SYS_WIN32;
00582       else if (!strcmp( optarg, "64" )) typelib_kind = SYS_WIN64;
00583       else error( "Invalid -m argument '%s'\n", optarg );
00584       break;
00585     case 'N':
00586       no_preprocess = 1;
00587       break;
00588     case 'o':
00589       output_name = xstrdup(optarg);
00590       break;
00591     case 'O':
00592       if (!strcmp( optarg, "s" )) stub_mode = MODE_Os;
00593       else if (!strcmp( optarg, "i" )) stub_mode = MODE_Oi;
00594       else if (!strcmp( optarg, "ic" )) stub_mode = MODE_Oif;
00595       else if (!strcmp( optarg, "if" )) stub_mode = MODE_Oif;
00596       else if (!strcmp( optarg, "icf" )) stub_mode = MODE_Oif;
00597       else error( "Invalid argument '-O%s'\n", optarg );
00598       break;
00599     case 'p':
00600       do_everything = 0;
00601       do_proxies = 1;
00602       break;
00603     case 'P':
00604       proxy_name = xstrdup(optarg);
00605       break;
00606     case 'r':
00607       do_everything = 0;
00608       do_regscript = 1;
00609       break;
00610     case 's':
00611       do_everything = 0;
00612       do_server = 1;
00613       break;
00614     case 'S':
00615       server_name = xstrdup(optarg);
00616       break;
00617     case 't':
00618       do_everything = 0;
00619       do_typelib = 1;
00620       break;
00621     case 'T':
00622       typelib_name = xstrdup(optarg);
00623       break;
00624     case 'u':
00625       do_everything = 0;
00626       do_idfile = 1;
00627       break;
00628     case 'U':
00629       idfile_name = xstrdup(optarg);
00630       break;
00631     case 'V':
00632       printf("%s", version_string);
00633       return 0;
00634     case 'W':
00635       pedantic = 1;
00636       break;
00637     default:
00638       fprintf(stderr, "%s", usage);
00639       return 1;
00640     }
00641   }
00642 
00643   if(do_everything) {
00644     set_everything(TRUE);
00645   }
00646 
00647   if (!output_name) output_name = dup_basename(input_name, ".idl");
00648 
00649   if (!do_everything &&
00650       do_header + do_typelib + do_proxies + do_client +
00651       do_server + do_regscript + do_idfile + do_dlldata == 1)
00652   {
00653       if (do_header) header_name = output_name;
00654       else if (do_typelib) typelib_name = output_name;
00655       else if (do_proxies) proxy_name = output_name;
00656       else if (do_client) client_name = output_name;
00657       else if (do_server) server_name = output_name;
00658       else if (do_regscript) regscript_name = output_name;
00659       else if (do_idfile) idfile_name = output_name;
00660       else if (do_dlldata) dlldata_name = output_name;
00661   }
00662 
00663   if (!dlldata_name && do_dlldata)
00664     dlldata_name = xstrdup("dlldata.c");
00665 
00666   if(optind < argc) {
00667     if (do_dlldata && !do_everything) {
00668       struct list filenames = LIST_INIT(filenames);
00669       for ( ; optind < argc; ++optind)
00670         add_filename_node(&filenames, argv[optind]);
00671 
00672       write_dlldata_list(&filenames);
00673       free_filename_nodes(&filenames);
00674       return 0;
00675     }
00676     else if (optind != argc - 1) {
00677       fprintf(stderr, "%s", usage);
00678       return 1;
00679     }
00680     else
00681       input_name = xstrdup(argv[optind]);
00682   }
00683   else {
00684     fprintf(stderr, "%s", usage);
00685     return 1;
00686   }
00687 
00688   if(debuglevel)
00689   {
00690     setbuf(stdout, NULL);
00691     setbuf(stderr, NULL);
00692   }
00693 
00694   parser_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0;
00695   yy_flex_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0;
00696 
00697   wpp_set_debug( (debuglevel & DEBUGLEVEL_PPLEX) != 0,
00698                  (debuglevel & DEBUGLEVEL_PPTRACE) != 0,
00699                  (debuglevel & DEBUGLEVEL_PPMSG) != 0 );
00700 
00701   if (!header_name) {
00702     header_name = dup_basename(input_name, ".idl");
00703     strcat(header_name, ".h");
00704   }
00705 
00706   if (!typelib_name && do_typelib) {
00707     typelib_name = dup_basename(input_name, ".idl");
00708     strcat(typelib_name, ".tlb");
00709   }
00710 
00711   if (!proxy_name && do_proxies) {
00712     proxy_name = dup_basename(input_name, ".idl");
00713     strcat(proxy_name, "_p.c");
00714   }
00715 
00716   if (!client_name && do_client) {
00717     client_name = dup_basename(input_name, ".idl");
00718     strcat(client_name, "_c.c");
00719   }
00720 
00721   if (!server_name && do_server) {
00722     server_name = dup_basename(input_name, ".idl");
00723     strcat(server_name, "_s.c");
00724   }
00725 
00726   if (!regscript_name && do_regscript) {
00727     regscript_name = dup_basename(input_name, ".idl");
00728     strcat(regscript_name, "_r.rgs");
00729   }
00730 
00731   if (!idfile_name && do_idfile) {
00732     idfile_name = dup_basename(input_name, ".idl");
00733     strcat(idfile_name, "_i.c");
00734   }
00735 
00736   if (do_proxies) proxy_token = dup_basename_token(proxy_name,"_p.c");
00737   if (do_client) client_token = dup_basename_token(client_name,"_c.c");
00738   if (do_server) server_token = dup_basename_token(server_name,"_s.c");
00739   if (do_regscript) regscript_token = dup_basename_token(regscript_name,"_r.rgs");
00740 
00741   add_widl_version_define();
00742   wpp_add_define("_WIN32", NULL);
00743 
00744   atexit(rm_tempfile);
00745   if (!no_preprocess)
00746   {
00747     chat("Starting preprocess\n");
00748 
00749     if (!preprocess_only)
00750     {
00751         FILE *output;
00752         int fd;
00753         char *name = xmalloc( strlen(header_name) + 8 );
00754 
00755         strcpy( name, header_name );
00756         strcat( name, ".XXXXXX" );
00757 
00758         if ((fd = mkstemps( name, 0 )) == -1)
00759             error("Could not generate a temp name from %s\n", name);
00760 
00761         temp_name = name;
00762         if (!(output = fdopen(fd, "wt")))
00763             error("Could not open fd %s for writing\n", name);
00764 
00765         ret = wpp_parse( input_name, output );
00766         fclose( output );
00767     }
00768     else
00769     {
00770         ret = wpp_parse( input_name, stdout );
00771     }
00772 
00773     if(ret) exit(1);
00774     if(preprocess_only) exit(0);
00775     if(!(parser_in = fopen(temp_name, "r"))) {
00776       fprintf(stderr, "Could not open %s for input\n", temp_name);
00777       return 1;
00778     }
00779   }
00780   else {
00781     if(!(parser_in = fopen(input_name, "r"))) {
00782       fprintf(stderr, "Could not open %s for input\n", input_name);
00783       return 1;
00784     }
00785   }
00786 
00787   header_token = make_token(header_name);
00788 
00789   init_types();
00790   ret = parser_parse();
00791 
00792   fclose(parser_in);
00793 
00794   if(ret) {
00795     exit(1);
00796   }
00797 
00798   /* Everything has been done successfully, don't delete any files.  */
00799   set_everything(FALSE);
00800   local_stubs_name = NULL;
00801 
00802   return 0;
00803 }
00804 
00805 static void rm_tempfile(void)
00806 {
00807   abort_import();
00808   if(temp_name)
00809     unlink(temp_name);
00810   if (do_header)
00811     unlink(header_name);
00812   if (local_stubs_name)
00813     unlink(local_stubs_name);
00814   if (do_client)
00815     unlink(client_name);
00816   if (do_server)
00817     unlink(server_name);
00818   if (do_regscript)
00819     unlink(regscript_name);
00820   if (do_idfile)
00821     unlink(idfile_name);
00822   if (do_proxies)
00823     unlink(proxy_name);
00824   if (do_typelib)
00825     unlink(typelib_name);
00826 }

Generated on Sat May 26 2012 04:36:52 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.