widl patch again

Ove Kaaven ovehk at ping.uio.no
Fri Nov 8 09:57:03 CST 2002


OK, this is a widl patch that is merged against a clean wine tree, and
should hopefully work there

Log:
Ove Kaaven <ovek at transgaming.com>
Support for enums, arrays, encapsulated unions, signed/unsigned
qualifiers, and some other improvements.

Index: tools/widl/header.c
===================================================================
RCS file: /home/wine/wine/tools/widl/header.c,v
retrieving revision 1.2
diff -u -r1.2 header.c
--- tools/widl/header.c	13 Aug 2002 03:30:58 -0000	1.2
+++ tools/widl/header.c	8 Nov 2002 15:45:41 -0000
@@ -51,13 +51,13 @@
   return 0;
 }
 
-static void write_pident(var_t *v)
+static void write_pident(FILE *h, var_t *v)
 {
   int c;
   for (c=0; c<v->ptr_level; c++) {
-    fprintf(header, "*");
+    fprintf(h, "*");
   }
-  if (v->name) fprintf(header, "%s", v->name);
+  if (v->name) fprintf(h, "%s", v->name);
 }
 
 void write_name(FILE *h, var_t *v)
@@ -70,22 +70,66 @@
   return v->name;
 }
 
+static void write_array(FILE *h, expr_t *v)
+{
+  if (!v) return;
+  while (NEXT_LINK(v)) v = NEXT_LINK(v);
+  fprintf(h, "[");
+  while (v) {
+    if (v->type == EXPR_NUM)
+      fprintf(h, "%ld", v->u.lval); /* statically sized array */
+    else
+      fprintf(h, "1"); /* dynamically sized array */
+    if (PREV_LINK(v))
+      fprintf(h, ", ");
+    v = PREV_LINK(v);
+  }
+  fprintf(h, "]");
+}
+
+static void write_field(FILE *h, var_t *v)
+{
+  if (!v) return;
+  if (v->type) {
+    indent(0);
+    write_type(h, v->type, NULL, v->tname);
+    if (get_name(v)) {
+      fprintf(h, " ");
+      write_pident(h, v);
+    }
+    write_array(h, v->array);
+    fprintf(h, ";\n");
+  }
+}
+
 static void write_fields(FILE *h, var_t *v)
 {
+  var_t *first = v;
+  if (!v) return;
+  while (NEXT_LINK(v)) v = NEXT_LINK(v);
+  while (v) {
+    write_field(h, v);
+    if (v == first) break;
+    v = PREV_LINK(v);
+  }
+}
+
+static void write_enums(FILE *h, var_t *v)
+{
   if (!v) return;
   while (NEXT_LINK(v)) v = NEXT_LINK(v);
   while (v) {
-    if (v->type) {
+    if (get_name(v)) {
       indent(0);
-      write_type(h, v->type, NULL, v->tname);
-      if (get_name(v)) {
-        fprintf(header, " ");
-        write_pident(v);
-      }
-      fprintf(header, ";\n");
+      write_name(h, v);
+      if (v->has_val)
+        fprintf(h, " = %ld", v->lval);
     }
+    if (PREV_LINK(v))
+      fprintf(h, ",\n");
     v = PREV_LINK(v);
   }
+  fprintf(h, "\n");
 }
 
 void write_type(FILE *h, type_t *t, var_t *v, char *n)
@@ -96,25 +140,52 @@
   else {
     if (t->is_const) fprintf(h, "const ");
     if (t->type) {
+      if (t->sign > 0) fprintf(h, "signed ");
+      else if (t->sign < 0) fprintf(h, "unsigned ");
       switch (t->type) {
       case RPC_FC_BYTE:
-        fprintf(h, "byte");
+        if (t->ref) fprintf(h, t->ref->name);
+        else fprintf(h, "byte");
         break;
       case RPC_FC_CHAR:
-        fprintf(h, "char");
+        if (t->ref) fprintf(h, t->ref->name);
+        else fprintf(h, "char");
+        break;
+      case RPC_FC_WCHAR:
+        fprintf(h, "wchar_t");
         break;
       case RPC_FC_USHORT:
-        fprintf(h, "unsigned ");
       case RPC_FC_SHORT:
         if (t->ref) fprintf(h, t->ref->name);
-        fprintf(h, "short");
+        else fprintf(h, "short");
         break;
       case RPC_FC_ULONG:
-        fprintf(h, "unsigned ");
       case RPC_FC_LONG:
         if (t->ref) fprintf(h, t->ref->name);
         else fprintf(h, "long");
         break;
+      case RPC_FC_HYPER:
+        if (t->ref) fprintf(h, t->ref->name);
+        else fprintf(h, "__int64");
+        break;
+      case RPC_FC_FLOAT:
+        fprintf(h, "float");
+        break;
+      case RPC_FC_DOUBLE:
+        fprintf(h, "double");
+        break;
+      case RPC_FC_ENUM16:
+      case RPC_FC_ENUM32:
+        if (t->defined && !t->written) {
+          if (t->name) fprintf(h, "enum %s {\n", t->name);
+          else fprintf(h, "enum {\n");
+          indentation++;
+          write_enums(h, t->fields);
+          indent(-1);
+          fprintf(h, "}");
+        }
+        else fprintf(h, "enum %s", t->name);
+        break;
       case RPC_FC_STRUCT:
         if (t->defined && !t->written) {
           if (t->name) fprintf(h, "struct %s {\n", t->name);
@@ -126,6 +197,24 @@
         }
         else fprintf(h, "struct %s", t->name);
         break;
+      case RPC_FC_ENCAPSULATED_UNION:
+        if (t->defined && !t->written) {
+          var_t *d = t->fields;
+          if (t->name) fprintf(h, "struct %s {\n", t->name);
+          else fprintf(h, "struct {\n");
+          indentation++;
+          write_field(h, d);
+          indent(0);
+          fprintf(h, "union {\n");
+          indentation++;
+          write_fields(h, NEXT_LINK(d));
+          indent(-1);
+          fprintf(h, "} u;\n");
+          indent(-1);
+          fprintf(h, "}");
+        }
+        else fprintf(h, "struct %s", t->name);
+        break;
       case RPC_FC_NON_ENCAPSULATED_UNION:
         if (t->defined && !t->written) {
           if (t->name) fprintf(h, "union %s {\n", t->name);
@@ -163,16 +252,25 @@
   write_type(header, type, NULL, tname);
   fprintf(header, " ");
   while (names) {
-    write_pident(names);
+    write_pident(header, names);
     if (PREV_LINK(names))
       fprintf(header, ", ");
     names = PREV_LINK(names);
   }
-  fprintf(header, ";\n");
+  fprintf(header, ";\n\n");
 }
 
 /********** INTERFACES **********/
 
+UUID *get_uuid(attr_t *a)
+{
+  while (a) {
+    if (a->type == ATTR_UUID) return a->u.pval;
+    a = NEXT_LINK(a);
+  }
+  return NULL;
+}
+
 int is_object(attr_t *a)
 {
   while (a) {
@@ -362,12 +460,21 @@
 
 void write_forward(type_t *iface)
 {
-  if (!iface->written) {
+  if (is_object(iface->attrs) && !iface->written) {
     fprintf(header, "typedef struct %s %s;\n", iface->name, iface->name);
     iface->written = TRUE;
   }
 }
 
+void write_guid(type_t *iface)
+{
+  UUID *uuid = get_uuid(iface->attrs);
+  if (!uuid) return;
+  fprintf(header, "DEFINE_GUID(IID_%s, 0x%08lx, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x);\n",
+          iface->name, uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1],
+          uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7]);
+}
+
 void write_interface(type_t *iface)
 {
   if (!is_object(iface->attrs)) {
@@ -384,18 +491,19 @@
   fprintf(header, "/*****************************************************************************\n");
   fprintf(header, " * %s interface\n", iface->name);
   fprintf(header, " */\n");
+  write_guid(iface);
   write_forward(iface);
-  if (iface->ref)
-    fprintf(header, "#define ICOM_INTERFACE %s\n", iface->name);
+  fprintf(header, "#define ICOM_INTERFACE %s\n", iface->name);
   write_method_def(iface);
   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);
-  if (iface->ref) {
+  if (iface->ref)
     fprintf(header, "ICOM_DEFINE(%s,%s)\n", iface->name, iface->ref->name);
-    fprintf(header, "#undef ICOM_INTERFACE\n");
-  }
+  else
+    fprintf(header, "ICOM_DEFINE1(%s)\n", iface->name);
+  fprintf(header, "#undef ICOM_INTERFACE\n");
   fprintf(header, "\n");
   write_method_macro(iface, iface->name);
   fprintf(header, "\n");
Index: tools/widl/parser.l
===================================================================
RCS file: /home/wine/wine/tools/widl/parser.l,v
retrieving revision 1.3
diff -u -r1.3 parser.l
--- tools/widl/parser.l	25 Jul 2002 23:57:54 -0000	1.3
+++ tools/widl/parser.l	8 Nov 2002 15:45:41 -0000
@@ -71,6 +71,26 @@
 
 static void pop_import(void);
 
+static UUID* parse_uuid(const char*u)
+{
+  UUID* uuid = xmalloc(sizeof(UUID));
+  char b[3];
+  /* it would be nice to use UuidFromStringA */
+  uuid->Data1 = strtol(u, NULL, 16);
+  uuid->Data2 = strtol(u+9, NULL, 16);
+  uuid->Data3 = strtol(u+14, NULL, 16);
+  b[3] = 0;
+  memcpy(b, u+19, 2); uuid->Data4[0] = strtol(b, NULL, 16);
+  memcpy(b, u+21, 2); uuid->Data4[1] = strtol(b, NULL, 16);
+  memcpy(b, u+24, 2); uuid->Data4[2] = strtol(b, NULL, 16);
+  memcpy(b, u+26, 2); uuid->Data4[3] = strtol(b, NULL, 16);
+  memcpy(b, u+28, 2); uuid->Data4[4] = strtol(b, NULL, 16);
+  memcpy(b, u+30, 2); uuid->Data4[5] = strtol(b, NULL, 16);
+  memcpy(b, u+32, 2); uuid->Data4[6] = strtol(b, NULL, 16);
+  memcpy(b, u+34, 2); uuid->Data4[7] = strtol(b, NULL, 16);
+  return uuid;
+}
+
 %}
 
 /*
@@ -90,9 +110,15 @@
 <QUOTE>\\\"		addcchar(yytext[1]);
 <QUOTE>\\.		addcchar('\\'); addcchar(yytext[1]);
 <QUOTE>.		addcchar(yytext[0]);
-{uuid}			return aUUID;
-{hex}			return aNUM;
-{int}			return aNUM;
+{uuid}			{
+				yylval.uuid = parse_uuid(yytext);
+				return aUUID;
+			}
+{hex}			|
+{int}			{
+				yylval.num = strtol(yytext, NULL, 0);
+				return aNUM;
+			}
 {cident}		return kw_token(yytext);
 \n
 {ws}
Index: tools/widl/parser.y
===================================================================
RCS file: /home/wine/wine/tools/widl/parser.y,v
retrieving revision 1.2
diff -u -r1.2 parser.y
--- tools/widl/parser.y	13 Aug 2002 03:30:58 -0000	1.2
+++ tools/widl/parser.y	8 Nov 2002 15:45:41 -0000
@@ -64,11 +64,16 @@
 static attr_t *make_attr(enum attr_type type);
 static attr_t *make_attrv(enum attr_type type, DWORD val);
 static attr_t *make_attrp(enum attr_type type, void *val);
+static expr_t *make_expr(enum expr_type type);
+static expr_t *make_exprl(enum expr_type type, long val);
+static expr_t *make_exprs(enum expr_type type, char *val);
+static expr_t *make_expr1(enum expr_type type, expr_t *expr);
+static expr_t *make_expr2(enum expr_type type, expr_t *exp1, expr_t *exp2);
 static type_t *make_type(BYTE type, type_t *ref);
 static typeref_t *make_tref(char *name, type_t *ref);
 static typeref_t *uniq_tref(typeref_t *ref);
 static type_t *type_ref(typeref_t *ref);
-static void set_type(var_t *v, typeref_t *ref);
+static void set_type(var_t *v, typeref_t *ref, expr_t *arr);
 static var_t *make_var(char *name);
 static func_t *make_func(var_t *def, var_t *args);
 
@@ -83,16 +88,19 @@
 #define tsSTRUCT 2
 #define tsUNION  3
 
+static type_t std_bool = { "boolean" };
 static type_t std_int = { "int" };
 
 %}
 %union {
 	attr_t *attr;
+	expr_t *expr;
 	type_t *type;
 	typeref_t *tref;
 	var_t *var;
 	func_t *func;
 	char *str;
+	UUID *uuid;
 	int num;
 }
 
@@ -145,14 +153,15 @@
 %token tPOINTERTYPE
 
 %type <attr> m_attributes attributes attrib_list attribute
-%type <type> inherit interface interfacedef
+%type <expr> aexprs aexpr_list aexpr array
+%type <type> inherit interface interfacedef lib_statements
 %type <type> base_type int_std
 %type <type> enumdef structdef typedef uniondef
 %type <tref> type
 %type <var> m_args no_args args arg
-%type <var> fields field
+%type <var> fields field s_field cases case enums enum_list enum constdef
 %type <var> m_ident t_ident ident p_ident pident pident_list
-%type <func> funcdef statements
+%type <func> funcdef int_statements
 %type <num> expr pointer_type
 
 %left ','
@@ -167,22 +176,38 @@
 
 %%
 
-statements:					{ $$ = NULL; }
-	| statements funcdef ';'		{ LINK($2, $1); $$ = $2; }
-	| statements statement
+input:	  lib_statements			{ /* FIXME */ }
+	;
+
+lib_statements:					{ $$ = NULL; }
+	| lib_statements import
+	| lib_statements interface ';'
+	| 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
 	;
 
 statement: ';'					{}
 	| constdef				{}
 	| cppquote				{}
-	| enumdef ';'				{ if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n"); } }
+	| enumdef ';'				{ if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n\n"); } }
 	| externdef ';'				{}
-	| import				{}
-	| interface ';'				{}
-	| interfacedef				{}
-	| structdef ';'				{ if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n"); } }
+/*	| import				{} */
+/*	| interface ';'				{} */
+/*	| interfacedef				{} */
+	| structdef ';'				{ if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n\n"); } }
 	| typedef ';'				{}
-	| uniondef ';'				{ if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n"); } }
+	| uniondef ';'				{ if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n\n"); } }
 	;
 
 cppquote:	tCPPQUOTE '(' aSTRING ')'	{ if (!parse_only) fprintf(header, "%s\n", $3); }
@@ -204,40 +229,42 @@
 
 /* split into two rules to get bison to resolve a tVOID conflict */
 arg:	  attributes type pident array		{ $$ = $3;
-						  set_type($$, $2);
-						  $$->attrs = $1; /* FIXME: array */
+						  set_type($$, $2, $4);
+						  $$->attrs = $1;
 						}
 	| type pident array			{ $$ = $2;
-						  set_type($$, $1); /* FIXME: array */
+						  set_type($$, $1, $3);
 						}
 	;
 
-aexprs:
+aexprs:						{ $$ = make_expr(EXPR_VOID); }
 	| aexpr_list
 	;
 
 aexpr_list: aexpr
-	| aexprs ',' aexpr
+	| aexpr_list ',' aexpr			{ LINK($3, $1); $$ = $3; }
 	;
 
-aexpr:	  aNUM					{}
-	| aIDENTIFIER				{}
-	| aexpr '|' aexpr
-	| aexpr '&' aexpr
-	| aexpr '+' aexpr
-	| aexpr '-' aexpr
-	| aexpr '*' aexpr
-	| aexpr '/' aexpr
-	| '-' aexpr %prec NEG
-	| '*' aexpr %prec PPTR
-	| '(' type ')' aexpr %prec CAST
-	| '(' aexpr ')'
-	| tSIZEOF '(' type ')'
-	;
-
-array:
-	| '[' aexprs ']'
-	| '[' '*' ']'
+aexpr:	  aNUM					{ $$ = make_exprl(EXPR_NUM, $1); }
+	| aIDENTIFIER				{ $$ = make_exprs(EXPR_IDENTIFIER, $1); }
+	| aexpr '|' aexpr			{ $$ = make_expr2(EXPR_OR , $1, $3); }
+	| aexpr '&' aexpr			{ $$ = make_expr2(EXPR_AND, $1, $3); }
+	| aexpr '+' aexpr			{ $$ = make_expr2(EXPR_ADD, $1, $3); }
+	| aexpr '-' aexpr			{ $$ = make_expr2(EXPR_SUB, $1, $3); }
+	| aexpr '*' aexpr			{ $$ = make_expr2(EXPR_MUL, $1, $3); }
+	| aexpr '/' aexpr			{ $$ = make_expr2(EXPR_DIV, $1, $3); }
+	| aexpr SHL aexpr			{ $$ = make_expr2(EXPR_SHL, $1, $3); }
+	| aexpr SHR aexpr			{ $$ = make_expr2(EXPR_SHR, $1, $3); }
+	| '-' aexpr %prec NEG			{ $$ = make_expr1(EXPR_NEG, $2); }
+	| '*' aexpr %prec PPTR			{ $$ = make_expr1(EXPR_PPTR, $2); }
+	| '(' type ')' aexpr %prec CAST		{ $$ = $4; /* FIXME */ free($2); }
+	| '(' aexpr ')'				{ $$ = $2; }
+	| tSIZEOF '(' type ')'			{ $$ = make_exprl(EXPR_NUM, 0); /* FIXME */ free($3); warning("can't do sizeof() yet\n"); }
+	;
+
+array:						{ $$ = NULL; }
+	| '[' aexprs ']'			{ $$ = $2; }
+	| '[' '*' ']'				{ $$ = make_expr(EXPR_VOID); }
 	;
 
 m_attributes:					{ $$ = NULL; }
@@ -272,7 +299,7 @@
 	| tSTRING				{ $$ = make_attr(ATTR_STRING); }
 	| tSWITCHIS '(' aexpr ')'		{ $$ = NULL; }
 	| tSWITCHTYPE '(' type ')'		{ $$ = NULL; }
-	| tUUID '(' aUUID ')'			{ $$ = NULL; }
+	| tUUID '(' aUUID ')'			{ $$ = make_attrp(ATTR_UUID, $3); }
 	| tV1ENUM				{ $$ = make_attr(ATTR_V1ENUM); }
 	| tVERSION '(' version ')'		{ $$ = NULL; }
 	| tWIREMARSHAL '(' type ')'		{ $$ = make_attrp(ATTR_WIREMARSHAL, type_ref($3)); }
@@ -283,31 +310,39 @@
 	| tSTDCALL
 	;
 
-cases:
-	| cases case
+cases:						{ $$ = NULL; }
+	| cases case				{ LINK($2, $1); $$ = $2; }
 	;
 
-case:	  tCASE expr ':' field
-	| tDEFAULT ':' field
+case:	  tCASE expr ':' field			{ $$ = $4; }
+	| tDEFAULT ':' field			{ $$ = $3; }
 	;
 
-constdef: tCONST type ident '=' expr
+constdef: tCONST type ident '=' expr		{ $$ = $3;
+						  set_type($$, $2, NULL);
+						  $$->has_val = TRUE;
+						  $$->lval = $5;
+						}
 	;
 
-enums:
-	| enum_list ','
+enums:						{ $$ = NULL; }
+	| enum_list ','				{ $$ = $1; }
 	| enum_list
 	;
 
 enum_list: enum
-	| enum_list ',' enum
+	| enum_list ',' enum			{ LINK($3, $1); $$ = $3; }
 	;
 
-enum:	  ident '=' expr			{}
-	| ident					{}
+enum:	  ident '=' expr			{ $$ = $1;
+						  $$->has_val = TRUE;
+						  $$->lval = $3;
+						}
+	| ident					{ $$ = $1; }
 	;
 
-enumdef: tENUM t_ident '{' enums '}'		{ $$ = get_typev(RPC_FC_SHORT /* FIXME */, $2, tsENUM);
+enumdef: tENUM t_ident '{' enums '}'		{ $$ = get_typev(RPC_FC_ENUM16, $2, tsENUM);
+						  $$->fields = $4;
 						  $$->defined = TRUE;
 						}
 	;
@@ -317,11 +352,12 @@
 	;
 
 expr:	  aNUM
-	| aIDENTIFIER				{}
-	| expr '|' expr				{}
-	| expr SHL expr				{}
-	| expr SHR expr				{}
-	| '-' expr %prec NEG			{}
+	| aIDENTIFIER				{ $$ = 0; /* FIXME */ }
+	| expr '|' expr				{ $$ = $1 | $3; }
+	| expr '&' expr				{ $$ = $1 & $3; }
+	| expr SHL expr				{ $$ = $1 << $3; }
+	| expr SHR expr				{ $$ = $1 >> $3; }
+	| '-' expr %prec NEG			{ $$ = -$2; }
 	;
 
 externdef: tEXTERN tCONST type ident
@@ -331,15 +367,18 @@
 	| fields field				{ LINK($2, $1); $$ = $2; }
 	;
 
-field:	  m_attributes type pident array ';'	{ $$ = $3; set_type($$, $2); $$->attrs = $1; /* FIXME: array */ }
+field:	  s_field ';'				{ $$ = $1; }
 	| m_attributes uniondef ';'		{ $$ = make_var(NULL); $$->type = $2; $$->attrs = $1; }
 	| attributes ';'			{ $$ = make_var(NULL); $$->attrs = $1; }
 	| ';'					{ $$ = NULL; }
 	;
 
+s_field:  m_attributes type pident array	{ $$ = $3; set_type($$, $2, $4); $$->attrs = $1; }
+	;
+
 funcdef:
 	  m_attributes type callconv pident
-	  '(' m_args ')'			{ set_type($4, $2);
+	  '(' m_args ')'			{ set_type($4, $2, NULL);
 						  $4->attrs = $1;
 						  $$ = make_func($4, $6);
 						}
@@ -358,15 +397,20 @@
 	;
 
 base_type: tBYTE				{ $$ = make_type(RPC_FC_BYTE, NULL); }
-	| tCHAR					{ $$ = make_type(RPC_FC_CHAR, NULL); }
-	| tUNSIGNED tCHAR			{ $$ = make_type(RPC_FC_CHAR, NULL); }
 	| tWCHAR				{ $$ = make_type(RPC_FC_WCHAR, NULL); }
 	| int_std
-	| tSIGNED int_std			{ $$ = $2; /* FIXME */ }
-	| tUNSIGNED int_std			{ $$ = $2; /* FIXME */ }
+	| tSIGNED int_std			{ $$ = $2; $$->sign = 1; }
+	| tUNSIGNED int_std			{ $$ = $2; $$->sign = -1;
+						  switch ($$->type) {
+						  case RPC_FC_SMALL: $$->type = RPC_FC_USMALL; break;
+						  case RPC_FC_SHORT: $$->type = RPC_FC_USHORT; break;
+						  case RPC_FC_LONG:  $$->type = RPC_FC_ULONG;  break;
+						  default: break;
+						  }
+						}
 	| tFLOAT				{ $$ = make_type(RPC_FC_FLOAT, NULL); }
 	| tDOUBLE				{ $$ = make_type(RPC_FC_DOUBLE, NULL); }
-	| tBOOLEAN				{ $$ = make_type(RPC_FC_BYTE, NULL); /* ? */ }
+	| tBOOLEAN				{ $$ = make_type(RPC_FC_BYTE, &std_bool); /* ? */ }
 	;
 
 m_int:
@@ -378,6 +422,7 @@
 	| tLONG m_int				{ $$ = make_type(RPC_FC_LONG, NULL); }
 	| tHYPER m_int				{ $$ = make_type(RPC_FC_HYPER, NULL); }
 	| tINT64				{ $$ = make_type(RPC_FC_HYPER, NULL); }
+	| tCHAR					{ $$ = make_type(RPC_FC_CHAR, NULL); }
 	;
 
 inherit:					{ $$ = NULL; }
@@ -389,7 +434,7 @@
 	;
 
 interfacedef: attributes interface inherit
-	  '{' statements '}'			{ $$ = $2;
+	  '{' int_statements '}'		{ $$ = $2;
 						  if ($$->defined) yyerror("multiple definition error\n");
 						  $$->ref = $3;
 						  $$->attrs = $1;
@@ -400,7 +445,7 @@
 	;
 
 p_ident:  '*' pident %prec PPTR			{ $$ = $2; $$->ptr_level++; }
-	| tCONST p_ident			{ $$ = $2; }
+	| tCONST p_ident			{ $$ = $2; /* FIXME */ }
 	;
 
 pident:	  ident
@@ -451,8 +496,9 @@
 						  $$->defined = TRUE;
 						}
 	| tUNION t_ident
-	  tSWITCH '(' type ident ')'
+	  tSWITCH '(' s_field ')'
 	  m_ident '{' cases '}'			{ $$ = get_typev(RPC_FC_ENCAPSULATED_UNION, $2, tsUNION);
+						  LINK($5, $9); $$->fields = $5;
 						  $$->defined = TRUE;
 						}
 	;
@@ -469,6 +515,7 @@
   attr_t *a = xmalloc(sizeof(attr_t));
   a->type = type;
   a->u.ival = 0;
+  INIT_LINK(a);
   return a;
 }
 
@@ -477,6 +524,7 @@
   attr_t *a = xmalloc(sizeof(attr_t));
   a->type = type;
   a->u.ival = val;
+  INIT_LINK(a);
   return a;
 }
 
@@ -485,9 +533,111 @@
   attr_t *a = xmalloc(sizeof(attr_t));
   a->type = type;
   a->u.pval = val;
+  INIT_LINK(a);
   return a;
 }
 
+static expr_t *make_expr(enum expr_type type)
+{
+  expr_t *e = xmalloc(sizeof(expr_t));
+  e->type = type;
+  e->ref = NULL;
+  e->u.lval = 0;
+  INIT_LINK(e);
+  return e;
+}
+
+static expr_t *make_exprl(enum expr_type type, long val)
+{
+  expr_t *e = xmalloc(sizeof(expr_t));
+  e->type = type;
+  e->ref = NULL;
+  e->u.lval = val;
+  INIT_LINK(e);
+  return e;
+}
+
+static expr_t *make_exprs(enum expr_type type, char *val)
+{
+  expr_t *e = xmalloc(sizeof(expr_t));
+  /* FIXME: if type is EXPR_IDENTIFIER, we could check for match against const
+   * declaration, and change to appropriate type and value if so */
+  e->type = type;
+  e->ref = NULL;
+  e->u.sval = val;
+  INIT_LINK(e);
+  return e;
+}
+
+static expr_t *make_expr1(enum expr_type type, expr_t *expr)
+{
+  expr_t *e;
+  /* check for compile-time optimization */
+  if (expr->type == EXPR_NUM) {
+    switch (type) {
+    case EXPR_NEG:
+      expr->u.lval = -expr->u.lval;
+      return expr;
+    default:
+    }
+  }
+  e = xmalloc(sizeof(expr_t));
+  e->type = type;
+  e->ref = expr;
+  e->u.lval = 0;
+  INIT_LINK(e);
+  return e;
+}
+
+static expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2)
+{
+  expr_t *e;
+  /* check for compile-time optimization */
+  if (expr1->type == EXPR_NUM && expr2->type == EXPR_NUM) {
+    switch (type) {
+    case EXPR_ADD:
+      expr1->u.lval += expr2->u.lval;
+      free(expr2);
+      return expr1;
+    case EXPR_SUB:
+      expr1->u.lval -= expr2->u.lval;
+      free(expr2);
+      return expr1;
+    case EXPR_MUL:
+      expr1->u.lval *= expr2->u.lval;
+      free(expr2);
+      return expr1;
+    case EXPR_DIV:
+      expr1->u.lval /= expr2->u.lval;
+      free(expr2);
+      return expr1;
+    case EXPR_OR:
+      expr1->u.lval |= expr2->u.lval;
+      free(expr2);
+      return expr1;
+    case EXPR_AND:
+      expr1->u.lval &= expr2->u.lval;
+      free(expr2);
+      return expr1;
+    case EXPR_SHL:
+      expr1->u.lval <<= expr2->u.lval;
+      free(expr2);
+      return expr1;
+    case EXPR_SHR:
+      expr1->u.lval >>= expr2->u.lval;
+      free(expr2);
+      return expr1;
+    default:
+    }
+  }
+  e = xmalloc(sizeof(expr_t));
+  e->type = type;
+  e->ref = expr1;
+  e->u.ext = expr2;
+  INIT_LINK(e);
+  return e;
+}
+
 static type_t *make_type(BYTE type, type_t *ref)
 {
   type_t *t = xmalloc(sizeof(type_t));
@@ -500,6 +650,7 @@
   t->fields = NULL;
   t->ignore = parse_only;
   t->is_const = FALSE;
+  t->sign = 0;
   t->defined = FALSE;
   t->written = FALSE;
   INIT_LINK(t);
@@ -536,12 +687,13 @@
   return t;
 }
 
-static void set_type(var_t *v, typeref_t *ref)
+static void set_type(var_t *v, typeref_t *ref, expr_t *arr)
 {
   v->type = ref->ref;
   v->tname = ref->name;
   ref->name = NULL;
   free(ref);
+  v->array = arr;
 }
 
 static var_t *make_var(char *name)
@@ -552,6 +704,9 @@
   v->type = NULL;
   v->tname = NULL;
   v->attrs = NULL;
+  v->array = NULL;
+  v->has_val = FALSE;
+  v->lval = 0;
   INIT_LINK(v);
   return v;
 }
@@ -574,7 +729,7 @@
   struct rtype *next;
 };
 
-struct rtype *first;
+struct rtype *first_type;
 
 static type_t *reg_type(type_t *type, char *name, int t)
 {
@@ -587,8 +742,8 @@
   nt->name = name;
   nt->type = type;
   nt->t = t;
-  nt->next = first;
-  first = nt;
+  nt->next = first_type;
+  first_type = nt;
   return type;
 }
 
@@ -623,7 +778,7 @@
 
 static type_t *find_type(char *name, int t)
 {
-  struct rtype *cur = first;
+  struct rtype *cur = first_type;
   while (cur && (cur->t != t || strcmp(cur->name, name)))
     cur = cur->next;
   if (!cur) {
@@ -642,7 +797,7 @@
 
 int is_type(const char *name)
 {
-  struct rtype *cur = first;
+  struct rtype *cur = first_type;
   while (cur && (cur->t || strcmp(cur->name, name)))
     cur = cur->next;
   if (cur) return TRUE;
@@ -654,7 +809,7 @@
   struct rtype *cur = NULL;
   type_t *tp;
   if (name) {
-    cur = first;
+    cur = first_type;
     while (cur && (cur->t != t || strcmp(cur->name, name)))
       cur = cur->next;
   }
Index: tools/widl/proxy.c
===================================================================
RCS file: /home/wine/wine/tools/widl/proxy.c,v
retrieving revision 1.2
diff -u -r1.2 proxy.c
--- tools/widl/proxy.c	13 Aug 2002 03:30:58 -0000	1.2
+++ tools/widl/proxy.c	8 Nov 2002 15:45:42 -0000
@@ -300,12 +300,13 @@
 {
   if_list *lcur = if_first;
   if_list *cur;
+  char *file_id = "XXX";
   int c;
 
   if (!lcur) return;
   while (NEXT_LINK(lcur)) lcur = NEXT_LINK(lcur);
 
-  fprintf(proxy, "const CInterfaceProxyVtbl* _XXX_ProxyVtblList[] = {\n");
+  fprintf(proxy, "const CInterfaceProxyVtbl* _%s_ProxyVtblList[] = {\n", file_id);
   cur = lcur;
   while (cur) {
     fprintf(proxy, "    (CInterfaceProxyVtbl*)&%sProxyVtbl,\n", cur->iface->name);
@@ -315,7 +316,7 @@
   fprintf(proxy, "};\n");
   fprintf(proxy, "\n");
 
-  fprintf(proxy, "const CInterfaceStubVtbl* _XXX_StubVtblList[] = {\n");
+  fprintf(proxy, "const CInterfaceStubVtbl* _%s_StubVtblList[] = {\n", file_id);
   cur = lcur;
   while (cur) {
     fprintf(proxy, "    (CInterfaceStubVtbl*)&%sStubVtbl,\n", cur->iface->name);
@@ -325,7 +326,7 @@
   fprintf(proxy, "};\n");
   fprintf(proxy, "\n");
 
-  fprintf(proxy, "const PCInterfaceName _XXX_InterfaceNamesList[] = {\n");
+  fprintf(proxy, "const PCInterfaceName _%s_InterfaceNamesList[] = {\n", file_id);
   cur = lcur;
   while (cur) {
     fprintf(proxy, "    \"%s\",\n", cur->iface->name);
@@ -335,14 +336,14 @@
   fprintf(proxy, "};\n");
   fprintf(proxy, "\n");
 
-  fprintf(proxy, "#define _XXX_CHECK_IID(n) IID_GENERIC_CHECK_IID(_XXX, pIID, n)\n");
+  fprintf(proxy, "#define _%s_CHECK_IID(n) IID_GENERIC_CHECK_IID(_XXX, pIID, n)\n", file_id);
   fprintf(proxy, "\n");
-  fprintf(proxy, "int __stdcall _XXX_IID_Lookup(const IID* pIID, int* pIndex)\n");
+  fprintf(proxy, "int __stdcall _%s_IID_Lookup(const IID* pIID, int* pIndex)\n", file_id);
   fprintf(proxy, "{\n");
   cur = lcur;
   c = 0;
   while (cur) {
-    fprintf(proxy, "    if (!_XXX_CHECK_IID(%d)) {\n", c);
+    fprintf(proxy, "    if (!_%s_CHECK_IID(%d)) {\n", file_id, c);
     fprintf(proxy, "        *pIndex = %d\n", c);
     fprintf(proxy, "        return 1;\n");
     fprintf(proxy, "    }\n");
@@ -353,12 +354,12 @@
   fprintf(proxy, "}\n");
   fprintf(proxy, "\n");
 
-  fprintf(proxy, "const ExtendedProxyFileInfo XXX_ProxyFileInfo = {\n");
-  fprintf(proxy, "    (PCInterfaceProxyVtblList*)&_XXX_ProxyVtblList,\n");
-  fprintf(proxy, "    (PCInterfaceStubVtblList*)&_XXX_StubVtblList,\n");
-  fprintf(proxy, "    (const PCInterfaceName*)&_XXX_InterfaceNamesList,\n");
+  fprintf(proxy, "const ExtendedProxyFileInfo %s_ProxyFileInfo = {\n", file_id);
+  fprintf(proxy, "    (PCInterfaceProxyVtblList*)&_%s_ProxyVtblList,\n", file_id);
+  fprintf(proxy, "    (PCInterfaceStubVtblList*)&_%s_StubVtblList,\n", file_id);
+  fprintf(proxy, "    (const PCInterfaceName*)&_%s_InterfaceNamesList,\n", file_id);
   fprintf(proxy, "    0,\n");
-  fprintf(proxy, "    &_XXX_IID_Lookup,\n");
+  fprintf(proxy, "    &_%s_IID_Lookup,\n", file_id);
   fprintf(proxy, "    %d,\n", c);
   fprintf(proxy, "    1\n");
   fprintf(proxy, "};\n");
Index: tools/widl/widl.c
===================================================================
RCS file: /home/wine/wine/tools/widl/widl.c,v
retrieving revision 1.2
diff -u -r1.2 widl.c
--- tools/widl/widl.c	20 Jul 2002 19:00:52 -0000	1.2
+++ tools/widl/widl.c	8 Nov 2002 15:45:42 -0000
@@ -68,6 +68,7 @@
 
 char *input_name;
 char *header_name;
+char *header_token;
 char *proxy_name;
 char *temp_name;
 
@@ -83,6 +84,23 @@
 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;
@@ -173,20 +191,29 @@
 
     if(ret) exit(1);
     if(preprocess_only) exit(0);
-    input_name = temp_name;
+    if(!(yyin = fopen(temp_name, "r"))) {
+      fprintf(stderr, "Could not open %s for input\n", temp_name);
+      return 1;
+    }
   }
-
-  if(!(yyin = fopen(input_name, "r"))) {
-    fprintf(stderr, "Could not open %s for input\n", input_name);
-    return 1;
+  else {
+    if(!(yyin = fopen(input_name, "r"))) {
+      fprintf(stderr, "Could not open %s for input\n", input_name);
+      return 1;
+    }
   }
 
+  header_token = make_token(header_name);
+
   header = fopen(header_name, "w");
-  fprintf(header, "/*** Autogenerated by WIDL %s - Do not edit ***/\n", WIDL_FULLVERSION);
+  fprintf(header, "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", WIDL_FULLVERSION, input_name);
+  fprintf(header, "#ifndef __WIDL_%s\n", header_token);
+  fprintf(header, "#define __WIDL_%s\n", header_token);
 
   ret = yyparse();
 
   finish_proxy();
+  fprintf(header, "#endif /* __WIDL_%s */\n", header_token);
   fclose(header);
   fclose(yyin);
 
Index: tools/widl/widltypes.h
===================================================================
RCS file: /home/wine/wine/tools/widl/widltypes.h,v
retrieving revision 1.3
diff -u -r1.3 widltypes.h
--- tools/widl/widltypes.h	13 Aug 2002 03:30:58 -0000	1.3
+++ tools/widl/widltypes.h	8 Nov 2002 15:45:42 -0000
@@ -26,6 +26,7 @@
 #include "wine/rpcfc.h"
 
 typedef struct _attr_t attr_t;
+typedef struct _expr_t expr_t;
 typedef struct _type_t type_t;
 typedef struct _typeref_t typeref_t;
 typedef struct _var_t var_t;
@@ -57,10 +58,29 @@
     ATTR_POINTERDEFAULT,
     ATTR_POINTERTYPE,
     ATTR_STRING,
+    ATTR_UUID,
     ATTR_V1ENUM,
     ATTR_WIREMARSHAL,
 };
 
+enum expr_type
+{
+    EXPR_VOID,
+    EXPR_NUM,
+    EXPR_IDENTIFIER,
+    EXPR_NEG,
+    EXPR_PPTR,
+    EXPR_CAST,
+    EXPR_SHL,
+    EXPR_SHR,
+    EXPR_MUL,
+    EXPR_DIV,
+    EXPR_ADD,
+    EXPR_SUB,
+    EXPR_AND,
+    EXPR_OR,
+};
+
 struct _attr_t {
   enum attr_type type;
   union {
@@ -71,6 +91,18 @@
   DECL_LINK(attr_t)
 };
 
+struct _expr_t {
+  enum expr_type type;
+  expr_t *ref;
+  union {
+    long lval;
+    char *sval;
+    expr_t *ext;
+  } u;
+  /* parser-internal */
+  DECL_LINK(expr_t)
+};
+
 struct _type_t {
   char *name;
   BYTE type;
@@ -79,7 +111,7 @@
   attr_t *attrs;
   func_t *funcs;
   var_t *fields;
-  int ignore, is_const;
+  int ignore, is_const, sign;
   int defined, written;
 
   /* parser-internal */
@@ -95,9 +127,12 @@
 struct _var_t {
   char *name;
   int ptr_level;
+  expr_t *array;
   type_t *type;
   char *tname;
   attr_t *attrs;
+  int has_val;
+  long lval;
 
   /* parser-internal */
   DECL_LINK(var_t)




More information about the wine-patches mailing list