X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=glib%2Fgkeyfile.c;h=cc51eda690eaf9afea04a3475e4bb10e7cc9f580;hb=d217429729aad360f372633f2ec99778c0fc08d5;hp=ad8cdae5527da0514c3fb24c750710ac45b66274;hpb=9d3b37ac3fa7d5ea25a897e5baa7c7a66da0873f;p=platform%2Fupstream%2Fglib.git diff --git a/glib/gkeyfile.c b/glib/gkeyfile.c index ad8cdae..cc51eda 100644 --- a/glib/gkeyfile.c +++ b/glib/gkeyfile.c @@ -19,8 +19,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with GLib; see the file COPYING.LIB. If not, - * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * see . */ #include "config.h" @@ -36,13 +35,15 @@ #include #include #include -#ifdef HAVE_UNISTD_H +#ifdef G_OS_UNIX #include #endif #ifdef G_OS_WIN32 #include +#undef fstat #define fstat(a,b) _fstati64(a,b) +#undef stat #define stat _stati64 #ifndef S_ISREG @@ -73,17 +74,15 @@ * @short_description: parses .ini-like config files * * #GKeyFile lets you parse, edit or create files containing groups of - * key-value pairs, which we call key files for - * lack of a better name. Several freedesktop.org specifications use - * key files now, e.g the - * Desktop - * Entry Specification and the - * Icon - * Theme Specification. + * key-value pairs, which we call "key files" for lack of a better name. + * Several freedesktop.org specifications use key files now, e.g the + * [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec) + * and the + * [Icon Theme Specification](http://freedesktop.org/Standards/icon-theme-spec). * * The syntax of key files is described in detail in the - * Desktop - * Entry Specification, here is a quick summary: Key files + * [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec), + * here is a quick summary: Key files * consists of groups of key-value pairs, interspersed with comments. * * |[ @@ -114,11 +113,11 @@ * in '[' and ']', and ended implicitly by the start of the next group or * the end of the file. Each key-value pair must be contained in a group. * - * Key-value pairs generally have the form key=value, - * with the exception of localized strings, which have the form - * key[locale]=value, with a locale identifier of the - * form lang_COUNTRY@MODIFIER where - * COUNTRY and MODIFIER are optional. + * Key-value pairs generally have the form `key=value`, with the + * exception of localized strings, which have the form + * `key[locale]=value`, with a locale identifier of the + * form `lang_COUNTRY@MODIFIER` where `COUNTRY` and `MODIFIER` + * are optional. * Space before and after the '=' character are ignored. Newline, tab, * carriage return and backslash characters in value are escaped as \n, * \t, \r, and \\, respectively. To preserve leading spaces in values, @@ -131,24 +130,25 @@ * * This syntax is obviously inspired by the .ini files commonly met * on Windows, but there are some important differences: - * - * .ini files use the ';' character to begin comments, - * key files use the '#' character. - * Key files do not allow for ungrouped keys meaning only - * comments can precede the first group. - * Key files are always encoded in UTF-8. - * Key and Group names are case-sensitive. For example, a - * group called [GROUP] is a different from - * [group]. - * .ini files don't have a strongly typed boolean entry type, - * they only have GetProfileInt(). In key files, only - * true and false (in lower case) - * are allowed. - * + * + * - .ini files use the ';' character to begin comments, + * key files use the '#' character. + * + * - Key files do not allow for ungrouped keys meaning only + * comments can precede the first group. + * + * - Key files are always encoded in UTF-8. + * + * - Key and Group names are case-sensitive. For example, a group called + * [GROUP] is a different from [group]. + * + * - .ini files don't have a strongly typed boolean entry type, + * they only have GetProfileInt(). In key files, only + * true and false (in lower case) are allowed. * * Note that in contrast to the - * Desktop - * Entry Specification, groups in key files may contain the same + * [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec), + * groups in key files may contain the same * key multiple times; the last entry wins. Key files may also contain * multiple groups with the same name; they are merged together. * Another difference is that keys and group names in key files are not @@ -196,8 +196,8 @@ * G_KEY_FILE_DESKTOP_GROUP: * * The name of the main group of a desktop entry file, as defined in the - * Desktop - * Entry Specification. Consult the specification for more + * [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec). + * Consult the specification for more * details about the meanings of the keys below. * * Since: 2.14 @@ -306,7 +306,7 @@ * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string * giving the file name of a binary on disk used to determine if the * program is actually installed. It is only valid for desktop entries - * with the Application type. + * with the `Application` type. * * Since: 2.14 */ @@ -316,7 +316,7 @@ * * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string * giving the command line to execute. It is only valid for desktop - * entries with the Application type. + * entries with the `Application` type. * * Since: 2.14 */ @@ -326,7 +326,7 @@ * * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string * containing the working directory to run the program in. It is only - * valid for desktop entries with the Application type. + * valid for desktop entries with the `Application` type. * * Since: 2.14 */ @@ -337,7 +337,7 @@ * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean * stating whether the program should be run in a terminal window. * It is only valid for desktop entries with the - * Application type. + * `Application` type. * * Since: 2.14 */ @@ -365,9 +365,8 @@ * G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY: * * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean - * stating whether the application supports the Startup - * Notification Protocol Specification. + * stating whether the application supports the + * [Startup Notification Protocol Specification](http://www.freedesktop.org/Standards/startup-notification-spec). * * Since: 2.14 */ @@ -388,7 +387,7 @@ * * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string * giving the URL to access. It is only valid for desktop entries - * with the Link type. + * with the `Link` type. * * Since: 2.14 */ @@ -438,14 +437,13 @@ struct _GKeyFile GString *parse_buffer; /* Holds up to one line of not-yet-parsed data */ - /* Used for sizing the output buffer during serialization */ - gsize approximate_size; - gchar list_separator; GKeyFileFlags flags; gchar **locales; + + volatile gint ref_count; }; typedef struct _GKeyFileKeyValuePair GKeyFileKeyValuePair; @@ -455,7 +453,6 @@ struct _GKeyFileGroup const gchar *name; /* NULL for above first group (which will be comments) */ GKeyFileKeyValuePair *comment; /* Special comment that is stuck to the top of a group */ - gboolean has_trailing_blank_line; GList *key_value_pairs; @@ -556,12 +553,7 @@ static void g_key_file_parse_data (GKeyFile static void g_key_file_flush_parse_buffer (GKeyFile *key_file, GError **error); - -GQuark -g_key_file_error_quark (void) -{ - return g_quark_from_static_string ("g-key-file-error-quark"); -} +G_DEFINE_QUARK (g-key-file-error-quark, g_key_file_error) static void g_key_file_init (GKeyFile *key_file) @@ -571,7 +563,6 @@ g_key_file_init (GKeyFile *key_file) key_file->group_hash = g_hash_table_new (g_str_hash, g_str_equal); key_file->start_group = NULL; key_file->parse_buffer = g_string_sized_new (128); - key_file->approximate_size = 0; key_file->list_separator = ';'; key_file->flags = 0; key_file->locales = g_strdupv ((gchar **)g_get_language_names ()); @@ -602,8 +593,11 @@ g_key_file_clear (GKeyFile *key_file) g_key_file_remove_group_node (key_file, group_node); } - g_hash_table_destroy (key_file->group_hash); - key_file->group_hash = NULL; + if (key_file->group_hash != NULL) + { + g_hash_table_destroy (key_file->group_hash); + key_file->group_hash = NULL; + } g_warn_if_fail (key_file->groups == NULL); } @@ -617,7 +611,7 @@ g_key_file_clear (GKeyFile *key_file) * g_key_file_load_from_dirs() or g_key_file_load_from_data_dirs() to * read an existing key file. * - * Return value: an empty #GKeyFile. + * Returns: (transfer full): an empty #GKeyFile. * * Since: 2.6 **/ @@ -627,6 +621,7 @@ g_key_file_new (void) GKeyFile *key_file; key_file = g_slice_new0 (GKeyFile); + key_file->ref_count = 1; g_key_file_init (key_file); return key_file; @@ -743,7 +738,8 @@ g_key_file_load_from_fd (GKeyFile *key_file, gssize bytes_read; struct stat stat_buf; gchar read_buf[4096]; - + gchar list_separator; + if (fstat (fd, &stat_buf) < 0) { g_set_error_literal (error, G_FILE_ERROR, @@ -760,19 +756,10 @@ g_key_file_load_from_fd (GKeyFile *key_file, return FALSE; } - if (stat_buf.st_size == 0) - { - g_set_error_literal (error, G_KEY_FILE_ERROR, - G_KEY_FILE_ERROR_PARSE, - _("File is empty")); - return FALSE; - } - - if (key_file->approximate_size > 0) - { - g_key_file_clear (key_file); - g_key_file_init (key_file); - } + list_separator = key_file->list_separator; + g_key_file_clear (key_file); + g_key_file_init (key_file); + key_file->list_separator = list_separator; key_file->flags = flags; do @@ -819,15 +806,15 @@ g_key_file_load_from_fd (GKeyFile *key_file, /** * g_key_file_load_from_file: * @key_file: an empty #GKeyFile struct - * @file: the path of a filename to load, in the GLib filename encoding + * @file: (type filename): the path of a filename to load, in the GLib filename encoding * @flags: flags from #GKeyFileFlags * @error: return location for a #GError, or %NULL * * Loads a key file into an empty #GKeyFile structure. - * If the file could not be loaded then %error is set to + * If the file could not be loaded then @error is set to * either a #GFileError or #GKeyFileError. * - * Return value: %TRUE if a key file could be loaded, %FALSE otherwise + * Returns: %TRUE if a key file could be loaded, %FALSE otherwise * * Since: 2.6 **/ @@ -869,14 +856,14 @@ g_key_file_load_from_file (GKeyFile *key_file, * g_key_file_load_from_data: * @key_file: an empty #GKeyFile struct * @data: key file loaded in memory - * @length: the length of @data in bytes + * @length: the length of @data in bytes (or (gsize)-1 if data is nul-terminated) * @flags: flags from #GKeyFileFlags * @error: return location for a #GError, or %NULL * * Loads a key file from memory into an empty #GKeyFile structure. * If the object cannot be created then %error is set to a #GKeyFileError. * - * Return value: %TRUE if a key file could be loaded, %FALSE otherwise + * Returns: %TRUE if a key file could be loaded, %FALSE otherwise * * Since: 2.6 **/ @@ -888,19 +875,18 @@ g_key_file_load_from_data (GKeyFile *key_file, GError **error) { GError *key_file_error = NULL; + gchar list_separator; g_return_val_if_fail (key_file != NULL, FALSE); - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (length != 0, FALSE); + g_return_val_if_fail (data != NULL || length == 0, FALSE); if (length == (gsize)-1) length = strlen (data); - if (key_file->approximate_size > 0) - { - g_key_file_clear (key_file); - g_key_file_init (key_file); - } + list_separator = key_file->list_separator; + g_key_file_clear (key_file); + g_key_file_init (key_file); + key_file->list_separator = list_separator; key_file->flags = flags; g_key_file_parse_data (key_file, data, length, &key_file_error); @@ -925,9 +911,9 @@ g_key_file_load_from_data (GKeyFile *key_file, /** * g_key_file_load_from_dirs: * @key_file: an empty #GKeyFile struct - * @file: a relative path to a filename to open and parse - * @search_dirs: %NULL-terminated array of directories to search - * @full_path: return location for a string containing the full path + * @file: (type filename): a relative path to a filename to open and parse + * @search_dirs: (array zero-terminated=1) (element-type filename): %NULL-terminated array of directories to search + * @full_path: (out) (type filename) (allow-none): return location for a string containing the full path * of the file, or %NULL * @flags: flags from #GKeyFileFlags * @error: return location for a #GError, or %NULL @@ -938,7 +924,7 @@ g_key_file_load_from_data (GKeyFile *key_file, * be loaded then an %error is set to either a #GFileError or * #GKeyFileError. * - * Return value: %TRUE if a key file could be loaded, %FALSE otherwise + * Returns: %TRUE if a key file could be loaded, %FALSE otherwise * * Since: 2.14 **/ @@ -999,8 +985,8 @@ g_key_file_load_from_dirs (GKeyFile *key_file, /** * g_key_file_load_from_data_dirs: * @key_file: an empty #GKeyFile struct - * @file: a relative path to a filename to open and parse - * @full_path: return location for a string containing the full path + * @file: (type filename): a relative path to a filename to open and parse + * @full_path: (out) (type filename) (allow-none): return location for a string containing the full path * of the file, or %NULL * @flags: flags from #GKeyFileFlags * @error: return location for a #GError, or %NULL @@ -1011,7 +997,7 @@ g_key_file_load_from_dirs (GKeyFile *key_file, * @full_path. If the file could not be loaded then an %error is * set to either a #GFileError or #GKeyFileError. * - * Return value: %TRUE if a key file could be loaded, %FALSE othewise + * Returns: %TRUE if a key file could be loaded, %FALSE othewise * Since: 2.6 **/ gboolean @@ -1055,10 +1041,32 @@ g_key_file_load_from_data_dirs (GKeyFile *key_file, } /** - * g_key_file_free: + * g_key_file_ref: (skip) * @key_file: a #GKeyFile * - * Frees a #GKeyFile. + * Increases the reference count of @key_file. + * + * Returns: the same @key_file. + * + * Since: 2.32 + **/ +GKeyFile * +g_key_file_ref (GKeyFile *key_file) +{ + g_return_val_if_fail (key_file != NULL, NULL); + + g_atomic_int_inc (&key_file->ref_count); + + return key_file; +} + +/** + * g_key_file_free: (skip) + * @key_file: a #GKeyFile + * + * Clears all keys and groups from @key_file, and decreases the + * reference count by 1. If the reference count reaches zero, + * frees the key file and all its allocated memory. * * Since: 2.6 **/ @@ -1066,9 +1074,30 @@ void g_key_file_free (GKeyFile *key_file) { g_return_if_fail (key_file != NULL); - + g_key_file_clear (key_file); - g_slice_free (GKeyFile, key_file); + g_key_file_unref (key_file); +} + +/** + * g_key_file_unref: + * @key_file: a #GKeyFile + * + * Decreases the reference count of @key_file by 1. If the reference count + * reaches zero, frees the key file and all its allocated memory. + * + * Since: 2.32 + **/ +void +g_key_file_unref (GKeyFile *key_file) +{ + g_return_if_fail (key_file != NULL); + + if (g_atomic_int_dec_and_test (&key_file->ref_count)) + { + g_key_file_clear (key_file); + g_slice_free (GKeyFile, key_file); + } } /* If G_KEY_FILE_KEEP_TRANSLATIONS is not set, only returns @@ -1154,9 +1183,6 @@ g_key_file_parse_comment (GKeyFile *key_file, key_file->current_group->key_value_pairs = g_list_prepend (key_file->current_group->key_value_pairs, pair); - - if (length == 0 || line[0] != '#') - key_file->current_group->has_trailing_blank_line = TRUE; } static void @@ -1317,7 +1343,7 @@ g_key_file_parse_data (GKeyFile *key_file, gsize i; g_return_if_fail (key_file != NULL); - g_return_if_fail (data != NULL); + g_return_if_fail (data != NULL || length == 0); parse_error = NULL; @@ -1367,8 +1393,6 @@ g_key_file_parse_data (GKeyFile *key_file, i += line_length; } } - - key_file->approximate_size += length; } static void @@ -1399,7 +1423,7 @@ g_key_file_flush_parse_buffer (GKeyFile *key_file, /** * g_key_file_to_data: * @key_file: a #GKeyFile - * @length: return location for the length of the + * @length: (out) (allow-none): return location for the length of the * returned string, or %NULL * @error: return location for a #GError, or %NULL * @@ -1408,7 +1432,7 @@ g_key_file_flush_parse_buffer (GKeyFile *key_file, * Note that this function never reports an error, * so it is safe to pass %NULL as @error. * - * Return value: a newly allocated string holding + * Returns: a newly allocated string holding * the contents of the #GKeyFile * * Since: 2.6 @@ -1420,12 +1444,11 @@ g_key_file_to_data (GKeyFile *key_file, { GString *data_string; GList *group_node, *key_file_node; - gboolean has_blank_line = TRUE; g_return_val_if_fail (key_file != NULL, NULL); - data_string = g_string_sized_new (2 * key_file->approximate_size); - + data_string = g_string_new (NULL); + for (group_node = g_list_last (key_file->groups); group_node != NULL; group_node = group_node->prev) @@ -1435,9 +1458,9 @@ g_key_file_to_data (GKeyFile *key_file, group = (GKeyFileGroup *) group_node->data; /* separate groups by at least an empty line */ - if (!has_blank_line) - g_string_append_c (data_string, '\n'); - has_blank_line = group->has_trailing_blank_line; + if (data_string->len >= 2 && + data_string->str[data_string->len - 2] != '\n') + g_string_append_c (data_string, '\n'); if (group->comment != NULL) g_string_append_printf (data_string, "%s\n", group->comment->value); @@ -1470,7 +1493,7 @@ g_key_file_to_data (GKeyFile *key_file, * g_key_file_get_keys: * @key_file: a #GKeyFile * @group_name: a group name - * @length: return location for the number of keys returned, or %NULL + * @length: (out) (allow-none): return location for the number of keys returned, or %NULL * @error: return location for a #GError, or %NULL * * Returns all keys for the group name @group_name. The array of @@ -1479,7 +1502,7 @@ g_key_file_to_data (GKeyFile *key_file, * be found, %NULL is returned and @error is set to * #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. * - * Return value: a newly-allocated %NULL-terminated array of strings. + * Returns: (array zero-terminated=1) (transfer full): a newly-allocated %NULL-terminated array of strings. * Use g_strfreev() to free it. * * Since: 2.6 @@ -1550,7 +1573,7 @@ g_key_file_get_keys (GKeyFile *key_file, * * Returns the name of the start group of the file. * - * Return value: The start group of the key file. + * Returns: The start group of the key file. * * Since: 2.6 **/ @@ -1568,13 +1591,13 @@ g_key_file_get_start_group (GKeyFile *key_file) /** * g_key_file_get_groups: * @key_file: a #GKeyFile - * @length: return location for the number of returned groups, or %NULL + * @length: (out) (allow-none): return location for the number of returned groups, or %NULL * * Returns all groups in the key file loaded with @key_file. * The array of returned groups will be %NULL-terminated, so * @length may optionally be %NULL. * - * Return value: a newly-allocated %NULL-terminated array of strings. + * Returns: (array zero-terminated=1) (transfer full): a newly-allocated %NULL-terminated array of strings. * Use g_strfreev() to free it. * Since: 2.6 **/ @@ -1641,7 +1664,7 @@ g_key_file_get_groups (GKeyFile *key_file, * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. * * - * Return value: a newly allocated string or %NULL if the specified + * Returns: a newly allocated string or %NULL if the specified * key cannot be found. * * Since: 2.6 @@ -1752,7 +1775,7 @@ g_key_file_set_value (GKeyFile *key_file, * event that the @group_name cannot be found, %NULL is returned * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. * - * Return value: a newly allocated string or %NULL if the specified + * Returns: a newly allocated string or %NULL if the specified * key cannot be found. * * Since: 2.6 @@ -1853,7 +1876,7 @@ g_key_file_set_string (GKeyFile *key_file, * @key_file: a #GKeyFile * @group_name: a group name * @key: a key - * @length: return location for the number of returned strings, or %NULL + * @length: (out) (allow-none): return location for the number of returned strings, or %NULL * @error: return location for a #GError, or %NULL * * Returns the values associated with @key under @group_name. @@ -1863,7 +1886,7 @@ g_key_file_set_string (GKeyFile *key_file, * event that the @group_name cannot be found, %NULL is returned * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. * - * Return value: (array zero-terminated=1 length=length) (element-type utf8) (transfer full): + * Returns: (array zero-terminated=1 length=length) (element-type utf8) (transfer full): * a %NULL-terminated string array or %NULL if the specified * key cannot be found. The array should be freed with g_strfreev(). * @@ -1929,6 +1952,7 @@ g_key_file_get_string_list (GKeyFile *key_file, else g_propagate_error (error, key_file_error); + g_slist_free_full (pieces, g_free); return NULL; } @@ -2040,7 +2064,7 @@ g_key_file_set_locale_string (GKeyFile *key_file, * with @key cannot be interpreted or no suitable translation can * be found then the untranslated value is returned. * - * Return value: a newly allocated string or %NULL if the specified + * Returns: a newly allocated string or %NULL if the specified * key cannot be found. * * Since: 2.6 @@ -2110,13 +2134,13 @@ g_key_file_get_locale_string (GKeyFile *key_file, return translated_value; } -/** - * g_key_file_get_locale_string_list: +/** + * g_key_file_get_locale_string_list: * @key_file: a #GKeyFile * @group_name: a group name * @key: a key * @locale: (allow-none): a locale identifier or %NULL - * @length: (out): return location for the number of returned strings or %NULL + * @length: (out) (allow-none): return location for the number of returned strings or %NULL * @error: return location for a #GError or %NULL * * Returns the values associated with @key under @group_name @@ -2130,7 +2154,7 @@ g_key_file_get_locale_string (GKeyFile *key_file, * returned array is %NULL-terminated, so @length may optionally * be %NULL. * - * Return value: (array zero-terminated=1 length=length) (element-type utf8) (transfer full): a newly allocated %NULL-terminated string array + * Returns: (array zero-terminated=1 length=length) (element-type utf8) (transfer full): a newly allocated %NULL-terminated string array * or %NULL if the key isn't found. The string array should be freed * with g_strfreev(). * @@ -2191,7 +2215,7 @@ g_key_file_get_locale_string_list (GKeyFile *key_file, * @group_name: a group name * @key: a key * @locale: a locale identifier - * @list: a %NULL-terminated array of locale string values + * @list: (array zero-terminated=1 length=length): a %NULL-terminated array of locale string values * @length: the length of @list * * Associates a list of string values for @key and @locale under @@ -2250,7 +2274,7 @@ g_key_file_set_locale_string_list (GKeyFile *key_file, * associated with @key cannot be interpreted as a boolean then %FALSE * is returned and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. * - * Return value: the value associated with the key as a boolean, + * Returns: the value associated with the key as a boolean, * or %FALSE if the key was not found or could not be parsed. * * Since: 2.6 @@ -2333,7 +2357,7 @@ g_key_file_set_boolean (GKeyFile *key_file, * @key_file: a #GKeyFile * @group_name: a group name * @key: a key - * @length: the number of booleans returned + * @length: (out): the number of booleans returned * @error: return location for a #GError * * Returns the values associated with @key under @group_name as @@ -2344,7 +2368,7 @@ g_key_file_set_boolean (GKeyFile *key_file, * with @key cannot be interpreted as booleans then %NULL is returned * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. * - * Return value: (array length=length) (element-type gboolean) (transfer container): + * Returns: (array length=length) (element-type gboolean) (transfer container): * the values associated with the key as a list of booleans, or %NULL if the * key was not found or could not be parsed. The returned list of booleans * should be freed with g_free() when no longer needed. @@ -2411,7 +2435,7 @@ g_key_file_get_boolean_list (GKeyFile *key_file, * @key_file: a #GKeyFile * @group_name: a group name * @key: a key - * @list: an array of boolean values + * @list: (array length=length): an array of boolean values * @length: length of @list * * Associates a list of boolean values with @key under @group_name. @@ -2465,7 +2489,7 @@ g_key_file_set_boolean_list (GKeyFile *key_file, * with @key cannot be interpreted as an integer then 0 is returned * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. * - * Return value: the value associated with the key as an integer, or + * Returns: the value associated with the key as an integer, or * 0 if the key was not found or could not be parsed. * * Since: 2.6 @@ -2587,6 +2611,7 @@ g_key_file_get_int64 (GKeyFile *key_file, _("Key '%s' in group '%s' has value '%s' " "where %s was expected"), key, group_name, s, "int64"); + g_free (s); return 0; } @@ -2663,6 +2688,7 @@ g_key_file_get_uint64 (GKeyFile *key_file, _("Key '%s' in group '%s' has value '%s' " "where %s was expected"), key, group_name, s, "uint64"); + g_free (s); return 0; } @@ -2702,7 +2728,7 @@ g_key_file_set_uint64 (GKeyFile *key_file, * @key_file: a #GKeyFile * @group_name: a group name * @key: a key - * @length: the number of integers returned + * @length: (out): the number of integers returned * @error: return location for a #GError * * Returns the values associated with @key under @group_name as @@ -2713,7 +2739,7 @@ g_key_file_set_uint64 (GKeyFile *key_file, * with @key cannot be interpreted as integers then %NULL is returned * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. * - * Return value: (array length=length) (element-type gint) (transfer container): + * Returns: (array length=length) (element-type gint) (transfer container): * the values associated with the key as a list of integers, or %NULL if * the key was not found or could not be parsed. The returned list of * integers should be freed with g_free() when no longer needed. @@ -2778,7 +2804,7 @@ g_key_file_get_integer_list (GKeyFile *key_file, * @key_file: a #GKeyFile * @group_name: a group name * @key: a key - * @list: an array of integer values + * @list: (array length=length): an array of integer values * @length: number of integer values in @list * * Associates a list of integer values with @key under @group_name. @@ -2831,7 +2857,7 @@ g_key_file_set_integer_list (GKeyFile *key_file, * with @key cannot be interpreted as a double then 0.0 is returned * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. * - * Return value: the value associated with the key as a double, or + * Returns: the value associated with the key as a double, or * 0.0 if the key was not found or could not be parsed. * * Since: 2.12 @@ -2915,7 +2941,7 @@ g_key_file_set_double (GKeyFile *key_file, * @key_file: a #GKeyFile * @group_name: a group name * @key: a key - * @length: the number of doubles returned + * @length: (out): the number of doubles returned * @error: return location for a #GError * * Returns the values associated with @key under @group_name as @@ -2926,7 +2952,7 @@ g_key_file_set_double (GKeyFile *key_file, * with @key cannot be interpreted as doubles then %NULL is returned * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. * - * Return value: (array length=length) (element-type gdouble) (transfer container): + * Returns: (array length=length) (element-type gdouble) (transfer container): * the values associated with the key as a list of doubles, or %NULL if the * key was not found or could not be parsed. The returned list of doubles * should be freed with g_free() when no longer needed. @@ -2991,7 +3017,7 @@ g_key_file_get_double_list (GKeyFile *key_file, * @key_file: a #GKeyFile * @group_name: a group name * @key: a key - * @list: an array of double values + * @list: (array length=length): an array of double values * @length: number of double values in @list * * Associates a list of double values with @key under @@ -3155,14 +3181,8 @@ g_key_file_set_top_comment (GKeyFile *key_file, /* Note all keys must be comments at the top of * the file, so we can just free it all. */ - if (group->key_value_pairs != NULL) - { - g_list_foreach (group->key_value_pairs, - (GFunc) g_key_file_key_value_pair_free, - NULL); - g_list_free (group->key_value_pairs); - group->key_value_pairs = NULL; - } + g_list_free_full (group->key_value_pairs, (GDestroyNotify) g_key_file_key_value_pair_free); + group->key_value_pairs = NULL; if (comment == NULL) return TRUE; @@ -3180,8 +3200,8 @@ g_key_file_set_top_comment (GKeyFile *key_file, /** * g_key_file_set_comment: * @key_file: a #GKeyFile - * @group_name: a group name, or %NULL - * @key: a key + * @group_name: (allow-none): a group name, or %NULL + * @key: (allow-none): a key * @comment: a comment * @error: return location for a #GError * @@ -3219,9 +3239,6 @@ g_key_file_set_comment (GKeyFile *key_file, return FALSE; } - if (comment != NULL) - key_file->approximate_size += strlen (comment); - return TRUE; } @@ -3413,7 +3430,7 @@ g_key_file_get_top_comment (GKeyFile *key_file, /** * g_key_file_get_comment: * @key_file: a #GKeyFile - * @group_name: a group name, or %NULL + * @group_name: (allow-none): a group name, or %NULL * @key: a key * @error: return location for a #GError * @@ -3445,8 +3462,8 @@ g_key_file_get_comment (GKeyFile *key_file, /** * g_key_file_remove_comment: * @key_file: a #GKeyFile - * @group_name: a group name, or %NULL - * @key: a key + * @group_name: (allow-none): a group name, or %NULL + * @key: (allow-none): a key * @error: return location for a #GError * * Removes a comment above @key from @group_name. @@ -3482,7 +3499,7 @@ g_key_file_remove_comment (GKeyFile *key_file, * * Looks whether the key file has the group @group_name. * - * Return value: %TRUE if @group_name is a part of @key_file, %FALSE + * Returns: %TRUE if @group_name is a part of @key_file, %FALSE * otherwise. * Since: 2.6 **/ @@ -3542,16 +3559,15 @@ g_key_file_has_key_full (GKeyFile *key_file, * Looks whether the key file has the key @key in the group * @group_name. * - * This function does not follow the rules for #GError strictly; + * Note that this function does not follow the rules for #GError strictly; * the return value both carries meaning and signals an error. To use * this function, you must pass a #GError pointer in @error, and check - * whether it is not %NULL to see if an error occurred. + * whether it is not %NULL to see if an error occurred. * * Language bindings should use g_key_file_get_value() to test whether * or not a key exists. * - * Return value: %TRUE if @key is a part of @group_name, %FALSE - * otherwise. + * Returns: %TRUE if @key is a part of @group_name, %FALSE otherwise * * Since: 2.6 **/ @@ -3595,7 +3611,6 @@ g_key_file_add_group (GKeyFile *key_file, group->name = g_strdup (group_name); group->lookup_map = g_hash_table_new (g_str_hash, g_str_equal); key_file->groups = g_list_prepend (key_file->groups, group); - key_file->approximate_size += strlen (group_name) + 3; key_file->current_group = group; if (key_file->start_group == NULL) @@ -3636,11 +3651,7 @@ g_key_file_remove_key_value_pair_node (GKeyFile *key_file, group->key_value_pairs = g_list_remove_link (group->key_value_pairs, pair_node); - if (pair->key != NULL) - key_file->approximate_size -= strlen (pair->key) + 1; - g_warn_if_fail (pair->value != NULL); - key_file->approximate_size -= strlen (pair->value); g_key_file_key_value_pair_free (pair); @@ -3696,9 +3707,6 @@ g_key_file_remove_group_node (GKeyFile *key_file, key_file->groups = g_list_remove_link (key_file->groups, group_node); - if (group->name != NULL) - key_file->approximate_size -= strlen (group->name) + 3; - tmp = group->key_value_pairs; while (tmp != NULL) { @@ -3711,6 +3719,12 @@ g_key_file_remove_group_node (GKeyFile *key_file, g_warn_if_fail (group->key_value_pairs == NULL); + if (group->comment) + { + g_key_file_key_value_pair_free (group->comment); + group->comment = NULL; + } + if (group->lookup_map) { g_hash_table_destroy (group->lookup_map); @@ -3768,8 +3782,6 @@ g_key_file_add_key_value_pair (GKeyFile *key_file, { g_hash_table_replace (group->lookup_map, pair->key, pair); group->key_value_pairs = g_list_prepend (group->key_value_pairs, pair); - group->has_trailing_blank_line = FALSE; - key_file->approximate_size += strlen (pair->key) + strlen (pair->value) + 2; } static void @@ -3836,10 +3848,8 @@ g_key_file_remove_key (GKeyFile *key_file, return FALSE; } - key_file->approximate_size -= strlen (pair->key) + strlen (pair->value) + 2; - group->key_value_pairs = g_list_remove (group->key_value_pairs, pair); - g_hash_table_remove (group->lookup_map, pair->key); + g_hash_table_remove (group->lookup_map, pair->key); g_key_file_key_value_pair_free (pair); return TRUE; @@ -4360,3 +4370,41 @@ g_key_file_parse_comment_as_value (GKeyFile *key_file, return g_string_free (string, FALSE); } + +/** + * g_key_file_save_to_file: + * @key_file: a #GKeyFile + * @filename: the name of the file to write to + * @error: a pointer to a %NULL #GError, or %NULL + * + * Writes the contents of @key_file to @filename using + * g_file_set_contents(). + * + * This function can fail for any of the reasons that + * g_file_set_contents() may fail. + * + * Returns: %TRUE if successful, else %FALSE with @error set + * + * Since: 2.40 + */ +gboolean +g_key_file_save_to_file (GKeyFile *key_file, + const gchar *filename, + GError **error) +{ + gchar *contents; + gboolean success; + gsize length; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + contents = g_key_file_to_data (key_file, &length, NULL); + g_assert (contents != NULL); + + success = g_file_set_contents (filename, contents, length, error); + g_free (contents); + + return success; +}