widl: Generate header files from the parse tree instead of using hooks in the parser.
This commit is contained in:
parent
bf5a9cb61e
commit
6b955b514d
|
@ -205,7 +205,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
|
|||
switch (t->type) {
|
||||
case RPC_FC_ENUM16:
|
||||
case RPC_FC_ENUM32:
|
||||
if (!declonly && t->defined && !t->written && !t->ignore) {
|
||||
if (!declonly && t->defined && !t->written) {
|
||||
if (t->name) fprintf(h, "enum %s {\n", t->name);
|
||||
else fprintf(h, "enum {\n");
|
||||
t->written = TRUE;
|
||||
|
@ -223,7 +223,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
|
|||
case RPC_FC_PSTRUCT:
|
||||
case RPC_FC_BOGUS_STRUCT:
|
||||
case RPC_FC_ENCAPSULATED_UNION:
|
||||
if (!declonly && t->defined && !t->written && !t->ignore) {
|
||||
if (!declonly && t->defined && !t->written) {
|
||||
if (t->name) fprintf(h, "struct %s {\n", t->name);
|
||||
else fprintf(h, "struct {\n");
|
||||
t->written = TRUE;
|
||||
|
@ -238,7 +238,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
|
|||
else fprintf(h, "struct %s", t->name ? t->name : "");
|
||||
break;
|
||||
case RPC_FC_NON_ENCAPSULATED_UNION:
|
||||
if (!declonly && t->defined && !t->written && !t->ignore) {
|
||||
if (!declonly && t->defined && !t->written) {
|
||||
if (t->name) fprintf(h, "union %s {\n", t->name);
|
||||
else fprintf(h, "union {\n");
|
||||
t->written = TRUE;
|
||||
|
@ -426,7 +426,7 @@ void check_for_additional_prototype_types(const var_list_t *list)
|
|||
}
|
||||
}
|
||||
|
||||
void write_user_types(void)
|
||||
static void write_user_types(FILE *header)
|
||||
{
|
||||
user_type_t *ut;
|
||||
LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry)
|
||||
|
@ -439,7 +439,7 @@ void write_user_types(void)
|
|||
}
|
||||
}
|
||||
|
||||
void write_context_handle_rundowns(void)
|
||||
static void write_context_handle_rundowns(FILE *header)
|
||||
{
|
||||
context_handle_t *ch;
|
||||
LIST_FOR_EACH_ENTRY(ch, &context_handle_list, context_handle_t, entry)
|
||||
|
@ -449,7 +449,7 @@ void write_context_handle_rundowns(void)
|
|||
}
|
||||
}
|
||||
|
||||
void write_generic_handle_routines(void)
|
||||
static void write_generic_handle_routines(FILE *header)
|
||||
{
|
||||
generic_handle_t *gh;
|
||||
LIST_FOR_EACH_ENTRY(gh, &generic_handle_list, generic_handle_t, entry)
|
||||
|
@ -460,7 +460,7 @@ void write_generic_handle_routines(void)
|
|||
}
|
||||
}
|
||||
|
||||
void write_typedef(type_t *type)
|
||||
static void write_typedef(FILE *header, type_t *type)
|
||||
{
|
||||
fprintf(header, "typedef ");
|
||||
write_type_def_or_decl(header, type->orig, FALSE, "%s", type->name);
|
||||
|
@ -485,7 +485,7 @@ int is_const_decl(const var_t *var)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
void write_declaration(const var_t *v, int is_in_interface)
|
||||
static void write_declaration(FILE *header, const var_t *v)
|
||||
{
|
||||
if (is_const_decl(v) && v->eval)
|
||||
{
|
||||
|
@ -493,7 +493,7 @@ void write_declaration(const var_t *v, int is_in_interface)
|
|||
write_expr(header, v->eval, 0, 1, NULL, NULL, "");
|
||||
fprintf(header, ")\n\n");
|
||||
}
|
||||
else if (v->type->type != RPC_FC_FUNCTION || !is_in_interface)
|
||||
else
|
||||
{
|
||||
switch (v->stgclass)
|
||||
{
|
||||
|
@ -512,7 +512,7 @@ void write_declaration(const var_t *v, int is_in_interface)
|
|||
}
|
||||
}
|
||||
|
||||
void write_library(const typelib_t *typelib)
|
||||
static void write_library(FILE *header, const typelib_t *typelib)
|
||||
{
|
||||
const UUID *uuid = get_attrp(typelib->attrs, ATTR_UUID);
|
||||
fprintf(header, "\n");
|
||||
|
@ -846,55 +846,28 @@ void write_local_stubs(const statement_list_t *stmts)
|
|||
fclose(local_stubs);
|
||||
}
|
||||
|
||||
static void write_function_proto(FILE *header, const type_t *iface, const func_t *fun, const char *prefix)
|
||||
static void write_function_proto(FILE *header, const type_t *iface, const var_t *fun, const char *prefix)
|
||||
{
|
||||
var_t *def = fun->def;
|
||||
const char *callconv = get_attrp(def->type->attrs, ATTR_CALLCONV);
|
||||
const char *callconv = get_attrp(fun->type->attrs, ATTR_CALLCONV);
|
||||
|
||||
/* FIXME: do we need to handle call_as? */
|
||||
write_type_decl_left(header, get_func_return_type(fun));
|
||||
write_type_decl_left(header, fun->type->ref);
|
||||
fprintf(header, " ");
|
||||
if (callconv) fprintf(header, "%s ", callconv);
|
||||
fprintf(header, "%s%s(\n", prefix, get_name(def));
|
||||
if (fun->args)
|
||||
write_args(header, fun->args, iface->name, 0, TRUE);
|
||||
fprintf(header, "%s%s(\n", prefix, get_name(fun));
|
||||
if (fun->type->details.function->args)
|
||||
write_args(header, fun->type->details.function->args, iface->name, 0, TRUE);
|
||||
else
|
||||
fprintf(header, " void");
|
||||
fprintf(header, ");\n\n");
|
||||
}
|
||||
|
||||
static void write_function_protos(FILE *header, const type_t *iface)
|
||||
static void write_forward(FILE *header, type_t *iface)
|
||||
{
|
||||
const func_t *cur;
|
||||
int prefixes_differ = strcmp(prefix_client, prefix_server);
|
||||
|
||||
if (!iface->funcs) return;
|
||||
LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry )
|
||||
{
|
||||
if (prefixes_differ) {
|
||||
fprintf(header, "/* client prototype */\n");
|
||||
write_function_proto(header, iface, cur, prefix_client);
|
||||
fprintf(header, "/* server prototype */\n");
|
||||
}
|
||||
write_function_proto(header, iface, cur, prefix_server);
|
||||
}
|
||||
}
|
||||
|
||||
void write_forward(type_t *iface)
|
||||
{
|
||||
/* C/C++ forwards should only be written for object interfaces, so if we
|
||||
* have a full definition we only write one if we find [object] among the
|
||||
* attributes - however, if we don't have a full definition at this point
|
||||
* (i.e. this is an IDL forward), then we also assume that it is an object
|
||||
* interface, since non-object interfaces shouldn't need forwards */
|
||||
if ((!iface->defined || is_object(iface->attrs) || is_attr(iface->attrs, ATTR_DISPINTERFACE))
|
||||
&& !iface->written) {
|
||||
fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", iface->name);
|
||||
fprintf(header, "#define __%s_FWD_DEFINED__\n", iface->name);
|
||||
fprintf(header, "typedef interface %s %s;\n", iface->name, iface->name);
|
||||
fprintf(header, "#endif\n\n" );
|
||||
iface->written = TRUE;
|
||||
}
|
||||
fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", iface->name);
|
||||
fprintf(header, "#define __%s_FWD_DEFINED__\n", iface->name);
|
||||
fprintf(header, "typedef interface %s %s;\n", iface->name, iface->name);
|
||||
fprintf(header, "#endif\n\n" );
|
||||
}
|
||||
|
||||
static void write_iface_guid(FILE *header, const type_t *iface)
|
||||
|
@ -1031,22 +1004,7 @@ static void write_rpc_interface_end(FILE *header, const type_t *iface)
|
|||
fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name);
|
||||
}
|
||||
|
||||
void write_interface(type_t *iface)
|
||||
{
|
||||
if (is_attr(iface->attrs, ATTR_DISPINTERFACE) || is_object(iface->attrs))
|
||||
{
|
||||
write_com_interface_start(header, iface);
|
||||
write_com_interface_end(header, iface);
|
||||
}
|
||||
else
|
||||
{
|
||||
write_rpc_interface_start(header, iface);
|
||||
write_function_protos(header, iface);
|
||||
write_rpc_interface_end(header, iface);
|
||||
}
|
||||
}
|
||||
|
||||
void write_coclass(type_t *cocl)
|
||||
static void write_coclass(FILE *header, type_t *cocl)
|
||||
{
|
||||
fprintf(header, "/*****************************************************************************\n");
|
||||
fprintf(header, " * %s coclass\n", cocl->name);
|
||||
|
@ -1055,7 +1013,7 @@ void write_coclass(type_t *cocl)
|
|||
fprintf(header, "\n");
|
||||
}
|
||||
|
||||
void write_coclass_forward(type_t *cocl)
|
||||
static void write_coclass_forward(FILE *header, type_t *cocl)
|
||||
{
|
||||
fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", cocl->name);
|
||||
fprintf(header, "#define __%s_FWD_DEFINED__\n", cocl->name);
|
||||
|
@ -1063,7 +1021,7 @@ void write_coclass_forward(type_t *cocl)
|
|||
fprintf(header, "#endif /* defined __%s_FWD_DEFINED__ */\n\n", cocl->name );
|
||||
}
|
||||
|
||||
void write_import(const char *fname)
|
||||
static void write_import(FILE *header, const char *fname)
|
||||
{
|
||||
char *hname, *p;
|
||||
|
||||
|
@ -1074,3 +1032,194 @@ void write_import(const char *fname)
|
|||
fprintf(header, "#include <%s>\n", hname);
|
||||
free(hname);
|
||||
}
|
||||
|
||||
static void write_imports(FILE *header, const statement_list_t *stmts)
|
||||
{
|
||||
const statement_t *stmt;
|
||||
if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
|
||||
{
|
||||
switch (stmt->type)
|
||||
{
|
||||
case STMT_TYPE:
|
||||
if (stmt->u.type->type == RPC_FC_IP)
|
||||
write_imports(header, stmt->u.type->stmts);
|
||||
break;
|
||||
case STMT_TYPEREF:
|
||||
case STMT_IMPORTLIB:
|
||||
/* not included in header */
|
||||
break;
|
||||
case STMT_IMPORT:
|
||||
write_import(header, stmt->u.str);
|
||||
break;
|
||||
case STMT_TYPEDEF:
|
||||
case STMT_MODULE:
|
||||
case STMT_CPPQUOTE:
|
||||
case STMT_DECLARATION:
|
||||
/* not processed here */
|
||||
break;
|
||||
case STMT_LIBRARY:
|
||||
write_imports(header, stmt->u.lib->stmts);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void write_forward_decls(FILE *header, const statement_list_t *stmts)
|
||||
{
|
||||
const statement_t *stmt;
|
||||
if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
|
||||
{
|
||||
switch (stmt->type)
|
||||
{
|
||||
case STMT_TYPE:
|
||||
if (stmt->u.type->type == RPC_FC_IP)
|
||||
{
|
||||
if (is_object(stmt->u.type->attrs) || is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE))
|
||||
write_forward(header, stmt->u.type);
|
||||
}
|
||||
else if (stmt->u.type->type == RPC_FC_COCLASS)
|
||||
write_coclass_forward(header, stmt->u.type);
|
||||
break;
|
||||
case STMT_TYPEREF:
|
||||
case STMT_IMPORTLIB:
|
||||
/* not included in header */
|
||||
break;
|
||||
case STMT_IMPORT:
|
||||
case STMT_TYPEDEF:
|
||||
case STMT_MODULE:
|
||||
case STMT_CPPQUOTE:
|
||||
case STMT_DECLARATION:
|
||||
/* not processed here */
|
||||
break;
|
||||
case STMT_LIBRARY:
|
||||
write_forward_decls(header, stmt->u.lib->stmts);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void write_header_stmts(FILE *header, const statement_list_t *stmts, const type_t *iface, int ignore_funcs)
|
||||
{
|
||||
const statement_t *stmt;
|
||||
if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
|
||||
{
|
||||
switch (stmt->type)
|
||||
{
|
||||
case STMT_TYPE:
|
||||
if (stmt->u.type->type == RPC_FC_IP)
|
||||
{
|
||||
type_t *iface = stmt->u.type;
|
||||
if (is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE) || is_object(stmt->u.type->attrs))
|
||||
{
|
||||
write_com_interface_start(header, iface);
|
||||
write_header_stmts(header, iface->stmts, stmt->u.type, TRUE);
|
||||
write_com_interface_end(header, iface);
|
||||
}
|
||||
else
|
||||
{
|
||||
write_rpc_interface_start(header, iface);
|
||||
write_header_stmts(header, iface->stmts, iface, FALSE);
|
||||
write_rpc_interface_end(header, iface);
|
||||
}
|
||||
}
|
||||
else if (stmt->u.type->type == RPC_FC_COCLASS)
|
||||
write_coclass(header, stmt->u.type);
|
||||
else
|
||||
{
|
||||
write_type_def_or_decl(header, stmt->u.type, FALSE, NULL);
|
||||
fprintf(header, ";\n\n");
|
||||
}
|
||||
break;
|
||||
case STMT_TYPEREF:
|
||||
/* FIXME: shouldn't write out forward declarations for undefined
|
||||
* interfaces but a number of our IDL files depend on this */
|
||||
if (stmt->u.type->type == RPC_FC_IP && !stmt->u.type->written)
|
||||
write_forward(header, stmt->u.type);
|
||||
break;
|
||||
case STMT_IMPORTLIB:
|
||||
case STMT_MODULE:
|
||||
/* not included in header */
|
||||
break;
|
||||
case STMT_IMPORT:
|
||||
/* not processed here */
|
||||
break;
|
||||
case STMT_TYPEDEF:
|
||||
{
|
||||
const type_list_t *type_entry = stmt->u.type_list;
|
||||
for (; type_entry; type_entry = type_entry->next)
|
||||
write_typedef(header, type_entry->type);
|
||||
break;
|
||||
}
|
||||
case STMT_LIBRARY:
|
||||
write_library(header, stmt->u.lib);
|
||||
write_header_stmts(header, stmt->u.lib->stmts, NULL, FALSE);
|
||||
break;
|
||||
case STMT_CPPQUOTE:
|
||||
fprintf(header, "%s\n", stmt->u.str);
|
||||
break;
|
||||
case STMT_DECLARATION:
|
||||
if (iface && stmt->u.var->type->type == RPC_FC_FUNCTION)
|
||||
{
|
||||
if (!ignore_funcs)
|
||||
{
|
||||
int prefixes_differ = strcmp(prefix_client, prefix_server);
|
||||
|
||||
if (prefixes_differ)
|
||||
{
|
||||
fprintf(header, "/* client prototype */\n");
|
||||
write_function_proto(header, iface, stmt->u.var, prefix_client);
|
||||
fprintf(header, "/* server prototype */\n");
|
||||
}
|
||||
write_function_proto(header, iface, stmt->u.var, prefix_server);
|
||||
}
|
||||
}
|
||||
else
|
||||
write_declaration(header, stmt->u.var);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void write_header(const statement_list_t *stmts)
|
||||
{
|
||||
FILE *header;
|
||||
|
||||
if (!do_header) return;
|
||||
|
||||
if(!(header = fopen(header_name, "w"))) {
|
||||
error("Could not open %s for output\n", header_name);
|
||||
return;
|
||||
}
|
||||
fprintf(header, "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n\n", PACKAGE_VERSION, input_name);
|
||||
fprintf(header, "#include <rpc.h>\n" );
|
||||
fprintf(header, "#include <rpcndr.h>\n\n" );
|
||||
|
||||
fprintf(header, "#ifndef __WIDL_%s\n", header_token);
|
||||
fprintf(header, "#define __WIDL_%s\n\n", header_token);
|
||||
start_cplusplus_guard(header);
|
||||
|
||||
fprintf(header, "/* Headers for imported files */\n\n");
|
||||
write_imports(header, stmts);
|
||||
fprintf(header, "\n");
|
||||
|
||||
/* FIXME: should be before imported file includes */
|
||||
fprintf(header, "/* Forward declarations */\n\n");
|
||||
write_forward_decls(header, stmts);
|
||||
fprintf(header, "\n");
|
||||
|
||||
write_header_stmts(header, stmts, NULL, FALSE);
|
||||
|
||||
fprintf(header, "/* Begin additional prototypes for all interfaces */\n");
|
||||
fprintf(header, "\n");
|
||||
write_user_types(header);
|
||||
write_generic_handle_routines(header);
|
||||
write_context_handle_rundowns(header);
|
||||
fprintf(header, "\n");
|
||||
fprintf(header, "/* End additional prototypes */\n");
|
||||
fprintf(header, "\n");
|
||||
|
||||
end_cplusplus_guard(header);
|
||||
fprintf(header, "#endif /* __WIDL_%s */\n", header_token);
|
||||
|
||||
fclose(header);
|
||||
}
|
||||
|
|
|
@ -47,17 +47,6 @@ extern int need_proxy_file(const statement_list_t *stmts);
|
|||
extern const var_t *is_callas(const attr_list_t *list);
|
||||
extern void write_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent);
|
||||
extern void write_array(FILE *h, array_dims_t *v, int field);
|
||||
extern void write_import(const char *fname);
|
||||
extern void write_forward(type_t *iface);
|
||||
extern void write_interface(type_t *iface);
|
||||
extern void write_coclass(type_t *cocl);
|
||||
extern void write_coclass_forward(type_t *cocl);
|
||||
extern void write_typedef(type_t *type);
|
||||
extern void write_declaration(const var_t *v, int is_in_interface);
|
||||
extern void write_library(const typelib_t *typelib);
|
||||
extern void write_user_types(void);
|
||||
extern void write_context_handle_rundowns(void);
|
||||
extern void write_generic_handle_routines(void);
|
||||
extern const var_t* get_explicit_handle_var(const func_t* func);
|
||||
extern const type_t* get_explicit_generic_handle_type(const var_t* var);
|
||||
extern const var_t* get_explicit_generic_handle_var(const func_t* func);
|
||||
|
|
|
@ -46,5 +46,6 @@ void pop_import(void);
|
|||
int is_type(const char *name);
|
||||
|
||||
void check_functions(const type_t *iface);
|
||||
func_list_t *gen_function_list(const statement_list_t *stmts);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -69,7 +69,6 @@
|
|||
#define YYERROR_VERBOSE
|
||||
|
||||
unsigned char pointer_default = RPC_FC_UP;
|
||||
static int is_in_interface = FALSE;
|
||||
static int is_object_interface = FALSE;
|
||||
/* are we inside a library block? */
|
||||
static int is_inside_library = FALSE;
|
||||
|
@ -140,7 +139,6 @@ static type_t *get_type(unsigned char type, char *name, int t);
|
|||
static var_t *reg_const(var_t *var);
|
||||
|
||||
static char *gen_name(void);
|
||||
static statement_t *process_typedefs(var_list_t *names);
|
||||
static void check_arg(var_t *arg);
|
||||
static void check_all_user_types(const statement_list_t *stmts);
|
||||
static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs);
|
||||
|
@ -166,9 +164,10 @@ static statement_t *make_statement_library(typelib_t *typelib);
|
|||
static statement_t *make_statement_cppquote(const char *str);
|
||||
static statement_t *make_statement_importlib(const char *str);
|
||||
static statement_t *make_statement_module(type_t *type);
|
||||
static statement_t *make_statement_typedef(var_list_t *names);
|
||||
static statement_t *make_statement_import(const char *str);
|
||||
static statement_t *make_statement_typedef(var_list_t *names);
|
||||
static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt);
|
||||
static func_list_t *append_func_from_statement(func_list_t *list, statement_t *stmt);
|
||||
|
||||
#define tsENUM 1
|
||||
#define tsSTRUCT 2
|
||||
|
@ -320,7 +319,6 @@ static func_list_t *append_func_from_statement(func_list_t *list, statement_t *s
|
|||
%type <declarator> declarator direct_declarator init_declarator
|
||||
%type <declarator_list> declarator_list
|
||||
%type <func> funcdef
|
||||
%type <func_list> int_statements dispint_meths
|
||||
%type <type> coclass coclasshdr coclassdef
|
||||
%type <num> pointer_type version
|
||||
%type <str> libraryhdr callconv cppquote importlib import t_ident
|
||||
|
@ -328,7 +326,7 @@ static func_list_t *append_func_from_statement(func_list_t *list, statement_t *s
|
|||
%type <import> import_start
|
||||
%type <typelib> library_start librarydef
|
||||
%type <statement> statement typedef
|
||||
%type <stmt_list> gbl_statements imp_statements
|
||||
%type <stmt_list> gbl_statements imp_statements int_statements dispint_meths
|
||||
|
||||
%left ','
|
||||
%right '?' ':'
|
||||
|
@ -349,6 +347,7 @@ static func_list_t *append_func_from_statement(func_list_t *list, statement_t *s
|
|||
|
||||
input: gbl_statements { fix_incomplete();
|
||||
check_all_user_types($1);
|
||||
write_header($1);
|
||||
write_id_data($1);
|
||||
write_proxies($1);
|
||||
write_client($1);
|
||||
|
@ -359,15 +358,13 @@ input: gbl_statements { fix_incomplete();
|
|||
;
|
||||
|
||||
gbl_statements: { $$ = NULL; }
|
||||
| gbl_statements interfacedec { $$ = $1; }
|
||||
| gbl_statements interfacedec { $$ = append_statement($1, make_statement_reference($2)); }
|
||||
| gbl_statements interfacedef { $$ = append_statement($1, make_statement_type_decl($2)); }
|
||||
| gbl_statements coclass ';' { $$ = $1;
|
||||
reg_type($2, $2->name, 0);
|
||||
if (!parse_only && do_header) write_coclass_forward($2);
|
||||
}
|
||||
| gbl_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2));
|
||||
reg_type($2, $2->name, 0);
|
||||
if (!parse_only && do_header) write_coclass_forward($2);
|
||||
}
|
||||
| gbl_statements moduledef { $$ = append_statement($1, make_statement_module($2)); }
|
||||
| gbl_statements librarydef { $$ = append_statement($1, make_statement_library($2)); }
|
||||
|
@ -377,10 +374,9 @@ gbl_statements: { $$ = NULL; }
|
|||
imp_statements: { $$ = NULL; }
|
||||
| imp_statements interfacedec { $$ = append_statement($1, make_statement_reference($2)); }
|
||||
| imp_statements interfacedef { $$ = append_statement($1, make_statement_type_decl($2)); }
|
||||
| imp_statements coclass ';' { $$ = $1; reg_type($2, $2->name, 0); if (!parse_only && do_header) write_coclass_forward($2); }
|
||||
| imp_statements coclass ';' { $$ = $1; reg_type($2, $2->name, 0); }
|
||||
| imp_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2));
|
||||
reg_type($2, $2->name, 0);
|
||||
if (!parse_only && do_header) write_coclass_forward($2);
|
||||
}
|
||||
| imp_statements moduledef { $$ = append_statement($1, make_statement_module($2)); }
|
||||
| imp_statements statement { $$ = append_statement($1, $2); }
|
||||
|
@ -389,7 +385,7 @@ imp_statements: { $$ = NULL; }
|
|||
;
|
||||
|
||||
int_statements: { $$ = NULL; }
|
||||
| int_statements statement { $$ = append_func_from_statement( $1, $2 ); }
|
||||
| int_statements statement { $$ = append_statement($1, $2); }
|
||||
;
|
||||
|
||||
semicolon_opt:
|
||||
|
@ -398,15 +394,8 @@ semicolon_opt:
|
|||
|
||||
statement:
|
||||
cppquote { $$ = make_statement_cppquote($1); }
|
||||
| typedecl ';' { $$ = make_statement_type_decl($1);
|
||||
if (!parse_only && do_header) {
|
||||
write_type_def_or_decl(header, $1, FALSE, NULL);
|
||||
fprintf(header, ";\n\n");
|
||||
}
|
||||
}
|
||||
| declaration ';' { $$ = make_statement_declaration($1);
|
||||
if (!parse_only && do_header) write_declaration($1, is_in_interface);
|
||||
}
|
||||
| typedecl ';' { $$ = make_statement_type_decl($1); }
|
||||
| declaration ';' { $$ = make_statement_declaration($1); }
|
||||
| import { $$ = make_statement_import($1); }
|
||||
| typedef ';' { $$ = $1; }
|
||||
;
|
||||
|
@ -420,7 +409,7 @@ typedecl:
|
|||
| attributes uniondef { $$ = $2; $$->attrs = check_union_attrs($1); }
|
||||
;
|
||||
|
||||
cppquote: tCPPQUOTE '(' aSTRING ')' { $$ = $3; if (!parse_only && do_header) fprintf(header, "%s\n", $3); }
|
||||
cppquote: tCPPQUOTE '(' aSTRING ')' { $$ = $3; }
|
||||
;
|
||||
import_start: tIMPORT aSTRING ';' { assert(yychar == YYEMPTY);
|
||||
$$ = xmalloc(sizeof(struct _import_t));
|
||||
|
@ -433,7 +422,6 @@ import_start: tIMPORT aSTRING ';' { assert(yychar == YYEMPTY);
|
|||
import: import_start imp_statements aEOF { $$ = $1->name;
|
||||
if ($1->import_performed) pop_import();
|
||||
free($1);
|
||||
if (!parse_only && do_header) write_import($$);
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -445,7 +433,6 @@ libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; }
|
|||
;
|
||||
library_start: attributes libraryhdr '{' { $$ = make_library($2, check_library_attrs($2, $1));
|
||||
if (!parse_only) start_typelib($$);
|
||||
if (!parse_only && do_header) write_library($$);
|
||||
is_inside_library = TRUE;
|
||||
}
|
||||
;
|
||||
|
@ -841,8 +828,6 @@ coclass: tCOCLASS aIDENTIFIER { $$ = make_class($2); }
|
|||
coclasshdr: attributes coclass { $$ = $2;
|
||||
check_def($$);
|
||||
$$->attrs = check_coclass_attrs($2->name, $1);
|
||||
if (!parse_only && do_header)
|
||||
write_coclass($$);
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -866,14 +851,12 @@ dispinterface: tDISPINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); $$-
|
|||
;
|
||||
|
||||
dispinterfacehdr: attributes dispinterface { attr_t *attrs;
|
||||
is_in_interface = TRUE;
|
||||
is_object_interface = TRUE;
|
||||
$$ = $2;
|
||||
check_def($$);
|
||||
attrs = make_attr(ATTR_DISPINTERFACE);
|
||||
$$->attrs = append_attr( check_dispiface_attrs($2->name, $1), attrs );
|
||||
$$->defined = TRUE;
|
||||
if (!parse_only && do_header) write_forward($$);
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -890,14 +873,10 @@ dispinterfacedef: dispinterfacehdr '{'
|
|||
dispint_meths
|
||||
'}' { $$ = $1;
|
||||
type_dispinterface_define($$, $3, $4);
|
||||
if (!parse_only && do_header) write_interface($$);
|
||||
is_in_interface = FALSE;
|
||||
}
|
||||
| dispinterfacehdr
|
||||
'{' interface ';' '}' { $$ = $1;
|
||||
type_dispinterface_define_from_iface($$, $3);
|
||||
if (!parse_only && do_header) write_interface($$);
|
||||
is_in_interface = FALSE;
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -914,20 +893,16 @@ interfacehdr: attributes interface { $$.interface = $2;
|
|||
if (is_attr($1, ATTR_POINTERDEFAULT))
|
||||
pointer_default = get_attrv($1, ATTR_POINTERDEFAULT);
|
||||
is_object_interface = is_object($1);
|
||||
is_in_interface = TRUE;
|
||||
check_def($2);
|
||||
$2->attrs = check_iface_attrs($2->name, $1);
|
||||
$2->defined = TRUE;
|
||||
if (!parse_only && do_header) write_forward($2);
|
||||
}
|
||||
;
|
||||
|
||||
interfacedef: interfacehdr inherit
|
||||
'{' int_statements '}' semicolon_opt { $$ = $1.interface;
|
||||
type_interface_define($$, $2, $4);
|
||||
if (!parse_only && do_header) write_interface($$);
|
||||
pointer_default = $1.old_pointer_default;
|
||||
is_in_interface = FALSE;
|
||||
}
|
||||
/* MIDL is able to import the definition of a base class from inside the
|
||||
* definition of a derived class, I'll try to support it with this rule */
|
||||
|
@ -935,16 +910,14 @@ interfacedef: interfacehdr inherit
|
|||
'{' import int_statements '}'
|
||||
semicolon_opt { $$ = $1.interface;
|
||||
type_interface_define($$, find_type_or_error2($3, 0), $6);
|
||||
if (!parse_only && do_header) write_interface($$);
|
||||
pointer_default = $1.old_pointer_default;
|
||||
is_in_interface = FALSE;
|
||||
}
|
||||
| dispinterfacedef semicolon_opt { $$ = $1; }
|
||||
;
|
||||
|
||||
interfacedec:
|
||||
interface ';' { $$ = $1; if (!parse_only && do_header) write_forward($$); }
|
||||
| dispinterface ';' { $$ = $1; if (!parse_only && do_header) write_forward($$); }
|
||||
interface ';' { $$ = $1; }
|
||||
| dispinterface ';' { $$ = $1; }
|
||||
;
|
||||
|
||||
module: tMODULE aIDENTIFIER { $$ = make_type(0, NULL); $$->name = $2; $$->kind = TKIND_MODULE; }
|
||||
|
@ -958,8 +931,8 @@ modulehdr: attributes module { $$ = $2;
|
|||
|
||||
moduledef: modulehdr '{' int_statements '}'
|
||||
semicolon_opt { $$ = $1;
|
||||
$$->funcs = $3;
|
||||
/* FIXME: if (!parse_only && do_header) write_module($$); */
|
||||
$$->stmts = $3;
|
||||
$$->funcs = gen_function_list($3);
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -1046,7 +1019,7 @@ type: tVOID { $$ = find_type_or_error("void", 0); }
|
|||
|
||||
typedef: tTYPEDEF m_attributes decl_spec declarator_list
|
||||
{ reg_typedefs($3, $4, check_typedef_attrs($2));
|
||||
$$ = process_typedefs($4);
|
||||
$$ = make_statement_typedef($4);
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -1735,7 +1708,6 @@ static func_t *make_func(var_t *def)
|
|||
func_t *f = xmalloc(sizeof(func_t));
|
||||
f->def = def;
|
||||
f->args = def->type->details.function->args;
|
||||
f->ignore = parse_only;
|
||||
f->idx = -1;
|
||||
return f;
|
||||
}
|
||||
|
@ -2010,6 +1982,25 @@ var_t *find_const(const char *name, int f)
|
|||
return cur->var;
|
||||
}
|
||||
|
||||
func_list_t *gen_function_list(const statement_list_t *stmts)
|
||||
{
|
||||
func_list_t *func_list = NULL;
|
||||
const statement_t *stmt;
|
||||
if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
|
||||
{
|
||||
if (stmt->type == STMT_DECLARATION)
|
||||
{
|
||||
var_t *var = stmt->u.var;
|
||||
if (var->stgclass == STG_NONE && var->type->type == RPC_FC_FUNCTION)
|
||||
{
|
||||
check_function_attrs(var->name, var->type->attrs);
|
||||
func_list = append_func(func_list, make_func(var));
|
||||
}
|
||||
}
|
||||
}
|
||||
return func_list;
|
||||
}
|
||||
|
||||
static char *gen_name(void)
|
||||
{
|
||||
static const char format[] = "__WIDL_%s_generated_name_%08lX";
|
||||
|
@ -2677,7 +2668,7 @@ static statement_t *make_statement_module(type_t *type)
|
|||
return stmt;
|
||||
}
|
||||
|
||||
static statement_t *process_typedefs(declarator_list_t *decls)
|
||||
static statement_t *make_statement_typedef(declarator_list_t *decls)
|
||||
{
|
||||
declarator_t *decl, *next;
|
||||
statement_t *stmt;
|
||||
|
@ -2697,9 +2688,6 @@ static statement_t *process_typedefs(declarator_list_t *decls)
|
|||
(*type_list)->type = type;
|
||||
(*type_list)->next = NULL;
|
||||
|
||||
if (! parse_only && do_header)
|
||||
write_typedef(type);
|
||||
|
||||
type_list = &(*type_list)->next;
|
||||
free(decl);
|
||||
free(var);
|
||||
|
@ -2720,20 +2708,6 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s
|
|||
return list;
|
||||
}
|
||||
|
||||
static func_list_t *append_func_from_statement(func_list_t *list, statement_t *stmt)
|
||||
{
|
||||
if (stmt->type == STMT_DECLARATION)
|
||||
{
|
||||
var_t *var = stmt->u.var;
|
||||
if (var->stgclass == STG_NONE && var->type->type == RPC_FC_FUNCTION)
|
||||
{
|
||||
check_function_attrs(var->name, var->type->attrs);
|
||||
return append_func(list, make_func(stmt->u.var));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
void init_loc_info(loc_info_t *i)
|
||||
{
|
||||
i->input_name = input_name ? input_name : "stdin";
|
||||
|
|
|
@ -64,13 +64,14 @@ static int compute_method_indexes(type_t *iface)
|
|||
return idx;
|
||||
}
|
||||
|
||||
void type_interface_define(type_t *iface, type_t *inherit, func_list_t *funcs)
|
||||
void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts)
|
||||
{
|
||||
iface->ref = inherit;
|
||||
iface->details.iface = xmalloc(sizeof(*iface->details.iface));
|
||||
iface->funcs = funcs;
|
||||
iface->funcs = gen_function_list(stmts);
|
||||
iface->details.iface->disp_props = NULL;
|
||||
iface->details.iface->disp_methods = NULL;
|
||||
iface->stmts = stmts;
|
||||
iface->defined = TRUE;
|
||||
check_functions(iface);
|
||||
compute_method_indexes(iface);
|
||||
|
@ -84,7 +85,7 @@ void type_dispinterface_define(type_t *iface, var_list_t *props, func_list_t *me
|
|||
iface->funcs = NULL;
|
||||
iface->details.iface->disp_props = props;
|
||||
iface->details.iface->disp_methods = methods;
|
||||
iface->funcs = methods;
|
||||
iface->stmts = NULL;
|
||||
iface->defined = TRUE;
|
||||
check_functions(iface);
|
||||
compute_method_indexes(iface);
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
type_t *type_new_function(var_list_t *args);
|
||||
type_t *type_new_pointer(type_t *ref, attr_list_t *attrs);
|
||||
void type_interface_define(type_t *iface, type_t *inherit, func_list_t *funcs);
|
||||
void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts);
|
||||
void type_dispinterface_define(type_t *iface, var_list_t *props, func_list_t *methods);
|
||||
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface);
|
||||
|
||||
|
|
|
@ -213,14 +213,14 @@ static void set_everything(int x)
|
|||
do_dlldata = x;
|
||||
}
|
||||
|
||||
static void start_cplusplus_guard(FILE *fp)
|
||||
void start_cplusplus_guard(FILE *fp)
|
||||
{
|
||||
fprintf(fp, "#ifdef __cplusplus\n");
|
||||
fprintf(fp, "extern \"C\" {\n");
|
||||
fprintf(fp, "#endif\n\n");
|
||||
}
|
||||
|
||||
static void end_cplusplus_guard(FILE *fp)
|
||||
void end_cplusplus_guard(FILE *fp)
|
||||
{
|
||||
fprintf(fp, "#ifdef __cplusplus\n");
|
||||
fprintf(fp, "}\n");
|
||||
|
@ -626,38 +626,11 @@ int main(int argc,char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
if(do_header) {
|
||||
header_token = make_token(header_name);
|
||||
|
||||
if(!(header = fopen(header_name, "w"))) {
|
||||
fprintf(stderr, "Could not open %s for output\n", header_name);
|
||||
return 1;
|
||||
}
|
||||
fprintf(header, "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name);
|
||||
fprintf(header, "#include <rpc.h>\n" );
|
||||
fprintf(header, "#include <rpcndr.h>\n\n" );
|
||||
fprintf(header, "#ifndef __WIDL_%s\n", header_token);
|
||||
fprintf(header, "#define __WIDL_%s\n", header_token);
|
||||
start_cplusplus_guard(header);
|
||||
}
|
||||
header_token = make_token(header_name);
|
||||
|
||||
init_types();
|
||||
ret = parser_parse();
|
||||
|
||||
if(do_header) {
|
||||
fprintf(header, "/* Begin additional prototypes for all interfaces */\n");
|
||||
fprintf(header, "\n");
|
||||
write_user_types();
|
||||
write_generic_handle_routines();
|
||||
write_context_handle_rundowns();
|
||||
fprintf(header, "\n");
|
||||
fprintf(header, "/* End additional prototypes */\n");
|
||||
fprintf(header, "\n");
|
||||
end_cplusplus_guard(header);
|
||||
fprintf(header, "#endif /* __WIDL_%s */\n", header_token);
|
||||
fclose(header);
|
||||
}
|
||||
|
||||
fclose(parser_in);
|
||||
|
||||
if(ret) {
|
||||
|
|
|
@ -50,6 +50,7 @@ extern int do_win64;
|
|||
|
||||
extern char *input_name;
|
||||
extern char *header_name;
|
||||
extern char *header_token;
|
||||
extern char *local_stubs_name;
|
||||
extern char *typelib_name;
|
||||
extern char *dlldata_name;
|
||||
|
@ -67,9 +68,7 @@ extern time_t now;
|
|||
extern int line_number;
|
||||
extern int char_number;
|
||||
|
||||
extern FILE* header;
|
||||
extern FILE* idfile;
|
||||
|
||||
extern void write_header(const statement_list_t *stmts);
|
||||
extern void write_id_data(const statement_list_t *stmts);
|
||||
extern void write_proxies(const statement_list_t *stmts);
|
||||
extern void write_client(const statement_list_t *stmts);
|
||||
|
@ -77,4 +76,7 @@ extern void write_server(const statement_list_t *stmts);
|
|||
extern void write_local_stubs(const statement_list_t *stmts);
|
||||
extern void write_dlldata(const statement_list_t *stmts);
|
||||
|
||||
extern void start_cplusplus_guard(FILE *fp);
|
||||
extern void end_cplusplus_guard(FILE *fp);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -295,6 +295,7 @@ struct _type_t {
|
|||
struct iface_details *iface;
|
||||
} details;
|
||||
func_list_t *funcs; /* interfaces and modules */
|
||||
statement_list_t *stmts; /* interfaces and modules */
|
||||
ifref_list_t *ifaces; /* coclasses */
|
||||
unsigned long dim; /* array dimension */
|
||||
expr_t *size_is, *length_is;
|
||||
|
@ -339,7 +340,7 @@ struct _declarator_t {
|
|||
struct _func_t {
|
||||
var_t *def;
|
||||
var_list_t *args;
|
||||
int ignore, idx;
|
||||
int idx;
|
||||
|
||||
/* parser-internal */
|
||||
struct list entry;
|
||||
|
|
Loading…
Reference in New Issue