widl patch again
Ove Kaaven
ovehk at ping.uio.no
Fri Nov 8 11:23:00 CST 2002
I seem to have sent a newer patch than the log I used (and there was a bug
in the patch too), let's try again
Log:
Ove Kaaven <ovek at transgaming.com>
Support for enums, arrays, encapsulated unions, signed/unsigned
qualifiers, UUIDs, include guards, the new ICOM_DEFINE1 macro, 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[2] = 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