widl: Added support for namespaced enums.

This commit is contained in:
Jacek Caban 2015-08-07 15:41:55 +02:00 committed by Alexandre Julliard
parent a99bb3468a
commit 88987c0a95
6 changed files with 79 additions and 29 deletions

View file

@ -256,7 +256,7 @@ static void write_fields(FILE *h, var_list_t *fields)
}
}
static void write_enums(FILE *h, var_list_t *enums)
static void write_enums(FILE *h, var_list_t *enums, const char *enum_name)
{
var_t *v;
if (!enums) return;
@ -264,7 +264,10 @@ static void write_enums(FILE *h, var_list_t *enums)
{
if (v->name) {
indent(h, 0);
fprintf(h, "%s", get_name(v));
if(!enum_name)
fprintf(h, "%s", get_name(v));
else
fprintf(h, "%s_%s", enum_name, get_name(v));
if (v->eval) {
fprintf(h, " = ");
write_expr(h, v->eval, 0, 1, NULL, NULL, "");
@ -281,10 +284,14 @@ int needs_space_after(type_t *t)
(!is_ptr(t) && (!is_array(t) || !type_array_is_decl_as_ptr(t) || t->name)));
}
void write_type_left(FILE *h, type_t *t, int declonly)
void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
{
const char *name;
if (!h) return;
name = type_get_name(t, name_type);
if (is_attr(t->attrs, ATTR_CONST) &&
(type_is_alias(t) || !is_ptr(t)))
fprintf(h, "const ");
@ -294,15 +301,15 @@ void write_type_left(FILE *h, type_t *t, int declonly)
switch (type_get_type_detect_alias(t)) {
case TYPE_ENUM:
if (!declonly && t->defined && !t->written) {
if (t->name) fprintf(h, "enum %s {\n", t->name);
if (name) fprintf(h, "enum %s {\n", name);
else fprintf(h, "enum {\n");
t->written = TRUE;
indentation++;
write_enums(h, type_enum_get_values(t));
write_enums(h, type_enum_get_values(t), is_global_namespace(t->namespace) ? NULL : t->name);
indent(h, -1);
fprintf(h, "}");
}
else fprintf(h, "enum %s", t->name ? t->name : "");
else fprintf(h, "enum %s", name ? name : "");
break;
case TYPE_STRUCT:
case TYPE_ENCAPSULATED_UNION:
@ -333,7 +340,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
else fprintf(h, "union %s", t->name ? t->name : "");
break;
case TYPE_POINTER:
write_type_left(h, type_pointer_get_ref(t), declonly);
write_type_left(h, type_pointer_get_ref(t), name_type, declonly);
fprintf(h, "%s*", needs_space_after(type_pointer_get_ref(t)) ? " " : "");
if (is_attr(t->attrs, ATTR_CONST)) fprintf(h, "const ");
break;
@ -342,7 +349,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
fprintf(h, "%s", t->name);
else
{
write_type_left(h, type_array_get_element(t), declonly);
write_type_left(h, type_array_get_element(t), name_type, declonly);
if (type_array_is_decl_as_ptr(t))
fprintf(h, "%s*", needs_space_after(type_array_get_element(t)) ? " " : "");
}
@ -397,7 +404,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
fprintf(h, "void");
break;
case TYPE_BITFIELD:
write_type_left(h, type_bitfield_get_field(t), declonly);
write_type_left(h, type_bitfield_get_field(t), name_type, declonly);
break;
case TYPE_ALIAS:
case TYPE_FUNCTION:
@ -463,14 +470,14 @@ static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const c
const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
if (!callconv && is_object_interface) callconv = "STDMETHODCALLTYPE";
if (is_attr(pt->attrs, ATTR_INLINE)) fprintf(h, "inline ");
write_type_left(h, type_function_get_rettype(pt), declonly);
write_type_left(h, type_function_get_rettype(pt), NAME_DEFAULT, declonly);
fputc(' ', h);
if (ptr_level) fputc('(', h);
if (callconv) fprintf(h, "%s ", callconv);
for (i = 0; i < ptr_level; i++)
fputc('*', h);
} else
write_type_left(h, t, declonly);
write_type_left(h, t, NAME_DEFAULT, declonly);
}
if (name) fprintf(h, "%s%s", !t || needs_space_after(t) ? " " : "", name );
@ -496,6 +503,30 @@ static void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *na
write_type_v(f, t, field, FALSE, name);
}
static void write_type_definition(FILE *f, type_t *t)
{
int in_namespace = t->namespace && !is_global_namespace(t->namespace);
int save_written = t->written;
if(in_namespace) {
fprintf(f, "#ifdef __cplusplus\n");
fprintf(f, "} /* extern \"C\" */\n");
write_namespace_start(f, t->namespace);
}
indent(f, 0);
write_type_left(f, t, NAME_DEFAULT, FALSE);
fprintf(f, ";\n");
if(in_namespace) {
t->written = save_written;
write_namespace_end(f, t->namespace);
fprintf(f, "extern \"C\" {\n");
fprintf(f, "#else\n");
write_type_left(f, t, NAME_C, FALSE);
fprintf(f, ";\n");
fprintf(f, "#endif\n\n");
}
}
void write_type_decl(FILE *f, type_t *t, const char *name)
{
write_type_v(f, t, FALSE, TRUE, name);
@ -503,7 +534,7 @@ void write_type_decl(FILE *f, type_t *t, const char *name)
void write_type_decl_left(FILE *f, type_t *t)
{
write_type_left(f, t, TRUE);
write_type_left(f, t, NAME_DEFAULT, TRUE);
}
static int user_type_registered(const char *name)
@ -1539,8 +1570,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
write_coclass(header, stmt->u.type);
else
{
write_type_def_or_decl(header, stmt->u.type, FALSE, NULL);
fprintf(header, ";\n\n");
write_type_definition(header, stmt->u.type);
}
break;
case STMT_TYPEREF:

View file

@ -29,7 +29,7 @@ extern int is_attr(const attr_list_t *list, enum attr_type t);
extern void *get_attrp(const attr_list_t *list, enum attr_type t);
extern unsigned int get_attrv(const attr_list_t *list, enum attr_type t);
extern const char* get_name(const var_t *v);
extern void write_type_left(FILE *h, type_t *t, int declonly);
extern void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly);
extern void write_type_right(FILE *h, type_t *t, int is_field);
extern void write_type_decl(FILE *f, type_t *t, const char *name);
extern void write_type_decl_left(FILE *f, type_t *t);

View file

@ -378,7 +378,7 @@ statement:
typedecl:
enumdef
| tENUM aIDENTIFIER { $$ = type_new_enum($2, FALSE, NULL); }
| tENUM aIDENTIFIER { $$ = type_new_enum($2, current_namespace, FALSE, NULL); }
| structdef
| tSTRUCT aIDENTIFIER { $$ = type_new_struct($2, FALSE, NULL); }
| uniondef
@ -633,7 +633,7 @@ enum: ident '=' expr_int_const { $$ = reg_const($1);
}
;
enumdef: tENUM t_ident '{' enums '}' { $$ = type_new_enum($2, TRUE, $4); }
enumdef: tENUM t_ident '{' enums '}' { $$ = type_new_enum($2, current_namespace, TRUE, $4); }
;
m_exprs: m_expr { $$ = append_expr( NULL, $1 ); }
@ -1098,7 +1098,7 @@ type: tVOID { $$ = type_new_void(); }
| aKNOWNTYPE { $$ = find_type_or_error($1, 0); }
| base_type { $$ = $1; }
| enumdef { $$ = $1; }
| tENUM aIDENTIFIER { $$ = type_new_enum($2, FALSE, NULL); }
| tENUM aIDENTIFIER { $$ = type_new_enum($2, current_namespace, FALSE, NULL); }
| structdef { $$ = $1; }
| tSTRUCT aIDENTIFIER { $$ = type_new_struct($2, FALSE, NULL); }
| uniondef { $$ = $1; }
@ -1809,6 +1809,10 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
hash = hash_ident(name);
nt = xmalloc(sizeof(struct rtype));
nt->name = name;
if (is_global_namespace(namespace))
type->c_name = name;
else
type->c_name = format_namespace(namespace, "__x_", "_C", name);
nt->type = type;
nt->t = t;
nt->next = namespace->type_hash[hash];
@ -1983,10 +1987,6 @@ type_t *get_type(enum type_type type, char *name, struct namespace *namespace, i
tp = make_type(type);
tp->name = name;
tp->namespace = namespace;
if (is_global_namespace(namespace))
tp->c_name = name;
else
tp->c_name = format_namespace(namespace, "__x_", "_C", name);
if (!name) return tp;
return reg_type(tp, name, namespace, t);
}

View file

@ -4735,7 +4735,7 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
if (args) LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
{
print_file(file, 2, "%s", "");
write_type_left( file, (type_t *)arg->type, TRUE );
write_type_left( file, (type_t *)arg->type, NAME_DEFAULT, TRUE );
if (needs_space_after( arg->type )) fputc( ' ', file );
if (is_array( arg->type ) && !type_array_is_decl_as_ptr( arg->type )) fputc( '*', file );
@ -4800,9 +4800,9 @@ int write_expr_eval_routines(FILE *file, const char *iface)
else
{
print_file(file, 1, "%s", "");
write_type_left(file, (type_t *)eval->cont_type, TRUE);
write_type_left(file, (type_t *)eval->cont_type, NAME_DEFAULT, TRUE);
fprintf(file, " *%s = (", var_name);
write_type_left(file, (type_t *)eval->cont_type, TRUE);
write_type_left(file, (type_t *)eval->cont_type, NAME_DEFAULT, TRUE);
fprintf(file, " *)(pStubMsg->StackTop - %u);\n", eval->baseoff);
}
print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */

View file

@ -78,6 +78,19 @@ static const var_t *find_arg(const var_list_t *args, const char *name)
return NULL;
}
const char *type_get_name(const type_t *type, enum name_type name_type)
{
switch(name_type) {
case NAME_DEFAULT:
return type->name;
case NAME_C:
return type->c_name;
}
assert(0);
return NULL;
}
static char *append_namespace(char *ptr, struct namespace *namespace, const char *separator)
{
if(is_global_namespace(namespace)) {
@ -258,11 +271,12 @@ type_t *type_new_void(void)
return void_type;
}
type_t *type_new_enum(const char *name, int defined, var_list_t *enums)
type_t *type_new_enum(const char *name, struct namespace *namespace, int defined, var_list_t *enums)
{
type_t *tag_type = name ? find_type(name, NULL, tsENUM) : NULL;
type_t *tag_type = name ? find_type(name, namespace, tsENUM) : NULL;
type_t *t = make_type(TYPE_ENUM);
t->name = name;
t->namespace = namespace;
if (tag_type && tag_type->details.enumeration)
t->details.enumeration = tag_type->details.enumeration;
@ -276,7 +290,7 @@ type_t *type_new_enum(const char *name, int defined, var_list_t *enums)
if (name)
{
if (defined)
reg_type(t, name, NULL, tsENUM);
reg_type(t, name, namespace, tsENUM);
else
add_incomplete(t);
}

View file

@ -24,6 +24,11 @@
#ifndef WIDL_TYPE_TREE_H
#define WIDL_TYPE_TREE_H
enum name_type {
NAME_DEFAULT,
NAME_C
};
type_t *type_new_function(var_list_t *args);
type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs);
type_t *type_new_alias(type_t *t, const char *name);
@ -35,7 +40,7 @@ type_t *type_new_basic(enum type_basic_type basic_type);
type_t *type_new_int(enum type_basic_type basic_type, int sign);
type_t *type_new_void(void);
type_t *type_new_coclass(char *name);
type_t *type_new_enum(const char *name, int defined, var_list_t *enums);
type_t *type_new_enum(const char *name, struct namespace *namespace, int defined, var_list_t *enums);
type_t *type_new_struct(char *name, int defined, var_list_t *fields);
type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields);
type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases);
@ -46,6 +51,7 @@ void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface);
void type_module_define(type_t *module, statement_list_t *stmts);
type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces);
int type_is_equal(const type_t *type1, const type_t *type2);
const char *type_get_name(const type_t *type, enum name_type name_type);
/* FIXME: shouldn't need to export this */
type_t *duptype(type_t *t, int dupname);