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) ...@@ -53,13 +53,13 @@ int is_void(type_t *t, var_t *v)
return 0; return 0;
} }
static void write_pident(var_t *v) static void write_pident(FILE *h, var_t *v)
{ {
int c; int c;
for (c=0; c<v->ptr_level; 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) void write_name(FILE *h, var_t *v)
...@@ -72,22 +72,66 @@ char* get_name(var_t *v) ...@@ -72,22 +72,66 @@ char* get_name(var_t *v)
return v->name; 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) 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; if (!v) return;
while (NEXT_LINK(v)) v = NEXT_LINK(v); while (NEXT_LINK(v)) v = NEXT_LINK(v);
while (v) { while (v) {
if (v->type) { if (get_name(v)) {
indent(0); indent(0);
write_type(h, v->type, NULL, v->tname); write_name(h, v);
if (get_name(v)) { if (v->has_val)
fprintf(header, " "); fprintf(h, " = %ld", v->lval);
write_pident(v);
}
fprintf(header, ";\n");
} }
if (PREV_LINK(v))
fprintf(h, ",\n");
v = PREV_LINK(v); v = PREV_LINK(v);
} }
fprintf(h, "\n");
} }
void write_type(FILE *h, type_t *t, var_t *v, char *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) ...@@ -98,25 +142,52 @@ void write_type(FILE *h, type_t *t, var_t *v, char *n)
else { else {
if (t->is_const) fprintf(h, "const "); if (t->is_const) fprintf(h, "const ");
if (t->type) { if (t->type) {
if (t->sign > 0) fprintf(h, "signed ");
else if (t->sign < 0) fprintf(h, "unsigned ");
switch (t->type) { switch (t->type) {
case RPC_FC_BYTE: case RPC_FC_BYTE:
fprintf(h, "byte"); if (t->ref) fprintf(h, t->ref->name);
else fprintf(h, "byte");
break; break;
case RPC_FC_CHAR: 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; break;
case RPC_FC_USHORT: case RPC_FC_USHORT:
fprintf(h, "unsigned ");
case RPC_FC_SHORT: case RPC_FC_SHORT:
if (t->ref) fprintf(h, t->ref->name); if (t->ref) fprintf(h, t->ref->name);
fprintf(h, "short"); else fprintf(h, "short");
break; break;
case RPC_FC_ULONG: case RPC_FC_ULONG:
fprintf(h, "unsigned ");
case RPC_FC_LONG: case RPC_FC_LONG:
if (t->ref) fprintf(h, t->ref->name); if (t->ref) fprintf(h, t->ref->name);
else fprintf(h, "long"); else fprintf(h, "long");
break; 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: case RPC_FC_STRUCT:
if (t->defined && !t->written) { if (t->defined && !t->written) {
if (t->name) fprintf(h, "struct %s {\n", t->name); 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) ...@@ -128,6 +199,24 @@ void write_type(FILE *h, type_t *t, var_t *v, char *n)
} }
else fprintf(h, "struct %s", t->name); else fprintf(h, "struct %s", t->name);
break; 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: case RPC_FC_NON_ENCAPSULATED_UNION:
if (t->defined && !t->written) { if (t->defined && !t->written) {
if (t->name) fprintf(h, "union %s {\n", t->name); if (t->name) fprintf(h, "union %s {\n", t->name);
...@@ -165,16 +254,25 @@ void write_typedef(type_t *type, var_t *names) ...@@ -165,16 +254,25 @@ void write_typedef(type_t *type, var_t *names)
write_type(header, type, NULL, tname); write_type(header, type, NULL, tname);
fprintf(header, " "); fprintf(header, " ");
while (names) { while (names) {
write_pident(names); write_pident(header, names);
if (PREV_LINK(names)) if (PREV_LINK(names))
fprintf(header, ", "); fprintf(header, ", ");
names = PREV_LINK(names); names = PREV_LINK(names);
} }
fprintf(header, ";\n"); fprintf(header, ";\n\n");
} }
/********** INTERFACES **********/ /********** 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) int is_object(attr_t *a)
{ {
while (a) { while (a) {
...@@ -364,12 +462,21 @@ static void write_method_proto(type_t *iface) ...@@ -364,12 +462,21 @@ static void write_method_proto(type_t *iface)
void write_forward(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); fprintf(header, "typedef struct %s %s;\n", iface->name, iface->name);
iface->written = TRUE; 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) void write_interface(type_t *iface)
{ {
if (!is_object(iface->attrs)) { if (!is_object(iface->attrs)) {
...@@ -386,18 +493,19 @@ void write_interface(type_t *iface) ...@@ -386,18 +493,19 @@ void write_interface(type_t *iface)
fprintf(header, "/*****************************************************************************\n"); fprintf(header, "/*****************************************************************************\n");
fprintf(header, " * %s interface\n", iface->name); fprintf(header, " * %s interface\n", iface->name);
fprintf(header, " */\n"); fprintf(header, " */\n");
write_guid(iface);
write_forward(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); write_method_def(iface);
fprintf(header, "#define %s_IMETHODS \\\n", iface->name); fprintf(header, "#define %s_IMETHODS \\\n", iface->name);
if (iface->ref) if (iface->ref)
fprintf(header, " %s_IMETHODS \\\n", iface->ref->name); 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) { if (iface->ref)
fprintf(header, "ICOM_DEFINE(%s,%s)\n", iface->name, iface->ref->name); 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"); fprintf(header, "\n");
write_method_macro(iface, iface->name); write_method_macro(iface, iface->name);
fprintf(header, "\n"); fprintf(header, "\n");
......
...@@ -75,6 +75,26 @@ int import_stack_ptr = 0; ...@@ -75,6 +75,26 @@ int import_stack_ptr = 0;
static void pop_import(void); 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); ...@@ -94,9 +114,15 @@ static void pop_import(void);
<QUOTE>\\\" addcchar(yytext[1]); <QUOTE>\\\" addcchar(yytext[1]);
<QUOTE>\\. addcchar('\\'); addcchar(yytext[1]); <QUOTE>\\. addcchar('\\'); addcchar(yytext[1]);
<QUOTE>. addcchar(yytext[0]); <QUOTE>. addcchar(yytext[0]);
{uuid} return aUUID; {uuid} {
{hex} return aNUM; yylval.uuid = parse_uuid(yytext);
{int} return aNUM; return aUUID;
}
{hex} |
{int} {
yylval.num = strtol(yytext, NULL, 0);
return aNUM;
}
{cident} return kw_token(yytext); {cident} return kw_token(yytext);
\n \n
{ws} {ws}
......
...@@ -302,12 +302,13 @@ void finish_proxy(void) ...@@ -302,12 +302,13 @@ void finish_proxy(void)
{ {
if_list *lcur = if_first; if_list *lcur = if_first;
if_list *cur; if_list *cur;
char *file_id = "XXX";
int c; int c;
if (!lcur) return; if (!lcur) return;
while (NEXT_LINK(lcur)) lcur = NEXT_LINK(lcur); 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; cur = lcur;
while (cur) { while (cur) {
fprintf(proxy, " (CInterfaceProxyVtbl*)&%sProxyVtbl,\n", cur->iface->name); fprintf(proxy, " (CInterfaceProxyVtbl*)&%sProxyVtbl,\n", cur->iface->name);
...@@ -317,7 +318,7 @@ void finish_proxy(void) ...@@ -317,7 +318,7 @@ void finish_proxy(void)
fprintf(proxy, "};\n"); fprintf(proxy, "};\n");
fprintf(proxy, "\n"); fprintf(proxy, "\n");
fprintf(proxy, "const CInterfaceStubVtbl* _XXX_StubVtblList[] = {\n"); fprintf(proxy, "const CInterfaceStubVtbl* _%s_StubVtblList[] = {\n", file_id);
cur = lcur; cur = lcur;
while (cur) { while (cur) {
fprintf(proxy, " (CInterfaceStubVtbl*)&%sStubVtbl,\n", cur->iface->name); fprintf(proxy, " (CInterfaceStubVtbl*)&%sStubVtbl,\n", cur->iface->name);
...@@ -327,7 +328,7 @@ void finish_proxy(void) ...@@ -327,7 +328,7 @@ void finish_proxy(void)
fprintf(proxy, "};\n"); fprintf(proxy, "};\n");
fprintf(proxy, "\n"); fprintf(proxy, "\n");
fprintf(proxy, "const PCInterfaceName _XXX_InterfaceNamesList[] = {\n"); fprintf(proxy, "const PCInterfaceName _%s_InterfaceNamesList[] = {\n", file_id);
cur = lcur; cur = lcur;
while (cur) { while (cur) {
fprintf(proxy, " \"%s\",\n", cur->iface->name); fprintf(proxy, " \"%s\",\n", cur->iface->name);
...@@ -337,14 +338,14 @@ void finish_proxy(void) ...@@ -337,14 +338,14 @@ void finish_proxy(void)
fprintf(proxy, "};\n"); fprintf(proxy, "};\n");
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, "\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"); fprintf(proxy, "{\n");
cur = lcur; cur = lcur;
c = 0; c = 0;
while (cur) { 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, " *pIndex = %d\n", c);
fprintf(proxy, " return 1;\n"); fprintf(proxy, " return 1;\n");
fprintf(proxy, " }\n"); fprintf(proxy, " }\n");
...@@ -355,12 +356,12 @@ void finish_proxy(void) ...@@ -355,12 +356,12 @@ void finish_proxy(void)
fprintf(proxy, "}\n"); fprintf(proxy, "}\n");
fprintf(proxy, "\n"); fprintf(proxy, "\n");
fprintf(proxy, "const ExtendedProxyFileInfo XXX_ProxyFileInfo = {\n"); fprintf(proxy, "const ExtendedProxyFileInfo %s_ProxyFileInfo = {\n", file_id);
fprintf(proxy, " (PCInterfaceProxyVtblList*)&_XXX_ProxyVtblList,\n"); fprintf(proxy, " (PCInterfaceProxyVtblList*)&_%s_ProxyVtblList,\n", file_id);
fprintf(proxy, " (PCInterfaceStubVtblList*)&_XXX_StubVtblList,\n"); fprintf(proxy, " (PCInterfaceStubVtblList*)&_%s_StubVtblList,\n", file_id);
fprintf(proxy, " (const PCInterfaceName*)&_XXX_InterfaceNamesList,\n"); fprintf(proxy, " (const PCInterfaceName*)&_%s_InterfaceNamesList,\n", file_id);
fprintf(proxy, " 0,\n"); 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, " %d,\n", c);
fprintf(proxy, " 1\n"); fprintf(proxy, " 1\n");
fprintf(proxy, "};\n"); fprintf(proxy, "};\n");
......
...@@ -70,6 +70,7 @@ int no_preprocess = 0; ...@@ -70,6 +70,7 @@ int no_preprocess = 0;
char *input_name; char *input_name;
char *header_name; char *header_name;
char *header_token;
char *proxy_name; char *proxy_name;
char *temp_name; char *temp_name;
...@@ -85,6 +86,23 @@ int getopt (int argc, char *const *argv, const char *optstring); ...@@ -85,6 +86,23 @@ int getopt (int argc, char *const *argv, const char *optstring);
static void rm_tempfile(void); static void rm_tempfile(void);
static void segvhandler(int sig); 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[]) int main(int argc,char *argv[])
{ {
extern char* optarg; extern char* optarg;
...@@ -175,20 +193,29 @@ int main(int argc,char *argv[]) ...@@ -175,20 +193,29 @@ int main(int argc,char *argv[])
if(ret) exit(1); if(ret) exit(1);
if(preprocess_only) exit(0); 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;
}
} }
else {
if(!(yyin = fopen(input_name, "r"))) { if(!(yyin = fopen(input_name, "r"))) {
fprintf(stderr, "Could not open %s for input\n", input_name); fprintf(stderr, "Could not open %s for input\n", input_name);
return 1; return 1;
}
} }
header_token = make_token(header_name);
header = fopen(header_name, "w"); 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(); ret = yyparse();
finish_proxy(); finish_proxy();
fprintf(header, "#endif /* __WIDL_%s */\n", header_token);
fclose(header); fclose(header);
fclose(yyin); fclose(yyin);
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "wine/rpcfc.h" #include "wine/rpcfc.h"
typedef struct _attr_t attr_t; typedef struct _attr_t attr_t;
typedef struct _expr_t expr_t;
typedef struct _type_t type_t; typedef struct _type_t type_t;
typedef struct _typeref_t typeref_t; typedef struct _typeref_t typeref_t;
typedef struct _var_t var_t; typedef struct _var_t var_t;
...@@ -57,10 +58,29 @@ enum attr_type ...@@ -57,10 +58,29 @@ enum attr_type
ATTR_POINTERDEFAULT, ATTR_POINTERDEFAULT,
ATTR_POINTERTYPE, ATTR_POINTERTYPE,
ATTR_STRING, ATTR_STRING,
ATTR_UUID,
ATTR_V1ENUM, ATTR_V1ENUM,
ATTR_WIREMARSHAL, 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 { struct _attr_t {
enum attr_type type; enum attr_type type;
union { union {
...@@ -71,6 +91,18 @@ struct _attr_t { ...@@ -71,6 +91,18 @@ struct _attr_t {
DECL_LINK(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 { struct _type_t {
char *name; char *name;
BYTE type; BYTE type;
...@@ -79,7 +111,7 @@ struct _type_t { ...@@ -79,7 +111,7 @@ struct _type_t {
attr_t *attrs; attr_t *attrs;
func_t *funcs; func_t *funcs;
var_t *fields; var_t *fields;
int ignore, is_const; int ignore, is_const, sign;
int defined, written; int defined, written;
/* parser-internal */ /* parser-internal */
...@@ -95,9 +127,12 @@ struct _typeref_t { ...@@ -95,9 +127,12 @@ struct _typeref_t {
struct _var_t { struct _var_t {
char *name; char *name;
int ptr_level; int ptr_level;
expr_t *array;
type_t *type; type_t *type;
char *tname; char *tname;
attr_t *attrs; attr_t *attrs;
int has_val;
long lval;
/* parser-internal */ /* parser-internal */
DECL_LINK(var_t) 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