keyfile: add nm_keyfile_handler_data_warn_get() and construct message lazy

Add an accessor for the warning event.

Also, as we now have an accessor, we can construct the warning
message only if it actually needed.
This commit is contained in:
Thomas Haller 2020-05-25 19:37:01 +02:00
parent 4230a1d4fb
commit 00b3a3505a
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
3 changed files with 68 additions and 13 deletions

View file

@ -119,7 +119,9 @@ GKeyFile *nm_keyfile_write (NMConnection *connection,
*/
typedef struct {
NMKeyfileWarnSeverity severity;
const char *message;
char *message;
const char *fmt;
va_list ap;
} NMKeyfileHandlerDataWarn;
/**
@ -160,6 +162,12 @@ void nm_keyfile_handler_data_get_context (const NMKeyfileHandlerData *handler_da
NMSetting **out_cur_setting,
const char **out_cur_property_name);
void nm_keyfile_handler_data_warn_get (const NMKeyfileHandlerData *handler_data,
const char **out_message,
NMKeyfileWarnSeverity *out_severity);
const char *_nm_keyfile_handler_data_warn_get_message (const NMKeyfileHandlerData *handler_data);
/*****************************************************************************/
char *nm_keyfile_plugin_kf_get_string (GKeyFile *kf, const char *group, const char *key, GError **error);

View file

@ -103,12 +103,14 @@ _key_file_handler_data_init_write (NMKeyfileHandlerData *handler_data,
&info->error);
}
_nm_printf (5, 6)
static void
_handle_warn (KeyfileReaderInfo *info,
const char *kf_key,
const char *cur_property,
NMKeyfileWarnSeverity severity,
char *message)
const char *fmt,
...)
{
NMKeyfileHandlerData handler_data;
@ -119,15 +121,21 @@ _handle_warn (KeyfileReaderInfo *info,
cur_property);
handler_data.warn = (NMKeyfileHandlerDataWarn) {
.severity = severity,
.message = message,
.message = NULL,
.fmt = fmt,
};
va_start (handler_data.warn.ap, fmt);
info->read_handler (info->keyfile,
info->connection,
NM_KEYFILE_HANDLER_TYPE_WARN,
&handler_data,
info->user_data);
g_free (message);
va_end (handler_data.warn.ap);
g_free (handler_data.warn.message);
}
#define handle_warn(arg_info, arg_kf_key, arg_property_name, arg_severity, ...) \
@ -141,7 +149,7 @@ _handle_warn (KeyfileReaderInfo *info,
(arg_kf_key), \
(arg_property_name), \
(arg_severity), \
g_strdup_printf (__VA_ARGS__)); \
__VA_ARGS__); \
} \
_info->error == NULL; \
})
@ -4393,3 +4401,40 @@ nm_keyfile_handler_data_get_context (const NMKeyfileHandlerData *handler_data,
NM_SET_OUT (out_cur_setting, handler_data->cur_setting);
NM_SET_OUT (out_cur_property_name, handler_data->cur_property);
}
const char *
_nm_keyfile_handler_data_warn_get_message (const NMKeyfileHandlerData *handler_data)
{
nm_assert (handler_data);
nm_assert (handler_data->type == NM_KEYFILE_HANDLER_TYPE_WARN);
if (!handler_data->warn.message) {
/* we cast the const away. @handler_data is const w.r.t. visible mutations
* from POV of the user. Internally, we construct the message in
* a lazy manner. It's like a mutable field in C++. */
NM_PRAGMA_WARNING_DISABLE ("-Wformat-nonliteral")
((NMKeyfileHandlerData *) handler_data)->warn.message = g_strdup_vprintf (handler_data->warn.fmt,
((NMKeyfileHandlerData *) handler_data)->warn.ap);
NM_PRAGMA_WARNING_REENABLE
}
return handler_data->warn.message;
}
/**
* nm_keyfile_handler_data_warn_get:
* @handler_data: the #NMKeyfileHandlerData for a %NM_KEYFILE_HANDLER_TYPE_WARN
* event.
* @out_message: (out) (allow-none) (transfer none): the warning message.
* @out_severity: (out) (allow-none): the #NMKeyfileWarnSeverity warning severity.
*/
void
nm_keyfile_handler_data_warn_get (const NMKeyfileHandlerData *handler_data,
const char **out_message,
NMKeyfileWarnSeverity *out_severity)
{
g_return_if_fail (handler_data);
g_return_if_fail (handler_data->type == NM_KEYFILE_HANDLER_TYPE_WARN);
NM_SET_OUT (out_message, _nm_keyfile_handler_data_warn_get_message (handler_data));
NM_SET_OUT (out_severity, handler_data->warn.severity);
}

View file

@ -17,11 +17,15 @@
/*****************************************************************************/
static const char *
_fmt_warn (const char *group, NMSetting *setting, const char *property_name, const char *message, char **out_message)
_fmt_warn (const NMKeyfileHandlerData *handler_data, char **out_message)
{
const char *setting_name = setting ? nm_setting_get_name (setting) : NULL;
const char *group = handler_data->kf_group_name;
const char *message = _nm_keyfile_handler_data_warn_get_message (handler_data);
if (group) {
NMSetting *setting = handler_data->cur_setting;
const char *property_name = handler_data->cur_property;
const char *setting_name = setting ? nm_setting_get_name (setting) : NULL;
char *res;
if (setting_name) {
@ -37,8 +41,9 @@ _fmt_warn (const char *group, NMSetting *setting, const char *property_name, con
res = g_strdup_printf ("%s: %s", group, message);
*out_message = res;
return res;
} else
return message;
}
return message;
}
typedef struct {
@ -76,10 +81,7 @@ _handler_read (GKeyFile *keyfile,
NULL,
nm_connection_get_uuid (connection),
"keyfile: %s",
_fmt_warn (handler_data->kf_group_name,
handler_data->cur_setting,
handler_data->cur_property,
warn_data->message,
_fmt_warn (handler_data,
&message_free));
g_free (message_free);
return TRUE;