Commit ea7ab4da authored by Dan Hipschman's avatar Dan Hipschman Committed by Alexandre Julliard

widl: Add a --local-stubs option.

parent e7636c13
......@@ -702,7 +702,6 @@ static void write_method_proto(const type_t *iface)
LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry )
{
const var_t *def = cur->def;
const var_t *cas = is_callas(def->attrs);
if (!is_local(def->attrs)) {
/* proxy prototype */
......@@ -721,30 +720,69 @@ static void write_method_proto(const type_t *iface)
fprintf(header, " PRPC_MESSAGE pRpcMessage,\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) {
const func_t *m;
LIST_FOR_EACH_ENTRY( m, iface->funcs, const func_t, entry )
if (!strcmp(m->def->name, cas->name)) break;
LIST_FOR_EACH_ENTRY(m, iface->funcs, const func_t, entry)
if (!strcmp(m->def->name, cas->name))
break;
if (&m->entry != iface->funcs) {
const var_t *mdef = m->def;
/* proxy prototype - use local prototype */
write_type_decl_left(header, mdef->type);
fprintf(header, " CALLBACK %s_", iface->name);
write_name(header, mdef);
fprintf(header, "_Proxy(\n");
write_args(header, m->args, iface->name, 1, TRUE);
fprintf(header, ");\n");
/* stub prototype - use remotable prototype */
write_type_decl_left(header, def->type);
fprintf(header, " __RPC_STUB %s_", iface->name);
write_name(header, mdef);
fprintf(header, "_Stub(\n");
write_args(header, cur->args, iface->name, 1, TRUE);
fprintf(header, ");\n");
write_type_decl_left(fp, mdef->type);
fprintf(fp, " CALLBACK %s_", iface->name);
write_name(fp, mdef);
fprintf(fp, "_Proxy(\n");
write_args(fp, m->args, iface->name, 1, TRUE);
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");
}
else {
parser_warning("invalid call_as attribute (%s -> %s)\n", def->name, cas->name);
fprintf(fp, "}\n\n");
}
else
fprintf(fp, ";\n");
/* stub prototype - use remotable prototype */
write_type_decl_left(fp, def->type);
fprintf(fp, " __RPC_STUB %s_", iface->name);
write_name(fp, mdef);
fprintf(fp, "_Stub(\n");
write_args(fp, cur->args, iface->name, 1, TRUE);
fprintf(fp, ")");
if (body)
/* Remotable methods must all return HRESULTs. */
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, "\n");
write_method_proto(iface);
write_locals(header, iface, FALSE);
fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name);
}
......
......@@ -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_interface(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_forward(type_t *cocl);
extern void write_typedef(type_t *type);
......
......@@ -816,6 +816,7 @@ interfacedef: interfacehdr inherit
$$->funcs = $4;
compute_method_indexes($$);
if (!parse_only && do_header) write_interface($$);
if (!parse_only && local_stubs) write_locals(local_stubs, $$, TRUE);
if (!parse_only && do_idfile) write_iid($$);
pointer_default = $1.old_pointer_default;
}
......@@ -828,6 +829,7 @@ interfacedef: interfacehdr inherit
$$->funcs = $6;
compute_method_indexes($$);
if (!parse_only && do_header) write_interface($$);
if (!parse_only && local_stubs) write_locals(local_stubs, $$, TRUE);
if (!parse_only && do_idfile) write_iid($$);
pointer_default = $1.old_pointer_default;
}
......
......@@ -62,6 +62,7 @@ static const char usage[] =
" -h Generate headers\n"
" -H file Name of header file (default is infile.h)\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"
" --oldnames Use old naming conventions\n"
" -p Generate proxy\n"
......@@ -108,6 +109,7 @@ int old_names = 0;
char *input_name;
char *header_name;
char *local_stubs_name;
char *header_token;
char *typelib_name;
char *dlldata_name;
......@@ -126,6 +128,7 @@ const char *prefix_server = "";
int line_number = 1;
FILE *header;
FILE *local_stubs;
FILE *proxy;
FILE *idfile;
......@@ -135,6 +138,7 @@ enum {
OLDNAMES_OPTION = CHAR_MAX + 1,
DLLDATA_OPTION,
DLLDATA_ONLY_OPTION,
LOCAL_STUBS_OPTION,
PREFIX_ALL_OPTION,
PREFIX_CLIENT_OPTION,
PREFIX_SERVER_OPTION
......@@ -145,6 +149,7 @@ static const char short_options[] =
static const struct option long_options[] = {
{ "dlldata", required_argument, 0, DLLDATA_OPTION },
{ "dlldata-only", no_argument, 0, DLLDATA_ONLY_OPTION },
{ "local-stubs", required_argument, 0, LOCAL_STUBS_OPTION },
{ "oldnames", no_argument, 0, OLDNAMES_OPTION },
{ "prefix-all", required_argument, 0, PREFIX_ALL_OPTION },
{ "prefix-client", required_argument, 0, PREFIX_CLIENT_OPTION },
......@@ -350,6 +355,10 @@ int main(int argc,char *argv[])
do_everything = 0;
do_dlldata = 1;
break;
case LOCAL_STUBS_OPTION:
do_everything = 0;
local_stubs_name = xstrdup(optarg);
break;
case OLDNAMES_OPTION:
old_names = 1;
break;
......@@ -554,6 +563,17 @@ int main(int argc,char *argv[])
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) {
idfile_token = make_token(idfile_name);
......@@ -587,6 +607,10 @@ int main(int argc,char *argv[])
fclose(header);
}
if (local_stubs) {
fclose(local_stubs);
}
if (do_idfile) {
fprintf(idfile, "\n");
end_cplusplus_guard(idfile);
......@@ -602,6 +626,8 @@ int main(int argc,char *argv[])
/* Everything has been done successfully, don't delete any files. */
set_everything(FALSE);
local_stubs_name = NULL;
return 0;
}
......@@ -612,6 +638,8 @@ static void rm_tempfile(void)
unlink(temp_name);
if (do_header)
unlink(header_name);
if (local_stubs_name)
unlink(local_stubs_name);
if (do_client)
unlink(client_name);
if (do_server)
......
......@@ -48,6 +48,7 @@ extern int old_names;
extern char *input_name;
extern char *header_name;
extern char *local_stubs_name;
extern char *typelib_name;
extern char *dlldata_name;
extern char *proxy_name;
......@@ -64,6 +65,7 @@ extern int line_number;
extern int char_number;
extern FILE* header;
extern FILE* local_stubs;
extern FILE* idfile;
extern void write_proxies(ifref_list_t *ifaces);
......
......@@ -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
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,
\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
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
......@@ -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
number. For the meaning of values, see the \fBDebug\fR section.
.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
Debug level \fIn\fR is a bitmask with the following meaning:
* 0x01 Tell which resource is parsed (verbose mode)
......
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