From: Steve Lhomme robux4@ycbcr.xyz
Otherwise we end up with types like ABI::IInspectable.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
With this last series, it should now be possible to declare WinRT interfaces in IDLs, and implement the corresponding stubs in Wine. The C interfaces should now be fully compatible with MIDL.
I still have a patch from Steve Lhomme to make C++ interfaces compatible too but I have to clean it up first.
tools/widl/typetree.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index 9d0b5576d45..40d987b7a28 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -105,9 +105,10 @@ static size_t append_namespace(char **buf, size_t *len, size_t pos, struct names static size_t append_namespaces(char **buf, size_t *len, size_t pos, struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, const char *abi_prefix) { + int nested = namespace && !is_global_namespace(namespace); size_t n = 0; n += strappend(buf, len, pos + n, "%s", prefix); - n += append_namespace(buf, len, pos + n, namespace, separator, abi_prefix); + if (nested) n += append_namespace(buf, len, pos + n, namespace, separator, abi_prefix); n += strappend(buf, len, pos + n, "%s", suffix); return n; }
From: Steve Lhomme robux4@ycbcr.xyz
This is what MIDL does and avoid mismatching and even fixes some compiling issues.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- tools/widl/header.c | 4 ++-- tools/widl/parser.y | 6 ++++++ tools/widl/typetree.c | 15 +++++++++++++++ tools/widl/typetree.h | 1 + tools/widl/widltypes.h | 1 + 5 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c index 3c8ad09bd63..5ab8a3cc26f 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -465,13 +465,13 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i case TYPE_INTERFACE: case TYPE_MODULE: case TYPE_COCLASS: - fprintf(h, "%s", name); + fprintf(h, "%s", type_get_qualified_name(t, name_type)); break; case TYPE_RUNTIMECLASS: fprintf(h, "%s", type_get_name(type_runtimeclass_get_default_iface(t), name_type)); break; case TYPE_DELEGATE: - fprintf(h, "%s", type_get_name(type_delegate_get_iface(t), name_type)); + fprintf(h, "%s", type_get_qualified_name(type_delegate_get_iface(t), name_type)); break; case TYPE_VOID: fprintf(h, "void"); diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 4c115adf4ab..eb8035c39bc 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -2073,9 +2073,15 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in nt = xmalloc(sizeof(struct rtype)); nt->name = name; if (is_global_namespace(namespace)) + { type->c_name = name; + type->qualified_name = name; + } else + { type->c_name = format_namespace(namespace, "__x_", "_C", name, use_abi_namespace ? "ABI" : NULL); + type->qualified_name = format_namespace(namespace, "", "::", name, use_abi_namespace ? "ABI" : NULL); + } nt->type = type; nt->t = t; nt->next = namespace->type_hash[hash]; diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index 40d987b7a28..319dd4ae65a 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -51,6 +51,7 @@ type_t *make_type(enum type_type type) t->attrs = NULL; t->c_name = NULL; t->signature = NULL; + t->qualified_name = NULL; memset(&t->details, 0, sizeof(t->details)); t->typestring_offset = 0; t->ptrdesc = 0; @@ -91,6 +92,19 @@ const char *type_get_name(const type_t *type, enum name_type name_type) return NULL; }
+const char *type_get_qualified_name(const type_t *type, enum name_type name_type) +{ + switch(name_type) { + case NAME_DEFAULT: + return type->qualified_name; + case NAME_C: + return type->c_name; + } + + assert(0); + return NULL; +} + static size_t append_namespace(char **buf, size_t *len, size_t pos, struct namespace *namespace, const char *separator, const char *abi_prefix) { int nested = namespace && !is_global_namespace(namespace); @@ -820,6 +834,7 @@ static void compute_delegate_iface_names(type_t *delegate, type_t *type, typeref iface->name = strmake("I%s", delegate->name); if (type) iface->c_name = format_parameterized_type_c_name(type, params, "I"); else iface->c_name = format_namespace(delegate->namespace, "__x_", "_C", iface->name, use_abi_namespace ? "ABI" : NULL); + iface->qualified_name = format_namespace(delegate->namespace, "", "::", iface->name, use_abi_namespace ? "ABI" : NULL); }
type_t *type_delegate_declare(char *name, struct namespace *namespace) diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h index c8bccc2fec9..805e96a9305 100644 --- a/tools/widl/typetree.h +++ b/tools/widl/typetree.h @@ -75,6 +75,7 @@ type_t *type_parameterized_type_specialize_declare(type_t *type, typeref_list_t type_t *type_parameterized_type_specialize_define(type_t *type); int type_is_equal(const type_t *type1, const type_t *type2); const char *type_get_name(const type_t *type, enum name_type name_type); +const char *type_get_qualified_name(const type_t *type, enum name_type name_type); char *gen_name(void); extern int is_attr(const attr_list_t *list, enum attr_type t);
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index e01bd122b45..81646cae1d1 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -503,6 +503,7 @@ struct _type_t { } details; const char *c_name; const char *signature; + const char *qualified_name; unsigned int typestring_offset; unsigned int ptrdesc; /* used for complex structs */ int typelib_idx;
Signed-off-by: Jacek Caban jacek@codeweavers.com
From: Steve Lhomme robux4@ycbcr.xyz
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- tools/widl/header.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/tools/widl/header.c b/tools/widl/header.c index 5ab8a3cc26f..e1dcab9b75b 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -1482,6 +1482,8 @@ static void write_forward(FILE *header, type_t *iface) fprintf(header, "#define __%s_FWD_DEFINED__\n", iface->c_name); fprintf(header, "typedef interface %s %s;\n", iface->c_name, iface->c_name); fprintf(header, "#ifdef __cplusplus\n"); + if (iface->namespace && !is_global_namespace(iface->namespace)) + fprintf(header, "#define %s %s\n", iface->c_name, iface->qualified_name); write_namespace_start(header, iface->namespace); if (strchr(iface->name, '<')) write_line(header, 0, "template<> struct %s;", iface->name); else write_line(header, 0, "interface %s;", iface->name);
Signed-off-by: Jacek Caban jacek@codeweavers.com
From: Steve Lhomme robux4@ycbcr.xyz
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- tools/widl/header.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c index e1dcab9b75b..82aad0f11ca 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -135,15 +135,13 @@ static void write_guid(FILE *f, const char *guid_prefix, const char *name, const
static void write_uuid_decl(FILE *f, type_t *type, const UUID *uuid) { - char *name = format_namespace(type->namespace, "", "::", type->name, use_abi_namespace ? "ABI" : NULL); fprintf(f, "#ifdef __CRT_UUID_DECL\n"); fprintf(f, "__CRT_UUID_DECL(%s, 0x%08x, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x," "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n", - name, uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1], + type->c_name, uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7]); fprintf(f, "#endif\n"); - free(name); }
static const char *uuid_string(const UUID *uuid)
Signed-off-by: Jacek Caban jacek@codeweavers.com
This generates additional macros to help keeping implementation simple, guarded with WIDL_USING ifdefs, like this:
#ifdef WIDL_USING_WINDOWS_FOO_IFOO #define IFooVtbl __x_ABI_CWindows_CFoo_CIFooVtbl #define IFoo __x_ABI_CWindows_CFoo_CIFoo #define IFoo_DoFoo __x_ABI_CWindows_CFoo_CIFoo_DoFoo #endif /* WIDL_USING_WINDOWS_FOO_IFOO */
Implementation files can define the desired WIDL_USING preprocessor macros before including the header, and then implement or use the interface methods with the simple non-prefixed names instead.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- tools/widl/header.c | 68 ++++++++++++++++++++++++++++++++++++++++++ tools/widl/typetree.c | 19 ++++++++++++ tools/widl/widltypes.h | 1 + 3 files changed, 88 insertions(+)
diff --git a/tools/widl/header.c b/tools/widl/header.c index 82aad0f11ca..8ca74d5a6f4 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -48,6 +48,8 @@ static void write_type_v(FILE *f, const decl_spec_t *t, int is_field, int declon static void write_apicontract_guard_start(FILE *header, const expr_t *expr); static void write_apicontract_guard_end(FILE *header, const expr_t *expr);
+static void write_widl_using_macros(FILE *header, type_t *iface); + static void indent(FILE *h, int delta) { int c; @@ -604,6 +606,7 @@ static void write_type_definition(FILE *f, type_t *t, int declonly) fprintf(f, "#else\n"); write_type_left(f, &ds, NAME_C, declonly, TRUE); fprintf(f, ";\n"); + if (winrt_mode) write_widl_using_macros(f, t); fprintf(f, "#endif\n\n"); } if (contract) write_apicontract_guard_end(f, contract); @@ -1536,6 +1539,70 @@ static void write_com_interface_start(FILE *header, const type_t *iface) fprintf(header,"#define __%s_%sINTERFACE_DEFINED__\n\n", iface->c_name, dispinterface ? "DISP" : ""); }
+static char *get_winrt_guard_macro(type_t *iface) +{ + unsigned int len; + char *macro, *tmp = (char *)iface->c_name; + int i; + + if (!strncmp(tmp, "__x", 3)) tmp += 3; + if (!strncmp(tmp, "_ABI", 4)) tmp += 4; + macro = xstrdup(tmp); + + len = strlen(macro) + 1; + for (tmp = strstr(macro, "__F"); tmp; tmp = strstr(tmp, "__F")) + memmove(tmp + 1, tmp + 3, len - (tmp - macro) - 3); + for (tmp = strstr(macro, "__C"); tmp; tmp = strstr(tmp, "__C")) + memmove(tmp + 1, tmp + 3, len - (tmp - macro) - 3); + for (tmp = strstr(macro, "_C"); tmp; tmp = strstr(tmp, "_C")) + memmove(tmp + 1, tmp + 2, len - (tmp - macro) - 2); + + for (i = strlen(macro); i > 0; --i) macro[i - 1] = toupper(macro[i - 1]); + + return macro; +} + +static void write_widl_using_method_macros(FILE *header, const type_t *iface, const type_t *top_iface) +{ + const statement_t *stmt; + const char *name = top_iface->short_name ? top_iface->short_name : top_iface->name; + + if (type_iface_get_inherit(iface)) write_widl_using_method_macros(header, type_iface_get_inherit(iface), top_iface); + + STATEMENTS_FOR_EACH_FUNC(stmt, type_iface_get_stmts(iface)) + { + const var_t *func = stmt->u.var; + const char *func_name; + + if (is_override_method(iface, top_iface, func)) continue; + if (is_callas(func->attrs)) continue; + + func_name = get_name(func); + fprintf(header, "#define %s_%s %s_%s\n", name, func_name, top_iface->c_name, func_name); + } +} + +static void write_widl_using_macros(FILE *header, type_t *iface) +{ + const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); + const char *name = iface->short_name ? iface->short_name : iface->name; + char *macro; + + if (!strcmp(iface->name, iface->c_name)) return; + + macro = get_winrt_guard_macro(iface); + fprintf(header, "#ifdef WIDL_USING%s\n", macro); + + if (uuid) fprintf(header, "#define IID_%s IID_%s\n", name, iface->c_name); + if (iface->type_type == TYPE_INTERFACE) fprintf(header, "#define %sVtbl %sVtbl\n", name, iface->c_name); + fprintf(header, "#define %s %s\n", name, iface->c_name); + + if (iface->type_type == TYPE_INTERFACE) write_widl_using_method_macros(header, iface, iface); + + fprintf(header, "#endif /* WIDL_USING_%s */\n", macro); + free(macro); +} + static void write_com_interface_end(FILE *header, type_t *iface) { int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE); @@ -1608,6 +1675,7 @@ static void write_com_interface_end(FILE *header, type_t *iface) fprintf(header, "#else\n"); write_inline_wrappers(header, type, type, iface->c_name); fprintf(header, "#endif\n"); + if (winrt_mode) write_widl_using_macros(header, iface); fprintf(header, "#endif\n"); fprintf(header, "\n"); fprintf(header, "#endif\n"); diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index 319dd4ae65a..8bce314018a 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -52,6 +52,7 @@ type_t *make_type(enum type_type type) t->c_name = NULL; t->signature = NULL; t->qualified_name = NULL; + t->short_name = NULL; memset(&t->details, 0, sizeof(t->details)); t->typestring_offset = 0; t->ptrdesc = 0; @@ -334,6 +335,22 @@ static char *format_parameterized_type_signature(type_t *type, typeref_list_t *p return buf; }
+static char *format_parameterized_type_short_name(type_t *type, typeref_list_t *params, const char *prefix) +{ + size_t len = 0, pos = 0; + char *buf = NULL; + typeref_t *ref; + + pos += strappend(&buf, &len, pos, "%s%s", prefix, type->name); + if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry) + { + for (type = ref->type; type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) {} + pos += strappend(&buf, &len, pos, "_%s", type->name); + } + + return buf; +} + type_t *type_new_function(var_list_t *args) { var_t *arg; @@ -1151,11 +1168,13 @@ type_t *type_parameterized_type_specialize_declare(type_t *type, typeref_list_t new_type->name = format_parameterized_type_name(type, params); reg_type(new_type, new_type->name, new_type->namespace, 0); new_type->c_name = format_parameterized_type_c_name(type, params, ""); + new_type->short_name = format_parameterized_type_short_name(type, params, "");
if (new_type->type_type == TYPE_DELEGATE) { new_type->details.delegate.iface = duptype(tmpl->details.delegate.iface, 0); compute_delegate_iface_names(new_type, type, params); + new_type->details.delegate.iface->short_name = format_parameterized_type_short_name(type, params, "I"); }
return new_type; diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 81646cae1d1..bedba40d903 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -504,6 +504,7 @@ struct _type_t { const char *c_name; const char *signature; const char *qualified_name; + const char *short_name; unsigned int typestring_offset; unsigned int ptrdesc; /* used for complex structs */ int typelib_idx;
Hi Rémi,
On 19.02.2021 12:04, Rémi Bernon wrote:
This generates additional macros to help keeping implementation simple, guarded with WIDL_USING ifdefs, like this:
#ifdef WIDL_USING_WINDOWS_FOO_IFOO
I would find it more readable if we didn't follow all-uppercase for macro rule here, something like:
#define WIDL_using_Windows_Foo_IFoo
But it's a matter of taste, so I'm mentioning it just for consideration.
#define IFooVtbl __x_ABI_CWindows_CFoo_CIFooVtbl #define IFoo __x_ABI_CWindows_CFoo_CIFoo
Typedefs for those would express it a bit more precisely in C (although we will need macros for other things anyway, so...).
#define IFoo_DoFoo __x_ABI_CWindows_CFoo_CIFoo_DoFoo #endif /* WIDL_USING_WINDOWS_FOO_IFOO */
Implementation files can define the desired WIDL_USING preprocessor macros before including the header, and then implement or use the interface methods with the simple non-prefixed names instead.
How about extending it a bit more to allow specifying entire namespaces in using statements, so something like:
#define WIDL_using_Windows_Foo
would have an effect on all interfaces in this exact namespace.
Signed-off-by: Rémi Bernonrbernon@codeweavers.com
tools/widl/header.c | 68 ++++++++++++++++++++++++++++++++++++++++++ tools/widl/typetree.c | 19 ++++++++++++ tools/widl/widltypes.h | 1 + 3 files changed, 88 insertions(+)
diff --git a/tools/widl/header.c b/tools/widl/header.c index 82aad0f11ca..8ca74d5a6f4 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -48,6 +48,8 @@ static void write_type_v(FILE *f, const decl_spec_t *t, int is_field, int declon static void write_apicontract_guard_start(FILE *header, const expr_t *expr); static void write_apicontract_guard_end(FILE *header, const expr_t *expr);
+static void write_widl_using_macros(FILE *header, type_t *iface);
- static void indent(FILE *h, int delta) { int c;
@@ -604,6 +606,7 @@ static void write_type_definition(FILE *f, type_t *t, int declonly) fprintf(f, "#else\n"); write_type_left(f, &ds, NAME_C, declonly, TRUE); fprintf(f, ";\n");
if (winrt_mode) write_widl_using_macros(f, t); fprintf(f, "#endif\n\n"); } if (contract) write_apicontract_guard_end(f, contract);
@@ -1536,6 +1539,70 @@ static void write_com_interface_start(FILE *header, const type_t *iface) fprintf(header,"#define __%s_%sINTERFACE_DEFINED__\n\n", iface->c_name, dispinterface ? "DISP" : ""); }
+static char *get_winrt_guard_macro(type_t *iface) +{
- unsigned int len;
- char *macro, *tmp = (char *)iface->c_name;
- int i;
- if (!strncmp(tmp, "__x", 3)) tmp += 3;
- if (!strncmp(tmp, "_ABI", 4)) tmp += 4;
- macro = xstrdup(tmp);
- len = strlen(macro) + 1;
- for (tmp = strstr(macro, "__F"); tmp; tmp = strstr(tmp, "__F"))
memmove(tmp + 1, tmp + 3, len - (tmp - macro) - 3);
- for (tmp = strstr(macro, "__C"); tmp; tmp = strstr(tmp, "__C"))
memmove(tmp + 1, tmp + 3, len - (tmp - macro) - 3);
- for (tmp = strstr(macro, "_C"); tmp; tmp = strstr(tmp, "_C"))
memmove(tmp + 1, tmp + 2, len - (tmp - macro) - 2);
- for (i = strlen(macro); i > 0; --i) macro[i - 1] = toupper(macro[i - 1]);
- return macro;
+}
Could you just compute it from namespace and name stored in type_t instead of parsing a previously computed string? It looks like a job for format_namespace().
Thanks,
Jacek
Hi Jacek!
On 2/19/21 5:48 PM, Jacek Caban wrote:
Hi Rémi,
On 19.02.2021 12:04, Rémi Bernon wrote:
This generates additional macros to help keeping implementation simple, guarded with WIDL_USING ifdefs, like this:
#ifdef WIDL_USING_WINDOWS_FOO_IFOO
I would find it more readable if we didn't follow all-uppercase for macro rule here, something like:
#define WIDL_using_Windows_Foo_IFoo
But it's a matter of taste, so I'm mentioning it just for consideration.
Yeah I don't really like it much, but I can see one reason to make something like that, which would also possibly solve the [1] below:
For making things simpler to type, it could just be the type C name prefixed by WIDL_USING_, like in:
#define WIDL_USING_CWindows_CGaming_CInput_CIRawGameController
The generation of the guard macros would just have to remove the __x_ABI_ prefix, and developers just need to copy paste the type names they want without having to remove the C prefixes or mess with the name case.
#define IFooVtbl __x_ABI_CWindows_CFoo_CIFooVtbl #define IFoo __x_ABI_CWindows_CFoo_CIFoo
Typedefs for those would express it a bit more precisely in C (although we will need macros for other things anyway, so...).
I don't really mind, but having all this just act on the preprocessor pass seems more consistent to me. The preprocessed output would use the underlying types and method names everywhere.
#define IFoo_DoFoo __x_ABI_CWindows_CFoo_CIFoo_DoFoo #endif /* WIDL_USING_WINDOWS_FOO_IFOO */
Implementation files can define the desired WIDL_USING preprocessor macros before including the header, and then implement or use the interface methods with the simple non-prefixed names instead.
How about extending it a bit more to allow specifying entire namespaces in using statements, so something like:
#define WIDL_using_Windows_Foo
would have an effect on all interfaces in this exact namespace.
I was afraid of making its scope too large, in case there's some types which would conflict together. I think having it per type is a bit verbose but at least it stays under control.
Could it be added later, if we need to implement a large amount of WinRT DLLs where adding each type proves too verbose?
Signed-off-by: Rémi Bernonrbernon@codeweavers.com
tools/widl/header.c | 68 ++++++++++++++++++++++++++++++++++++++++++ tools/widl/typetree.c | 19 ++++++++++++ tools/widl/widltypes.h | 1 + 3 files changed, 88 insertions(+)
diff --git a/tools/widl/header.c b/tools/widl/header.c index 82aad0f11ca..8ca74d5a6f4 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -48,6 +48,8 @@ static void write_type_v(FILE *f, const decl_spec_t *t, int is_field, int declon static void write_apicontract_guard_start(FILE *header, const expr_t *expr); static void write_apicontract_guard_end(FILE *header, const expr_t *expr); +static void write_widl_using_macros(FILE *header, type_t *iface);
static void indent(FILE *h, int delta) { int c; @@ -604,6 +606,7 @@ static void write_type_definition(FILE *f, type_t *t, int declonly) fprintf(f, "#else\n"); write_type_left(f, &ds, NAME_C, declonly, TRUE); fprintf(f, ";\n"); + if (winrt_mode) write_widl_using_macros(f, t); fprintf(f, "#endif\n\n"); } if (contract) write_apicontract_guard_end(f, contract); @@ -1536,6 +1539,70 @@ static void write_com_interface_start(FILE *header, const type_t *iface) fprintf(header,"#define __%s_%sINTERFACE_DEFINED__\n\n", iface->c_name, dispinterface ? "DISP" : ""); } +static char *get_winrt_guard_macro(type_t *iface) +{ + unsigned int len; + char *macro, *tmp = (char *)iface->c_name; + int i;
+ if (!strncmp(tmp, "__x", 3)) tmp += 3; + if (!strncmp(tmp, "_ABI", 4)) tmp += 4; + macro = xstrdup(tmp);
+ len = strlen(macro) + 1; + for (tmp = strstr(macro, "__F"); tmp; tmp = strstr(tmp, "__F")) + memmove(tmp + 1, tmp + 3, len - (tmp - macro) - 3); + for (tmp = strstr(macro, "__C"); tmp; tmp = strstr(tmp, "__C")) + memmove(tmp + 1, tmp + 3, len - (tmp - macro) - 3); + for (tmp = strstr(macro, "_C"); tmp; tmp = strstr(tmp, "_C")) + memmove(tmp + 1, tmp + 2, len - (tmp - macro) - 2);
+ for (i = strlen(macro); i > 0; --i) macro[i - 1] = toupper(macro[i - 1]);
+ return macro; +}
Could you just compute it from namespace and name stored in type_t instead of parsing a previously computed string? It looks like a job for format_namespace().
[1] Not really an issue anymore if we go the way mentioned in the first comment, but:
Hmm, I'd say yes, but using format_namespace directly would bypass the shorthands used for the C names of some types using foundation types (such as CWindow_CFoundation_CCollections -> __F), and they would end up expanded in the WIDL_using macros, not matching exactly the interface names.
Or we have to have another format_ helper which would apply the shorthands somehow, but in the end it's more or less what this does. Although reconstructing from the namespaces could be a bit more robust.
Cheers,
On 19.02.2021 18:18, Rémi Bernon wrote:
Hi Jacek!
On 2/19/21 5:48 PM, Jacek Caban wrote:
Hi Rémi,
On 19.02.2021 12:04, Rémi Bernon wrote:
This generates additional macros to help keeping implementation simple, guarded with WIDL_USING ifdefs, like this:
#ifdef WIDL_USING_WINDOWS_FOO_IFOO
I would find it more readable if we didn't follow all-uppercase for macro rule here, something like:
#define WIDL_using_Windows_Foo_IFoo
But it's a matter of taste, so I'm mentioning it just for consideration.
Yeah I don't really like it much, but I can see one reason to make something like that, which would also possibly solve the [1] below:
For making things simpler to type, it could just be the type C name prefixed by WIDL_USING_, like in:
#define WIDL_USING_CWindows_CGaming_CInput_CIRawGameController
The generation of the guard macros would just have to remove the __x_ABI_ prefix, and developers just need to copy paste the type names they want without having to remove the C prefixes or mess with the name case.
I hope that we can save developers from dealing with details about name mangling, at least in non-templated cases. Ideally they would be able to type it manually.
I was afraid of making its scope too large, in case there's some types which would conflict together. I think having it per type is a bit verbose but at least it stays under control.
Sure, we may have both mechanisms: use per-namespace macros whenever possible and fallback to per-type macros in problematic cases.
Could it be added later, if we need to implement a large amount of WinRT DLLs where adding each type proves too verbose?
Maybe we could implement only per-namespace macros and wait for an actual collision problem before implementing per-type variant?
Thanks,
Jacek
On 2/19/21 8:12 PM, Jacek Caban wrote:
On 19.02.2021 18:18, Rémi Bernon wrote:
Hi Jacek!
On 2/19/21 5:48 PM, Jacek Caban wrote:
Hi Rémi,
On 19.02.2021 12:04, Rémi Bernon wrote:
This generates additional macros to help keeping implementation simple, guarded with WIDL_USING ifdefs, like this:
#ifdef WIDL_USING_WINDOWS_FOO_IFOO
I would find it more readable if we didn't follow all-uppercase for macro rule here, something like:
#define WIDL_using_Windows_Foo_IFoo
But it's a matter of taste, so I'm mentioning it just for consideration.
Yeah I don't really like it much, but I can see one reason to make something like that, which would also possibly solve the [1] below:
For making things simpler to type, it could just be the type C name prefixed by WIDL_USING_, like in:
#define WIDL_USING_CWindows_CGaming_CInput_CIRawGameController
The generation of the guard macros would just have to remove the __x_ABI_ prefix, and developers just need to copy paste the type names they want without having to remove the C prefixes or mess with the name case.
I hope that we can save developers from dealing with details about name mangling, at least in non-templated cases. Ideally they would be able to type it manually.
Well, in that case all upper case could also save some effort trying to guess how the words are supposed to be capitalized :)
I was afraid of making its scope too large, in case there's some types which would conflict together. I think having it per type is a bit verbose but at least it stays under control.
Sure, we may have both mechanisms: use per-namespace macros whenever possible and fallback to per-type macros in problematic cases.
Could it be added later, if we need to implement a large amount of WinRT DLLs where adding each type proves too verbose?
Maybe we could implement only per-namespace macros and wait for an actual collision problem before implementing per-type variant?
Alright!
Thanks,
Jacek
On 19.02.2021 20:43, Rémi Bernon wrote:
On 2/19/21 8:12 PM, Jacek Caban wrote:
On 19.02.2021 18:18, Rémi Bernon wrote:
Hi Jacek!
On 2/19/21 5:48 PM, Jacek Caban wrote:
Hi Rémi,
On 19.02.2021 12:04, Rémi Bernon wrote:
This generates additional macros to help keeping implementation simple, guarded with WIDL_USING ifdefs, like this:
#ifdef WIDL_USING_WINDOWS_FOO_IFOO
I would find it more readable if we didn't follow all-uppercase for macro rule here, something like:
#define WIDL_using_Windows_Foo_IFoo
But it's a matter of taste, so I'm mentioning it just for consideration.
Yeah I don't really like it much, but I can see one reason to make something like that, which would also possibly solve the [1] below:
For making things simpler to type, it could just be the type C name prefixed by WIDL_USING_, like in:
#define WIDL_USING_CWindows_CGaming_CInput_CIRawGameController
The generation of the guard macros would just have to remove the __x_ABI_ prefix, and developers just need to copy paste the type names they want without having to remove the C prefixes or mess with the name case.
I hope that we can save developers from dealing with details about name mangling, at least in non-templated cases. Ideally they would be able to type it manually.
Well, in that case all upper case could also save some effort trying to guess how the words are supposed to be capitalized :)
The other way to look at this is that now you have to take the original spelling and do an additional step to upper case it :) My original comment also applied to the other part of the patch, which required developer to know when and how to use _F instead of _C. It may be less of a deal for namespaces, but if we ever want to apply it to per-type as well, I find IRAWGAMECONTROLLER much less readable than IRawGameController.
widl already generates a number of macros that include type names in their original casing. Upper casing only selected extension macros feels inconsistent to me.
Thanks,
Jacek
On 2/25/21 2:47 PM, Jacek Caban wrote:
On 19.02.2021 20:43, Rémi Bernon wrote:
On 2/19/21 8:12 PM, Jacek Caban wrote:
On 19.02.2021 18:18, Rémi Bernon wrote:
Hi Jacek!
On 2/19/21 5:48 PM, Jacek Caban wrote:
Hi Rémi,
On 19.02.2021 12:04, Rémi Bernon wrote:
This generates additional macros to help keeping implementation simple, guarded with WIDL_USING ifdefs, like this:
#ifdef WIDL_USING_WINDOWS_FOO_IFOO
I would find it more readable if we didn't follow all-uppercase for macro rule here, something like:
#define WIDL_using_Windows_Foo_IFoo
But it's a matter of taste, so I'm mentioning it just for consideration.
Yeah I don't really like it much, but I can see one reason to make something like that, which would also possibly solve the [1] below:
For making things simpler to type, it could just be the type C name prefixed by WIDL_USING_, like in:
#define WIDL_USING_CWindows_CGaming_CInput_CIRawGameController
The generation of the guard macros would just have to remove the __x_ABI_ prefix, and developers just need to copy paste the type names they want without having to remove the C prefixes or mess with the name case.
I hope that we can save developers from dealing with details about name mangling, at least in non-templated cases. Ideally they would be able to type it manually.
Well, in that case all upper case could also save some effort trying to guess how the words are supposed to be capitalized :)
The other way to look at this is that now you have to take the original spelling and do an additional step to upper case it :) My original comment also applied to the other part of the patch, which required developer to know when and how to use _F instead of _C. It may be less of a deal for namespaces, but if we ever want to apply it to per-type as well, I find IRAWGAMECONTROLLER much less readable than IRawGameController.
widl already generates a number of macros that include type names in their original casing. Upper casing only selected extension macros feels inconsistent to me.
Thanks,
Jacek
In my opinion this differs from the convenience macros that WIDL generates, as they are supposed to be used in the code, as a replacement to the vtable methods and types accesses. So having them consistent with the original method and types names is relevant.
In this case, I think it is instead some preprocessor control mechanism, in the same way as COBJMACROS / INITGUID / WIN32_NO_STATUS, but specific to WIDL, and to some extent to the WinRT namespaces. They won't be used in the code, but should only be defined once before including the WinRT headers. So to me it would be more natural for them to follow the "standard" preprocessor macro naming scheme.
In any case I can probably live with the camelcase style, even if WIDL_using_Windows_Foundation still feels a bit awkward :)
I'll send an update with the other things addressed once the other patches are upstream.