widl: Add a --local-stubs option.
This commit is contained in:
parent
e7636c13e5
commit
ea7ab4da66
|
@ -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");
|
||||
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");
|
||||
}
|
||||
fprintf(fp, "}\n\n");
|
||||
}
|
||||
else
|
||||
fprintf(fp, ";\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");
|
||||
}
|
||||
else {
|
||||
parser_warning("invalid call_as attribute (%s -> %s)\n", def->name, cas->name);
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue