widl: Added support for namespaced enums.
This commit is contained in:
parent
a99bb3468a
commit
88987c0a95
|
@ -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);
|
||||
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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue