[RFC] widl: Add option to generate classfactory
Fabian Maurer
dark.shadow4 at web.de
Sat Nov 10 16:20:48 CST 2018
Since the com simplification with the macros is probably not feasible,
here an approach that reuses an old idea - using widl to generate
a classfactory.
Feedback appreciated!
---
dlls/uiribbon/main.c | 141 ----------------
dlls/uiribbon/uiribbon.c | 8 +-
dlls/uiribbon/uiribbon_classes.idl | 1 +
tools/makedep.c | 9 +-
tools/widl/Makefile.in | 1 +
tools/widl/factory.c | 250 +++++++++++++++++++++++++++++
tools/widl/parser.y | 1 +
tools/widl/widl.c | 23 ++-
tools/widl/widl.h | 3 +
9 files changed, 291 insertions(+), 146 deletions(-)
create mode 100644 tools/widl/factory.c
diff --git a/dlls/uiribbon/main.c b/dlls/uiribbon/main.c
index a76c349ad9..b54644599f 100644
--- a/dlls/uiribbon/main.c
+++ b/dlls/uiribbon/main.c
@@ -56,147 +56,6 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
return TRUE;
}
-typedef struct {
- IClassFactory IClassFactory_iface;
-
- LONG ref;
- HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, void **ppObj);
-} IClassFactoryImpl;
-
-static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
-{
- return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
-}
-
-struct object_creation_info
-{
- const CLSID *clsid;
- HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, void **ppObj);
-};
-
-static const struct object_creation_info object_creation[] =
-{
- { &CLSID_UIRibbonFramework, UIRibbonFrameworkImpl_Create },
-};
-
-static HRESULT WINAPI XFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, void **ppobj)
-{
- IClassFactoryImpl *This = impl_from_IClassFactory(iface);
-
- if (IsEqualGUID(riid, &IID_IUnknown)
- || IsEqualGUID(riid, &IID_IClassFactory))
- {
- IClassFactory_AddRef(iface);
- *ppobj = &This->IClassFactory_iface;
- return S_OK;
- }
-
- WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
- return E_NOINTERFACE;
-}
-
-static ULONG WINAPI XFCF_AddRef(LPCLASSFACTORY iface)
-{
- IClassFactoryImpl *This = impl_from_IClassFactory(iface);
- return InterlockedIncrement(&This->ref);
-}
-
-static ULONG WINAPI XFCF_Release(LPCLASSFACTORY iface)
-{
- IClassFactoryImpl *This = impl_from_IClassFactory(iface);
-
- ULONG ref = InterlockedDecrement(&This->ref);
-
- if (ref == 0)
- HeapFree(GetProcessHeap(), 0, This);
-
- return ref;
-}
-
-static HRESULT WINAPI XFCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, void **ppobj)
-{
- IClassFactoryImpl *This = impl_from_IClassFactory(iface);
- HRESULT hres;
- LPUNKNOWN punk;
-
- TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
-
- *ppobj = NULL;
- hres = This->pfnCreateInstance(pOuter, (void **) &punk);
- if (SUCCEEDED(hres)) {
- hres = IUnknown_QueryInterface(punk, riid, ppobj);
- IUnknown_Release(punk);
- }
- return hres;
-}
-
-static HRESULT WINAPI XFCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
-{
- IClassFactoryImpl *This = impl_from_IClassFactory(iface);
- FIXME("(%p)->(%d), stub!\n",This,dolock);
- return S_OK;
-}
-
-static const IClassFactoryVtbl XFCF_Vtbl =
-{
- XFCF_QueryInterface,
- XFCF_AddRef,
- XFCF_Release,
- XFCF_CreateInstance,
- XFCF_LockServer
-};
-
-/*******************************************************************************
- * Retrieves class object from a DLL object
- *
- * NOTES
- * Docs say returns STDAPI
- *
- * PARAMS
- * rclsid [I] CLSID for the class object
- * riid [I] Reference to identifier of interface for class object
- * ppv [O] Address of variable to receive interface pointer for riid
- *
- * RETURNS
- * Success: S_OK
- * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
- * E_UNEXPECTED
- */
-HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
-{
- unsigned int i;
- IClassFactoryImpl *factory;
-
- TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
-
- if ( !IsEqualGUID( &IID_IClassFactory, riid )
- && ! IsEqualGUID( &IID_IUnknown, riid) )
- return E_NOINTERFACE;
-
- for (i = 0; i < ARRAY_SIZE(object_creation); i++)
- {
- if (IsEqualGUID(object_creation[i].clsid, rclsid))
- break;
- }
-
- if (i == ARRAY_SIZE(object_creation))
- {
- FIXME("%s: no class found.\n", debugstr_guid(rclsid));
- return CLASS_E_CLASSNOTAVAILABLE;
- }
-
- factory = HeapAlloc(GetProcessHeap(), 0, sizeof(*factory));
- if (factory == NULL) return E_OUTOFMEMORY;
-
- factory->IClassFactory_iface.lpVtbl = &XFCF_Vtbl;
- factory->ref = 1;
-
- factory->pfnCreateInstance = object_creation[i].pfnCreateInstance;
-
- *ppv = &(factory->IClassFactory_iface);
- return S_OK;
-}
-
HRESULT WINAPI DllCanUnloadNow(void)
{
return S_FALSE;
diff --git a/dlls/uiribbon/uiribbon.c b/dlls/uiribbon/uiribbon.c
index 58ac51aece..5385af5430 100644
--- a/dlls/uiribbon/uiribbon.c
+++ b/dlls/uiribbon/uiribbon.c
@@ -156,7 +156,7 @@ static const IUIFrameworkVtbl IUIFramework_Vtbl =
UIRibbonFrameworkImpl_SetModes
};
-HRESULT UIRibbonFrameworkImpl_Create(IUnknown *pUnkOuter, void **ppObj)
+HRESULT UIRibbonFramework_Create(IUnknown *pUnkOuter, void **ppObj)
{
UIRibbonFrameworkImpl *object;
@@ -173,3 +173,9 @@ HRESULT UIRibbonFrameworkImpl_Create(IUnknown *pUnkOuter, void **ppObj)
return S_OK;
}
+
+HRESULT UIRibbonImageFromBitmapFactory_Create(IUnknown *unk_outer, void **obj)
+{
+ FIXME("(%p, %p) - stub!\n", unk_outer, obj);
+ return E_FAIL;
+}
diff --git a/dlls/uiribbon/uiribbon_classes.idl b/dlls/uiribbon/uiribbon_classes.idl
index bd8bdde6b6..78d79a13fc 100644
--- a/dlls/uiribbon/uiribbon_classes.idl
+++ b/dlls/uiribbon/uiribbon_classes.idl
@@ -17,5 +17,6 @@
*/
#pragma makedep register
+#pragma makedep factory
#include "uiribbon.idl"
diff --git a/tools/makedep.c b/tools/makedep.c
index e3bb04ae82..755635f5dc 100644
--- a/tools/makedep.c
+++ b/tools/makedep.c
@@ -100,6 +100,7 @@ struct incl_file
#define FLAG_RC_PO 0x010000 /* rc file contains translations */
#define FLAG_C_IMPLIB 0x020000 /* file is part of an import library */
#define FLAG_SFD_FONTS 0x040000 /* sfd file generated bitmap fonts */
+#define FLAG_IDL_FACTORY 0x080000 /* generates a factory (_f.c) file */
static const struct
{
@@ -114,7 +115,8 @@ static const struct
{ FLAG_IDL_PROXY, "_p.c" },
{ FLAG_IDL_SERVER, "_s.c" },
{ FLAG_IDL_REGISTER, "_r.res" },
- { FLAG_IDL_HEADER, ".h" }
+ { FLAG_IDL_HEADER, ".h" },
+ { FLAG_IDL_FACTORY, "_f.c" }
};
#define HASH_SIZE 997
@@ -996,6 +998,7 @@ static void parse_pragma_directive( struct file *source, char *str )
else if (!strcmp( flag, "typelib" )) source->flags |= FLAG_IDL_TYPELIB;
else if (!strcmp( flag, "register" )) source->flags |= FLAG_IDL_REGISTER;
else if (!strcmp( flag, "regtypelib" )) source->flags |= FLAG_IDL_REGTYPELIB;
+ else if (!strcmp( flag, "factory" )) source->flags |= FLAG_IDL_FACTORY;
}
else if (strendswith( source->name, ".rc" ))
{
@@ -1821,6 +1824,10 @@ static void add_generated_sources( struct makefile *make )
add_dependency( file->file, replace_extension( source->name, ".idl", ".h" ), INCL_NORMAL );
add_all_includes( make, file, file->file );
}
+ if (source->file->flags & FLAG_IDL_FACTORY)
+ {
+ add_generated_source( make, replace_extension( source->name, ".idl", "_f.c" ), NULL );
+ }
if (source->file->flags & FLAG_IDL_IDENT)
{
file = add_generated_source( make, replace_extension( source->name, ".idl", "_i.c" ), NULL );
diff --git a/tools/widl/Makefile.in b/tools/widl/Makefile.in
index e06d6cc5b3..3e725a1c69 100644
--- a/tools/widl/Makefile.in
+++ b/tools/widl/Makefile.in
@@ -4,6 +4,7 @@ MANPAGES = widl.man.in
C_SRCS = \
client.c \
expr.c \
+ factory.c \
hash.c \
header.c \
proxy.c \
diff --git a/tools/widl/factory.c b/tools/widl/factory.c
new file mode 100644
index 0000000000..4ed0459b20
--- /dev/null
+++ b/tools/widl/factory.c
@@ -0,0 +1,250 @@
+/*
+ * IDL Compiler
+ *
+ * Copyright 2018 Fabian Maurer
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <string.h>
+#include <ctype.h>
+
+#include "widl.h"
+#include "utils.h"
+#include "parser.h"
+#include "header.h"
+
+#include "widltypes.h"
+#include "typegen.h"
+#include "expr.h"
+
+static FILE* factory;
+static int indent = 0;
+
+static void print_factory( const char *format, ... ) __attribute__((format (printf, 1, 2)));
+static void print_factory( const char *format, ... )
+{
+ va_list va;
+ va_start(va, format);
+ print(factory, indent, format, va);
+ va_end(va);
+}
+
+static void init_factory(void)
+{
+ if (factory) return;
+ if (!(factory = fopen(factory_name, "w")))
+ error("Could not open %s for output\n", factory_name);
+
+ print_factory("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name);
+ print_factory("#define COBJMACROS\n");
+ print_factory("#include \"%s\"\n", header_name);
+ print_factory("#include \"wine/debug.h\"\n");
+ print_factory("\n");
+ print_factory("WINE_DEFAULT_DEBUG_CHANNEL(classfactory);\n");
+ print_factory("const char *source = \"%s\";", dup_basename(input_name, ".idl"));
+ print_factory("\n");
+ print_factory("\n");
+
+}
+
+static void write_class_array(const statement_list_t *stmts)
+{
+ const statement_t *stmt;
+
+ /* Declare all functions which need to be provided for the factory */
+ LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
+ {
+ if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_COCLASS)
+ {
+ type_t *object = stmt->u.type;
+ print_factory("HRESULT %s_Create(IUnknown *unk_outer, void **obj);\n", object->name);
+ }
+ }
+ print_factory("\n");
+
+
+ print_factory("struct object_creation_info\n");
+ print_factory("{\n");
+ print_factory(" const CLSID *clsid;\n");
+ print_factory(" HRESULT (*pfnCreateInstance)(IUnknown *unk_outer, void **obj);\n");
+ print_factory("};\n");
+ print_factory("\n");
+
+ print_factory("static const struct object_creation_info object_creation[] =\n");
+ print_factory("{\n");
+
+ LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
+ {
+ if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_COCLASS)
+ {
+ type_t *object = stmt->u.type;
+ print_factory(" {&CLSID_%s, &%s_Create },\n", object->name, object->name);
+ }
+ }
+ print_factory("};\n");
+}
+
+void write_factory_methods(void)
+{
+ print_factory("typedef struct {\n");
+ print_factory(" IClassFactory IClassFactory_iface;\n");
+ print_factory(" LONG ref;\n");
+ print_factory(" HRESULT (*pfnCreateInstance)(IUnknown *unk_outer, void **obj);\n");
+ print_factory("} IClassFactoryImpl;\n");
+ print_factory("\n");
+
+ print_factory("static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)\n");
+ print_factory("{\n");
+ print_factory(" return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);\n");
+ print_factory("}\n");
+ print_factory("\n");
+
+ print_factory("static HRESULT WINAPI classfactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj)\n");
+ print_factory("{\n");
+ print_factory(" IClassFactoryImpl *impl = impl_from_IClassFactory(iface);\n");
+ print_factory("\n");
+ print_factory(" if (IsEqualGUID(riid, &IID_IUnknown)\n");
+ print_factory(" || IsEqualGUID(riid, &IID_IClassFactory))\n");
+ print_factory(" {\n");
+ print_factory(" IClassFactory_AddRef(iface);\n");
+ print_factory(" *ppobj = &impl->IClassFactory_iface;\n");
+ print_factory(" return S_OK;\n");
+ print_factory(" }\n");
+ print_factory("\n");
+ print_factory(" WARN(\"%%s - (%%p)->(%%s,%%p),not found\\n\", source, impl, debugstr_guid(riid), ppobj);\n");
+ print_factory(" return E_NOINTERFACE;\n");
+ print_factory("}\n");
+ print_factory("\n");
+
+ print_factory("static ULONG WINAPI classfactory_AddRef(IClassFactory *iface)\n");
+ print_factory("{\n");
+ print_factory(" IClassFactoryImpl *This = impl_from_IClassFactory(iface);\n");
+ print_factory(" return InterlockedIncrement(&This->ref);\n");
+ print_factory("}\n");
+ print_factory("\n");
+
+ print_factory("static ULONG WINAPI classfactory_Release(IClassFactory *iface)\n");
+ print_factory("{\n");
+ print_factory(" IClassFactoryImpl *impl = impl_from_IClassFactory(iface);\n");
+ print_factory(" ULONG ref = InterlockedDecrement(&impl->ref);\n");
+ print_factory("\n");
+ print_factory(" if (ref == 0)\n");
+ print_factory(" HeapFree(GetProcessHeap(), 0, impl);\n");
+ print_factory("\n");
+ print_factory(" return ref;\n");
+ print_factory("}\n");
+ print_factory("\n");
+
+ print_factory("static HRESULT WINAPI classfactory_CreateInstance(IClassFactory *iface, IUnknown *outer_unk, REFIID riid, void **ppobj)\n");
+ print_factory("{\n");
+ print_factory(" IClassFactoryImpl *impl = impl_from_IClassFactory(iface);\n");
+ print_factory(" HRESULT hres;\n");
+ print_factory(" IUnknown *unk;\n");
+ print_factory("\n");
+ print_factory(" TRACE(\"%%s - (%%p)->(%%p,%%s,%%p)\\n\", source, impl, outer_unk, debugstr_guid(riid), ppobj);\n");
+ print_factory("\n");
+ print_factory(" *ppobj = NULL;\n");
+ print_factory(" hres = impl->pfnCreateInstance(outer_unk, (void **) &unk);\n");
+ print_factory(" if (SUCCEEDED(hres))\n");
+ print_factory(" {\n");
+ print_factory(" hres = IUnknown_QueryInterface(unk, riid, ppobj);\n");
+ print_factory(" IUnknown_Release(unk);\n");
+ print_factory(" }\n");
+ print_factory(" return hres;\n");
+ print_factory("}\n");
+ print_factory("\n");
+
+ print_factory("static HRESULT WINAPI classfactory_LockServer(IClassFactory *iface, BOOL dolock)\n");
+ print_factory("{\n");
+ print_factory(" IClassFactoryImpl *impl = impl_from_IClassFactory(iface);\n");
+ print_factory(" FIXME(\"%%s - (%%p)->(%%d), stub!\\n\", source, impl, dolock);\n");
+ print_factory(" return S_OK;\n");
+ print_factory("}\n");
+ print_factory("\n");
+
+ print_factory("static const IClassFactoryVtbl classfactory_Vtbl =\n");
+ print_factory("{\n");
+ print_factory(" classfactory_QueryInterface,\n");
+ print_factory(" classfactory_AddRef,\n");
+ print_factory(" classfactory_Release,\n");
+ print_factory(" classfactory_CreateInstance,\n");
+ print_factory(" classfactory_LockServer\n");
+ print_factory("};\n");
+ print_factory("\n");
+
+ print_factory("HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)\n");
+ print_factory("{\n");
+ print_factory(" unsigned int i;\n");
+ print_factory(" IClassFactoryImpl *factory;\n");
+ print_factory("\n");
+ print_factory(" TRACE(\"(%%s - %%s,%%s,%%p)\\n\", source, debugstr_guid(rclsid), debugstr_guid(riid), ppv);\n");
+ print_factory("\n");
+ print_factory(" if (!IsEqualGUID(&IID_IClassFactory, riid)\n");
+ print_factory(" && !IsEqualGUID( &IID_IUnknown, riid))\n");
+ print_factory(" return E_NOINTERFACE;\n");
+ print_factory("\n");
+ print_factory(" for (i = 0; i < ARRAY_SIZE(object_creation); i++)\n");
+ print_factory(" {\n");
+ print_factory(" if (IsEqualGUID(object_creation[i].clsid, rclsid))\n");
+ print_factory(" break;\n");
+ print_factory(" }\n");
+ print_factory("\n");
+ print_factory(" if (i == ARRAY_SIZE(object_creation))\n");
+ print_factory(" {\n");
+ print_factory(" FIXME(\"%%s - %%s: no class found.\\n\", source, debugstr_guid(rclsid));\n");
+ print_factory(" return CLASS_E_CLASSNOTAVAILABLE;\n");
+ print_factory(" }\n");
+ print_factory("\n");
+ print_factory(" factory = HeapAlloc(GetProcessHeap(), 0, sizeof(*factory));\n");
+ print_factory(" if (factory == NULL)\n");
+ print_factory(" return E_OUTOFMEMORY;\n");
+ print_factory("\n");
+ print_factory(" factory->IClassFactory_iface.lpVtbl = &classfactory_Vtbl;\n");
+ print_factory(" factory->ref = 1;\n");
+ print_factory("\n");
+ print_factory(" factory->pfnCreateInstance = object_creation[i].pfnCreateInstance;\n");
+ print_factory("\n");
+ print_factory(" *ppv = &factory->IClassFactory_iface;\n");
+ print_factory(" return S_OK;\n");
+ print_factory("}\n");
+}
+
+void write_factory(const statement_list_t *stmts)
+{
+
+ if (!do_factory)
+ return;
+
+ if (!stmts)
+ return;
+
+ init_factory();
+ if (!factory)
+ return;
+
+ write_class_array(stmts);
+ write_factory_methods();
+
+ fclose(factory);
+}
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index d979394182..ed46b216d0 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -334,6 +334,7 @@ input: gbl_statements m_acf { fix_incomplete();
write_typelib_regscript($1);
write_dlldata($1);
write_local_stubs($1);
+ write_factory($1);
}
;
diff --git a/tools/widl/widl.c b/tools/widl/widl.c
index 410efb4c4c..6e10a5d092 100644
--- a/tools/widl/widl.c
+++ b/tools/widl/widl.c
@@ -58,6 +58,7 @@ static const char usage[] =
" -d n Set debug level to 'n'\n"
" -D id[=val] Define preprocessor identifier id=val\n"
" -E Preprocess only\n"
+" -f Generate class factory\n"
" --help Display this help and exit\n"
" -h Generate headers\n"
" -H file Name of header file (default is infile.h)\n"
@@ -111,6 +112,7 @@ int do_server = 0;
int do_regscript = 0;
int do_idfile = 0;
int do_dlldata = 0;
+int do_factory = 0;
static int no_preprocess = 0;
int old_names = 0;
int do_win32 = 1;
@@ -137,6 +139,7 @@ char *server_name;
char *server_token;
char *regscript_name;
char *regscript_token;
+char *factory_name;
static char *idfile_name;
char *temp_name;
const char *prefix_client = "";
@@ -172,7 +175,7 @@ enum {
};
static const char short_options[] =
- "b:cC:d:D:EhH:I:m:No:O:pP:rsS:tT:uU:VW";
+ "b:cC:d:D:EfhH:I:m:No:O:pP:rsS:tT:uU:VW";
static const struct option long_options[] = {
{ "acf", 1, NULL, ACF_OPTION },
{ "app_config", 0, NULL, APP_CONFIG_OPTION },
@@ -319,6 +322,7 @@ static void set_everything(int x)
do_regscript = x;
do_idfile = x;
do_dlldata = x;
+ do_factory = x;
}
void start_cplusplus_guard(FILE *fp)
@@ -647,6 +651,10 @@ int main(int argc,char *argv[])
do_everything = 0;
preprocess_only = 1;
break;
+ case 'f':
+ do_everything = 0;
+ do_factory = 1;
+ break;
case 'h':
do_everything = 0;
do_header = 1;
@@ -725,7 +733,7 @@ int main(int argc,char *argv[])
/* if nothing specified, try to guess output type from the output file name */
if (output_name && do_everything && !do_header && !do_typelib && !do_proxies &&
- !do_client && !do_server && !do_regscript && !do_idfile && !do_dlldata)
+ !do_client && !do_server && !do_regscript && !do_idfile && !do_dlldata && !do_factory)
{
do_everything = 0;
if (strendswith( output_name, ".h" )) do_header = 1;
@@ -737,6 +745,7 @@ int main(int argc,char *argv[])
else if (strendswith( output_name, "_r.res" )) do_regscript = 1;
else if (strendswith( output_name, "_t.res" )) do_typelib = 1;
else if (strendswith( output_name, "dlldata.c" )) do_dlldata = 1;
+ else if (strendswith( output_name, "_f.c" )) do_factory = 1;
else do_everything = 1;
}
@@ -747,7 +756,7 @@ int main(int argc,char *argv[])
if (!output_name) output_name = dup_basename(input_name, ".idl");
if (do_header + do_typelib + do_proxies + do_client +
- do_server + do_regscript + do_idfile + do_dlldata == 1)
+ do_server + do_regscript + do_idfile + do_dlldata + do_factory == 1)
{
if (do_header) header_name = output_name;
else if (do_typelib) typelib_name = output_name;
@@ -757,6 +766,7 @@ int main(int argc,char *argv[])
else if (do_regscript) regscript_name = output_name;
else if (do_idfile) idfile_name = output_name;
else if (do_dlldata) dlldata_name = output_name;
+ else if (do_factory) factory_name = output_name;
}
if (!dlldata_name && do_dlldata)
@@ -832,6 +842,11 @@ int main(int argc,char *argv[])
strcat(idfile_name, "_i.c");
}
+ if (!factory_name && do_factory) {
+ factory_name = dup_basename(input_name, ".idl");
+ strcat(factory_name, "_f.c");
+ }
+
if (do_proxies) proxy_token = dup_basename_token(proxy_name,"_p.c");
if (do_client) client_token = dup_basename_token(client_name,"_c.c");
if (do_server) server_token = dup_basename_token(server_name,"_s.c");
@@ -922,4 +937,6 @@ static void rm_tempfile(void)
unlink(proxy_name);
if (do_typelib)
unlink(typelib_name);
+ if (do_factory)
+ unlink(factory_name);
}
diff --git a/tools/widl/widl.h b/tools/widl/widl.h
index 118e2245c2..759a7b818e 100644
--- a/tools/widl/widl.h
+++ b/tools/widl/widl.h
@@ -44,6 +44,7 @@ extern int do_server;
extern int do_regscript;
extern int do_idfile;
extern int do_dlldata;
+extern int do_factory;
extern int old_names;
extern int do_win32;
extern int do_win64;
@@ -66,6 +67,7 @@ extern char *client_name;
extern char *client_token;
extern char *server_name;
extern char *server_token;
+extern char *factory_name;
extern char *regscript_name;
extern char *regscript_token;
extern const char *prefix_client;
@@ -94,6 +96,7 @@ extern void write_typelib_regscript(const statement_list_t *stmts);
extern void output_typelib_regscript( const typelib_t *typelib );
extern void write_local_stubs(const statement_list_t *stmts);
extern void write_dlldata(const statement_list_t *stmts);
+extern void write_factory(const statement_list_t *stmts);
extern void start_cplusplus_guard(FILE *fp);
extern void end_cplusplus_guard(FILE *fp);
--
2.19.1
More information about the wine-devel
mailing list