1 /* gkeyfile.c - key file parser 2 * 3 * Copyright 2004 Red Hat, Inc. 4 * 5 * Written by Ray Strode <rstrode (at) redhat.com> 6 * Matthias Clasen <mclasen (at) redhat.com> 7 * 8 * GLib is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU Lesser General Public License as 10 * published by the Free Software Foundation; either version 2 of the 11 * License, or (at your option) any later version. 12 * 13 * GLib is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with GLib; see the file COPYING.LIB. If not, 20 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 21 * Boston, MA 02111-1307, USA. 22 */ 23 24 #include "config.h" 25 26 #include "gkeyfile.h" 27 28 #include <errno.h> 29 #include <fcntl.h> 30 #include <locale.h> 31 #include <string.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <sys/types.h> 35 #include <sys/stat.h> 36 #ifdef HAVE_UNISTD_H 37 #include <unistd.h> 38 #endif 39 #ifdef G_OS_WIN32 40 #include <io.h> 41 42 #ifndef S_ISREG 43 #define S_ISREG(mode) ((mode)&_S_IFREG) 44 #endif 45 46 #endif /* G_OS_WIN23 */ 47 48 #include "gconvert.h" 49 #include "gdataset.h" 50 #include "gerror.h" 51 #include "gfileutils.h" 52 #include "ghash.h" 53 #include "glibintl.h" 54 #include "glist.h" 55 #include "gslist.h" 56 #include "gmem.h" 57 #include "gmessages.h" 58 #include "gstdio.h" 59 #include "gstring.h" 60 #include "gstrfuncs.h" 61 #include "gutils.h" 62 63 #include "galias.h" 64 65 typedef struct _GKeyFileGroup GKeyFileGroup; 66 67 struct _GKeyFile 68 { 69 GList *groups; 70 GHashTable *group_hash; 71 72 GKeyFileGroup *start_group; 73 GKeyFileGroup *current_group; 74 75 GString *parse_buffer; /* Holds up to one line of not-yet-parsed data */ 76 77 /* Used for sizing the output buffer during serialization 78 */ 79 gsize approximate_size; 80 81 gchar list_separator; 82 83 GKeyFileFlags flags; 84 85 gchar **locales; 86 }; 87 88 typedef struct _GKeyFileKeyValuePair GKeyFileKeyValuePair; 89 90 struct _GKeyFileGroup 91 { 92 const gchar *name; /* NULL for above first group (which will be comments) */ 93 94 GKeyFileKeyValuePair *comment; /* Special comment that is stuck to the top of a group */ 95 gboolean has_trailing_blank_line; 96 97 GList *key_value_pairs; 98 99 /* Used in parallel with key_value_pairs for 100 * increased lookup performance 101 */ 102 GHashTable *lookup_map; 103 }; 104 105 struct _GKeyFileKeyValuePair 106 { 107 gchar *key; /* NULL for comments */ 108 gchar *value; 109 }; 110 111 static gint find_file_in_data_dirs (const gchar *file, 112 const gchar **data_dirs, 113 gchar **output_file, 114 GError **error); 115 static gboolean g_key_file_load_from_fd (GKeyFile *key_file, 116 gint fd, 117 GKeyFileFlags flags, 118 GError **error); 119 static GList *g_key_file_lookup_group_node (GKeyFile *key_file, 120 const gchar *group_name); 121 static GKeyFileGroup *g_key_file_lookup_group (GKeyFile *key_file, 122 const gchar *group_name); 123 124 static GList *g_key_file_lookup_key_value_pair_node (GKeyFile *key_file, 125 GKeyFileGroup *group, 126 const gchar *key); 127 static GKeyFileKeyValuePair *g_key_file_lookup_key_value_pair (GKeyFile *key_file, 128 GKeyFileGroup *group, 129 const gchar *key); 130 131 static void g_key_file_remove_group_node (GKeyFile *key_file, 132 GList *group_node); 133 static void g_key_file_remove_key_value_pair_node (GKeyFile *key_file, 134 GKeyFileGroup *group, 135 GList *pair_node); 136 137 static void g_key_file_add_key (GKeyFile *key_file, 138 GKeyFileGroup *group, 139 const gchar *key, 140 const gchar *value); 141 static void g_key_file_add_group (GKeyFile *key_file, 142 const gchar *group_name); 143 static gboolean g_key_file_is_group_name (const gchar *name); 144 static gboolean g_key_file_is_key_name (const gchar *name); 145 static void g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair); 146 static gboolean g_key_file_line_is_comment (const gchar *line); 147 static gboolean g_key_file_line_is_group (const gchar *line); 148 static gboolean g_key_file_line_is_key_value_pair (const gchar *line); 149 static gchar *g_key_file_parse_value_as_string (GKeyFile *key_file, 150 const gchar *value, 151 GSList **separators, 152 GError **error); 153 static gchar *g_key_file_parse_string_as_value (GKeyFile *key_file, 154 const gchar *string, 155 gboolean escape_separator); 156 static gint g_key_file_parse_value_as_integer (GKeyFile *key_file, 157 const gchar *value, 158 GError **error); 159 static gchar *g_key_file_parse_integer_as_value (GKeyFile *key_file, 160 gint value); 161 static gdouble g_key_file_parse_value_as_double (GKeyFile *key_file, 162 const gchar *value, 163 GError **error); 164 static gboolean g_key_file_parse_value_as_boolean (GKeyFile *key_file, 165 const gchar *value, 166 GError **error); 167 static gchar *g_key_file_parse_boolean_as_value (GKeyFile *key_file, 168 gboolean value); 169 static gchar *g_key_file_parse_value_as_comment (GKeyFile *key_file, 170 const gchar *value); 171 static gchar *g_key_file_parse_comment_as_value (GKeyFile *key_file, 172 const gchar *comment); 173 static void g_key_file_parse_key_value_pair (GKeyFile *key_file, 174 const gchar *line, 175 gsize length, 176 GError **error); 177 static void g_key_file_parse_comment (GKeyFile *key_file, 178 const gchar *line, 179 gsize length, 180 GError **error); 181 static void g_key_file_parse_group (GKeyFile *key_file, 182 const gchar *line, 183 gsize length, 184 GError **error); 185 static gchar *key_get_locale (const gchar *key); 186 static void g_key_file_parse_data (GKeyFile *key_file, 187 const gchar *data, 188 gsize length, 189 GError **error); 190 static void g_key_file_flush_parse_buffer (GKeyFile *key_file, 191 GError **error); 192 193 194 GQuark 195 g_key_file_error_quark (void) 196 { 197 return g_quark_from_static_string ("g-key-file-error-quark"); 198 } 199 200 static void 201 g_key_file_init (GKeyFile *key_file) 202 { 203 key_file->current_group = g_slice_new0 (GKeyFileGroup); 204 key_file->groups = g_list_prepend (NULL, key_file->current_group); 205 key_file->group_hash = g_hash_table_new (g_str_hash, g_str_equal); 206 key_file->start_group = NULL; 207 key_file->parse_buffer = g_string_sized_new (128); 208 key_file->approximate_size = 0; 209 key_file->list_separator = ';'; 210 key_file->flags = 0; 211 key_file->locales = g_strdupv ((gchar **)g_get_language_names ()); 212 } 213 214 static void 215 g_key_file_clear (GKeyFile *key_file) 216 { 217 GList *tmp, *group_node; 218 219 if (key_file->locales) 220 { 221 g_strfreev (key_file->locales); 222 key_file->locales = NULL; 223 } 224 225 if (key_file->parse_buffer) 226 { 227 g_string_free (key_file->parse_buffer, TRUE); 228 key_file->parse_buffer = NULL; 229 } 230 231 tmp = key_file->groups; 232 while (tmp != NULL) 233 { 234 group_node = tmp; 235 tmp = tmp->next; 236 g_key_file_remove_group_node (key_file, group_node); 237 } 238 239 g_hash_table_destroy (key_file->group_hash); 240 key_file->group_hash = NULL; 241 242 g_warn_if_fail (key_file->groups == NULL); 243 } 244 245 246 /** 247 * g_key_file_new: 248 * 249 * Creates a new empty #GKeyFile object. Use 250 * g_key_file_load_from_file(), g_key_file_load_from_data(), 251 * g_key_file_load_from_dirs() or g_key_file_load_from_data_dirs() to 252 * read an existing key file. 253 * 254 * Return value: an empty #GKeyFile. 255 * 256 * Since: 2.6 257 **/ 258 GKeyFile * 259 g_key_file_new (void) 260 { 261 GKeyFile *key_file; 262 263 key_file = g_slice_new0 (GKeyFile); 264 g_key_file_init (key_file); 265 266 return key_file; 267 } 268 269 /** 270 * g_key_file_set_list_separator: 271 * @key_file: a #GKeyFile 272 * @separator: the separator 273 * 274 * Sets the character which is used to separate 275 * values in lists. Typically ';' or ',' are used 276 * as separators. The default list separator is ';'. 277 * 278 * Since: 2.6 279 */ 280 void 281 g_key_file_set_list_separator (GKeyFile *key_file, 282 gchar separator) 283 { 284 g_return_if_fail (key_file != NULL); 285 286 key_file->list_separator = separator; 287 } 288 289 290 /* Iterates through all the directories in *dirs trying to 291 * open file. When it successfully locates and opens a file it 292 * returns the file descriptor to the open file. It also 293 * outputs the absolute path of the file in output_file. 294 */ 295 static gint 296 find_file_in_data_dirs (const gchar *file, 297 const gchar **dirs, 298 gchar **output_file, 299 GError **error) 300 { 301 const gchar **data_dirs, *data_dir; 302 gchar *path; 303 gint fd; 304 305 path = NULL; 306 fd = -1; 307 308 if (dirs == NULL) 309 return fd; 310 311 data_dirs = dirs; 312 313 while (data_dirs && (data_dir = *data_dirs) && fd < 0) 314 { 315 gchar *candidate_file, *sub_dir; 316 317 candidate_file = (gchar *) file; 318 sub_dir = g_strdup (""); 319 while (candidate_file != NULL && fd < 0) 320 { 321 gchar *p; 322 323 path = g_build_filename (data_dir, sub_dir, 324 candidate_file, NULL); 325 326 fd = g_open (path, O_RDONLY, 0); 327 328 if (fd < 0) 329 { 330 g_free (path); 331 path = NULL; 332 } 333 334 candidate_file = strchr (candidate_file, '-'); 335 336 if (candidate_file == NULL) 337 break; 338 339 candidate_file++; 340 341 g_free (sub_dir); 342 sub_dir = g_strndup (file, candidate_file - file - 1); 343 344 for (p = sub_dir; *p != '\0'; p++) 345 { 346 if (*p == '-') 347 *p = G_DIR_SEPARATOR; 348 } 349 } 350 g_free (sub_dir); 351 data_dirs++; 352 } 353 354 if (fd < 0) 355 { 356 g_set_error_literal (error, G_KEY_FILE_ERROR, 357 G_KEY_FILE_ERROR_NOT_FOUND, 358 _("Valid key file could not be " 359 "found in search dirs")); 360 } 361 362 if (output_file != NULL && fd > 0) 363 *output_file = g_strdup (path); 364 365 g_free (path); 366 367 return fd; 368 } 369 370 static gboolean 371 g_key_file_load_from_fd (GKeyFile *key_file, 372 gint fd, 373 GKeyFileFlags flags, 374 GError **error) 375 { 376 GError *key_file_error = NULL; 377 gssize bytes_read; 378 struct stat stat_buf; 379 gchar read_buf[4096]; 380 381 if (fstat (fd, &stat_buf) < 0) 382 { 383 g_set_error_literal (error, G_FILE_ERROR, 384 g_file_error_from_errno (errno), 385 g_strerror (errno)); 386 return FALSE; 387 } 388 389 if (!S_ISREG (stat_buf.st_mode)) 390 { 391 g_set_error_literal (error, G_KEY_FILE_ERROR, 392 G_KEY_FILE_ERROR_PARSE, 393 _("Not a regular file")); 394 return FALSE; 395 } 396 397 if (stat_buf.st_size == 0) 398 { 399 g_set_error_literal (error, G_KEY_FILE_ERROR, 400 G_KEY_FILE_ERROR_PARSE, 401 _("File is empty")); 402 return FALSE; 403 } 404 405 if (key_file->approximate_size > 0) 406 { 407 g_key_file_clear (key_file); 408 g_key_file_init (key_file); 409 } 410 key_file->flags = flags; 411 412 bytes_read = 0; 413 do 414 { 415 bytes_read = read (fd, read_buf, 4096); 416 417 if (bytes_read == 0) /* End of File */ 418 break; 419 420 if (bytes_read < 0) 421 { 422 if (errno == EINTR || errno == EAGAIN) 423 continue; 424 425 g_set_error_literal (error, G_FILE_ERROR, 426 g_file_error_from_errno (errno), 427 g_strerror (errno)); 428 return FALSE; 429 } 430 431 g_key_file_parse_data (key_file, 432 read_buf, bytes_read, 433 &key_file_error); 434 } 435 while (!key_file_error); 436 437 if (key_file_error) 438 { 439 g_propagate_error (error, key_file_error); 440 return FALSE; 441 } 442 443 g_key_file_flush_parse_buffer (key_file, &key_file_error); 444 445 if (key_file_error) 446 { 447 g_propagate_error (error, key_file_error); 448 return FALSE; 449 } 450 451 return TRUE; 452 } 453 454 /** 455 * g_key_file_load_from_file: 456 * @key_file: an empty #GKeyFile struct 457 * @file: the path of a filename to load, in the GLib filename encoding 458 * @flags: flags from #GKeyFileFlags 459 * @error: return location for a #GError, or %NULL 460 * 461 * Loads a key file into an empty #GKeyFile structure. 462 * If the file could not be loaded then %error is set to 463 * either a #GFileError or #GKeyFileError. 464 * 465 * Return value: %TRUE if a key file could be loaded, %FALSE otherwise 466 * 467 * Since: 2.6 468 **/ 469 gboolean 470 g_key_file_load_from_file (GKeyFile *key_file, 471 const gchar *file, 472 GKeyFileFlags flags, 473 GError **error) 474 { 475 GError *key_file_error = NULL; 476 gint fd; 477 478 g_return_val_if_fail (key_file != NULL, FALSE); 479 g_return_val_if_fail (file != NULL, FALSE); 480 481 fd = g_open (file, O_RDONLY, 0); 482 483 if (fd < 0) 484 { 485 g_set_error_literal (error, G_FILE_ERROR, 486 g_file_error_from_errno (errno), 487 g_strerror (errno)); 488 return FALSE; 489 } 490 491 g_key_file_load_from_fd (key_file, fd, flags, &key_file_error); 492 close (fd); 493 494 if (key_file_error) 495 { 496 g_propagate_error (error, key_file_error); 497 return FALSE; 498 } 499 500 return TRUE; 501 } 502 503 /** 504 * g_key_file_load_from_data: 505 * @key_file: an empty #GKeyFile struct 506 * @data: key file loaded in memory 507 * @length: the length of @data in bytes 508 * @flags: flags from #GKeyFileFlags 509 * @error: return location for a #GError, or %NULL 510 * 511 * Loads a key file from memory into an empty #GKeyFile structure. 512 * If the object cannot be created then %error is set to a #GKeyFileError. 513 * 514 * Return value: %TRUE if a key file could be loaded, %FALSE otherwise 515 * 516 * Since: 2.6 517 **/ 518 gboolean 519 g_key_file_load_from_data (GKeyFile *key_file, 520 const gchar *data, 521 gsize length, 522 GKeyFileFlags flags, 523 GError **error) 524 { 525 GError *key_file_error = NULL; 526 527 g_return_val_if_fail (key_file != NULL, FALSE); 528 g_return_val_if_fail (data != NULL, FALSE); 529 g_return_val_if_fail (length != 0, FALSE); 530 531 if (length == (gsize)-1) 532 length = strlen (data); 533 534 if (key_file->approximate_size > 0) 535 { 536 g_key_file_clear (key_file); 537 g_key_file_init (key_file); 538 } 539 key_file->flags = flags; 540 541 g_key_file_parse_data (key_file, data, length, &key_file_error); 542 543 if (key_file_error) 544 { 545 g_propagate_error (error, key_file_error); 546 return FALSE; 547 } 548 549 g_key_file_flush_parse_buffer (key_file, &key_file_error); 550 551 if (key_file_error) 552 { 553 g_propagate_error (error, key_file_error); 554 return FALSE; 555 } 556 557 return TRUE; 558 } 559 560 /** 561 * g_key_file_load_from_dirs: 562 * @key_file: an empty #GKeyFile struct 563 * @file: a relative path to a filename to open and parse 564 * @search_dirs: %NULL-terminated array of directories to search 565 * @full_path: return location for a string containing the full path 566 * of the file, or %NULL 567 * @flags: flags from #GKeyFileFlags 568 * @error: return location for a #GError, or %NULL 569 * 570 * This function looks for a key file named @file in the paths 571 * specified in @search_dirs, loads the file into @key_file and 572 * returns the file's full path in @full_path. If the file could not 573 * be loaded then an %error is set to either a #GFileError or 574 * #GKeyFileError. 575 * 576 * Return value: %TRUE if a key file could be loaded, %FALSE otherwise 577 * 578 * Since: 2.14 579 **/ 580 gboolean 581 g_key_file_load_from_dirs (GKeyFile *key_file, 582 const gchar *file, 583 const gchar **search_dirs, 584 gchar **full_path, 585 GKeyFileFlags flags, 586 GError **error) 587 { 588 GError *key_file_error = NULL; 589 const gchar **data_dirs; 590 gchar *output_path; 591 gint fd; 592 gboolean found_file; 593 594 g_return_val_if_fail (key_file != NULL, FALSE); 595 g_return_val_if_fail (!g_path_is_absolute (file), FALSE); 596 g_return_val_if_fail (search_dirs != NULL, FALSE); 597 598 found_file = FALSE; 599 data_dirs = search_dirs; 600 output_path = NULL; 601 while (*data_dirs != NULL && !found_file) 602 { 603 g_free (output_path); 604 605 fd = find_file_in_data_dirs (file, data_dirs, &output_path, 606 &key_file_error); 607 608 if (fd < 0) 609 { 610 if (key_file_error) 611 g_propagate_error (error, key_file_error); 612 break; 613 } 614 615 found_file = g_key_file_load_from_fd (key_file, fd, flags, 616 &key_file_error); 617 close (fd); 618 619 if (key_file_error) 620 { 621 g_propagate_error (error, key_file_error); 622 break; 623 } 624 } 625 626 if (found_file && full_path) 627 *full_path = output_path; 628 else 629 g_free (output_path); 630 631 return found_file; 632 } 633 634 /** 635 * g_key_file_load_from_data_dirs: 636 * @key_file: an empty #GKeyFile struct 637 * @file: a relative path to a filename to open and parse 638 * @full_path: return location for a string containing the full path 639 * of the file, or %NULL 640 * @flags: flags from #GKeyFileFlags 641 * @error: return location for a #GError, or %NULL 642 * 643 * This function looks for a key file named @file in the paths 644 * returned from g_get_user_data_dir() and g_get_system_data_dirs(), 645 * loads the file into @key_file and returns the file's full path in 646 * @full_path. If the file could not be loaded then an %error is 647 * set to either a #GFileError or #GKeyFileError. 648 * 649 * Return value: %TRUE if a key file could be loaded, %FALSE othewise 650 * Since: 2.6 651 **/ 652 gboolean 653 g_key_file_load_from_data_dirs (GKeyFile *key_file, 654 const gchar *file, 655 gchar **full_path, 656 GKeyFileFlags flags, 657 GError **error) 658 { 659 gchar **all_data_dirs; 660 const gchar * user_data_dir; 661 const gchar * const * system_data_dirs; 662 gsize i, j; 663 gboolean found_file; 664 665 g_return_val_if_fail (key_file != NULL, FALSE); 666 g_return_val_if_fail (!g_path_is_absolute (file), FALSE); 667 668 user_data_dir = g_get_user_data_dir (); 669 system_data_dirs = g_get_system_data_dirs (); 670 all_data_dirs = g_new (gchar *, g_strv_length ((gchar **)system_data_dirs) + 2); 671 672 i = 0; 673 all_data_dirs[i++] = g_strdup (user_data_dir); 674 675 j = 0; 676 while (system_data_dirs[j] != NULL) 677 all_data_dirs[i++] = g_strdup (system_data_dirs[j++]); 678 all_data_dirs[i] = NULL; 679 680 found_file = g_key_file_load_from_dirs (key_file, 681 file, 682 (const gchar **)all_data_dirs, 683 full_path, 684 flags, 685 error); 686 687 g_strfreev (all_data_dirs); 688 689 return found_file; 690 } 691 692 /** 693 * g_key_file_free: 694 * @key_file: a #GKeyFile 695 * 696 * Frees a #GKeyFile. 697 * 698 * Since: 2.6 699 **/ 700 void 701 g_key_file_free (GKeyFile *key_file) 702 { 703 g_return_if_fail (key_file != NULL); 704 705 g_key_file_clear (key_file); 706 g_slice_free (GKeyFile, key_file); 707 } 708 709 /* If G_KEY_FILE_KEEP_TRANSLATIONS is not set, only returns 710 * true for locales that match those in g_get_language_names(). 711 */ 712 static gboolean 713 g_key_file_locale_is_interesting (GKeyFile *key_file, 714 const gchar *locale) 715 { 716 gsize i; 717 718 if (key_file->flags & G_KEY_FILE_KEEP_TRANSLATIONS) 719 return TRUE; 720 721 for (i = 0; key_file->locales[i] != NULL; i++) 722 { 723 if (g_ascii_strcasecmp (key_file->locales[i], locale) == 0) 724 return TRUE; 725 } 726 727 return FALSE; 728 } 729 730 static void 731 g_key_file_parse_line (GKeyFile *key_file, 732 const gchar *line, 733 gsize length, 734 GError **error) 735 { 736 GError *parse_error = NULL; 737 gchar *line_start; 738 739 g_return_if_fail (key_file != NULL); 740 g_return_if_fail (line != NULL); 741 742 line_start = (gchar *) line; 743 while (g_ascii_isspace (*line_start)) 744 line_start++; 745 746 if (g_key_file_line_is_comment (line_start)) 747 g_key_file_parse_comment (key_file, line, length, &parse_error); 748 else if (g_key_file_line_is_group (line_start)) 749 g_key_file_parse_group (key_file, line_start, 750 length - (line_start - line), 751 &parse_error); 752 else if (g_key_file_line_is_key_value_pair (line_start)) 753 g_key_file_parse_key_value_pair (key_file, line_start, 754 length - (line_start - line), 755 &parse_error); 756 else 757 { 758 gchar *line_utf8 = _g_utf8_make_valid (line); 759 g_set_error (error, G_KEY_FILE_ERROR, 760 G_KEY_FILE_ERROR_PARSE, 761 _("Key file contains line '%s' which is not " 762 "a key-value pair, group, or comment"), 763 line_utf8); 764 g_free (line_utf8); 765 766 return; 767 } 768 769 if (parse_error) 770 g_propagate_error (error, parse_error); 771 } 772 773 static void 774 g_key_file_parse_comment (GKeyFile *key_file, 775 const gchar *line, 776 gsize length, 777 GError **error) 778 { 779 GKeyFileKeyValuePair *pair; 780 781 if (!(key_file->flags & G_KEY_FILE_KEEP_COMMENTS)) 782 return; 783 784 g_warn_if_fail (key_file->current_group != NULL); 785 786 pair = g_slice_new (GKeyFileKeyValuePair); 787 pair->key = NULL; 788 pair->value = g_strndup (line, length); 789 790 key_file->current_group->key_value_pairs = 791 g_list_prepend (key_file->current_group->key_value_pairs, pair); 792 793 if (length == 0 || line[0] != '#') 794 key_file->current_group->has_trailing_blank_line = TRUE; 795 } 796 797 static void 798 g_key_file_parse_group (GKeyFile *key_file, 799 const gchar *line, 800 gsize length, 801 GError **error) 802 { 803 gchar *group_name; 804 const gchar *group_name_start, *group_name_end; 805 806 /* advance past opening '[' 807 */ 808 group_name_start = line + 1; 809 group_name_end = line + length - 1; 810 811 while (*group_name_end != ']') 812 group_name_end--; 813 814 group_name = g_strndup (group_name_start, 815 group_name_end - group_name_start); 816 817 if (!g_key_file_is_group_name (group_name)) 818 { 819 g_set_error (error, G_KEY_FILE_ERROR, 820 G_KEY_FILE_ERROR_PARSE, 821 _("Invalid group name: %s"), group_name); 822 g_free (group_name); 823 return; 824 } 825 826 g_key_file_add_group (key_file, group_name); 827 g_free (group_name); 828 } 829 830 static void 831 g_key_file_parse_key_value_pair (GKeyFile *key_file, 832 const gchar *line, 833 gsize length, 834 GError **error) 835 { 836 gchar *key, *value, *key_end, *value_start, *locale; 837 gsize key_len, value_len; 838 839 if (key_file->current_group == NULL || key_file->current_group->name == NULL) 840 { 841 g_set_error_literal (error, G_KEY_FILE_ERROR, 842 G_KEY_FILE_ERROR_GROUP_NOT_FOUND, 843 _("Key file does not start with a group")); 844 return; 845 } 846 847 key_end = value_start = strchr (line, '='); 848 849 g_warn_if_fail (key_end != NULL); 850 851 key_end--; 852 value_start++; 853 854 /* Pull the key name from the line (chomping trailing whitespace) 855 */ 856 while (g_ascii_isspace (*key_end)) 857 key_end--; 858 859 key_len = key_end - line + 2; 860 861 g_warn_if_fail (key_len <= length); 862 863 key = g_strndup (line, key_len - 1); 864 865 if (!g_key_file_is_key_name (key)) 866 { 867 g_set_error (error, G_KEY_FILE_ERROR, 868 G_KEY_FILE_ERROR_PARSE, 869 _("Invalid key name: %s"), key); 870 g_free (key); 871 return; 872 } 873 874 /* Pull the value from the line (chugging leading whitespace) 875 */ 876 while (g_ascii_isspace (*value_start)) 877 value_start++; 878 879 value_len = line + length - value_start + 1; 880 881 value = g_strndup (value_start, value_len); 882 883 g_warn_if_fail (key_file->start_group != NULL); 884 885 if (key_file->current_group 886 && key_file->current_group->name 887 && strcmp (key_file->start_group->name, 888 key_file->current_group->name) == 0 889 && strcmp (key, "Encoding") == 0) 890 { 891 if (g_ascii_strcasecmp (value, "UTF-8") != 0) 892 { 893 gchar *value_utf8 = _g_utf8_make_valid (value); 894 g_set_error (error, G_KEY_FILE_ERROR, 895 G_KEY_FILE_ERROR_UNKNOWN_ENCODING, 896 _("Key file contains unsupported " 897 "encoding '%s'"), value_utf8); 898 g_free (value_utf8); 899 900 g_free (key); 901 g_free (value); 902 return; 903 } 904 } 905 906 /* Is this key a translation? If so, is it one that we care about? 907 */ 908 locale = key_get_locale (key); 909 910 if (locale == NULL || g_key_file_locale_is_interesting (key_file, locale)) 911 g_key_file_add_key (key_file, key_file->current_group, key, value); 912 913 g_free (locale); 914 g_free (key); 915 g_free (value); 916 } 917 918 static gchar * 919 key_get_locale (const gchar *key) 920 { 921 gchar *locale; 922 923 locale = g_strrstr (key, "["); 924 925 if (locale && strlen (locale) <= 2) 926 locale = NULL; 927 928 if (locale) 929 locale = g_strndup (locale + 1, strlen (locale) - 2); 930 931 return locale; 932 } 933 934 static void 935 g_key_file_parse_data (GKeyFile *key_file, 936 const gchar *data, 937 gsize length, 938 GError **error) 939 { 940 GError *parse_error; 941 gsize i; 942 943 g_return_if_fail (key_file != NULL); 944 g_return_if_fail (data != NULL); 945 946 parse_error = NULL; 947 948 for (i = 0; i < length; i++) 949 { 950 if (data[i] == '\n') 951 { 952 if (i > 0 && data[i - 1] == '\r') 953 g_string_erase (key_file->parse_buffer, 954 key_file->parse_buffer->len - 1, 955 1); 956 957 /* When a newline is encountered flush the parse buffer so that the 958 * line can be parsed. Note that completely blank lines won't show 959 * up in the parse buffer, so they get parsed directly. 960 */ 961 if (key_file->parse_buffer->len > 0) 962 g_key_file_flush_parse_buffer (key_file, &parse_error); 963 else 964 g_key_file_parse_comment (key_file, "", 1, &parse_error); 965 966 if (parse_error) 967 { 968 g_propagate_error (error, parse_error); 969 return; 970 } 971 } 972 else 973 g_string_append_c (key_file->parse_buffer, data[i]); 974 } 975 976 key_file->approximate_size += length; 977 } 978 979 static void 980 g_key_file_flush_parse_buffer (GKeyFile *key_file, 981 GError **error) 982 { 983 GError *file_error = NULL; 984 985 g_return_if_fail (key_file != NULL); 986 987 file_error = NULL; 988 989 if (key_file->parse_buffer->len > 0) 990 { 991 g_key_file_parse_line (key_file, key_file->parse_buffer->str, 992 key_file->parse_buffer->len, 993 &file_error); 994 g_string_erase (key_file->parse_buffer, 0, -1); 995 996 if (file_error) 997 { 998 g_propagate_error (error, file_error); 999 return; 1000 } 1001 } 1002 } 1003 1004 /** 1005 * g_key_file_to_data: 1006 * @key_file: a #GKeyFile 1007 * @length: return location for the length of the 1008 * returned string, or %NULL 1009 * @error: return location for a #GError, or %NULL 1010 * 1011 * This function outputs @key_file as a string. 1012 * 1013 * Note that this function never reports an error, 1014 * so it is safe to pass %NULL as @error. 1015 * 1016 * Return value: a newly allocated string holding 1017 * the contents of the #GKeyFile 1018 * 1019 * Since: 2.6 1020 **/ 1021 gchar * 1022 g_key_file_to_data (GKeyFile *key_file, 1023 gsize *length, 1024 GError **error) 1025 { 1026 GString *data_string; 1027 GList *group_node, *key_file_node; 1028 gboolean has_blank_line = TRUE; 1029 1030 g_return_val_if_fail (key_file != NULL, NULL); 1031 1032 data_string = g_string_sized_new (2 * key_file->approximate_size); 1033 1034 for (group_node = g_list_last (key_file->groups); 1035 group_node != NULL; 1036 group_node = group_node->prev) 1037 { 1038 GKeyFileGroup *group; 1039 1040 group = (GKeyFileGroup *) group_node->data; 1041 1042 /* separate groups by at least an empty line */ 1043 if (!has_blank_line) 1044 g_string_append_c (data_string, '\n'); 1045 has_blank_line = group->has_trailing_blank_line; 1046 1047 if (group->comment != NULL) 1048 g_string_append_printf (data_string, "%s\n", group->comment->value); 1049 1050 if (group->name != NULL) 1051 g_string_append_printf (data_string, "[%s]\n", group->name); 1052 1053 for (key_file_node = g_list_last (group->key_value_pairs); 1054 key_file_node != NULL; 1055 key_file_node = key_file_node->prev) 1056 { 1057 GKeyFileKeyValuePair *pair; 1058 1059 pair = (GKeyFileKeyValuePair *) key_file_node->data; 1060 1061 if (pair->key != NULL) 1062 g_string_append_printf (data_string, "%s=%s\n", pair->key, pair->value); 1063 else 1064 g_string_append_printf (data_string, "%s\n", pair->value); 1065 } 1066 } 1067 1068 if (length) 1069 *length = data_string->len; 1070 1071 return g_string_free (data_string, FALSE); 1072 } 1073 1074 /** 1075 * g_key_file_get_keys: 1076 * @key_file: a #GKeyFile 1077 * @group_name: a group name 1078 * @length: return location for the number of keys returned, or %NULL 1079 * @error: return location for a #GError, or %NULL 1080 * 1081 * Returns all keys for the group name @group_name. The array of 1082 * returned keys will be %NULL-terminated, so @length may 1083 * optionally be %NULL. In the event that the @group_name cannot 1084 * be found, %NULL is returned and @error is set to 1085 * #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. 1086 * 1087 * Return value: a newly-allocated %NULL-terminated array of strings. 1088 * Use g_strfreev() to free it. 1089 * 1090 * Since: 2.6 1091 **/ 1092 gchar ** 1093 g_key_file_get_keys (GKeyFile *key_file, 1094 const gchar *group_name, 1095 gsize *length, 1096 GError **error) 1097 { 1098 GKeyFileGroup *group; 1099 GList *tmp; 1100 gchar **keys; 1101 gsize i, num_keys; 1102 1103 g_return_val_if_fail (key_file != NULL, NULL); 1104 g_return_val_if_fail (group_name != NULL, NULL); 1105 1106 group = g_key_file_lookup_group (key_file, group_name); 1107 1108 if (!group) 1109 { 1110 g_set_error (error, G_KEY_FILE_ERROR, 1111 G_KEY_FILE_ERROR_GROUP_NOT_FOUND, 1112 _("Key file does not have group '%s'"), 1113 group_name ? group_name : "(null)"); 1114 return NULL; 1115 } 1116 1117 num_keys = 0; 1118 for (tmp = group->key_value_pairs; tmp; tmp = tmp->next) 1119 { 1120 GKeyFileKeyValuePair *pair; 1121 1122 pair = (GKeyFileKeyValuePair *) tmp->data; 1123 1124 if (pair->key) 1125 num_keys++; 1126 } 1127 1128 keys = g_new (gchar *, num_keys + 1); 1129 1130 i = num_keys - 1; 1131 for (tmp = group->key_value_pairs; tmp; tmp = tmp->next) 1132 { 1133 GKeyFileKeyValuePair *pair; 1134 1135 pair = (GKeyFileKeyValuePair *) tmp->data; 1136 1137 if (pair->key) 1138 { 1139 keys[i] = g_strdup (pair->key); 1140 i--; 1141 } 1142 } 1143 1144 keys[num_keys] = NULL; 1145 1146 if (length) 1147 *length = num_keys; 1148 1149 return keys; 1150 } 1151 1152 /** 1153 * g_key_file_get_start_group: 1154 * @key_file: a #GKeyFile 1155 * 1156 * Returns the name of the start group of the file. 1157 * 1158 * Return value: The start group of the key file. 1159 * 1160 * Since: 2.6 1161 **/ 1162 gchar * 1163 g_key_file_get_start_group (GKeyFile *key_file) 1164 { 1165 g_return_val_if_fail (key_file != NULL, NULL); 1166 1167 if (key_file->start_group) 1168 return g_strdup (key_file->start_group->name); 1169 1170 return NULL; 1171 } 1172 1173 /** 1174 * g_key_file_get_groups: 1175 * @key_file: a #GKeyFile 1176 * @length: return location for the number of returned groups, or %NULL 1177 * 1178 * Returns all groups in the key file loaded with @key_file. 1179 * The array of returned groups will be %NULL-terminated, so 1180 * @length may optionally be %NULL. 1181 * 1182 * Return value: a newly-allocated %NULL-terminated array of strings. 1183 * Use g_strfreev() to free it. 1184 * Since: 2.6 1185 **/ 1186 gchar ** 1187 g_key_file_get_groups (GKeyFile *key_file, 1188 gsize *length) 1189 { 1190 GList *group_node; 1191 gchar **groups; 1192 gsize i, num_groups; 1193 1194 g_return_val_if_fail (key_file != NULL, NULL); 1195 1196 num_groups = g_list_length (key_file->groups); 1197 1198 g_return_val_if_fail (num_groups > 0, NULL); 1199 1200 group_node = g_list_last (key_file->groups); 1201 1202 g_return_val_if_fail (((GKeyFileGroup *) group_node->data)->name == NULL, NULL); 1203 1204 /* Only need num_groups instead of num_groups + 1 1205 * because the first group of the file (last in the 1206 * list) is always the comment group at the top, 1207 * which we skip 1208 */ 1209 groups = g_new (gchar *, num_groups); 1210 1211 1212 i = 0; 1213 for (group_node = group_node->prev; 1214 group_node != NULL; 1215 group_node = group_node->prev) 1216 { 1217 GKeyFileGroup *group; 1218 1219 group = (GKeyFileGroup *) group_node->data; 1220 1221 g_warn_if_fail (group->name != NULL); 1222 1223 groups[i++] = g_strdup (group->name); 1224 } 1225 groups[i] = NULL; 1226 1227 if (length) 1228 *length = i; 1229 1230 return groups; 1231 } 1232 1233 /** 1234 * g_key_file_get_value: 1235 * @key_file: a #GKeyFile 1236 * @group_name: a group name 1237 * @key: a key 1238 * @error: return location for a #GError, or %NULL 1239 * 1240 * Returns the raw value associated with @key under @group_name. 1241 * Use g_key_file_get_string() to retrieve an unescaped UTF-8 string. 1242 * 1243 * In the event the key cannot be found, %NULL is returned and 1244 * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. In the 1245 * event that the @group_name cannot be found, %NULL is returned 1246 * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. 1247 * 1248 * 1249 * Return value: a newly allocated string or %NULL if the specified 1250 * key cannot be found. 1251 * 1252 * Since: 2.6 1253 **/ 1254 gchar * 1255 g_key_file_get_value (GKeyFile *key_file, 1256 const gchar *group_name, 1257 const gchar *key, 1258 GError **error) 1259 { 1260 GKeyFileGroup *group; 1261 GKeyFileKeyValuePair *pair; 1262 gchar *value = NULL; 1263 1264 g_return_val_if_fail (key_file != NULL, NULL); 1265 g_return_val_if_fail (group_name != NULL, NULL); 1266 g_return_val_if_fail (key != NULL, NULL); 1267 1268 group = g_key_file_lookup_group (key_file, group_name); 1269 1270 if (!group) 1271 { 1272 g_set_error (error, G_KEY_FILE_ERROR, 1273 G_KEY_FILE_ERROR_GROUP_NOT_FOUND, 1274 _("Key file does not have group '%s'"), 1275 group_name ? group_name : "(null)"); 1276 return NULL; 1277 } 1278 1279 pair = g_key_file_lookup_key_value_pair (key_file, group, key); 1280 1281 if (pair) 1282 value = g_strdup (pair->value); 1283 else 1284 g_set_error (error, G_KEY_FILE_ERROR, 1285 G_KEY_FILE_ERROR_KEY_NOT_FOUND, 1286 _("Key file does not have key '%s'"), key); 1287 1288 return value; 1289 } 1290 1291 /** 1292 * g_key_file_set_value: 1293 * @key_file: a #GKeyFile 1294 * @group_name: a group name 1295 * @key: a key 1296 * @value: a string 1297 * 1298 * Associates a new value with @key under @group_name. 1299 * 1300 * If @key cannot be found then it is created. If @group_name cannot 1301 * be found then it is created. To set an UTF-8 string which may contain 1302 * characters that need escaping (such as newlines or spaces), use 1303 * g_key_file_set_string(). 1304 * 1305 * Since: 2.6 1306 **/ 1307 void 1308 g_key_file_set_value (GKeyFile *key_file, 1309 const gchar *group_name, 1310 const gchar *key, 1311 const gchar *value) 1312 { 1313 GKeyFileGroup *group; 1314 GKeyFileKeyValuePair *pair; 1315 1316 g_return_if_fail (key_file != NULL); 1317 g_return_if_fail (g_key_file_is_group_name (group_name)); 1318 g_return_if_fail (g_key_file_is_key_name (key)); 1319 g_return_if_fail (value != NULL); 1320 1321 group = g_key_file_lookup_group (key_file, group_name); 1322 1323 if (!group) 1324 { 1325 g_key_file_add_group (key_file, group_name); 1326 group = (GKeyFileGroup *) key_file->groups->data; 1327 1328 g_key_file_add_key (key_file, group, key, value); 1329 } 1330 else 1331 { 1332 pair = g_key_file_lookup_key_value_pair (key_file, group, key); 1333 1334 if (!pair) 1335 g_key_file_add_key (key_file, group, key, value); 1336 else 1337 { 1338 g_free (pair->value); 1339 pair->value = g_strdup (value); 1340 } 1341 } 1342 } 1343 1344 /** 1345 * g_key_file_get_string: 1346 * @key_file: a #GKeyFile 1347 * @group_name: a group name 1348 * @key: a key 1349 * @error: return location for a #GError, or %NULL 1350 * 1351 * Returns the string value associated with @key under @group_name. 1352 * Unlike g_key_file_get_value(), this function handles escape sequences 1353 * like \s. 1354 * 1355 * In the event the key cannot be found, %NULL is returned and 1356 * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. In the 1357 * event that the @group_name cannot be found, %NULL is returned 1358 * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. 1359 * 1360 * Return value: a newly allocated string or %NULL if the specified 1361 * key cannot be found. 1362 * 1363 * Since: 2.6 1364 **/ 1365 gchar * 1366 g_key_file_get_string (GKeyFile *key_file, 1367 const gchar *group_name, 1368 const gchar *key, 1369 GError **error) 1370 { 1371 gchar *value, *string_value; 1372 GError *key_file_error; 1373 1374 g_return_val_if_fail (key_file != NULL, NULL); 1375 g_return_val_if_fail (group_name != NULL, NULL); 1376 g_return_val_if_fail (key != NULL, NULL); 1377 1378 key_file_error = NULL; 1379 1380 value = g_key_file_get_value (key_file, group_name, key, &key_file_error); 1381 1382 if (key_file_error) 1383 { 1384 g_propagate_error (error, key_file_error); 1385 return NULL; 1386 } 1387 1388 if (!g_utf8_validate (value, -1, NULL)) 1389 { 1390 gchar *value_utf8 = _g_utf8_make_valid (value); 1391 g_set_error (error, G_KEY_FILE_ERROR, 1392 G_KEY_FILE_ERROR_UNKNOWN_ENCODING, 1393 _("Key file contains key '%s' with value '%s' " 1394 "which is not UTF-8"), key, value_utf8); 1395 g_free (value_utf8); 1396 g_free (value); 1397 1398 return NULL; 1399 } 1400 1401 string_value = g_key_file_parse_value_as_string (key_file, value, NULL, 1402 &key_file_error); 1403 g_free (value); 1404 1405 if (key_file_error) 1406 { 1407 if (g_error_matches (key_file_error, 1408 G_KEY_FILE_ERROR, 1409 G_KEY_FILE_ERROR_INVALID_VALUE)) 1410 { 1411 g_set_error (error, G_KEY_FILE_ERROR, 1412 G_KEY_FILE_ERROR_INVALID_VALUE, 1413 _("Key file contains key '%s' " 1414 "which has value that cannot be interpreted."), 1415 key); 1416 g_error_free (key_file_error); 1417 } 1418 else 1419 g_propagate_error (error, key_file_error); 1420 } 1421 1422 return string_value; 1423 } 1424 1425 /** 1426 * g_key_file_set_string: 1427 * @key_file: a #GKeyFile 1428 * @group_name: a group name 1429 * @key: a key 1430 * @string: a string 1431 * 1432 * Associates a new string value with @key under @group_name. 1433 * If @key cannot be found then it is created. 1434 * If @group_name cannot be found then it is created. 1435 * Unlike g_key_file_set_value(), this function handles characters 1436 * that need escaping, such as newlines. 1437 * 1438 * Since: 2.6 1439 **/ 1440 void 1441 g_key_file_set_string (GKeyFile *key_file, 1442 const gchar *group_name, 1443 const gchar *key, 1444 const gchar *string) 1445 { 1446 gchar *value; 1447 1448 g_return_if_fail (key_file != NULL); 1449 g_return_if_fail (string != NULL); 1450 1451 value = g_key_file_parse_string_as_value (key_file, string, FALSE); 1452 g_key_file_set_value (key_file, group_name, key, value); 1453 g_free (value); 1454 } 1455 1456 /** 1457 * g_key_file_get_string_list: 1458 * @key_file: a #GKeyFile 1459 * @group_name: a group name 1460 * @key: a key 1461 * @length: return location for the number of returned strings, or %NULL 1462 * @error: return location for a #GError, or %NULL 1463 * 1464 * Returns the values associated with @key under @group_name. 1465 * 1466 * In the event the key cannot be found, %NULL is returned and 1467 * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. In the 1468 * event that the @group_name cannot be found, %NULL is returned 1469 * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. 1470 * 1471 * Return value: a %NULL-terminated string array or %NULL if the specified 1472 * key cannot be found. The array should be freed with g_strfreev(). 1473 * 1474 * Since: 2.6 1475 **/ 1476 gchar ** 1477 g_key_file_get_string_list (GKeyFile *key_file, 1478 const gchar *group_name, 1479 const gchar *key, 1480 gsize *length, 1481 GError **error) 1482 { 1483 GError *key_file_error = NULL; 1484 gchar *value, *string_value, **values; 1485 gint i, len; 1486 GSList *p, *pieces = NULL; 1487 1488 g_return_val_if_fail (key_file != NULL, NULL); 1489 g_return_val_if_fail (group_name != NULL, NULL); 1490 g_return_val_if_fail (key != NULL, NULL); 1491 1492 if (length) 1493 *length = 0; 1494 1495 value = g_key_file_get_value (key_file, group_name, key, &key_file_error); 1496 1497 if (key_file_error) 1498 { 1499 g_propagate_error (error, key_file_error); 1500 return NULL; 1501 } 1502 1503 if (!g_utf8_validate (value, -1, NULL)) 1504 { 1505 gchar *value_utf8 = _g_utf8_make_valid (value); 1506 g_set_error (error, G_KEY_FILE_ERROR, 1507 G_KEY_FILE_ERROR_UNKNOWN_ENCODING, 1508 _("Key file contains key '%s' with value '%s' " 1509 "which is not UTF-8"), key, value_utf8); 1510 g_free (value_utf8); 1511 g_free (value); 1512 1513 return NULL; 1514 } 1515 1516 string_value = g_key_file_parse_value_as_string (key_file, value, &pieces, &key_file_error); 1517 g_free (value); 1518 g_free (string_value); 1519 1520 if (key_file_error) 1521 { 1522 if (g_error_matches (key_file_error, 1523 G_KEY_FILE_ERROR, 1524 G_KEY_FILE_ERROR_INVALID_VALUE)) 1525 { 1526 g_set_error (error, G_KEY_FILE_ERROR, 1527 G_KEY_FILE_ERROR_INVALID_VALUE, 1528 _("Key file contains key '%s' " 1529 "which has value that cannot be interpreted."), 1530 key); 1531 g_error_free (key_file_error); 1532 } 1533 else 1534 g_propagate_error (error, key_file_error); 1535 1536 return NULL; 1537 } 1538 1539 len = g_slist_length (pieces); 1540 values = g_new (gchar *, len + 1); 1541 for (p = pieces, i = 0; p; p = p->next) 1542 values[i++] = p->data; 1543 values[len] = NULL; 1544 1545 g_slist_free (pieces); 1546 1547 if (length) 1548 *length = len; 1549 1550 return values; 1551 } 1552 1553 /** 1554 * g_key_file_set_string_list: 1555 * @key_file: a #GKeyFile 1556 * @group_name: a group name 1557 * @key: a key 1558 * @list: an array of string values 1559 * @length: number of string values in @list 1560 * 1561 * Associates a list of string values for @key under @group_name. 1562 * If @key cannot be found then it is created. 1563 * If @group_name cannot be found then it is created. 1564 * 1565 * Since: 2.6 1566 **/ 1567 void 1568 g_key_file_set_string_list (GKeyFile *key_file, 1569 const gchar *group_name, 1570 const gchar *key, 1571 const gchar * const list[], 1572 gsize length) 1573 { 1574 GString *value_list; 1575 gsize i; 1576 1577 g_return_if_fail (key_file != NULL); 1578 g_return_if_fail (list != NULL); 1579 1580 value_list = g_string_sized_new (length * 128); 1581 for (i = 0; i < length && list[i] != NULL; i++) 1582 { 1583 gchar *value; 1584 1585 value = g_key_file_parse_string_as_value (key_file, list[i], TRUE); 1586 g_string_append (value_list, value); 1587 g_string_append_c (value_list, key_file->list_separator); 1588 1589 g_free (value); 1590 } 1591 1592 g_key_file_set_value (key_file, group_name, key, value_list->str); 1593 g_string_free (value_list, TRUE); 1594 } 1595 1596 /** 1597 * g_key_file_set_locale_string: 1598 * @key_file: a #GKeyFile 1599 * @group_name: a group name 1600 * @key: a key 1601 * @locale: a locale identifier 1602 * @string: a string 1603 * 1604 * Associates a string value for @key and @locale under @group_name. 1605 * If the translation for @key cannot be found then it is created. 1606 * 1607 * Since: 2.6 1608 **/ 1609 void 1610 g_key_file_set_locale_string (GKeyFile *key_file, 1611 const gchar *group_name, 1612 const gchar *key, 1613 const gchar *locale, 1614 const gchar *string) 1615 { 1616 gchar *full_key, *value; 1617 1618 g_return_if_fail (key_file != NULL); 1619 g_return_if_fail (key != NULL); 1620 g_return_if_fail (locale != NULL); 1621 g_return_if_fail (string != NULL); 1622 1623 value = g_key_file_parse_string_as_value (key_file, string, FALSE); 1624 full_key = g_strdup_printf ("%s[%s]", key, locale); 1625 g_key_file_set_value (key_file, group_name, full_key, value); 1626 g_free (full_key); 1627 g_free (value); 1628 } 1629 1630 extern GSList *_g_compute_locale_variants (const gchar *locale); 1631 1632 /** 1633 * g_key_file_get_locale_string: 1634 * @key_file: a #GKeyFile 1635 * @group_name: a group name 1636 * @key: a key 1637 * @locale: a locale identifier or %NULL 1638 * @error: return location for a #GError, or %NULL 1639 * 1640 * Returns the value associated with @key under @group_name 1641 * translated in the given @locale if available. If @locale is 1642 * %NULL then the current locale is assumed. 1643 * 1644 * If @key cannot be found then %NULL is returned and @error is set 1645 * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the value associated 1646 * with @key cannot be interpreted or no suitable translation can 1647 * be found then the untranslated value is returned. 1648 * 1649 * Return value: a newly allocated string or %NULL if the specified 1650 * key cannot be found. 1651 * 1652 * Since: 2.6 1653 **/ 1654 gchar * 1655 g_key_file_get_locale_string (GKeyFile *key_file, 1656 const gchar *group_name, 1657 const gchar *key, 1658 const gchar *locale, 1659 GError **error) 1660 { 1661 gchar *candidate_key, *translated_value; 1662 GError *key_file_error; 1663 gchar **languages; 1664 gboolean free_languages = FALSE; 1665 gint i; 1666 1667 g_return_val_if_fail (key_file != NULL, NULL); 1668 g_return_val_if_fail (group_name != NULL, NULL); 1669 g_return_val_if_fail (key != NULL, NULL); 1670 1671 candidate_key = NULL; 1672 translated_value = NULL; 1673 key_file_error = NULL; 1674 1675 if (locale) 1676 { 1677 GSList *l, *list; 1678 1679 list = _g_compute_locale_variants (locale); 1680 1681 languages = g_new (gchar *, g_slist_length (list) + 1); 1682 for (l = list, i = 0; l; l = l->next, i++) 1683 languages[i] = l->data; 1684 languages[i] = NULL; 1685 1686 g_slist_free (list); 1687 free_languages = TRUE; 1688 } 1689 else 1690 { 1691 languages = (gchar **) g_get_language_names (); 1692 free_languages = FALSE; 1693 } 1694 1695 for (i = 0; languages[i]; i++) 1696 { 1697 candidate_key = g_strdup_printf ("%s[%s]", key, languages[i]); 1698 1699 translated_value = g_key_file_get_string (key_file, 1700 group_name, 1701 candidate_key, NULL); 1702 g_free (candidate_key); 1703 1704 if (translated_value) 1705 break; 1706 1707 g_free (translated_value); 1708 translated_value = NULL; 1709 } 1710 1711 /* Fallback to untranslated key 1712 */ 1713 if (!translated_value) 1714 { 1715 translated_value = g_key_file_get_string (key_file, group_name, key, 1716 &key_file_error); 1717 1718 if (!translated_value) 1719 g_propagate_error (error, key_file_error); 1720 } 1721 1722 if (free_languages) 1723 g_strfreev (languages); 1724 1725 return translated_value; 1726 } 1727 1728 /** 1729 * g_key_file_get_locale_string_list: 1730 * @key_file: a #GKeyFile 1731 * @group_name: a group name 1732 * @key: a key 1733 * @locale: a locale identifier or %NULL 1734 * @length: return location for the number of returned strings or %NULL 1735 * @error: return location for a #GError or %NULL 1736 * 1737 * Returns the values associated with @key under @group_name 1738 * translated in the given @locale if available. If @locale is 1739 * %NULL then the current locale is assumed. 1740 1741 * If @key cannot be found then %NULL is returned and @error is set 1742 * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the values associated 1743 * with @key cannot be interpreted or no suitable translations 1744 * can be found then the untranslated values are returned. The 1745 * returned array is %NULL-terminated, so @length may optionally 1746 * be %NULL. 1747 * 1748 * Return value: a newly allocated %NULL-terminated string array 1749 * or %NULL if the key isn't found. The string array should be freed 1750 * with g_strfreev(). 1751 * 1752 * Since: 2.6 1753 **/ 1754 gchar ** 1755 g_key_file_get_locale_string_list (GKeyFile *key_file, 1756 const gchar *group_name, 1757 const gchar *key, 1758 const gchar *locale, 1759 gsize *length, 1760 GError **error) 1761 { 1762 GError *key_file_error; 1763 gchar **values, *value; 1764 char list_separator[2]; 1765 gsize len; 1766 1767 g_return_val_if_fail (key_file != NULL, NULL); 1768 g_return_val_if_fail (group_name != NULL, NULL); 1769 g_return_val_if_fail (key != NULL, NULL); 1770 1771 key_file_error = NULL; 1772 1773 value = g_key_file_get_locale_string (key_file, group_name, 1774 key, locale, 1775 &key_file_error); 1776 1777 if (key_file_error) 1778 g_propagate_error (error, key_file_error); 1779 1780 if (!value) 1781 { 1782 if (length) 1783 *length = 0; 1784 return NULL; 1785 } 1786 1787 len = strlen (value); 1788 if (value[len - 1] == key_file->list_separator) 1789 value[len - 1] = '\0'; 1790 1791 list_separator[0] = key_file->list_separator; 1792 list_separator[1] = '\0'; 1793 values = g_strsplit (value, list_separator, 0); 1794 1795 g_free (value); 1796 1797 if (length) 1798 *length = g_strv_length (values); 1799 1800 return values; 1801 } 1802 1803 /** 1804 * g_key_file_set_locale_string_list: 1805 * @key_file: a #GKeyFile 1806 * @group_name: a group name 1807 * @key: a key 1808 * @locale: a locale identifier 1809 * @list: a %NULL-terminated array of locale string values 1810 * @length: the length of @list 1811 * 1812 * Associates a list of string values for @key and @locale under 1813 * @group_name. If the translation for @key cannot be found then 1814 * it is created. 1815 * 1816 * Since: 2.6 1817 **/ 1818 void 1819 g_key_file_set_locale_string_list (GKeyFile *key_file, 1820 const gchar *group_name, 1821 const gchar *key, 1822 const gchar *locale, 1823 const gchar * const list[], 1824 gsize length) 1825 { 1826 GString *value_list; 1827 gchar *full_key; 1828 gsize i; 1829 1830 g_return_if_fail (key_file != NULL); 1831 g_return_if_fail (key != NULL); 1832 g_return_if_fail (locale != NULL); 1833 g_return_if_fail (length != 0); 1834 1835 value_list = g_string_sized_new (length * 128); 1836 for (i = 0; i < length && list[i] != NULL; i++) 1837 { 1838 gchar *value; 1839 1840 value = g_key_file_parse_string_as_value (key_file, list[i], TRUE); 1841 g_string_append (value_list, value); 1842 g_string_append_c (value_list, key_file->list_separator); 1843 1844 g_free (value); 1845 } 1846 1847 full_key = g_strdup_printf ("%s[%s]", key, locale); 1848 g_key_file_set_value (key_file, group_name, full_key, value_list->str); 1849 g_free (full_key); 1850 g_string_free (value_list, TRUE); 1851 } 1852 1853 /** 1854 * g_key_file_get_boolean: 1855 * @key_file: a #GKeyFile 1856 * @group_name: a group name 1857 * @key: a key 1858 * @error: return location for a #GError 1859 * 1860 * Returns the value associated with @key under @group_name as a 1861 * boolean. 1862 * 1863 * If @key cannot be found then %FALSE is returned and @error is set 1864 * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value 1865 * associated with @key cannot be interpreted as a boolean then %FALSE 1866 * is returned and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. 1867 * 1868 * Return value: the value associated with the key as a boolean, 1869 * or %FALSE if the key was not found or could not be parsed. 1870 * 1871 * Since: 2.6 1872 **/ 1873 gboolean 1874 g_key_file_get_boolean (GKeyFile *key_file, 1875 const gchar *group_name, 1876 const gchar *key, 1877 GError **error) 1878 { 1879 GError *key_file_error = NULL; 1880 gchar *value; 1881 gboolean bool_value; 1882 1883 g_return_val_if_fail (key_file != NULL, FALSE); 1884 g_return_val_if_fail (group_name != NULL, FALSE); 1885 g_return_val_if_fail (key != NULL, FALSE); 1886 1887 value = g_key_file_get_value (key_file, group_name, key, &key_file_error); 1888 1889 if (!value) 1890 { 1891 g_propagate_error (error, key_file_error); 1892 return FALSE; 1893 } 1894 1895 bool_value = g_key_file_parse_value_as_boolean (key_file, value, 1896 &key_file_error); 1897 g_free (value); 1898 1899 if (key_file_error) 1900 { 1901 if (g_error_matches (key_file_error, 1902 G_KEY_FILE_ERROR, 1903 G_KEY_FILE_ERROR_INVALID_VALUE)) 1904 { 1905 g_set_error (error, G_KEY_FILE_ERROR, 1906 G_KEY_FILE_ERROR_INVALID_VALUE, 1907 _("Key file contains key '%s' " 1908 "which has value that cannot be interpreted."), 1909 key); 1910 g_error_free (key_file_error); 1911 } 1912 else 1913 g_propagate_error (error, key_file_error); 1914 } 1915 1916 return bool_value; 1917 } 1918 1919 /** 1920 * g_key_file_set_boolean: 1921 * @key_file: a #GKeyFile 1922 * @group_name: a group name 1923 * @key: a key 1924 * @value: %TRUE or %FALSE 1925 * 1926 * Associates a new boolean value with @key under @group_name. 1927 * If @key cannot be found then it is created. 1928 * 1929 * Since: 2.6 1930 **/ 1931 void 1932 g_key_file_set_boolean (GKeyFile *key_file, 1933 const gchar *group_name, 1934 const gchar *key, 1935 gboolean value) 1936 { 1937 gchar *result; 1938 1939 g_return_if_fail (key_file != NULL); 1940 1941 result = g_key_file_parse_boolean_as_value (key_file, value); 1942 g_key_file_set_value (key_file, group_name, key, result); 1943 g_free (result); 1944 } 1945 1946 /** 1947 * g_key_file_get_boolean_list: 1948 * @key_file: a #GKeyFile 1949 * @group_name: a group name 1950 * @key: a key 1951 * @length: the number of booleans returned 1952 * @error: return location for a #GError 1953 * 1954 * Returns the values associated with @key under @group_name as 1955 * booleans. 1956 * 1957 * If @key cannot be found then %NULL is returned and @error is set to 1958 * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated 1959 * with @key cannot be interpreted as booleans then %NULL is returned 1960 * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. 1961 * 1962 * Return value: the values associated with the key as a list of 1963 * booleans, or %NULL if the key was not found or could not be parsed. 1964 * 1965 * Since: 2.6 1966 **/ 1967 gboolean * 1968 g_key_file_get_boolean_list (GKeyFile *key_file, 1969 const gchar *group_name, 1970 const gchar *key, 1971 gsize *length, 1972 GError **error) 1973 { 1974 GError *key_file_error; 1975 gchar **values; 1976 gboolean *bool_values; 1977 gsize i, num_bools; 1978 1979 g_return_val_if_fail (key_file != NULL, NULL); 1980 g_return_val_if_fail (group_name != NULL, NULL); 1981 g_return_val_if_fail (key != NULL, NULL); 1982 1983 if (length) 1984 *length = 0; 1985 1986 key_file_error = NULL; 1987 1988 values = g_key_file_get_string_list (key_file, group_name, key, 1989 &num_bools, &key_file_error); 1990 1991 if (key_file_error) 1992 g_propagate_error (error, key_file_error); 1993 1994 if (!values) 1995 return NULL; 1996 1997 bool_values = g_new (gboolean, num_bools); 1998 1999 for (i = 0; i < num_bools; i++) 2000 { 2001 bool_values[i] = g_key_file_parse_value_as_boolean (key_file, 2002 values[i], 2003 &key_file_error); 2004 2005 if (key_file_error) 2006 { 2007 g_propagate_error (error, key_file_error); 2008 g_strfreev (values); 2009 g_free (bool_values); 2010 2011 return NULL; 2012 } 2013 } 2014 g_strfreev (values); 2015 2016 if (length) 2017 *length = num_bools; 2018 2019 return bool_values; 2020 } 2021 2022 /** 2023 * g_key_file_set_boolean_list: 2024 * @key_file: a #GKeyFile 2025 * @group_name: a group name 2026 * @key: a key 2027 * @list: an array of boolean values 2028 * @length: length of @list 2029 * 2030 * Associates a list of boolean values with @key under @group_name. 2031 * If @key cannot be found then it is created. 2032 * If @group_name is %NULL, the start_group is used. 2033 * 2034 * Since: 2.6 2035 **/ 2036 void 2037 g_key_file_set_boolean_list (GKeyFile *key_file, 2038 const gchar *group_name, 2039 const gchar *key, 2040 gboolean list[], 2041 gsize length) 2042 { 2043 GString *value_list; 2044 gsize i; 2045 2046 g_return_if_fail (key_file != NULL); 2047 g_return_if_fail (list != NULL); 2048 2049 value_list = g_string_sized_new (length * 8); 2050 for (i = 0; i < length; i++) 2051 { 2052 gchar *value; 2053 2054 value = g_key_file_parse_boolean_as_value (key_file, list[i]); 2055 2056 g_string_append (value_list, value); 2057 g_string_append_c (value_list, key_file->list_separator); 2058 2059 g_free (value); 2060 } 2061 2062 g_key_file_set_value (key_file, group_name, key, value_list->str); 2063 g_string_free (value_list, TRUE); 2064 } 2065 2066 /** 2067 * g_key_file_get_integer: 2068 * @key_file: a #GKeyFile 2069 * @group_name: a group name 2070 * @key: a key 2071 * @error: return location for a #GError 2072 * 2073 * Returns the value associated with @key under @group_name as an 2074 * integer. 2075 * 2076 * If @key cannot be found then 0 is returned and @error is set to 2077 * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value associated 2078 * with @key cannot be interpreted as an integer then 0 is returned 2079 * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. 2080 * 2081 * Return value: the value associated with the key as an integer, or 2082 * 0 if the key was not found or could not be parsed. 2083 * 2084 * Since: 2.6 2085 **/ 2086 gint 2087 g_key_file_get_integer (GKeyFile *key_file, 2088 const gchar *group_name, 2089 const gchar *key, 2090 GError **error) 2091 { 2092 GError *key_file_error; 2093 gchar *value; 2094 gint int_value; 2095 2096 g_return_val_if_fail (key_file != NULL, -1); 2097 g_return_val_if_fail (group_name != NULL, -1); 2098 g_return_val_if_fail (key != NULL, -1); 2099 2100 key_file_error = NULL; 2101 2102 value = g_key_file_get_value (key_file, group_name, key, &key_file_error); 2103 2104 if (key_file_error) 2105 { 2106 g_propagate_error (error, key_file_error); 2107 return 0; 2108 } 2109 2110 int_value = g_key_file_parse_value_as_integer (key_file, value, 2111 &key_file_error); 2112 g_free (value); 2113 2114 if (key_file_error) 2115 { 2116 if (g_error_matches (key_file_error, 2117 G_KEY_FILE_ERROR, 2118 G_KEY_FILE_ERROR_INVALID_VALUE)) 2119 { 2120 g_set_error (error, G_KEY_FILE_ERROR, 2121 G_KEY_FILE_ERROR_INVALID_VALUE, 2122 _("Key file contains key '%s' in group '%s' " 2123 "which has value that cannot be interpreted."), key, 2124 group_name); 2125 g_error_free (key_file_error); 2126 } 2127 else 2128 g_propagate_error (error, key_file_error); 2129 } 2130 2131 return int_value; 2132 } 2133 2134 /** 2135 * g_key_file_set_integer: 2136 * @key_file: a #GKeyFile 2137 * @group_name: a group name 2138 * @key: a key 2139 * @value: an integer value 2140 * 2141 * Associates a new integer value with @key under @group_name. 2142 * If @key cannot be found then it is created. 2143 * 2144 * Since: 2.6 2145 **/ 2146 void 2147 g_key_file_set_integer (GKeyFile *key_file, 2148 const gchar *group_name, 2149 const gchar *key, 2150 gint value) 2151 { 2152 gchar *result; 2153 2154 g_return_if_fail (key_file != NULL); 2155 2156 result = g_key_file_parse_integer_as_value (key_file, value); 2157 g_key_file_set_value (key_file, group_name, key, result); 2158 g_free (result); 2159 } 2160 2161 /** 2162 * g_key_file_get_integer_list: 2163 * @key_file: a #GKeyFile 2164 * @group_name: a group name 2165 * @key: a key 2166 * @length: the number of integers returned 2167 * @error: return location for a #GError 2168 * 2169 * Returns the values associated with @key under @group_name as 2170 * integers. 2171 * 2172 * If @key cannot be found then %NULL is returned and @error is set to 2173 * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated 2174 * with @key cannot be interpreted as integers then %NULL is returned 2175 * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. 2176 * 2177 * Return value: the values associated with the key as a list of 2178 * integers, or %NULL if the key was not found or could not be parsed. 2179 * 2180 * Since: 2.6 2181 **/ 2182 gint * 2183 g_key_file_get_integer_list (GKeyFile *key_file, 2184 const gchar *group_name, 2185 const gchar *key, 2186 gsize *length, 2187 GError **error) 2188 { 2189 GError *key_file_error = NULL; 2190 gchar **values; 2191 gint *int_values; 2192 gsize i, num_ints; 2193 2194 g_return_val_if_fail (key_file != NULL, NULL); 2195 g_return_val_if_fail (group_name != NULL, NULL); 2196 g_return_val_if_fail (key != NULL, NULL); 2197 2198 if (length) 2199 *length = 0; 2200 2201 values = g_key_file_get_string_list (key_file, group_name, key, 2202 &num_ints, &key_file_error); 2203 2204 if (key_file_error) 2205 g_propagate_error (error, key_file_error); 2206 2207 if (!values) 2208 return NULL; 2209 2210 int_values = g_new (gint, num_ints); 2211 2212 for (i = 0; i < num_ints; i++) 2213 { 2214 int_values[i] = g_key_file_parse_value_as_integer (key_file, 2215 values[i], 2216 &key_file_error); 2217 2218 if (key_file_error) 2219 { 2220 g_propagate_error (error, key_file_error); 2221 g_strfreev (values); 2222 g_free (int_values); 2223 2224 return NULL; 2225 } 2226 } 2227 g_strfreev (values); 2228 2229 if (length) 2230 *length = num_ints; 2231 2232 return int_values; 2233 } 2234 2235 /** 2236 * g_key_file_set_integer_list: 2237 * @key_file: a #GKeyFile 2238 * @group_name: a group name 2239 * @key: a key 2240 * @list: an array of integer values 2241 * @length: number of integer values in @list 2242 * 2243 * Associates a list of integer values with @key under @group_name. 2244 * If @key cannot be found then it is created. 2245 * 2246 * Since: 2.6 2247 **/ 2248 void 2249 g_key_file_set_integer_list (GKeyFile *key_file, 2250 const gchar *group_name, 2251 const gchar *key, 2252 gint list[], 2253 gsize length) 2254 { 2255 GString *values; 2256 gsize i; 2257 2258 g_return_if_fail (key_file != NULL); 2259 g_return_if_fail (list != NULL); 2260 2261 values = g_string_sized_new (length * 16); 2262 for (i = 0; i < length; i++) 2263 { 2264 gchar *value; 2265 2266 value = g_key_file_parse_integer_as_value (key_file, list[i]); 2267 2268 g_string_append (values, value); 2269 g_string_append_c (values, key_file->list_separator); 2270 2271 g_free (value); 2272 } 2273 2274 g_key_file_set_value (key_file, group_name, key, values->str); 2275 g_string_free (values, TRUE); 2276 } 2277 2278 /** 2279 * g_key_file_get_double: 2280 * @key_file: a #GKeyFile 2281 * @group_name: a group name 2282 * @key: a key 2283 * @error: return location for a #GError 2284 * 2285 * Returns the value associated with @key under @group_name as a 2286 * double. If @group_name is %NULL, the start_group is used. 2287 * 2288 * If @key cannot be found then 0.0 is returned and @error is set to 2289 * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value associated 2290 * with @key cannot be interpreted as a double then 0.0 is returned 2291 * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. 2292 * 2293 * Return value: the value associated with the key as a double, or 2294 * 0.0 if the key was not found or could not be parsed. 2295 * 2296 * Since: 2.12 2297 **/ 2298 gdouble 2299 g_key_file_get_double (GKeyFile *key_file, 2300 const gchar *group_name, 2301 const gchar *key, 2302 GError **error) 2303 { 2304 GError *key_file_error; 2305 gchar *value; 2306 gdouble double_value; 2307 2308 g_return_val_if_fail (key_file != NULL, -1); 2309 g_return_val_if_fail (group_name != NULL, -1); 2310 g_return_val_if_fail (key != NULL, -1); 2311 2312 key_file_error = NULL; 2313 2314 value = g_key_file_get_value (key_file, group_name, key, &key_file_error); 2315 2316 if (key_file_error) 2317 { 2318 g_propagate_error (error, key_file_error); 2319 return 0; 2320 } 2321 2322 double_value = g_key_file_parse_value_as_double (key_file, value, 2323 &key_file_error); 2324 g_free (value); 2325 2326 if (key_file_error) 2327 { 2328 if (g_error_matches (key_file_error, 2329 G_KEY_FILE_ERROR, 2330 G_KEY_FILE_ERROR_INVALID_VALUE)) 2331 { 2332 g_set_error (error, G_KEY_FILE_ERROR, 2333 G_KEY_FILE_ERROR_INVALID_VALUE, 2334 _("Key file contains key '%s' in group '%s' " 2335 "which has value that cannot be interpreted."), key, 2336 group_name); 2337 g_error_free (key_file_error); 2338 } 2339 else 2340 g_propagate_error (error, key_file_error); 2341 } 2342 2343 return double_value; 2344 } 2345 2346 /** 2347 * g_key_file_set_double: 2348 * @key_file: a #GKeyFile 2349 * @group_name: a group name 2350 * @key: a key 2351 * @value: an double value 2352 * 2353 * Associates a new double value with @key under @group_name. 2354 * If @key cannot be found then it is created. 2355 * 2356 * Since: 2.12 2357 **/ 2358 void 2359 g_key_file_set_double (GKeyFile *key_file, 2360 const gchar *group_name, 2361 const gchar *key, 2362 gdouble value) 2363 { 2364 gchar result[G_ASCII_DTOSTR_BUF_SIZE]; 2365 2366 g_return_if_fail (key_file != NULL); 2367 2368 g_ascii_dtostr (result, sizeof (result), value); 2369 g_key_file_set_value (key_file, group_name, key, result); 2370 } 2371 2372 /** 2373 * g_key_file_get_double_list: 2374 * @key_file: a #GKeyFile 2375 * @group_name: a group name 2376 * @key: a key 2377 * @length: the number of doubles returned 2378 * @error: return location for a #GError 2379 * 2380 * Returns the values associated with @key under @group_name as 2381 * doubles. 2382 * 2383 * If @key cannot be found then %NULL is returned and @error is set to 2384 * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated 2385 * with @key cannot be interpreted as doubles then %NULL is returned 2386 * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. 2387 * 2388 * Return value: the values associated with the key as a list of 2389 * doubles, or %NULL if the key was not found or could not be parsed. 2390 * 2391 * Since: 2.12 2392 **/ 2393 gdouble * 2394 g_key_file_get_double_list (GKeyFile *key_file, 2395 const gchar *group_name, 2396 const gchar *key, 2397 gsize *length, 2398 GError **error) 2399 { 2400 GError *key_file_error = NULL; 2401 gchar **values; 2402 gdouble *double_values; 2403 gsize i, num_doubles; 2404 2405 g_return_val_if_fail (key_file != NULL, NULL); 2406 g_return_val_if_fail (group_name != NULL, NULL); 2407 g_return_val_if_fail (key != NULL, NULL); 2408 2409 if (length) 2410 *length = 0; 2411 2412 values = g_key_file_get_string_list (key_file, group_name, key, 2413 &num_doubles, &key_file_error); 2414 2415 if (key_file_error) 2416 g_propagate_error (error, key_file_error); 2417 2418 if (!values) 2419 return NULL; 2420 2421 double_values = g_new (gdouble, num_doubles); 2422 2423 for (i = 0; i < num_doubles; i++) 2424 { 2425 double_values[i] = g_key_file_parse_value_as_double (key_file, 2426 values[i], 2427 &key_file_error); 2428 2429 if (key_file_error) 2430 { 2431 g_propagate_error (error, key_file_error); 2432 g_strfreev (values); 2433 g_free (double_values); 2434 2435 return NULL; 2436 } 2437 } 2438 g_strfreev (values); 2439 2440 if (length) 2441 *length = num_doubles; 2442 2443 return double_values; 2444 } 2445 2446 /** 2447 * g_key_file_set_double_list: 2448 * @key_file: a #GKeyFile 2449 * @group_name: a group name 2450 * @key: a key 2451 * @list: an array of double values 2452 * @length: number of double values in @list 2453 * 2454 * Associates a list of double values with @key under 2455 * @group_name. If @key cannot be found then it is created. 2456 * 2457 * Since: 2.12 2458 **/ 2459 void 2460 g_key_file_set_double_list (GKeyFile *key_file, 2461 const gchar *group_name, 2462 const gchar *key, 2463 gdouble list[], 2464 gsize length) 2465 { 2466 GString *values; 2467 gsize i; 2468 2469 g_return_if_fail (key_file != NULL); 2470 g_return_if_fail (list != NULL); 2471 2472 values = g_string_sized_new (length * 16); 2473 for (i = 0; i < length; i++) 2474 { 2475 gchar result[G_ASCII_DTOSTR_BUF_SIZE]; 2476 2477 g_ascii_dtostr( result, sizeof (result), list[i] ); 2478 2479 g_string_append (values, result); 2480 g_string_append_c (values, key_file->list_separator); 2481 } 2482 2483 g_key_file_set_value (key_file, group_name, key, values->str); 2484 g_string_free (values, TRUE); 2485 } 2486 2487 static gboolean 2488 g_key_file_set_key_comment (GKeyFile *key_file, 2489 const gchar *group_name, 2490 const gchar *key, 2491 const gchar *comment, 2492 GError **error) 2493 { 2494 GKeyFileGroup *group; 2495 GKeyFileKeyValuePair *pair; 2496 GList *key_node, *comment_node, *tmp; 2497 2498 group = g_key_file_lookup_group (key_file, group_name); 2499 if (!group) 2500 { 2501 g_set_error (error, G_KEY_FILE_ERROR, 2502 G_KEY_FILE_ERROR_GROUP_NOT_FOUND, 2503 _("Key file does not have group '%s'"), 2504 group_name ? group_name : "(null)"); 2505 2506 return FALSE; 2507 } 2508 2509 /* First find the key the comments are supposed to be 2510 * associated with 2511 */ 2512 key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key); 2513 2514 if (key_node == NULL) 2515 { 2516 g_set_error (error, G_KEY_FILE_ERROR, 2517 G_KEY_FILE_ERROR_KEY_NOT_FOUND, 2518 _("Key file does not have key '%s' in group '%s'"), 2519 key, group->name); 2520 return FALSE; 2521 } 2522 2523 /* Then find all the comments already associated with the 2524 * key and free them 2525 */ 2526 tmp = key_node->next; 2527 while (tmp != NULL) 2528 { 2529 pair = (GKeyFileKeyValuePair *) tmp->data; 2530 2531 if (pair->key != NULL) 2532 break; 2533 2534 comment_node = tmp; 2535 tmp = tmp->next; 2536 g_key_file_remove_key_value_pair_node (key_file, group, 2537 comment_node); 2538 } 2539 2540 if (comment == NULL) 2541 return TRUE; 2542 2543 /* Now we can add our new comment 2544 */ 2545 pair = g_slice_new (GKeyFileKeyValuePair); 2546 pair->key = NULL; 2547 pair->value = g_key_file_parse_comment_as_value (key_file, comment); 2548 2549 key_node = g_list_insert (key_node, pair, 1); 2550 2551 return TRUE; 2552 } 2553 2554 static gboolean 2555 g_key_file_set_group_comment (GKeyFile *key_file, 2556 const gchar *group_name, 2557 const gchar *comment, 2558 GError **error) 2559 { 2560 GKeyFileGroup *group; 2561 2562 g_return_val_if_fail (g_key_file_is_group_name (group_name), FALSE); 2563 2564 group = g_key_file_lookup_group (key_file, group_name); 2565 if (!group) 2566 { 2567 g_set_error (error, G_KEY_FILE_ERROR, 2568 G_KEY_FILE_ERROR_GROUP_NOT_FOUND, 2569 _("Key file does not have group '%s'"), 2570 group_name ? group_name : "(null)"); 2571 2572 return FALSE; 2573 } 2574 2575 /* First remove any existing comment 2576 */ 2577 if (group->comment) 2578 { 2579 g_key_file_key_value_pair_free (group->comment); 2580 group->comment = NULL; 2581 } 2582 2583 if (comment == NULL) 2584 return TRUE; 2585 2586 /* Now we can add our new comment 2587 */ 2588 group->comment = g_slice_new (GKeyFileKeyValuePair); 2589 group->comment->key = NULL; 2590 group->comment->value = g_key_file_parse_comment_as_value (key_file, comment); 2591 2592 return TRUE; 2593 } 2594 2595 static gboolean 2596 g_key_file_set_top_comment (GKeyFile *key_file, 2597 const gchar *comment, 2598 GError **error) 2599 { 2600 GList *group_node; 2601 GKeyFileGroup *group; 2602 GKeyFileKeyValuePair *pair; 2603 2604 /* The last group in the list should be the top (comments only) 2605 * group in the file 2606 */ 2607 g_warn_if_fail (key_file->groups != NULL); 2608 group_node = g_list_last (key_file->groups); 2609 group = (GKeyFileGroup *) group_node->data; 2610 g_warn_if_fail (group->name == NULL); 2611 2612 /* Note all keys must be comments at the top of 2613 * the file, so we can just free it all. 2614 */ 2615 if (group->key_value_pairs != NULL) 2616 { 2617 g_list_foreach (group->key_value_pairs, 2618 (GFunc) g_key_file_key_value_pair_free, 2619 NULL); 2620 g_list_free (group->key_value_pairs); 2621 group->key_value_pairs = NULL; 2622 } 2623 2624 if (comment == NULL) 2625 return TRUE; 2626 2627 pair = g_slice_new (GKeyFileKeyValuePair); 2628 pair->key = NULL; 2629 pair->value = g_key_file_parse_comment_as_value (key_file, comment); 2630 2631 group->key_value_pairs = 2632 g_list_prepend (group->key_value_pairs, pair); 2633 2634 return TRUE; 2635 } 2636 2637 /** 2638 * g_key_file_set_comment: 2639 * @key_file: a #GKeyFile 2640 * @group_name: a group name, or %NULL 2641 * @key: a key 2642 * @comment: a comment 2643 * @error: return location for a #GError 2644 * 2645 * Places a comment above @key from @group_name. 2646 * If @key is %NULL then @comment will be written above @group_name. 2647 * If both @key and @group_name are %NULL, then @comment will be 2648 * written above the first group in the file. 2649 * 2650 * Returns: %TRUE if the comment was written, %FALSE otherwise 2651 * 2652 * Since: 2.6 2653 **/ 2654 gboolean 2655 g_key_file_set_comment (GKeyFile *key_file, 2656 const gchar *group_name, 2657 const gchar *key, 2658 const gchar *comment, 2659 GError **error) 2660 { 2661 g_return_val_if_fail (key_file != NULL, FALSE); 2662 2663 if (group_name != NULL && key != NULL) 2664 { 2665 if (!g_key_file_set_key_comment (key_file, group_name, key, comment, error)) 2666 return FALSE; 2667 } 2668 else if (group_name != NULL) 2669 { 2670 if (!g_key_file_set_group_comment (key_file, group_name, comment, error)) 2671 return FALSE; 2672 } 2673 else 2674 { 2675 if (!g_key_file_set_top_comment (key_file, comment, error)) 2676 return FALSE; 2677 } 2678 2679 if (comment != NULL) 2680 key_file->approximate_size += strlen (comment); 2681 2682 return TRUE; 2683 } 2684 2685 static gchar * 2686 g_key_file_get_key_comment (GKeyFile *key_file, 2687 const gchar *group_name, 2688 const gchar *key, 2689 GError **error) 2690 { 2691 GKeyFileGroup *group; 2692 GKeyFileKeyValuePair *pair; 2693 GList *key_node, *tmp; 2694 GString *string; 2695 gchar *comment; 2696 2697 g_return_val_if_fail (g_key_file_is_group_name (group_name), NULL); 2698 2699 group = g_key_file_lookup_group (key_file, group_name); 2700 if (!group) 2701 { 2702 g_set_error (error, G_KEY_FILE_ERROR, 2703 G_KEY_FILE_ERROR_GROUP_NOT_FOUND, 2704 _("Key file does not have group '%s'"), 2705 group_name ? group_name : "(null)"); 2706 2707 return NULL; 2708 } 2709 2710 /* First find the key the comments are supposed to be 2711 * associated with 2712 */ 2713 key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key); 2714 2715 if (key_node == NULL) 2716 { 2717 g_set_error (error, G_KEY_FILE_ERROR, 2718 G_KEY_FILE_ERROR_KEY_NOT_FOUND, 2719 _("Key file does not have key '%s' in group '%s'"), 2720 key, group->name); 2721 return NULL; 2722 } 2723 2724 string = NULL; 2725 2726 /* Then find all the comments already associated with the 2727 * key and concatentate them. 2728 */ 2729 tmp = key_node->next; 2730 if (!key_node->next) 2731 return NULL; 2732 2733 pair = (GKeyFileKeyValuePair *) tmp->data; 2734 if (pair->key != NULL) 2735 return NULL; 2736 2737 while (tmp->next) 2738 { 2739 pair = (GKeyFileKeyValuePair *) tmp->next->data; 2740 2741 if (pair->key != NULL) 2742 break; 2743 2744 tmp = tmp->next; 2745 } 2746 2747 while (tmp != key_node) 2748 { 2749 pair = (GKeyFileKeyValuePair *) tmp->data; 2750 2751 if (string == NULL) 2752 string = g_string_sized_new (512); 2753 2754 comment = g_key_file_parse_value_as_comment (key_file, pair->value); 2755 g_string_append (string, comment); 2756 g_free (comment); 2757 2758 tmp = tmp->prev; 2759 } 2760 2761 if (string != NULL) 2762 { 2763 comment = string->str; 2764 g_string_free (string, FALSE); 2765 } 2766 else 2767 comment = NULL; 2768 2769 return comment; 2770 } 2771 2772 static gchar * 2773 get_group_comment (GKeyFile *key_file, 2774 GKeyFileGroup *group, 2775 GError **error) 2776 { 2777 GString *string; 2778 GList *tmp; 2779 gchar *comment; 2780 2781 string = NULL; 2782 2783 tmp = group->key_value_pairs; 2784 while (tmp) 2785 { 2786 GKeyFileKeyValuePair *pair; 2787 2788 pair = (GKeyFileKeyValuePair *) tmp->data; 2789 2790 if (pair->key != NULL) 2791 { 2792 tmp = tmp->prev; 2793 break; 2794 } 2795 2796 if (tmp->next == NULL) 2797 break; 2798 2799 tmp = tmp->next; 2800 } 2801 2802 while (tmp != NULL) 2803 { 2804 GKeyFileKeyValuePair *pair; 2805 2806 pair = (GKeyFileKeyValuePair *) tmp->data; 2807 2808 if (string == NULL) 2809 string = g_string_sized_new (512); 2810 2811 comment = g_key_file_parse_value_as_comment (key_file, pair->value); 2812 g_string_append (string, comment); 2813 g_free (comment); 2814 2815 tmp = tmp->prev; 2816 } 2817 2818 if (string != NULL) 2819 return g_string_free (string, FALSE); 2820 2821 return NULL; 2822 } 2823 2824 static gchar * 2825 g_key_file_get_group_comment (GKeyFile *key_file, 2826 const gchar *group_name, 2827 GError **error) 2828 { 2829 GList *group_node; 2830 GKeyFileGroup *group; 2831 2832 group = g_key_file_lookup_group (key_file, group_name); 2833 if (!group) 2834 { 2835 g_set_error (error, G_KEY_FILE_ERROR, 2836 G_KEY_FILE_ERROR_GROUP_NOT_FOUND, 2837 _("Key file does not have group '%s'"), 2838 group_name ? group_name : "(null)"); 2839 2840 return NULL; 2841 } 2842 2843 if (group->comment) 2844 return g_strdup (group->comment->value); 2845 2846 group_node = g_key_file_lookup_group_node (key_file, group_name); 2847 group_node = group_node->next; 2848 group = (GKeyFileGroup *)group_node->data; 2849 return get_group_comment (key_file, group, error); 2850 } 2851 2852 static gchar * 2853 g_key_file_get_top_comment (GKeyFile *key_file, 2854 GError **error) 2855 { 2856 GList *group_node; 2857 GKeyFileGroup *group; 2858 2859 /* The last group in the list should be the top (comments only) 2860 * group in the file 2861 */ 2862 g_warn_if_fail (key_file->groups != NULL); 2863 group_node = g_list_last (key_file->groups); 2864 group = (GKeyFileGroup *) group_node->data; 2865 g_warn_if_fail (group->name == NULL); 2866 2867 return get_group_comment (key_file, group, error); 2868 } 2869 2870 /** 2871 * g_key_file_get_comment: 2872 * @key_file: a #GKeyFile 2873 * @group_name: a group name, or %NULL 2874 * @key: a key 2875 * @error: return location for a #GError 2876 * 2877 * Retrieves a comment above @key from @group_name. 2878 * If @key is %NULL then @comment will be read from above 2879 * @group_name. If both @key and @group_name are %NULL, then 2880 * @comment will be read from above the first group in the file. 2881 * 2882 * Returns: a comment that should be freed with g_free() 2883 * 2884 * Since: 2.6 2885 **/ 2886 gchar * 2887 g_key_file_get_comment (GKeyFile *key_file, 2888 const gchar *group_name, 2889 const gchar *key, 2890 GError **error) 2891 { 2892 g_return_val_if_fail (key_file != NULL, NULL); 2893 2894 if (group_name != NULL && key != NULL) 2895 return g_key_file_get_key_comment (key_file, group_name, key, error); 2896 else if (group_name != NULL) 2897 return g_key_file_get_group_comment (key_file, group_name, error); 2898 else 2899 return g_key_file_get_top_comment (key_file, error); 2900 } 2901 2902 /** 2903 * g_key_file_remove_comment: 2904 * @key_file: a #GKeyFile 2905 * @group_name: a group name, or %NULL 2906 * @key: a key 2907 * @error: return location for a #GError 2908 * 2909 * Removes a comment above @key from @group_name. 2910 * If @key is %NULL then @comment will be removed above @group_name. 2911 * If both @key and @group_name are %NULL, then @comment will 2912 * be removed above the first group in the file. 2913 * 2914 * Returns: %TRUE if the comment was removed, %FALSE otherwise 2915 * 2916 * Since: 2.6 2917 **/ 2918 2919 gboolean 2920 g_key_file_remove_comment (GKeyFile *key_file, 2921 const gchar *group_name, 2922 const gchar *key, 2923 GError **error) 2924 { 2925 g_return_val_if_fail (key_file != NULL, FALSE); 2926 2927 if (group_name != NULL && key != NULL) 2928 return g_key_file_set_key_comment (key_file, group_name, key, NULL, error); 2929 else if (group_name != NULL) 2930 return g_key_file_set_group_comment (key_file, group_name, NULL, error); 2931 else 2932 return g_key_file_set_top_comment (key_file, NULL, error); 2933 } 2934 2935 /** 2936 * g_key_file_has_group: 2937 * @key_file: a #GKeyFile 2938 * @group_name: a group name 2939 * 2940 * Looks whether the key file has the group @group_name. 2941 * 2942 * Return value: %TRUE if @group_name is a part of @key_file, %FALSE 2943 * otherwise. 2944 * Since: 2.6 2945 **/ 2946 gboolean 2947 g_key_file_has_group (GKeyFile *key_file, 2948 const gchar *group_name) 2949 { 2950 g_return_val_if_fail (key_file != NULL, FALSE); 2951 g_return_val_if_fail (group_name != NULL, FALSE); 2952 2953 return g_key_file_lookup_group (key_file, group_name) != NULL; 2954 } 2955 2956 /** 2957 * g_key_file_has_key: 2958 * @key_file: a #GKeyFile 2959 * @group_name: a group name 2960 * @key: a key name 2961 * @error: return location for a #GError 2962 * 2963 * Looks whether the key file has the key @key in the group 2964 * @group_name. 2965 * 2966 * Return value: %TRUE if @key is a part of @group_name, %FALSE 2967 * otherwise. 2968 * 2969 * Since: 2.6 2970 **/ 2971 gboolean 2972 g_key_file_has_key (GKeyFile *key_file, 2973 const gchar *group_name, 2974 const gchar *key, 2975 GError **error) 2976 { 2977 GKeyFileKeyValuePair *pair; 2978 GKeyFileGroup *group; 2979 2980 g_return_val_if_fail (key_file != NULL, FALSE); 2981 g_return_val_if_fail (group_name != NULL, FALSE); 2982 g_return_val_if_fail (key != NULL, FALSE); 2983 2984 group = g_key_file_lookup_group (key_file, group_name); 2985 2986 if (!group) 2987 { 2988 g_set_error (error, G_KEY_FILE_ERROR, 2989 G_KEY_FILE_ERROR_GROUP_NOT_FOUND, 2990 _("Key file does not have group '%s'"), 2991 group_name ? group_name : "(null)"); 2992 2993 return FALSE; 2994 } 2995 2996 pair = g_key_file_lookup_key_value_pair (key_file, group, key); 2997 2998 return pair != NULL; 2999 } 3000 3001 static void 3002 g_key_file_add_group (GKeyFile *key_file, 3003 const gchar *group_name) 3004 { 3005 GKeyFileGroup *group; 3006 3007 g_return_if_fail (key_file != NULL); 3008 g_return_if_fail (g_key_file_is_group_name (group_name)); 3009 3010 group = g_key_file_lookup_group (key_file, group_name); 3011 if (group != NULL) 3012 { 3013 key_file->current_group = group; 3014 return; 3015 } 3016 3017 group = g_slice_new0 (GKeyFileGroup); 3018 group->name = g_strdup (group_name); 3019 group->lookup_map = g_hash_table_new (g_str_hash, g_str_equal); 3020 key_file->groups = g_list_prepend (key_file->groups, group); 3021 key_file->approximate_size += strlen (group_name) + 3; 3022 key_file->current_group = group; 3023 3024 if (key_file->start_group == NULL) 3025 key_file->start_group = group; 3026 3027 g_hash_table_insert (key_file->group_hash, (gpointer)group->name, group); 3028 } 3029 3030 static void 3031 g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair) 3032 { 3033 if (pair != NULL) 3034 { 3035 g_free (pair->key); 3036 g_free (pair->value); 3037 g_slice_free (GKeyFileKeyValuePair, pair); 3038 } 3039 } 3040 3041 /* Be careful not to call this function on a node with data in the 3042 * lookup map without removing it from the lookup map, first. 3043 * 3044 * Some current cases where this warning is not a concern are 3045 * when: 3046 * - the node being removed is a comment node 3047 * - the entire lookup map is getting destroyed soon after 3048 * anyway. 3049 */ 3050 static void 3051 g_key_file_remove_key_value_pair_node (GKeyFile *key_file, 3052 GKeyFileGroup *group, 3053 GList *pair_node) 3054 { 3055 3056 GKeyFileKeyValuePair *pair; 3057 3058 pair = (GKeyFileKeyValuePair *) pair_node->data; 3059 3060 group->key_value_pairs = g_list_remove_link (group->key_value_pairs, pair_node); 3061 3062 if (pair->key != NULL) 3063 key_file->approximate_size -= strlen (pair->key) + 1; 3064 3065 g_warn_if_fail (pair->value != NULL); 3066 key_file->approximate_size -= strlen (pair->value); 3067 3068 g_key_file_key_value_pair_free (pair); 3069 3070 g_list_free_1 (pair_node); 3071 } 3072 3073 static void 3074 g_key_file_remove_group_node (GKeyFile *key_file, 3075 GList *group_node) 3076 { 3077 GKeyFileGroup *group; 3078 GList *tmp; 3079 3080 group = (GKeyFileGroup *) group_node->data; 3081 3082 if (group->name) 3083 g_hash_table_remove (key_file->group_hash, group->name); 3084 3085 /* If the current group gets deleted make the current group the last 3086 * added group. 3087 */ 3088 if (key_file->current_group == group) 3089 { 3090 /* groups should always contain at least the top comment group, 3091 * unless g_key_file_clear has been called 3092 */ 3093 if (key_file->groups) 3094 key_file->current_group = (GKeyFileGroup *) key_file->groups->data; 3095 else 3096 key_file->current_group = NULL; 3097 } 3098 3099 /* If the start group gets deleted make the start group the first 3100 * added group. 3101 */ 3102 if (key_file->start_group == group) 3103 { 3104 tmp = g_list_last (key_file->groups); 3105 while (tmp != NULL) 3106 { 3107 if (tmp != group_node && 3108 ((GKeyFileGroup *) tmp->data)->name != NULL) 3109 break; 3110 3111 tmp = tmp->prev; 3112 } 3113 3114 if (tmp) 3115 key_file->start_group = (GKeyFileGroup *) tmp->data; 3116 else 3117 key_file->start_group = NULL; 3118 } 3119 3120 key_file->groups = g_list_remove_link (key_file->groups, group_node); 3121 3122 if (group->name != NULL) 3123 key_file->approximate_size -= strlen (group->name) + 3; 3124 3125 tmp = group->key_value_pairs; 3126 while (tmp != NULL) 3127 { 3128 GList *pair_node; 3129 3130 pair_node = tmp; 3131 tmp = tmp->next; 3132 g_key_file_remove_key_value_pair_node (key_file, group, pair_node); 3133 } 3134 3135 g_warn_if_fail (group->key_value_pairs == NULL); 3136 3137 if (group->lookup_map) 3138 { 3139 g_hash_table_destroy (group->lookup_map); 3140 group->lookup_map = NULL; 3141 } 3142 3143 g_free ((gchar *) group->name); 3144 g_slice_free (GKeyFileGroup, group); 3145 g_list_free_1 (group_node); 3146 } 3147 3148 /** 3149 * g_key_file_remove_group: 3150 * @key_file: a #GKeyFile 3151 * @group_name: a group name 3152 * @error: return location for a #GError or %NULL 3153 * 3154 * Removes the specified group, @group_name, 3155 * from the key file. 3156 * 3157 * Returns: %TRUE if the group was removed, %FALSE otherwise 3158 * 3159 * Since: 2.6 3160 **/ 3161 gboolean 3162 g_key_file_remove_group (GKeyFile *key_file, 3163 const gchar *group_name, 3164 GError **error) 3165 { 3166 GList *group_node; 3167 3168 g_return_val_if_fail (key_file != NULL, FALSE); 3169 g_return_val_if_fail (group_name != NULL, FALSE); 3170 3171 group_node = g_key_file_lookup_group_node (key_file, group_name); 3172 3173 if (!group_node) 3174 { 3175 g_set_error (error, G_KEY_FILE_ERROR, 3176 G_KEY_FILE_ERROR_GROUP_NOT_FOUND, 3177 _("Key file does not have group '%s'"), 3178 group_name); 3179 return FALSE; 3180 } 3181 3182 g_key_file_remove_group_node (key_file, group_node); 3183 3184 return TRUE; 3185 } 3186 3187 static void 3188 g_key_file_add_key (GKeyFile *key_file, 3189 GKeyFileGroup *group, 3190 const gchar *key, 3191 const gchar *value) 3192 { 3193 GKeyFileKeyValuePair *pair; 3194 3195 pair = g_slice_new (GKeyFileKeyValuePair); 3196 pair->key = g_strdup (key); 3197 pair->value = g_strdup (value); 3198 3199 g_hash_table_replace (group->lookup_map, pair->key, pair); 3200 group->key_value_pairs = g_list_prepend (group->key_value_pairs, pair); 3201 group->has_trailing_blank_line = FALSE; 3202 key_file->approximate_size += strlen (key) + strlen (value) + 2; 3203 } 3204 3205 /** 3206 * g_key_file_remove_key: 3207 * @key_file: a #GKeyFile 3208 * @group_name: a group name 3209 * @key: a key name to remove 3210 * @error: return location for a #GError or %NULL 3211 * 3212 * Removes @key in @group_name from the key file. 3213 * 3214 * Returns: %TRUE if the key was removed, %FALSE otherwise 3215 * 3216 * Since: 2.6 3217 **/ 3218 gboolean 3219 g_key_file_remove_key (GKeyFile *key_file, 3220 const gchar *group_name, 3221 const gchar *key, 3222 GError **error) 3223 { 3224 GKeyFileGroup *group; 3225 GKeyFileKeyValuePair *pair; 3226 3227 g_return_val_if_fail (key_file != NULL, FALSE); 3228 g_return_val_if_fail (group_name != NULL, FALSE); 3229 g_return_val_if_fail (key != NULL, FALSE); 3230 3231 pair = NULL; 3232 3233 group = g_key_file_lookup_group (key_file, group_name); 3234 if (!group) 3235 { 3236 g_set_error (error, G_KEY_FILE_ERROR, 3237 G_KEY_FILE_ERROR_GROUP_NOT_FOUND, 3238 _("Key file does not have group '%s'"), 3239 group_name ? group_name : "(null)"); 3240 return FALSE; 3241 } 3242 3243 pair = g_key_file_lookup_key_value_pair (key_file, group, key); 3244 3245 if (!pair) 3246 { 3247 g_set_error (error, G_KEY_FILE_ERROR, 3248 G_KEY_FILE_ERROR_KEY_NOT_FOUND, 3249 _("Key file does not have key '%s' in group '%s'"), 3250 key, group->name); 3251 return FALSE; 3252 } 3253 3254 key_file->approximate_size -= strlen (pair->key) + strlen (pair->value) + 2; 3255 3256 group->key_value_pairs = g_list_remove (group->key_value_pairs, pair); 3257 g_hash_table_remove (group->lookup_map, pair->key); 3258 g_key_file_key_value_pair_free (pair); 3259 3260 return TRUE; 3261 } 3262 3263 static GList * 3264 g_key_file_lookup_group_node (GKeyFile *key_file, 3265 const gchar *group_name) 3266 { 3267 GKeyFileGroup *group; 3268 GList *tmp; 3269 3270 for (tmp = key_file->groups; tmp != NULL; tmp = tmp->next) 3271 { 3272 group = (GKeyFileGroup *) tmp->data; 3273 3274 if (group && group->name && strcmp (group->name, group_name) == 0) 3275 break; 3276 } 3277 3278 return tmp; 3279 } 3280 3281 static GKeyFileGroup * 3282 g_key_file_lookup_group (GKeyFile *key_file, 3283 const gchar *group_name) 3284 { 3285 return (GKeyFileGroup *)g_hash_table_lookup (key_file->group_hash, group_name); 3286 } 3287 3288 static GList * 3289 g_key_file_lookup_key_value_pair_node (GKeyFile *key_file, 3290 GKeyFileGroup *group, 3291 const gchar *key) 3292 { 3293 GList *key_node; 3294 3295 for (key_node = group->key_value_pairs; 3296 key_node != NULL; 3297 key_node = key_node->next) 3298 { 3299 GKeyFileKeyValuePair *pair; 3300 3301 pair = (GKeyFileKeyValuePair *) key_node->data; 3302 3303 if (pair->key && strcmp (pair->key, key) == 0) 3304 break; 3305 } 3306 3307 return key_node; 3308 } 3309 3310 static GKeyFileKeyValuePair * 3311 g_key_file_lookup_key_value_pair (GKeyFile *key_file, 3312 GKeyFileGroup *group, 3313 const gchar *key) 3314 { 3315 return (GKeyFileKeyValuePair *) g_hash_table_lookup (group->lookup_map, key); 3316 } 3317 3318 /* Lines starting with # or consisting entirely of whitespace are merely 3319 * recorded, not parsed. This function assumes all leading whitespace 3320 * has been stripped. 3321 */ 3322 static gboolean 3323 g_key_file_line_is_comment (const gchar *line) 3324 { 3325 return (*line == '#' || *line == '\0' || *line == '\n'); 3326 } 3327 3328 static gboolean 3329 g_key_file_is_group_name (const gchar *name) 3330 { 3331 gchar *p, *q; 3332 3333 if (name == NULL) 3334 return FALSE; 3335 3336 p = q = (gchar *) name; 3337 while (*q && *q != ']' && *q != '[' && !g_ascii_iscntrl (*q)) 3338 q = g_utf8_find_next_char (q, NULL); 3339 3340 if (*q != '\0' || q == p) 3341 return FALSE; 3342 3343 return TRUE; 3344 } 3345 3346 static gboolean 3347 g_key_file_is_key_name (const gchar *name) 3348 { 3349 gchar *p, *q; 3350 3351 if (name == NULL) 3352 return FALSE; 3353 3354 p = q = (gchar *) name; 3355 /* We accept a little more than the desktop entry spec says, 3356 * since gnome-vfs uses mime-types as keys in its cache. 3357 */ 3358 while (*q && *q != '=' && *q != '[' && *q != ']') 3359 q = g_utf8_find_next_char (q, NULL); 3360 3361 /* No empty keys, please */ 3362 if (q == p) 3363 return FALSE; 3364 3365 /* We accept spaces in the middle of keys to not break 3366 * existing apps, but we don't tolerate initial or final 3367 * spaces, which would lead to silent corruption when 3368 * rereading the file. 3369 */ 3370 if (*p == ' ' || q[-1] == ' ') 3371 return FALSE; 3372 3373 if (*q == '[') 3374 { 3375 q++; 3376 while (*q && (g_unichar_isalnum (g_utf8_get_char_validated (q, -1)) || *q == '-' || *q == '_' || *q == '.' || *q == '@')) 3377 q = g_utf8_find_next_char (q, NULL); 3378 3379 if (*q != ']') 3380 return FALSE; 3381 3382 q++; 3383 } 3384 3385 if (*q != '\0') 3386 return FALSE; 3387 3388 return TRUE; 3389 } 3390 3391 /* A group in a key file is made up of a starting '[' followed by one 3392 * or more letters making up the group name followed by ']'. 3393 */ 3394 static gboolean 3395 g_key_file_line_is_group (const gchar *line) 3396 { 3397 gchar *p; 3398 3399 p = (gchar *) line; 3400 if (*p != '[') 3401 return FALSE; 3402 3403 p++; 3404 3405 while (*p && *p != ']') 3406 p = g_utf8_find_next_char (p, NULL); 3407 3408 if (*p != ']') 3409 return FALSE; 3410 3411 /* silently accept whitespace after the ] */ 3412 p = g_utf8_find_next_char (p, NULL); 3413 while (*p == ' ' || *p == '\t') 3414 p = g_utf8_find_next_char (p, NULL); 3415 3416 if (*p) 3417 return FALSE; 3418 3419 return TRUE; 3420 } 3421 3422 static gboolean 3423 g_key_file_line_is_key_value_pair (const gchar *line) 3424 { 3425 gchar *p; 3426 3427 p = (gchar *) g_utf8_strchr (line, -1, '='); 3428 3429 if (!p) 3430 return FALSE; 3431 3432 /* Key must be non-empty 3433 */ 3434 if (*p == line[0]) 3435 return FALSE; 3436 3437 return TRUE; 3438 } 3439 3440 static gchar * 3441 g_key_file_parse_value_as_string (GKeyFile *key_file, 3442 const gchar *value, 3443 GSList **pieces, 3444 GError **error) 3445 { 3446 gchar *string_value, *p, *q0, *q; 3447 3448 string_value = g_new (gchar, strlen (value) + 1); 3449 3450 p = (gchar *) value; 3451 q0 = q = string_value; 3452 while (*p) 3453 { 3454 if (*p == '\\') 3455 { 3456 p++; 3457 3458 switch (*p) 3459 { 3460 case 's': 3461 *q = ' '; 3462 break; 3463 3464 case 'n': 3465 *q = '\n'; 3466 break; 3467 3468 case 't': 3469 *q = '\t'; 3470 break; 3471 3472 case 'r': 3473 *q = '\r'; 3474 break; 3475 3476 case '\\': 3477 *q = '\\'; 3478 break; 3479 3480 case '\0': 3481 g_set_error_literal (error, G_KEY_FILE_ERROR, 3482 G_KEY_FILE_ERROR_INVALID_VALUE, 3483 _("Key file contains escape character " 3484 "at end of line")); 3485 break; 3486 3487 default: 3488 if (pieces && *p == key_file->list_separator) 3489 *q = key_file->list_separator; 3490 else 3491 { 3492 *q++ = '\\'; 3493 *q = *p; 3494 3495 if (*error == NULL) 3496 { 3497 gchar sequence[3]; 3498 3499 sequence[0] = '\\'; 3500 sequence[1] = *p; 3501 sequence[2] = '\0'; 3502 3503 g_set_error (error, G_KEY_FILE_ERROR, 3504 G_KEY_FILE_ERROR_INVALID_VALUE, 3505 _("Key file contains invalid escape " 3506 "sequence '%s'"), sequence); 3507 } 3508 } 3509 break; 3510 } 3511 } 3512 else 3513 { 3514 *q = *p; 3515 if (pieces && (*p == key_file->list_separator)) 3516 { 3517 *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0)); 3518 q0 = q + 1; 3519 } 3520 } 3521 3522 if (*p == '\0') 3523 break; 3524 3525 q++; 3526 p++; 3527 } 3528 3529 *q = '\0'; 3530 if (pieces) 3531 { 3532 if (q0 < q) 3533 *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0)); 3534 *pieces = g_slist_reverse (*pieces); 3535 } 3536 3537 return string_value; 3538 } 3539 3540 static gchar * 3541 g_key_file_parse_string_as_value (GKeyFile *key_file, 3542 const gchar *string, 3543 gboolean escape_separator) 3544 { 3545 gchar *value, *p, *q; 3546 gsize length; 3547 gboolean parsing_leading_space; 3548 3549 length = strlen (string) + 1; 3550 3551 /* Worst case would be that every character needs to be escaped. 3552 * In other words every character turns to two characters 3553 */ 3554 value = g_new (gchar, 2 * length); 3555 3556 p = (gchar *) string; 3557 q = value; 3558 parsing_leading_space = TRUE; 3559 while (p < (string + length - 1)) 3560 { 3561 gchar escaped_character[3] = { '\\', 0, 0 }; 3562 3563 switch (*p) 3564 { 3565 case ' ': 3566 if (parsing_leading_space) 3567 { 3568 escaped_character[1] = 's'; 3569 strcpy (q, escaped_character); 3570 q += 2; 3571 } 3572 else 3573 { 3574 *q = *p; 3575 q++; 3576 } 3577 break; 3578 case '\t': 3579 if (parsing_leading_space) 3580 { 3581 escaped_character[1] = 't'; 3582 strcpy (q, escaped_character); 3583 q += 2; 3584 } 3585 else 3586 { 3587 *q = *p; 3588 q++; 3589 } 3590 break; 3591 case '\n': 3592 escaped_character[1] = 'n'; 3593 strcpy (q, escaped_character); 3594 q += 2; 3595 break; 3596 case '\r': 3597 escaped_character[1] = 'r'; 3598 strcpy (q, escaped_character); 3599 q += 2; 3600 break; 3601 case '\\': 3602 escaped_character[1] = '\\'; 3603 strcpy (q, escaped_character); 3604 q += 2; 3605 parsing_leading_space = FALSE; 3606 break; 3607 default: 3608 if (escape_separator && *p == key_file->list_separator) 3609 { 3610 escaped_character[1] = key_file->list_separator; 3611 strcpy (q, escaped_character); 3612 q += 2; 3613 parsing_leading_space = TRUE; 3614 } 3615 else 3616 { 3617 *q = *p; 3618 q++; 3619 parsing_leading_space = FALSE; 3620 } 3621 break; 3622 } 3623 p++; 3624 } 3625 *q = '\0'; 3626 3627 return value; 3628 } 3629 3630 static gint 3631 g_key_file_parse_value_as_integer (GKeyFile *key_file, 3632 const gchar *value, 3633 GError **error) 3634 { 3635 gchar *end_of_valid_int; 3636 glong long_value; 3637 gint int_value; 3638 3639 errno = 0; 3640 long_value = strtol (value, &end_of_valid_int, 10); 3641 3642 if (*value == '\0' || *end_of_valid_int != '\0') 3643 { 3644 gchar *value_utf8 = _g_utf8_make_valid (value); 3645 g_set_error (error, G_KEY_FILE_ERROR, 3646 G_KEY_FILE_ERROR_INVALID_VALUE, 3647 _("Value '%s' cannot be interpreted " 3648 "as a number."), value_utf8); 3649 g_free (value_utf8); 3650 3651 return 0; 3652 } 3653 3654 int_value = long_value; 3655 if (int_value != long_value || errno == ERANGE) 3656 { 3657 gchar *value_utf8 = _g_utf8_make_valid (value); 3658 g_set_error (error, 3659 G_KEY_FILE_ERROR, 3660 G_KEY_FILE_ERROR_INVALID_VALUE, 3661 _("Integer value '%s' out of range"), 3662 value_utf8); 3663 g_free (value_utf8); 3664 3665 return 0; 3666 } 3667 3668 return int_value; 3669 } 3670 3671 static gchar * 3672 g_key_file_parse_integer_as_value (GKeyFile *key_file, 3673 gint value) 3674 3675 { 3676 return g_strdup_printf ("%d", value); 3677 } 3678 3679 static gdouble 3680 g_key_file_parse_value_as_double (GKeyFile *key_file, 3681 const gchar *value, 3682 GError **error) 3683 { 3684 gchar *end_of_valid_d; 3685 gdouble double_value = 0; 3686 3687 double_value = g_ascii_strtod (value, &end_of_valid_d); 3688 3689 if (*end_of_valid_d != '\0' || end_of_valid_d == value) 3690 { 3691 gchar *value_utf8 = _g_utf8_make_valid (value); 3692 g_set_error (error, G_KEY_FILE_ERROR, 3693 G_KEY_FILE_ERROR_INVALID_VALUE, 3694 _("Value '%s' cannot be interpreted " 3695 "as a float number."), 3696 value_utf8); 3697 g_free (value_utf8); 3698 } 3699 3700 return double_value; 3701 } 3702 3703 static gboolean 3704 g_key_file_parse_value_as_boolean (GKeyFile *key_file, 3705 const gchar *value, 3706 GError **error) 3707 { 3708 gchar *value_utf8; 3709 3710 if (strcmp (value, "true") == 0 || strcmp (value, "1") == 0) 3711 return TRUE; 3712 else if (strcmp (value, "false") == 0 || strcmp (value, "0") == 0) 3713 return FALSE; 3714 3715 value_utf8 = _g_utf8_make_valid (value); 3716 g_set_error (error, G_KEY_FILE_ERROR, 3717 G_KEY_FILE_ERROR_INVALID_VALUE, 3718 _("Value '%s' cannot be interpreted " 3719 "as a boolean."), value_utf8); 3720 g_free (value_utf8); 3721 3722 return FALSE; 3723 } 3724 3725 static gchar * 3726 g_key_file_parse_boolean_as_value (GKeyFile *key_file, 3727 gboolean value) 3728 { 3729 if (value) 3730 return g_strdup ("true"); 3731 else 3732 return g_strdup ("false"); 3733 } 3734 3735 static gchar * 3736 g_key_file_parse_value_as_comment (GKeyFile *key_file, 3737 const gchar *value) 3738 { 3739 GString *string; 3740 gchar **lines; 3741 gsize i; 3742 3743 string = g_string_sized_new (512); 3744 3745 lines = g_strsplit (value, "\n", 0); 3746 3747 for (i = 0; lines[i] != NULL; i++) 3748 { 3749 if (lines[i][0] != '#') 3750 g_string_append_printf (string, "%s\n", lines[i]); 3751 else 3752 g_string_append_printf (string, "%s\n", lines[i] + 1); 3753 } 3754 g_strfreev (lines); 3755 3756 return g_string_free (string, FALSE); 3757 } 3758 3759 static gchar * 3760 g_key_file_parse_comment_as_value (GKeyFile *key_file, 3761 const gchar *comment) 3762 { 3763 GString *string; 3764 gchar **lines; 3765 gsize i; 3766 3767 string = g_string_sized_new (512); 3768 3769 lines = g_strsplit (comment, "\n", 0); 3770 3771 for (i = 0; lines[i] != NULL; i++) 3772 g_string_append_printf (string, "#%s%s", lines[i], 3773 lines[i + 1] == NULL? "" : "\n"); 3774 g_strfreev (lines); 3775 3776 return g_string_free (string, FALSE); 3777 } 3778 3779 #define __G_KEY_FILE_C__ 3780 #include "galiasdef.c" 3781