Commit 03c7d468 authored by Ove Kaaven's avatar Ove Kaaven Committed by Alexandre Julliard

Support for enums, arrays, encapsulated unions, signed/unsigned

qualifiers, UUIDs, include guards, the new ICOM_DEFINE1 macro, and some other improvements.
parent dec35a35
......@@ -53,13 +53,13 @@ int is_void(type_t *t, var_t *v)
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)
......@@ -72,22 +72,66 @@ char* get_name(var_t *v)
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)
......@@ -98,25 +142,52 @@ void write_type(FILE *h, type_t *t, var_t *v, char *n)
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);
......@@ -128,6 +199,24 @@ void write_type(FILE *h, type_t *t, var_t *v, char *n)
}
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);
......@@ -165,16 +254,25 @@ void write_typedef(type_t *type, var_t *names)
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) {
......@@ -364,12 +462,21 @@ static void write_method_proto(type_t *iface)
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)) {
......@@ -386,18 +493,19 @@ void write_interface(type_t *iface)
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");
......
......@@ -75,6 +75,26 @@ int import_stack_ptr = 0;
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;
}
%}
/*
......@@ -94,9 +114,15 @@ static void pop_import(void);
<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}
......
......@@ -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 @@ static type_t *get_typev(BYTE type, var_t *name, int t);
#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 @@ static type_t std_int = { "int" };
%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 @@ static type_t std_int = { "int" };
%%
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 @@ args: arg
/* 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 ')'
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:
| '[' aexprs ']'
| '[' '*' ']'
array: { $$ = NULL; }
| '[' aexprs ']' { $$ = $2; }
| '[' '*' ']' { $$ = make_expr(EXPR_VOID); }
;
m_attributes: { $$ = NULL; }
......@@ -272,7 +299,7 @@ attribute:
| 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 @@ callconv:
| 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_list: expr {}
;
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: { $$ = NULL; }
| 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 @@ ident: aIDENTIFIER { $$ = make_var($1); }
;
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 @@ int_std: tINT { $$ = make_type(RPC_FC_LONG, &std_int); } /* win32 only */
| 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 @@ interface: tINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); if (!parse
;
interfacedef: attributes interface inherit
'{' statements '}' { $$ = $2;
'{' int_statements '}' { $$ = $2;
if ($$->defined) yyerror("multiple definition error\n");
$$->ref = $3;
$$->attrs = $1;
......@@ -400,7 +445,7 @@ interfacedef: attributes interface inherit
;
p_ident: '*' pident %prec PPTR { $$ = $2; $$->ptr_level++; }
| tCONST p_ident { $$ = $2; }
| tCONST p_ident { $$ = $2; /* FIXME */ }
;
pident: ident
......@@ -451,8 +496,9 @@ uniondef: tUNION t_ident '{' fields '}' { $$ = get_typev(RPC_FC_NON_ENCAPSULATE
$$->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 @@ static attr_t *make_attr(enum attr_type type)
attr_t *a = xmalloc(sizeof(attr_t));
a->type = type;
a->u.ival = 0;
INIT_LINK(a);
return a;
}
......@@ -477,6 +524,7 @@ static attr_t *make_attrv(enum attr_type type, DWORD val)
attr_t *a = xmalloc(sizeof(attr_t));
a->type = type;
a->u.ival = val;
INIT_LINK(a);
return a;
}
......@@ -485,9 +533,111 @@ static attr_t *make_attrp(enum attr_type type, void *val)
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 @@ static type_t *make_type(BYTE type, type_t *ref)
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 @@ static type_t *type_ref(typeref_t *ref)
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 @@ static var_t *make_var(char *name)
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 {
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 @@ static type_t *reg_type(type_t *type, char *name, int t)
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 *reg_types(type_t *type, var_t *names, int t)
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 @@ static type_t *find_type2(char *name, int t)
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 @@ static type_t *get_type(BYTE type, char *name, int t)
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;
}
......
......@@ -302,12 +302,13 @@ void finish_proxy(void)
{
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);
......@@ -317,7 +318,7 @@ void finish_proxy(void)
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);
......@@ -327,7 +328,7 @@ void finish_proxy(void)
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);
......@@ -337,14 +338,14 @@ void finish_proxy(void)
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");
......@@ -355,12 +356,12 @@ void finish_proxy(void)
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");
......
......@@ -70,6 +70,7 @@ int no_preprocess = 0;
char *input_name;
char *header_name;
char *header_token;
char *proxy_name;
char *temp_name;
......@@ -85,6 +86,23 @@ int getopt (int argc, char *const *argv, const char *optstring);
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;
......@@ -175,20 +193,29 @@ int main(int argc,char *argv[])
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);
......
......@@ -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 @@ enum attr_type
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 @@ struct _attr_t {
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 @@ struct _type_t {
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 _typeref_t {
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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment