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}
......
......@@ -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