Commit 88987c0a authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

widl: Added support for namespaced enums.

parent a99bb346
...@@ -256,7 +256,7 @@ static void write_fields(FILE *h, var_list_t *fields) ...@@ -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; var_t *v;
if (!enums) return; if (!enums) return;
...@@ -264,7 +264,10 @@ static void write_enums(FILE *h, var_list_t *enums) ...@@ -264,7 +264,10 @@ static void write_enums(FILE *h, var_list_t *enums)
{ {
if (v->name) { if (v->name) {
indent(h, 0); 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) { if (v->eval) {
fprintf(h, " = "); fprintf(h, " = ");
write_expr(h, v->eval, 0, 1, NULL, NULL, ""); write_expr(h, v->eval, 0, 1, NULL, NULL, "");
...@@ -281,10 +284,14 @@ int needs_space_after(type_t *t) ...@@ -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))); (!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; if (!h) return;
name = type_get_name(t, name_type);
if (is_attr(t->attrs, ATTR_CONST) && if (is_attr(t->attrs, ATTR_CONST) &&
(type_is_alias(t) || !is_ptr(t))) (type_is_alias(t) || !is_ptr(t)))
fprintf(h, "const "); fprintf(h, "const ");
...@@ -294,15 +301,15 @@ void write_type_left(FILE *h, type_t *t, int declonly) ...@@ -294,15 +301,15 @@ void write_type_left(FILE *h, type_t *t, int declonly)
switch (type_get_type_detect_alias(t)) { switch (type_get_type_detect_alias(t)) {
case TYPE_ENUM: case TYPE_ENUM:
if (!declonly && t->defined && !t->written) { 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"); else fprintf(h, "enum {\n");
t->written = TRUE; t->written = TRUE;
indentation++; 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); indent(h, -1);
fprintf(h, "}"); fprintf(h, "}");
} }
else fprintf(h, "enum %s", t->name ? t->name : ""); else fprintf(h, "enum %s", name ? name : "");
break; break;
case TYPE_STRUCT: case TYPE_STRUCT:
case TYPE_ENCAPSULATED_UNION: case TYPE_ENCAPSULATED_UNION:
...@@ -333,7 +340,7 @@ void write_type_left(FILE *h, type_t *t, int declonly) ...@@ -333,7 +340,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
else fprintf(h, "union %s", t->name ? t->name : ""); else fprintf(h, "union %s", t->name ? t->name : "");
break; break;
case TYPE_POINTER: 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)) ? " " : ""); fprintf(h, "%s*", needs_space_after(type_pointer_get_ref(t)) ? " " : "");
if (is_attr(t->attrs, ATTR_CONST)) fprintf(h, "const "); if (is_attr(t->attrs, ATTR_CONST)) fprintf(h, "const ");
break; break;
...@@ -342,7 +349,7 @@ void write_type_left(FILE *h, type_t *t, int declonly) ...@@ -342,7 +349,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
fprintf(h, "%s", t->name); fprintf(h, "%s", t->name);
else 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)) if (type_array_is_decl_as_ptr(t))
fprintf(h, "%s*", needs_space_after(type_array_get_element(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) ...@@ -397,7 +404,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
fprintf(h, "void"); fprintf(h, "void");
break; break;
case TYPE_BITFIELD: 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; break;
case TYPE_ALIAS: case TYPE_ALIAS:
case TYPE_FUNCTION: case TYPE_FUNCTION:
...@@ -463,14 +470,14 @@ static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const c ...@@ -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); const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
if (!callconv && is_object_interface) callconv = "STDMETHODCALLTYPE"; if (!callconv && is_object_interface) callconv = "STDMETHODCALLTYPE";
if (is_attr(pt->attrs, ATTR_INLINE)) fprintf(h, "inline "); 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); fputc(' ', h);
if (ptr_level) fputc('(', h); if (ptr_level) fputc('(', h);
if (callconv) fprintf(h, "%s ", callconv); if (callconv) fprintf(h, "%s ", callconv);
for (i = 0; i < ptr_level; i++) for (i = 0; i < ptr_level; i++)
fputc('*', h); fputc('*', h);
} else } 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 ); 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 ...@@ -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); 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) void write_type_decl(FILE *f, type_t *t, const char *name)
{ {
write_type_v(f, t, FALSE, TRUE, 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) ...@@ -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) 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) 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 ...@@ -1539,8 +1570,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
write_coclass(header, stmt->u.type); write_coclass(header, stmt->u.type);
else else
{ {
write_type_def_or_decl(header, stmt->u.type, FALSE, NULL); write_type_definition(header, stmt->u.type);
fprintf(header, ";\n\n");
} }
break; break;
case STMT_TYPEREF: case STMT_TYPEREF:
......
...@@ -29,7 +29,7 @@ extern int is_attr(const attr_list_t *list, enum attr_type t); ...@@ -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 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 unsigned int get_attrv(const attr_list_t *list, enum attr_type t);
extern const char* get_name(const var_t *v); 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_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(FILE *f, type_t *t, const char *name);
extern void write_type_decl_left(FILE *f, type_t *t); extern void write_type_decl_left(FILE *f, type_t *t);
......
...@@ -378,7 +378,7 @@ statement: ...@@ -378,7 +378,7 @@ statement:
typedecl: typedecl:
enumdef enumdef
| tENUM aIDENTIFIER { $$ = type_new_enum($2, FALSE, NULL); } | tENUM aIDENTIFIER { $$ = type_new_enum($2, current_namespace, FALSE, NULL); }
| structdef | structdef
| tSTRUCT aIDENTIFIER { $$ = type_new_struct($2, FALSE, NULL); } | tSTRUCT aIDENTIFIER { $$ = type_new_struct($2, FALSE, NULL); }
| uniondef | uniondef
...@@ -633,7 +633,7 @@ enum: ident '=' expr_int_const { $$ = reg_const($1); ...@@ -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 ); } m_exprs: m_expr { $$ = append_expr( NULL, $1 ); }
...@@ -1098,7 +1098,7 @@ type: tVOID { $$ = type_new_void(); } ...@@ -1098,7 +1098,7 @@ type: tVOID { $$ = type_new_void(); }
| aKNOWNTYPE { $$ = find_type_or_error($1, 0); } | aKNOWNTYPE { $$ = find_type_or_error($1, 0); }
| base_type { $$ = $1; } | base_type { $$ = $1; }
| enumdef { $$ = $1; } | enumdef { $$ = $1; }
| tENUM aIDENTIFIER { $$ = type_new_enum($2, FALSE, NULL); } | tENUM aIDENTIFIER { $$ = type_new_enum($2, current_namespace, FALSE, NULL); }
| structdef { $$ = $1; } | structdef { $$ = $1; }
| tSTRUCT aIDENTIFIER { $$ = type_new_struct($2, FALSE, NULL); } | tSTRUCT aIDENTIFIER { $$ = type_new_struct($2, FALSE, NULL); }
| uniondef { $$ = $1; } | uniondef { $$ = $1; }
...@@ -1809,6 +1809,10 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in ...@@ -1809,6 +1809,10 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
hash = hash_ident(name); hash = hash_ident(name);
nt = xmalloc(sizeof(struct rtype)); nt = xmalloc(sizeof(struct rtype));
nt->name = name; 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->type = type;
nt->t = t; nt->t = t;
nt->next = namespace->type_hash[hash]; nt->next = namespace->type_hash[hash];
...@@ -1983,10 +1987,6 @@ type_t *get_type(enum type_type type, char *name, struct namespace *namespace, i ...@@ -1983,10 +1987,6 @@ type_t *get_type(enum type_type type, char *name, struct namespace *namespace, i
tp = make_type(type); tp = make_type(type);
tp->name = name; tp->name = name;
tp->namespace = namespace; 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; if (!name) return tp;
return reg_type(tp, name, namespace, t); return reg_type(tp, name, namespace, t);
} }
......
...@@ -4735,7 +4735,7 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun ...@@ -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 ) if (args) LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
{ {
print_file(file, 2, "%s", ""); 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 (needs_space_after( arg->type )) fputc( ' ', file );
if (is_array( arg->type ) && !type_array_is_decl_as_ptr( 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) ...@@ -4800,9 +4800,9 @@ int write_expr_eval_routines(FILE *file, const char *iface)
else else
{ {
print_file(file, 1, "%s", ""); 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); 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); fprintf(file, " *)(pStubMsg->StackTop - %u);\n", eval->baseoff);
} }
print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */ print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */
......
...@@ -78,6 +78,19 @@ static const var_t *find_arg(const var_list_t *args, const char *name) ...@@ -78,6 +78,19 @@ static const var_t *find_arg(const var_list_t *args, const char *name)
return NULL; 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) static char *append_namespace(char *ptr, struct namespace *namespace, const char *separator)
{ {
if(is_global_namespace(namespace)) { if(is_global_namespace(namespace)) {
...@@ -258,11 +271,12 @@ type_t *type_new_void(void) ...@@ -258,11 +271,12 @@ type_t *type_new_void(void)
return void_type; 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); type_t *t = make_type(TYPE_ENUM);
t->name = name; t->name = name;
t->namespace = namespace;
if (tag_type && tag_type->details.enumeration) if (tag_type && tag_type->details.enumeration)
t->details.enumeration = 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) ...@@ -276,7 +290,7 @@ type_t *type_new_enum(const char *name, int defined, var_list_t *enums)
if (name) if (name)
{ {
if (defined) if (defined)
reg_type(t, name, NULL, tsENUM); reg_type(t, name, namespace, tsENUM);
else else
add_incomplete(t); add_incomplete(t);
} }
......
...@@ -24,6 +24,11 @@ ...@@ -24,6 +24,11 @@
#ifndef WIDL_TYPE_TREE_H #ifndef WIDL_TYPE_TREE_H
#define 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_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_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs);
type_t *type_new_alias(type_t *t, const char *name); 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); ...@@ -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_int(enum type_basic_type basic_type, int sign);
type_t *type_new_void(void); type_t *type_new_void(void);
type_t *type_new_coclass(char *name); 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_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_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); 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); ...@@ -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); void type_module_define(type_t *module, statement_list_t *stmts);
type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces); type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces);
int type_is_equal(const type_t *type1, const type_t *type2); 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 */ /* FIXME: shouldn't need to export this */
type_t *duptype(type_t *t, int dupname); type_t *duptype(type_t *t, int dupname);
......
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