Patch is against ReWind, so applying it against Wine will give "offset 15/16 lines" (that's the length of the LGPL text at the top of each file in Wine, of course)... but I see no other warnings from --dry-run, so it should be ok. Log: Ove Kaaven <ovek@transgaming.com> Added "generate headers only" command-line option. Implemented imports from inside interface definitions. Fixed a few problems with generating header files for COM interfaces. Index: tools/widl/header.c =================================================================== RCS file: /cvsroot/rewind/rewind/tools/widl/header.c,v retrieving revision 1.3 diff -u -r1.3 header.c --- tools/widl/header.c 18 Nov 2002 18:08:46 -0000 1.3 +++ tools/widl/header.c 18 Nov 2002 23:52:31 -0000 @@ -409,8 +409,8 @@ fprintf(header, "void __RPC_STUB %s_", iface->name); write_name(header,def); fprintf(header, "_Stub(\n"); - fprintf(header, " IRpcStubBuffer* This,\n"); - fprintf(header, " IRpcChannelBuffer* pRpcChannelBuffer,\n"); + fprintf(header, " struct IRpcStubBuffer* This,\n"); + fprintf(header, " struct IRpcChannelBuffer* pRpcChannelBuffer,\n"); fprintf(header, " PRPC_MESSAGE pRpcMessage,\n"); fprintf(header, " DWORD* pdwStubPhase);\n"); } @@ -446,7 +446,12 @@ void write_forward(type_t *iface) { - if (is_object(iface->attrs) && !iface->written) { + /* C/C++ forwards should only be written for object interfaces, so if we + * have a full definition we only write one if we find [object] among the + * attributes - however, if we don't have a full definition at this point + * (i.e. this is an IDL forward), then we also assume that it is an object + * interface, since non-object interfaces shouldn't need forwards */ + if ((!iface->defined || is_object(iface->attrs)) && !iface->written) { fprintf(header, "typedef struct %s %s;\n", iface->name, iface->name); iface->written = TRUE; } @@ -484,7 +489,7 @@ fprintf(header, "#define %s_IMETHODS \\\n", iface->name); if (iface->ref) fprintf(header, " %s_IMETHODS \\\n", iface->ref->name); - fprintf(header, " %s_METHODS \\\n", iface->name); + fprintf(header, " %s_METHODS\n", iface->name); if (iface->ref) fprintf(header, "ICOM_DEFINE(%s,%s)\n", iface->name, iface->ref->name); else Index: tools/widl/parser.l =================================================================== RCS file: /cvsroot/rewind/rewind/tools/widl/parser.l,v retrieving revision 1.2 diff -u -r1.2 parser.l --- tools/widl/parser.l 18 Nov 2002 18:08:59 -0000 1.2 +++ tools/widl/parser.l 18 Nov 2002 23:52:32 -0000 @@ -111,7 +111,10 @@ \>\> return SHR; . return yytext[0]; <<EOF>> { - if (import_stack_ptr) pop_import(); + if (import_stack_ptr) { + pop_import(); + return aEOF; + } else yyterminate(); } %% Index: tools/widl/parser.y =================================================================== RCS file: /cvsroot/rewind/rewind/tools/widl/parser.y,v retrieving revision 1.4 diff -u -r1.4 parser.y --- tools/widl/parser.y 18 Nov 2002 18:09:11 -0000 1.4 +++ tools/widl/parser.y 18 Nov 2002 23:52:32 -0000 @@ -94,6 +94,7 @@ %token <num> aNUM %token <str> aSTRING %token <uuid> aUUID +%token aEOF %token SHL SHR %token tAGGREGATABLE tALLOCATE tAPPOBJECT tARRAYS tASYNC tASYNCUUID %token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT @@ -139,7 +140,7 @@ %type <attr> m_attributes attributes attrib_list attribute %type <expr> aexprs aexpr_list aexpr array -%type <type> inherit interface interfacedef lib_statements +%type <type> inherit interface interfacehdr interfacedef lib_statements %type <type> base_type int_std %type <type> enumdef structdef typedef uniondef %type <tref> type @@ -165,18 +166,12 @@ ; lib_statements: { $$ = NULL; } - | lib_statements import - | lib_statements interface ';' + | lib_statements interface ';' { if (!parse_only) write_forward($2); } | lib_statements interfacedef { LINK($2, $1); $$ = $2; } /* | lib_statements librarydef (when implemented) */ | lib_statements statement ; -/* we can't import from inside interfaces yet - * (it's not entirely clear how Microsoft manages that yet, - * but in MIDL you can derive a class from a base class and then - * import the base class definition from inside the interface, - * which I don't quite know how to pull off in yacc/bison yet) */ int_statements: { $$ = NULL; } | int_statements funcdef ';' { LINK($2, $1); $$ = $2; } | int_statements statement @@ -187,7 +182,7 @@ | cppquote {} | enumdef ';' { if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n\n"); } } | externdef ';' {} -/* | import {} */ + | import {} /* | interface ';' {} */ /* | interfacedef {} */ | structdef ';' { if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n\n"); } } @@ -196,9 +191,11 @@ ; cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only) fprintf(header, "%s\n", $3); } -; -import: tIMPORT aSTRING ';' { do_import($2); } -; + ; +import_start: tIMPORT aSTRING ';' { do_import($2); } + ; +import: import_start input aEOF {} + ; m_args: { $$ = NULL; } | args @@ -414,17 +411,31 @@ | ':' aKNOWNTYPE { $$ = find_type2($2, 0); } ; -interface: tINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); if (!parse_only) write_forward($$); } - | tINTERFACE aKNOWNTYPE { $$ = get_type(RPC_FC_IP, $2, 0); if (!parse_only) write_forward($$); } +interface: tINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); } + | tINTERFACE aKNOWNTYPE { $$ = get_type(RPC_FC_IP, $2, 0); } ; -interfacedef: attributes interface inherit - '{' int_statements '}' { $$ = $2; +interfacehdr: attributes interface { $$ = $2; if ($$->defined) yyerror("multiple definition error\n"); - $$->ref = $3; $$->attrs = $1; - $$->funcs = $5; $$->defined = TRUE; + if (!parse_only) write_forward($$); + } + ; + +interfacedef: interfacehdr inherit + '{' int_statements '}' { $$ = $1; + $$->ref = $2; + $$->funcs = $4; + if (!parse_only) write_interface($$); + } +/* MIDL is able to import the definition of a base class from inside the + * definition of a derived class, I'll try to support it with this rule */ + | interfacehdr ':' aIDENTIFIER + '{' import int_statements '}' { $$ = $1; + $$->ref = find_type2($3, 0); + if (!$$->ref) yyerror("base class %s not found in import\n", $3); + $$->funcs = $6; if (!parse_only) write_interface($$); } ; Index: tools/widl/proxy.c =================================================================== RCS file: /cvsroot/rewind/rewind/tools/widl/proxy.c,v retrieving revision 1.3 diff -u -r1.3 proxy.c --- tools/widl/proxy.c 18 Nov 2002 18:09:15 -0000 1.3 +++ tools/widl/proxy.c 18 Nov 2002 23:52:32 -0000 @@ -221,6 +221,8 @@ return; } + if (header_only) return; + while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); /* FIXME: check for [oleautomation], shouldn't generate proxies/stubs if specified */ Index: tools/widl/widl.c =================================================================== RCS file: /cvsroot/rewind/rewind/tools/widl/widl.c,v retrieving revision 1.2 diff -u -r1.2 widl.c --- tools/widl/widl.c 18 Nov 2002 18:09:21 -0000 1.2 +++ tools/widl/widl.c 18 Nov 2002 23:52:32 -0000 @@ -28,6 +28,7 @@ " -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" @@ -50,6 +51,7 @@ int pedantic = 0; int preprocess_only = 0; +int header_only = 0; int no_preprocess = 0; char *input_name; @@ -98,7 +100,7 @@ now = time(NULL); - while((optc = getopt(argc, argv, "d:D:EH:I:NVW")) != EOF) { + while((optc = getopt(argc, argv, "d:D:EhH:I:NVW")) != EOF) { switch(optc) { case 'd': debuglevel = strtol(optarg, NULL, 0); @@ -108,6 +110,9 @@ break; case 'E': preprocess_only = 1; + break; + case 'h': + header_only = 1; break; case 'H': header_name = strdup(optarg); Index: tools/widl/widl.h =================================================================== RCS file: /cvsroot/rewind/rewind/tools/widl/widl.h,v retrieving revision 1.1 diff -u -r1.1 widl.h --- tools/widl/widl.h 8 Jun 2002 13:18:16 -0000 1.1 +++ tools/widl/widl.h 18 Nov 2002 23:52:32 -0000 @@ -24,6 +24,7 @@ extern int win32; extern int pedantic; +extern int header_only; extern char *input_name; extern char *header_name;