X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=glib%2Fgkeyfile.c;h=cc51eda690eaf9afea04a3475e4bb10e7cc9f580;hb=2a53b4d0e2c98a14aedf31e38f0ad1fb2e8fe26f;hp=33b3c36bb4f48f19c5b1f57f9c031a7b185fdc8d;hpb=e94a5f4f8394fe6a7160850c12ea8079215e4323;p=platform%2Fupstream%2Fglib.git diff --git a/glib/gkeyfile.c b/glib/gkeyfile.c index 33b3c36..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 */ @@ -454,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; @@ -555,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) @@ -618,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: (transfer full): an empty #GKeyFile. + * Returns: (transfer full): an empty #GKeyFile. * * Since: 2.6 **/ @@ -818,10 +811,10 @@ g_key_file_load_from_fd (GKeyFile *key_file, * @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 **/ @@ -862,15 +855,15 @@ g_key_file_load_from_file (GKeyFile *key_file, /** * g_key_file_load_from_data: * @key_file: an empty #GKeyFile struct - * @data: (array length=length): key file loaded in memory - * @length: the length of @data in bytes + * @data: key file loaded in memory + * @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 **/ @@ -885,8 +878,7 @@ g_key_file_load_from_data (GKeyFile *key_file, 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); @@ -921,7 +913,7 @@ g_key_file_load_from_data (GKeyFile *key_file, * @key_file: an empty #GKeyFile struct * @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): return location for a string containing the full path + * @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 @@ -932,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 **/ @@ -994,7 +986,7 @@ g_key_file_load_from_dirs (GKeyFile *key_file, * g_key_file_load_from_data_dirs: * @key_file: an empty #GKeyFile struct * @file: (type filename): a relative path to a filename to open and parse - * @full_path: (out) (type filename): return location for a string containing the full path + * @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 @@ -1005,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 @@ -1191,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 @@ -1354,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; @@ -1443,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 @@ -1455,7 +1444,6 @@ 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); @@ -1470,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); @@ -1505,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: (out): 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 @@ -1514,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: (array zero-terminated=1) (transfer full): 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 @@ -1585,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 **/ @@ -1609,7 +1597,7 @@ g_key_file_get_start_group (GKeyFile *key_file) * The array of returned groups will be %NULL-terminated, so * @length may optionally be %NULL. * - * Return value: (array zero-terminated=1) (transfer full): 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 **/ @@ -1676,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 @@ -1787,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 @@ -1898,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(). * @@ -2076,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 @@ -2166,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(). * @@ -2286,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 @@ -2380,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. @@ -2501,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 @@ -2623,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; } @@ -2699,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; } @@ -2749,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. @@ -2867,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 @@ -2962,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. @@ -3440,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 * @@ -3509,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 **/ @@ -3569,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 **/ @@ -3793,7 +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; } static void @@ -4382,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; +}