Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenwidl.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
1.7.6.1
|