another widl patch

Ove Kaaven ovehk at ping.uio.no
Mon Nov 18 18:25:05 CST 2002


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 at 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;




More information about the wine-patches mailing list