widl: Add a --local-stubs option.

oldstable
Dan Hipschman 2007-10-30 19:07:36 -07:00 committed by Alexandre Julliard
parent e7636c13e5
commit ea7ab4da66
6 changed files with 96 additions and 19 deletions

View File

@ -702,7 +702,6 @@ static void write_method_proto(const type_t *iface)
LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry )
{ {
const var_t *def = cur->def; const var_t *def = cur->def;
const var_t *cas = is_callas(def->attrs);
if (!is_local(def->attrs)) { if (!is_local(def->attrs)) {
/* proxy prototype */ /* proxy prototype */
@ -721,30 +720,69 @@ static void write_method_proto(const type_t *iface)
fprintf(header, " PRPC_MESSAGE pRpcMessage,\n"); fprintf(header, " PRPC_MESSAGE pRpcMessage,\n");
fprintf(header, " DWORD* pdwStubPhase);\n"); fprintf(header, " DWORD* pdwStubPhase);\n");
} }
}
}
void write_locals(FILE *fp, const type_t *iface, int body)
{
static const char comment[]
= "/* WIDL-generated stub. You must provide an implementation for this. */";
const func_list_t *funcs = iface->funcs;
const func_t *cur;
if (!is_object(iface->attrs) || !funcs)
return;
LIST_FOR_EACH_ENTRY(cur, funcs, const func_t, entry) {
const var_t *def = cur->def;
const var_t *cas = is_callas(def->attrs);
if (cas) { if (cas) {
const func_t *m; const func_t *m;
LIST_FOR_EACH_ENTRY( m, iface->funcs, const func_t, entry ) LIST_FOR_EACH_ENTRY(m, iface->funcs, const func_t, entry)
if (!strcmp(m->def->name, cas->name)) break; if (!strcmp(m->def->name, cas->name))
break;
if (&m->entry != iface->funcs) { if (&m->entry != iface->funcs) {
const var_t *mdef = m->def; const var_t *mdef = m->def;
/* proxy prototype - use local prototype */ /* proxy prototype - use local prototype */
write_type_decl_left(header, mdef->type); write_type_decl_left(fp, mdef->type);
fprintf(header, " CALLBACK %s_", iface->name); fprintf(fp, " CALLBACK %s_", iface->name);
write_name(header, mdef); write_name(fp, mdef);
fprintf(header, "_Proxy(\n"); fprintf(fp, "_Proxy(\n");
write_args(header, m->args, iface->name, 1, TRUE); write_args(fp, m->args, iface->name, 1, TRUE);
fprintf(header, ");\n"); fprintf(fp, ")");
if (body) {
type_t *rt = mdef->type;
fprintf(fp, "\n{\n");
fprintf(fp, " %s\n", comment);
if (rt->name && strcmp(rt->name, "HRESULT") == 0)
fprintf(fp, " return E_NOTIMPL;\n");
else if (rt->type) {
fprintf(fp, " ");
write_type_decl(fp, rt, "rv");
fprintf(fp, ";\n");
fprintf(fp, " memset(&rv, 0, sizeof rv);\n");
fprintf(fp, " return rv;\n");
}
fprintf(fp, "}\n\n");
}
else
fprintf(fp, ";\n");
/* stub prototype - use remotable prototype */ /* stub prototype - use remotable prototype */
write_type_decl_left(header, def->type); write_type_decl_left(fp, def->type);
fprintf(header, " __RPC_STUB %s_", iface->name); fprintf(fp, " __RPC_STUB %s_", iface->name);
write_name(header, mdef); write_name(fp, mdef);
fprintf(header, "_Stub(\n"); fprintf(fp, "_Stub(\n");
write_args(header, cur->args, iface->name, 1, TRUE); write_args(fp, cur->args, iface->name, 1, TRUE);
fprintf(header, ");\n"); fprintf(fp, ")");
} if (body)
else { /* Remotable methods must all return HRESULTs. */
parser_warning("invalid call_as attribute (%s -> %s)\n", def->name, cas->name); fprintf(fp, "\n{\n %s\n return E_NOTIMPL;\n}\n\n", comment);
else
fprintf(fp, ";\n");
} }
else
error_loc("invalid call_as attribute (%s -> %s)\n", def->name, cas->name);
} }
} }
} }
@ -894,6 +932,7 @@ static void write_com_interface(type_t *iface)
fprintf(header, "#endif\n"); fprintf(header, "#endif\n");
fprintf(header, "\n"); fprintf(header, "\n");
write_method_proto(iface); write_method_proto(iface);
write_locals(header, iface, FALSE);
fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name); fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name);
} }

View File

@ -50,6 +50,7 @@ extern void write_array(FILE *h, array_dims_t *v, int field);
extern void write_forward(type_t *iface); extern void write_forward(type_t *iface);
extern void write_interface(type_t *iface); extern void write_interface(type_t *iface);
extern void write_dispinterface(type_t *iface); extern void write_dispinterface(type_t *iface);
extern void write_locals(FILE *fp, const type_t *iface, int body);
extern void write_coclass(type_t *cocl); extern void write_coclass(type_t *cocl);
extern void write_coclass_forward(type_t *cocl); extern void write_coclass_forward(type_t *cocl);
extern void write_typedef(type_t *type); extern void write_typedef(type_t *type);

View File

@ -816,6 +816,7 @@ interfacedef: interfacehdr inherit
$$->funcs = $4; $$->funcs = $4;
compute_method_indexes($$); compute_method_indexes($$);
if (!parse_only && do_header) write_interface($$); if (!parse_only && do_header) write_interface($$);
if (!parse_only && local_stubs) write_locals(local_stubs, $$, TRUE);
if (!parse_only && do_idfile) write_iid($$); if (!parse_only && do_idfile) write_iid($$);
pointer_default = $1.old_pointer_default; pointer_default = $1.old_pointer_default;
} }
@ -828,6 +829,7 @@ interfacedef: interfacehdr inherit
$$->funcs = $6; $$->funcs = $6;
compute_method_indexes($$); compute_method_indexes($$);
if (!parse_only && do_header) write_interface($$); if (!parse_only && do_header) write_interface($$);
if (!parse_only && local_stubs) write_locals(local_stubs, $$, TRUE);
if (!parse_only && do_idfile) write_iid($$); if (!parse_only && do_idfile) write_iid($$);
pointer_default = $1.old_pointer_default; pointer_default = $1.old_pointer_default;
} }

View File

@ -62,6 +62,7 @@ static const char usage[] =
" -h Generate headers\n" " -h Generate headers\n"
" -H file Name of header file (default is infile.h)\n" " -H file Name of header file (default is infile.h)\n"
" -I path Set include search dir to path (multiple -I allowed)\n" " -I path Set include search dir to path (multiple -I allowed)\n"
" --local-stubs=file Write empty stubs for call_as/local methods to file\n"
" -N Do not preprocess input\n" " -N Do not preprocess input\n"
" --oldnames Use old naming conventions\n" " --oldnames Use old naming conventions\n"
" -p Generate proxy\n" " -p Generate proxy\n"
@ -108,6 +109,7 @@ int old_names = 0;
char *input_name; char *input_name;
char *header_name; char *header_name;
char *local_stubs_name;
char *header_token; char *header_token;
char *typelib_name; char *typelib_name;
char *dlldata_name; char *dlldata_name;
@ -126,6 +128,7 @@ const char *prefix_server = "";
int line_number = 1; int line_number = 1;
FILE *header; FILE *header;
FILE *local_stubs;
FILE *proxy; FILE *proxy;
FILE *idfile; FILE *idfile;
@ -135,6 +138,7 @@ enum {
OLDNAMES_OPTION = CHAR_MAX + 1, OLDNAMES_OPTION = CHAR_MAX + 1,
DLLDATA_OPTION, DLLDATA_OPTION,
DLLDATA_ONLY_OPTION, DLLDATA_ONLY_OPTION,
LOCAL_STUBS_OPTION,
PREFIX_ALL_OPTION, PREFIX_ALL_OPTION,
PREFIX_CLIENT_OPTION, PREFIX_CLIENT_OPTION,
PREFIX_SERVER_OPTION PREFIX_SERVER_OPTION
@ -145,6 +149,7 @@ static const char short_options[] =
static const struct option long_options[] = { static const struct option long_options[] = {
{ "dlldata", required_argument, 0, DLLDATA_OPTION }, { "dlldata", required_argument, 0, DLLDATA_OPTION },
{ "dlldata-only", no_argument, 0, DLLDATA_ONLY_OPTION }, { "dlldata-only", no_argument, 0, DLLDATA_ONLY_OPTION },
{ "local-stubs", required_argument, 0, LOCAL_STUBS_OPTION },
{ "oldnames", no_argument, 0, OLDNAMES_OPTION }, { "oldnames", no_argument, 0, OLDNAMES_OPTION },
{ "prefix-all", required_argument, 0, PREFIX_ALL_OPTION }, { "prefix-all", required_argument, 0, PREFIX_ALL_OPTION },
{ "prefix-client", required_argument, 0, PREFIX_CLIENT_OPTION }, { "prefix-client", required_argument, 0, PREFIX_CLIENT_OPTION },
@ -350,6 +355,10 @@ int main(int argc,char *argv[])
do_everything = 0; do_everything = 0;
do_dlldata = 1; do_dlldata = 1;
break; break;
case LOCAL_STUBS_OPTION:
do_everything = 0;
local_stubs_name = xstrdup(optarg);
break;
case OLDNAMES_OPTION: case OLDNAMES_OPTION:
old_names = 1; old_names = 1;
break; break;
@ -554,6 +563,17 @@ int main(int argc,char *argv[])
start_cplusplus_guard(header); start_cplusplus_guard(header);
} }
if (local_stubs_name) {
local_stubs = fopen(local_stubs_name, "w");
if (!local_stubs) {
fprintf(stderr, "Could not open %s for output\n", local_stubs_name);
return 1;
}
fprintf(local_stubs, "/* call_as/local stubs for %s */\n\n", input_name);
fprintf(local_stubs, "#include <objbase.h>\n");
fprintf(local_stubs, "#include \"%s\"\n\n", header_name);
}
if (do_idfile) { if (do_idfile) {
idfile_token = make_token(idfile_name); idfile_token = make_token(idfile_name);
@ -587,6 +607,10 @@ int main(int argc,char *argv[])
fclose(header); fclose(header);
} }
if (local_stubs) {
fclose(local_stubs);
}
if (do_idfile) { if (do_idfile) {
fprintf(idfile, "\n"); fprintf(idfile, "\n");
end_cplusplus_guard(idfile); end_cplusplus_guard(idfile);
@ -602,6 +626,8 @@ int main(int argc,char *argv[])
/* Everything has been done successfully, don't delete any files. */ /* Everything has been done successfully, don't delete any files. */
set_everything(FALSE); set_everything(FALSE);
local_stubs_name = NULL;
return 0; return 0;
} }
@ -612,6 +638,8 @@ static void rm_tempfile(void)
unlink(temp_name); unlink(temp_name);
if (do_header) if (do_header)
unlink(header_name); unlink(header_name);
if (local_stubs_name)
unlink(local_stubs_name);
if (do_client) if (do_client)
unlink(client_name); unlink(client_name);
if (do_server) if (do_server)

View File

@ -48,6 +48,7 @@ extern int old_names;
extern char *input_name; extern char *input_name;
extern char *header_name; extern char *header_name;
extern char *local_stubs_name;
extern char *typelib_name; extern char *typelib_name;
extern char *dlldata_name; extern char *dlldata_name;
extern char *proxy_name; extern char *proxy_name;
@ -64,6 +65,7 @@ extern int line_number;
extern int char_number; extern int char_number;
extern FILE* header; extern FILE* header;
extern FILE* local_stubs;
extern FILE* idfile; extern FILE* idfile;
extern void write_proxies(ifref_list_t *ifaces); extern void write_proxies(ifref_list_t *ifaces);

View File

@ -12,7 +12,7 @@ widl \- Wine Interface Definition Language (IDL) compiler
When no options are used the program will generate a header file, and possibly When no options are used the program will generate a header file, and possibly
client and server stubs, proxy and dlldata files, a typelib, and a UUID file, client and server stubs, proxy and dlldata files, a typelib, and a UUID file,
depending on the contents of the IDL file. If any of the options \fB-c\fR, depending on the contents of the IDL file. If any of the options \fB-c\fR,
\fB-h\fR, \fB-p\fR, \fB-s\fR, \fB-t\fR, or \fB-u\fR are given, \fB-h\fR, \fB-p\fR, \fB-s\fR, \fB-t\fR, \fB-u\fR, or \fB--local-stubs\fR are given,
.B widl .B widl
will only generate the requested files, and no others. When run with will only generate the requested files, and no others. When run with
\fB--dlldata-only\fR, widl will only generate a dlldata file, and it will \fB--dlldata-only\fR, widl will only generate a dlldata file, and it will
@ -98,6 +98,11 @@ Set debug level to the nonnegative integer \fIn\fR. If
prefixed with \fB0x\fR, it will be interpretted as a hexidecimal prefixed with \fB0x\fR, it will be interpretted as a hexidecimal
number. For the meaning of values, see the \fBDebug\fR section. number. For the meaning of values, see the \fBDebug\fR section.
.PP .PP
.B Miscellaneous options:
.IP "\fB--local-stubs=\fIfile\fR"
Generate empty stubs for call_as/local methods in an object interface and
write them to \fIfile\fR.
.PP
.SH Debug .SH Debug
Debug level \fIn\fR is a bitmask with the following meaning: Debug level \fIn\fR is a bitmask with the following meaning:
* 0x01 Tell which resource is parsed (verbose mode) * 0x01 Tell which resource is parsed (verbose mode)