Merge branch 'wip/Jehan/g_param_is_valid_property_name' into 'master'

gobject: new g_param_is_valid_property_name() function.

See merge request GNOME/glib!1302
This commit is contained in:
Philip Withnall 2020-03-04 15:30:38 +00:00
commit 2510d5aae0
13 changed files with 171 additions and 37 deletions

View File

@ -280,6 +280,10 @@
<title>Index of new symbols in 2.64</title>
<xi:include href="xml/api-index-2.64.xml"><xi:fallback /></xi:include>
</index>
<index id="api-index-2-66" role="2.66">
<title>Index of new symbols in 2.66</title>
<xi:include href="xml/api-index-2.66.xml"><xi:fallback /></xi:include>
</index>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>

View File

@ -136,6 +136,7 @@ GLIB_VERSION_2_58
GLIB_VERSION_2_60
GLIB_VERSION_2_62
GLIB_VERSION_2_64
GLIB_VERSION_2_66
GLIB_VERSION_MIN_REQUIRED
GLIB_VERSION_MAX_ALLOWED
GLIB_DISABLE_DEPRECATION_WARNINGS
@ -162,6 +163,7 @@ GLIB_AVAILABLE_ENUMERATOR_IN_2_58
GLIB_AVAILABLE_ENUMERATOR_IN_2_60
GLIB_AVAILABLE_ENUMERATOR_IN_2_62
GLIB_AVAILABLE_ENUMERATOR_IN_2_64
GLIB_AVAILABLE_ENUMERATOR_IN_2_66
GLIB_AVAILABLE_IN_ALL
GLIB_AVAILABLE_IN_2_26
GLIB_AVAILABLE_IN_2_28
@ -183,6 +185,7 @@ GLIB_AVAILABLE_IN_2_58
GLIB_AVAILABLE_IN_2_60
GLIB_AVAILABLE_IN_2_62
GLIB_AVAILABLE_IN_2_64
GLIB_AVAILABLE_IN_2_66
GLIB_AVAILABLE_MACRO_IN_2_26
GLIB_AVAILABLE_MACRO_IN_2_28
GLIB_AVAILABLE_MACRO_IN_2_30
@ -203,6 +206,7 @@ GLIB_AVAILABLE_MACRO_IN_2_58
GLIB_AVAILABLE_MACRO_IN_2_60
GLIB_AVAILABLE_MACRO_IN_2_62
GLIB_AVAILABLE_MACRO_IN_2_64
GLIB_AVAILABLE_MACRO_IN_2_66
GLIB_AVAILABLE_TYPE_IN_2_26
GLIB_AVAILABLE_TYPE_IN_2_28
GLIB_AVAILABLE_TYPE_IN_2_30
@ -223,6 +227,7 @@ GLIB_AVAILABLE_TYPE_IN_2_58
GLIB_AVAILABLE_TYPE_IN_2_60
GLIB_AVAILABLE_TYPE_IN_2_62
GLIB_AVAILABLE_TYPE_IN_2_64
GLIB_AVAILABLE_TYPE_IN_2_66
GLIB_DEPRECATED_ENUMERATOR
GLIB_DEPRECATED_ENUMERATOR_FOR
GLIB_DEPRECATED_ENUMERATOR_IN_2_26
@ -265,6 +270,8 @@ GLIB_DEPRECATED_ENUMERATOR_IN_2_62
GLIB_DEPRECATED_ENUMERATOR_IN_2_62_FOR
GLIB_DEPRECATED_ENUMERATOR_IN_2_64
GLIB_DEPRECATED_ENUMERATOR_IN_2_64_FOR
GLIB_DEPRECATED_ENUMERATOR_IN_2_66
GLIB_DEPRECATED_ENUMERATOR_IN_2_66_FOR
GLIB_DEPRECATED_IN_2_26
GLIB_DEPRECATED_IN_2_26_FOR
GLIB_DEPRECATED_IN_2_28
@ -305,6 +312,8 @@ GLIB_DEPRECATED_IN_2_62
GLIB_DEPRECATED_IN_2_62_FOR
GLIB_DEPRECATED_IN_2_64
GLIB_DEPRECATED_IN_2_64_FOR
GLIB_DEPRECATED_IN_2_66
GLIB_DEPRECATED_IN_2_66_FOR
GLIB_DEPRECATED_MACRO
GLIB_DEPRECATED_MACRO_FOR
GLIB_DEPRECATED_MACRO_IN_2_26
@ -347,6 +356,8 @@ GLIB_DEPRECATED_MACRO_IN_2_62
GLIB_DEPRECATED_MACRO_IN_2_62_FOR
GLIB_DEPRECATED_MACRO_IN_2_64
GLIB_DEPRECATED_MACRO_IN_2_64_FOR
GLIB_DEPRECATED_MACRO_IN_2_66
GLIB_DEPRECATED_MACRO_IN_2_66_FOR
GLIB_DEPRECATED_TYPE
GLIB_DEPRECATED_TYPE_FOR
GLIB_DEPRECATED_TYPE_IN_2_26
@ -389,6 +400,8 @@ GLIB_DEPRECATED_TYPE_IN_2_62
GLIB_DEPRECATED_TYPE_IN_2_62_FOR
GLIB_DEPRECATED_TYPE_IN_2_64
GLIB_DEPRECATED_TYPE_IN_2_64_FOR
GLIB_DEPRECATED_TYPE_IN_2_66
GLIB_DEPRECATED_TYPE_IN_2_66_FOR
GLIB_VERSION_CUR_STABLE
GLIB_VERSION_PREV_STABLE
</SECTION>

View File

@ -200,6 +200,10 @@
<title>Index of new symbols in 2.62</title>
<xi:include href="xml/api-index-2.62.xml"><xi:fallback /></xi:include>
</index>
<index id="api-index-2-66" role="2.66">
<title>Index of new symbols in 2.66</title>
<xi:include href="xml/api-index-2.66.xml"><xi:fallback /></xi:include>
</index>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>

View File

@ -521,6 +521,7 @@ g_param_value_defaults
g_param_value_validate
g_param_value_convert
g_param_values_cmp
g_param_spec_is_valid_name
g_param_spec_get_name
g_param_spec_get_name_quark
g_param_spec_get_nick
@ -859,6 +860,7 @@ g_signal_override_class_handler
g_signal_chain_from_overridden_handler
g_signal_add_emission_hook
g_signal_remove_emission_hook
g_signal_is_valid_name
g_signal_parse_name
g_signal_get_invocation_hint
g_signal_type_cclosure_new

View File

@ -7,7 +7,7 @@
stable_2_series_versions = [
'26', '28', '30', '32', '34', '36', '38',
'40', '42', '44', '46', '48', '50', '52', '54', '56', '58',
'60', '62', '64',
'60', '62', '64', '66',
]
ignore_decorators = [

View File

@ -235,6 +235,16 @@
*/
#define GLIB_VERSION_2_64 (G_ENCODE_VERSION (2, 64))
/**
* GLIB_VERSION_2_66:
*
* A macro that evaluates to the 2.66 version of GLib, in a format
* that can be used by the C pre-processor.
*
* Since: 2.66
*/
#define GLIB_VERSION_2_66 (G_ENCODE_VERSION (2, 66))
/* evaluates to the current stable version; for development cycles,
* this means the next stable target
*/
@ -962,4 +972,36 @@
# define GLIB_AVAILABLE_TYPE_IN_2_64
#endif
#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_66
# define GLIB_DEPRECATED_IN_2_66 GLIB_DEPRECATED
# define GLIB_DEPRECATED_IN_2_66_FOR(f) GLIB_DEPRECATED_FOR(f)
# define GLIB_DEPRECATED_MACRO_IN_2_66 GLIB_DEPRECATED_MACRO
# define GLIB_DEPRECATED_MACRO_IN_2_66_FOR(f) GLIB_DEPRECATED_MACRO_FOR(f)
# define GLIB_DEPRECATED_ENUMERATOR_IN_2_66 GLIB_DEPRECATED_ENUMERATOR
# define GLIB_DEPRECATED_ENUMERATOR_IN_2_66_FOR(f) GLIB_DEPRECATED_ENUMERATOR_FOR(f)
# define GLIB_DEPRECATED_TYPE_IN_2_66 GLIB_DEPRECATED_TYPE
# define GLIB_DEPRECATED_TYPE_IN_2_66_FOR(f) GLIB_DEPRECATED_TYPE_FOR(f)
#else
# define GLIB_DEPRECATED_IN_2_66 _GLIB_EXTERN
# define GLIB_DEPRECATED_IN_2_66_FOR(f) _GLIB_EXTERN
# define GLIB_DEPRECATED_MACRO_IN_2_66
# define GLIB_DEPRECATED_MACRO_IN_2_66_FOR(f)
# define GLIB_DEPRECATED_ENUMERATOR_IN_2_66
# define GLIB_DEPRECATED_ENUMERATOR_IN_2_66_FOR(f)
# define GLIB_DEPRECATED_TYPE_IN_2_66
# define GLIB_DEPRECATED_TYPE_IN_2_66_FOR(f)
#endif
#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_66
# define GLIB_AVAILABLE_IN_2_66 GLIB_UNAVAILABLE(2, 66)
# define GLIB_AVAILABLE_MACRO_IN_2_66 GLIB_UNAVAILABLE_MACRO(2, 66)
# define GLIB_AVAILABLE_ENUMERATOR_IN_2_66 GLIB_UNAVAILABLE_ENUMERATOR(2, 66)
# define GLIB_AVAILABLE_TYPE_IN_2_66 GLIB_UNAVAILABLE_TYPE(2, 66)
#else
# define GLIB_AVAILABLE_IN_2_66 _GLIB_EXTERN
# define GLIB_AVAILABLE_MACRO_IN_2_66
# define GLIB_AVAILABLE_ENUMERATOR_IN_2_66
# define GLIB_AVAILABLE_TYPE_IN_2_66
#endif
#endif /* __G_VERSION_MACROS_H__ */

View File

@ -41,8 +41,8 @@
*
* ## Parameter names # {#canonical-parameter-names}
*
* A property name consists of segments consisting of ASCII letters and
* digits, separated by either the `-` or `_` character. The first
* A property name consists of one or more segments consisting of ASCII letters
* and digits, separated by either the `-` or `_` character. The first
* character of a property name must be a letter. These are the same rules as
* for signal naming (see g_signal_new()).
*
@ -381,20 +381,34 @@ is_canonical (const gchar *key)
return (strchr (key, '_') == NULL);
}
static gboolean
is_valid_property_name (const gchar *key)
/**
* g_param_spec_is_valid_name:
* @name: the canonical name of the property
*
* Validate a property name for a #GParamSpec. This can be useful for
* dynamically-generated properties which need to be validated at run-time
* before actually trying to create them.
*
* See [canonical parameter names][canonical-parameter-names] for details of
* the rules for valid names.
*
* Returns: %TRUE if @name is a valid property name, %FALSE otherwise.
* Since: 2.66
*/
gboolean
g_param_spec_is_valid_name (const gchar *name)
{
const gchar *p;
/* First character must be a letter. */
if ((key[0] < 'A' || key[0] > 'Z') &&
(key[0] < 'a' || key[0] > 'z'))
if ((name[0] < 'A' || name[0] > 'Z') &&
(name[0] < 'a' || name[0] > 'z'))
return FALSE;
for (p = key; *p != 0; p++)
for (p = name; *p != 0; p++)
{
const gchar c = *p;
if (c != '-' && c != '_' &&
(c < '0' || c > '9') &&
(c < 'A' || c > 'Z') &&
@ -439,7 +453,7 @@ g_param_spec_internal (GType param_type,
g_return_val_if_fail (G_TYPE_IS_PARAM (param_type) && param_type != G_TYPE_PARAM, NULL);
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (is_valid_property_name (name), NULL);
g_return_val_if_fail (g_param_spec_is_valid_name (name), NULL);
g_return_val_if_fail (!(flags & G_PARAM_STATIC_NAME) || is_canonical (name), NULL);
pspec = (gpointer) g_type_create_instance (param_type);

View File

@ -395,6 +395,9 @@ GLIB_AVAILABLE_IN_ALL
GType g_param_type_register_static (const gchar *name,
const GParamSpecTypeInfo *pspec_info);
GLIB_AVAILABLE_IN_2_66
gboolean g_param_spec_is_valid_name (const gchar *name);
/* For registering builting types */
GType _g_param_type_register_static_constant (const gchar *name,
const GParamSpecTypeInfo *pspec_info,

View File

@ -367,33 +367,29 @@ is_canonical (const gchar *key)
return (strchr (key, '_') == NULL);
}
static gboolean
is_valid_signal_name (const gchar *key)
/**
* g_signal_is_valid_name:
* @name: the canonical name of the signal
*
* Validate a signal name. This can be useful for dynamically-generated signals
* which need to be validated at run-time before actually trying to create them.
*
* See [canonical parameter names][canonical-parameter-names] for details of
* the rules for valid names. The rules for signal names are the same as those
* for property names.
*
* Returns: %TRUE if @name is a valid signal name, %FALSE otherwise.
* Since: 2.66
*/
gboolean
g_signal_is_valid_name (const gchar *name)
{
const gchar *p;
/* FIXME: We allow this, against our own documentation (the leading `-` is
* invalid), because GTK has historically used this. */
if (g_str_equal (key, "-gtk-private-changed"))
if (g_str_equal (name, "-gtk-private-changed"))
return TRUE;
/* First character must be a letter. */
if ((key[0] < 'A' || key[0] > 'Z') &&
(key[0] < 'a' || key[0] > 'z'))
return FALSE;
for (p = key; *p != 0; p++)
{
const gchar c = *p;
if (c != '-' && c != '_' &&
(c < '0' || c > '9') &&
(c < 'A' || c > 'Z') &&
(c < 'a' || c > 'z'))
return FALSE;
}
return TRUE;
return g_param_spec_is_valid_name (name);
}
static inline guint
@ -1325,7 +1321,7 @@ g_signal_lookup (const gchar *name,
if (!g_type_name (itype))
g_warning (G_STRLOC ": unable to look up signal \"%s\" for invalid type id '%"G_GSIZE_FORMAT"'",
name, itype);
else if (!is_valid_signal_name (name))
else if (!g_signal_is_valid_name (name))
g_warning (G_STRLOC ": unable to look up invalid signal name \"%s\" on type '%s'",
name, g_type_name (itype));
}
@ -1712,7 +1708,7 @@ g_signal_newv (const gchar *signal_name,
GSignalCVaMarshaller va_marshaller;
g_return_val_if_fail (signal_name != NULL, 0);
g_return_val_if_fail (is_valid_signal_name (signal_name), 0);
g_return_val_if_fail (g_signal_is_valid_name (signal_name), 0);
g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0);
if (n_params)
g_return_val_if_fail (param_types != NULL, 0);

View File

@ -338,6 +338,8 @@ void g_signal_query (guint signal_id,
GLIB_AVAILABLE_IN_ALL
guint* g_signal_list_ids (GType itype,
guint *n_ids);
GLIB_AVAILABLE_IN_2_66
gboolean g_signal_is_valid_name (const gchar *name);
GLIB_AVAILABLE_IN_ALL
gboolean g_signal_parse_name (const gchar *detailed_signal,
GType itype,

View File

@ -126,7 +126,7 @@ test_param_invalid_name (gconstpointer test_data)
g_test_trap_subprocess (NULL, 0, 0);
g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*CRITICAL*is_valid_property_name (name)*");
g_test_trap_assert_stderr ("*CRITICAL*g_param_spec_is_valid_name (name)*");
}
static void
@ -846,6 +846,32 @@ test_param_default (void)
g_param_spec_unref (param);
}
static void
test_param_is_valid_name (void)
{
const gchar *valid_names[] =
{
"property",
"i",
"multiple-segments",
"segment0-SEGMENT1",
"using_underscores",
};
const gchar *invalid_names[] =
{
"",
"7zip",
"my_int:hello",
};
gsize i;
for (i = 0; i < G_N_ELEMENTS (valid_names); i++)
g_assert_true (g_param_spec_is_valid_name (valid_names[i]));
for (i = 0; i < G_N_ELEMENTS (invalid_names); i++)
g_assert_false (g_param_spec_is_valid_name (invalid_names[i]));
}
int
main (int argc, char *argv[])
{
@ -881,6 +907,7 @@ main (int argc, char *argv[])
g_test_add_func ("/value/transform", test_value_transform);
g_test_add_func ("/param/default", test_param_default);
g_test_add_func ("/param/is-valid-name", test_param_is_valid_name);
return g_test_run ();
}

View File

@ -1449,7 +1449,33 @@ test_signals_invalid_name (gconstpointer test_data)
g_test_trap_subprocess (NULL, 0, 0);
g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*CRITICAL*is_valid_signal_name (signal_name)*");
g_test_trap_assert_stderr ("*CRITICAL*g_signal_is_valid_name (signal_name)*");
}
static void
test_signal_is_valid_name (void)
{
const gchar *valid_names[] =
{
"signal",
"i",
"multiple-segments",
"segment0-SEGMENT1",
"using_underscores",
};
const gchar *invalid_names[] =
{
"",
"7zip",
"my_int:hello",
};
gsize i;
for (i = 0; i < G_N_ELEMENTS (valid_names); i++)
g_assert_true (g_signal_is_valid_name (valid_names[i]));
for (i = 0; i < G_N_ELEMENTS (invalid_names); i++)
g_assert_false (g_signal_is_valid_name (invalid_names[i]));
}
/* --- */
@ -1485,6 +1511,7 @@ main (int argc,
g_test_add_data_func ("/gobject/signals/invalid-name/colon", "my_int:hello", test_signals_invalid_name);
g_test_add_data_func ("/gobject/signals/invalid-name/first-char", "7zip", test_signals_invalid_name);
g_test_add_data_func ("/gobject/signals/invalid-name/empty", "", test_signals_invalid_name);
g_test_add_func ("/gobject/signals/is-valid-name", test_signal_is_valid_name);
return g_test_run ();
}

View File

@ -1,5 +1,5 @@
project('glib', 'c', 'cpp',
version : '2.64.0',
version : '2.65.0',
# NOTE: We keep this pinned at 0.49 because that's what Debian 10 ships
meson_version : '>= 0.49.2',
default_options : [