#endif /* G_OS_WIN32 */
#include "gtkicontheme.h"
-#include "gtkiconthemeparser.h"
#include "gtkiconcache.h"
#include "gtkintl.h"
#include "gtksettings.h"
GQuark context);
static void theme_subdir_load (GtkIconTheme *icon_theme,
IconTheme *theme,
- GtkIconThemeFile *theme_file,
+ GKeyFile *theme_file,
char *subdir);
static void do_theme_change (GtkIconTheme *icon_theme);
GtkIconThemePrivate *priv;
IconTheme *theme;
char *path;
- char *contents;
- char *directories;
- char *inherits;
- GtkIconThemeFile *theme_file;
+ GKeyFile *theme_file;
+ GError *error = NULL;
IconThemeDirMtime *dir_mtime;
struct stat stat_buf;
}
theme_file = NULL;
- for (i = 0; i < priv->search_path_len; i++)
+ for (i = 0; i < priv->search_path_len && !theme_file; i++)
{
path = g_build_filename (priv->search_path[i],
theme_name,
"index.theme",
NULL);
- if (g_file_test (path, G_FILE_TEST_IS_REGULAR)) {
- if (g_file_get_contents (path, &contents, NULL, NULL)) {
- theme_file = _gtk_icon_theme_file_new_from_string (contents, NULL);
- g_free (contents);
- g_free (path);
- break;
+ if (g_file_test (path, G_FILE_TEST_IS_REGULAR))
+ {
+ theme_file = g_key_file_new ();
+ g_key_file_set_list_separator (theme_file, ',');
+ g_key_file_load_from_file (theme_file, path, 0, &error);
+ if (error)
+ {
+ g_key_file_free (theme_file);
+ theme_file = NULL;
+ g_error_free (error);
+ error = NULL;
+ }
}
- }
g_free (path);
}
return;
theme = g_new (IconTheme, 1);
- if (!_gtk_icon_theme_file_get_locale_string (theme_file,
- "Icon Theme",
- "Name",
- &theme->display_name))
+ theme->display_name =
+ g_key_file_get_locale_string (theme_file, "Icon Theme", "Name", NULL, NULL);
+ if (!theme->display_name)
{
g_warning ("Theme file for %s has no name\n", theme_name);
g_free (theme);
- _gtk_icon_theme_file_free (theme_file);
+ g_key_file_free (theme_file);
return;
}
- if (!_gtk_icon_theme_file_get_string (theme_file,
- "Icon Theme",
- "Directories",
- &directories))
+ dirs = g_key_file_get_string_list (theme_file, "Icon Theme", "Directories", NULL, NULL);
+ if (!dirs)
{
g_warning ("Theme file for %s has no directories\n", theme_name);
g_free (theme->display_name);
g_free (theme);
- _gtk_icon_theme_file_free (theme_file);
+ g_key_file_free (theme_file);
return;
}
theme->name = g_strdup (theme_name);
- _gtk_icon_theme_file_get_locale_string (theme_file,
- "Icon Theme",
- "Comment",
- &theme->comment);
- _gtk_icon_theme_file_get_string (theme_file,
- "Icon Theme",
- "Example",
- &theme->example);
-
- dirs = g_strsplit (directories, ",", 0);
+ theme->comment =
+ g_key_file_get_locale_string (theme_file,
+ "Icon Theme", "Comment",
+ NULL, NULL);
+ theme->example =
+ g_key_file_get_string (theme_file,
+ "Icon Theme", "Example",
+ NULL);
theme->icon_caches = NULL;
theme->dirs = NULL;
for (i = 0; dirs[i] != NULL; i++)
- theme_subdir_load (icon_theme, theme, theme_file, dirs[i]);
+ theme_subdir_load (icon_theme, theme, theme_file, dirs[i]);
g_strfreev (dirs);
theme->dirs = g_list_reverse (theme->dirs);
- g_free (directories);
-
/* Prepend the finished theme */
priv->themes = g_list_prepend (priv->themes, theme);
- if (_gtk_icon_theme_file_get_string (theme_file,
+ themes = g_key_file_get_string_list (theme_file,
"Icon Theme",
"Inherits",
- &inherits))
+ NULL,
+ NULL);
+ if (themes)
{
- themes = g_strsplit (inherits, ",", 0);
-
for (i = 0; themes[i] != NULL; i++)
insert_theme (icon_theme, themes[i]);
g_strfreev (themes);
-
- g_free (inherits);
}
- _gtk_icon_theme_file_free (theme_file);
+ g_key_file_free (theme_file);
}
static void
static void
load_icon_data (IconThemeDir *dir, const char *path, const char *name)
{
- GtkIconThemeFile *icon_file;
+ GKeyFile *icon_file;
char *base_name;
char **split;
- char *contents;
+ gsize length;
char *dot;
char *str;
char *split_point;
int i;
+ gint *ivalues;
+ GError *error = NULL;
GtkIconData *data;
- if (g_file_get_contents (path, &contents, NULL, NULL))
+ icon_file = g_key_file_new ();
+ g_key_file_set_list_separator (icon_file, ',');
+ g_key_file_load_from_file (icon_file, path, 0, &error);
+ if (error)
{
- icon_file = _gtk_icon_theme_file_new_from_string (contents, NULL);
+ g_error_free (error);
+ return;
+ }
+ else
+ {
+ base_name = g_strdup (name);
+ dot = strrchr (base_name, '.');
+ *dot = 0;
+
+ data = g_new0 (GtkIconData, 1);
+ g_hash_table_replace (dir->icon_data, base_name, data);
- if (icon_file)
+ ivalues = g_key_file_get_integer_list (icon_file,
+ "Icon Data", "EmbeddedTextRectangle",
+ &length, NULL);
+ if (ivalues)
{
- base_name = g_strdup (name);
- dot = strrchr (base_name, '.');
- *dot = 0;
-
- data = g_new0 (GtkIconData, 1);
- g_hash_table_replace (dir->icon_data, base_name, data);
-
- if (_gtk_icon_theme_file_get_string (icon_file, "Icon Data",
- "EmbeddedTextRectangle",
- &str))
+ if (length == 4)
{
- split = g_strsplit (str, ",", 4);
-
- i = 0;
- while (split[i] != NULL)
- i++;
-
- if (i==4)
- {
- data->has_embedded_rect = TRUE;
- data->x0 = atoi (split[0]);
- data->y0 = atoi (split[1]);
- data->x1 = atoi (split[2]);
- data->y1 = atoi (split[3]);
- }
-
- g_strfreev (split);
- g_free (str);
+ data->has_embedded_rect = TRUE;
+ data->x0 = ivalues[0];
+ data->y0 = ivalues[1];
+ data->x1 = ivalues[2];
+ data->y1 = ivalues[3];
}
+
+ g_free (ivalues);
+ }
+
+ str = g_key_file_get_string (icon_file, "Icon Data", "AttachPoints", NULL);
+ if (str)
+ {
+ split = g_strsplit (str, "|", -1);
+
+ data->n_attach_points = g_strv_length (split);
+ data->attach_points = g_malloc (sizeof (GdkPoint) * data->n_attach_points);
-
- if (_gtk_icon_theme_file_get_string (icon_file, "Icon Data",
- "AttachPoints",
- &str))
+ i = 0;
+ while (split[i] != NULL && i < data->n_attach_points)
{
- split = g_strsplit (str, "|", -1);
-
- i = 0;
- while (split[i] != NULL)
- i++;
-
- data->n_attach_points = i;
- data->attach_points = g_malloc (sizeof (GdkPoint) * i);
-
- i = 0;
- while (split[i] != NULL && i < data->n_attach_points)
+ split_point = strchr (split[i], ',');
+ if (split_point)
{
- split_point = strchr (split[i], ',');
- if (split_point)
- {
- *split_point = 0;
- split_point++;
- data->attach_points[i].x = atoi (split[i]);
- data->attach_points[i].y = atoi (split_point);
- }
- i++;
+ *split_point = 0;
+ split_point++;
+ data->attach_points[i].x = atoi (split[i]);
+ data->attach_points[i].y = atoi (split_point);
}
-
- g_strfreev (split);
- g_free (str);
+ i++;
}
- _gtk_icon_theme_file_get_locale_string (icon_file, "Icon Data",
- "DisplayName",
- &data->display_name);
-
- _gtk_icon_theme_file_free (icon_file);
+ g_strfreev (split);
+ g_free (str);
}
- g_free (contents);
+
+ data->display_name = g_key_file_get_locale_string (icon_file,
+ "Icon Data", "DisplayName",
+ NULL, NULL);
+ g_key_file_free (icon_file);
}
-
}
static void
static void
theme_subdir_load (GtkIconTheme *icon_theme,
- IconTheme *theme,
- GtkIconThemeFile *theme_file,
- char *subdir)
+ IconTheme *theme,
+ GKeyFile *theme_file,
+ char *subdir)
{
int base;
char *type_string;
int max_size;
int threshold;
char *full_dir;
+ GError *error = NULL;
- if (!_gtk_icon_theme_file_get_integer (theme_file,
- subdir,
- "Size",
- &size))
+ size = g_key_file_get_integer (theme_file, subdir, "Size", &error);
+ if (error)
{
- g_warning ("Theme directory %s of theme %s has no size field\n", subdir, theme->name);
+ g_error_free (error);
+ g_warning ("Theme directory %s of theme %s has no size field\n",
+ subdir, theme->name);
return;
}
type = ICON_THEME_DIR_THRESHOLD;
- if (_gtk_icon_theme_file_get_string (theme_file, subdir, "Type", &type_string))
+ type_string = g_key_file_get_string (theme_file, subdir, "Type", NULL);
+ if (type_string)
{
if (strcmp (type_string, "Fixed") == 0)
type = ICON_THEME_DIR_FIXED;
}
context = 0;
- if (_gtk_icon_theme_file_get_string (theme_file, subdir, "Context", &context_string))
+ context_string = g_key_file_get_string (theme_file, subdir, "Context", NULL);
+ if (context_string)
{
context = g_quark_from_string (context_string);
g_free (context_string);
}
- if (!_gtk_icon_theme_file_get_integer (theme_file,
- subdir,
- "MaxSize",
- &max_size))
- max_size = size;
-
- if (!_gtk_icon_theme_file_get_integer (theme_file,
- subdir,
- "MinSize",
- &min_size))
- min_size = size;
+ max_size = g_key_file_get_integer (theme_file, subdir, "MaxSize", &error);
+ if (error)
+ {
+ max_size = size;
+
+ g_error_free (error);
+ error = NULL;
+ }
+
+ min_size = g_key_file_get_integer (theme_file, subdir, "MinSize", &error);
+ if (error)
+ {
+ min_size = size;
+
+ g_error_free (error);
+ error = NULL;
+ }
- if (!_gtk_icon_theme_file_get_integer (theme_file,
- subdir,
- "Threshold",
- &threshold))
- threshold = 2;
+ threshold = g_key_file_get_integer (theme_file, subdir, "Threshold", &error);
+ if (error)
+ {
+ threshold = 2;
+ g_error_free (error);
+ error = NULL;
+ }
+
for (base = 0; base < icon_theme->priv->search_path_len; base++)
{
GtkIconCache *cache;
+++ /dev/null
-/* GtkIconThemeParser - a parser of icon-theme files
- * gtk-icon-theme-parser.c Copyright (C) 2002, 2003 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <config.h>
-
-#include <string.h>
-#include <locale.h>
-#include <stdlib.h>
-
-#include "gtkalias.h"
-#include "gtkiconthemeparser.h"
-
-
-
-typedef struct _GtkIconThemeFileSection GtkIconThemeFileSection;
-typedef struct _GtkIconThemeFileLine GtkIconThemeFileLine;
-typedef struct _GtkIconThemeFileParser GtkIconThemeFileParser;
-
-struct _GtkIconThemeFileSection {
- GQuark section_name; /* 0 means just a comment block (before any section) */
- gint n_lines;
- GtkIconThemeFileLine *lines;
-};
-
-struct _GtkIconThemeFileLine {
- GQuark key; /* 0 means comment or blank line in value */
- char *locale;
- gchar *value;
-};
-
-struct _GtkIconThemeFile {
- gint n_sections;
- GtkIconThemeFileSection *sections;
- char *current_locale[2];
-};
-
-struct _GtkIconThemeFileParser {
- GtkIconThemeFile *df;
- gint current_section;
- gint n_allocated_lines;
- gint n_allocated_sections;
- gint line_nr;
- char *line;
-};
-
-#define VALID_KEY_CHAR 1
-#define VALID_LOCALE_CHAR 2
-static const guchar valid[256] = {
- 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
- 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
- 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x3 , 0x2 , 0x0 ,
- 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
- 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 ,
- 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x2 ,
- 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 ,
- 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
- 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
- 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
- 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
- 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
- 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
- 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
- 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
- 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
-};
-
-static void report_error (GtkIconThemeFileParser *parser,
- char *message,
- GtkIconThemeFileParseError error_code,
- GError **error);
-static GtkIconThemeFileSection *lookup_section (GtkIconThemeFile *df,
- const char *section);
-static GtkIconThemeFileLine * lookup_line (GtkIconThemeFile *df,
- GtkIconThemeFileSection *section,
- const char *keyname,
- const char *locale);
-
-
-GQuark
-_gtk_icon_theme_file_parse_error_quark (void)
-{
- static GQuark quark;
- if (!quark)
- quark = g_quark_from_static_string ("g_desktop_parse_error");
-
- return quark;
-}
-
-static void
-parser_free (GtkIconThemeFileParser *parser)
-{
- _gtk_icon_theme_file_free (parser->df);
-}
-
-static void
-gtk_icon_theme_file_line_free (GtkIconThemeFileLine *line)
-{
- g_free (line->locale);
- g_free (line->value);
-}
-
-static void
-gtk_icon_theme_file_section_free (GtkIconThemeFileSection *section)
-{
- int i;
-
- for (i = 0; i < section->n_lines; i++)
- gtk_icon_theme_file_line_free (§ion->lines[i]);
-
- g_free (section->lines);
-}
-
-void
-_gtk_icon_theme_file_free (GtkIconThemeFile *df)
-{
- int i;
-
- for (i = 0; i < df->n_sections; i++)
- gtk_icon_theme_file_section_free (&df->sections[i]);
- g_free (df->sections);
- g_free (df->current_locale[0]);
- g_free (df->current_locale[1]);
-
- g_free (df);
-}
-
-static void
-grow_lines (GtkIconThemeFileParser *parser)
-{
- int new_n_lines;
- GtkIconThemeFileSection *section;
-
- if (parser->n_allocated_lines == 0)
- new_n_lines = 1;
- else
- new_n_lines = parser->n_allocated_lines*2;
-
- section = &parser->df->sections[parser->current_section];
-
- section->lines = g_realloc (section->lines,
- sizeof (GtkIconThemeFileLine) * new_n_lines);
- parser->n_allocated_lines = new_n_lines;
-}
-
-static void
-grow_sections (GtkIconThemeFileParser *parser)
-{
- int new_n_sections;
-
- if (parser->n_allocated_sections == 0)
- new_n_sections = 1;
- else
- new_n_sections = parser->n_allocated_sections*2;
-
- parser->df->sections = g_renew (GtkIconThemeFileSection,
- parser->df->sections,
- new_n_sections);
- parser->n_allocated_sections = new_n_sections;
-}
-
-static gchar *
-unescape_string (gchar *str, gint len)
-{
- gchar *res;
- gchar *p, *q;
- gchar *end;
-
- /* len + 1 is enough, because unescaping never makes the
- * string longer */
- res = g_new (gchar, len + 1);
- p = str;
- q = res;
- end = str + len;
-
- while (p < end)
- {
- if (*p == 0)
- {
- /* Found an embedded null */
- g_free (res);
- return NULL;
- }
- if (*p == '\\')
- {
- p++;
- if (p >= end)
- {
- /* Escape at end of string */
- g_free (res);
- return NULL;
- }
-
- switch (*p)
- {
- case 's':
- *q++ = ' ';
- break;
- case 't':
- *q++ = '\t';
- break;
- case 'n':
- *q++ = '\n';
- break;
- case 'r':
- *q++ = '\r';
- break;
- case '\\':
- *q++ = '\\';
- break;
- default:
- /* Invalid escape code */
- g_free (res);
- return NULL;
- }
- p++;
- }
- else
- *q++ = *p++;
- }
- *q = 0;
-
- return res;
-}
-
-static gchar *
-escape_string (const gchar *str, gboolean escape_first_space)
-{
- gchar *res;
- char *q;
- const gchar *p;
- const gchar *end;
-
- /* len + 1 is enough, because unescaping never makes the
- * string longer */
- res = g_new (gchar, strlen (str)*2 + 1);
-
- p = str;
- q = res;
- end = str + strlen (str);
-
- while (*p)
- {
- if (*p == ' ')
- {
- if (escape_first_space && p == str)
- {
- *q++ = '\\';
- *q++ = 's';
- }
- else
- *q++ = ' ';
- }
- else if (*p == '\\')
- {
- *q++ = '\\';
- *q++ = '\\';
- }
- else if (*p == '\t')
- {
- *q++ = '\\';
- *q++ = 't';
- }
- else if (*p == '\n')
- {
- *q++ = '\\';
- *q++ = 'n';
- }
- else if (*p == '\r')
- {
- *q++ = '\\';
- *q++ = 'r';
- }
- else
- *q++ = *p;
- p++;
- }
- *q = 0;
-
- return res;
-}
-
-
-static void
-open_section (GtkIconThemeFileParser *parser,
- const char *name)
-{
- int n;
-
- if (parser->n_allocated_sections == parser->df->n_sections)
- grow_sections (parser);
-
- if (parser->current_section == 0 &&
- parser->df->sections[0].section_name == 0 &&
- parser->df->sections[0].n_lines == 0)
- {
- if (!name)
- g_warning ("non-initial NULL section\n");
-
- /* The initial section was empty. Piggyback on it. */
- parser->df->sections[0].section_name = g_quark_from_string (name);
-
- return;
- }
-
- n = parser->df->n_sections++;
-
- if (name)
- parser->df->sections[n].section_name = g_quark_from_string (name);
- else
- parser->df->sections[n].section_name = 0;
- parser->df->sections[n].n_lines = 0;
- parser->df->sections[n].lines = NULL;
-
- parser->current_section = n;
- parser->n_allocated_lines = 0;
- grow_lines (parser);
-}
-
-static GtkIconThemeFileLine *
-new_line (GtkIconThemeFileParser *parser)
-{
- GtkIconThemeFileSection *section;
- GtkIconThemeFileLine *line;
-
- section = &parser->df->sections[parser->current_section];
-
- if (parser->n_allocated_lines == section->n_lines)
- grow_lines (parser);
-
- line = §ion->lines[section->n_lines++];
-
- memset (line, 0, sizeof (GtkIconThemeFileLine));
-
- return line;
-}
-
-static gboolean
-is_blank_line (GtkIconThemeFileParser *parser)
-{
- gchar *p;
-
- p = parser->line;
-
- while (*p && *p != '\n')
- {
- if (!g_ascii_isspace (*p))
- return FALSE;
-
- p++;
- }
- return TRUE;
-}
-
-static void
-parse_comment_or_blank (GtkIconThemeFileParser *parser)
-{
- GtkIconThemeFileLine *line;
- gchar *line_end;
-
- line_end = strchr (parser->line, '\n');
- if (line_end == NULL)
- line_end = parser->line + strlen (parser->line);
-
- line = new_line (parser);
-
- line->value = g_strndup (parser->line, line_end - parser->line);
-
- parser->line = (line_end) ? line_end + 1 : NULL;
- parser->line_nr++;
-}
-
-static gboolean
-parse_section_start (GtkIconThemeFileParser *parser, GError **error)
-{
- gchar *line_end;
- gchar *section_name;
-
- line_end = strchr (parser->line, '\n');
- if (line_end == NULL)
- line_end = parser->line + strlen (parser->line);
-
- if (line_end - parser->line <= 2 ||
- line_end[-1] != ']')
- {
- report_error (parser, "Invalid syntax for section header", GTK_ICON_THEME_FILE_PARSE_ERROR_INVALID_SYNTAX, error);
- parser_free (parser);
- return FALSE;
- }
-
- section_name = unescape_string (parser->line + 1, line_end - parser->line - 2);
-
- if (section_name == NULL)
- {
- report_error (parser, "Invalid escaping in section name", GTK_ICON_THEME_FILE_PARSE_ERROR_INVALID_ESCAPES, error);
- parser_free (parser);
- return FALSE;
- }
-
- open_section (parser, section_name);
-
- parser->line = (line_end) ? line_end + 1 : NULL;
- parser->line_nr++;
-
- g_free (section_name);
-
- return TRUE;
-}
-
-static gboolean
-parse_key_value (GtkIconThemeFileParser *parser, GError **error)
-{
- GtkIconThemeFileLine *line;
- gchar *line_end;
- gchar *key_start;
- gchar *key_end;
- gchar *key;
- gchar *locale_start = NULL;
- gchar *locale_end = NULL;
- gchar *value_start;
- gchar *value;
- gchar *p;
-
- line_end = strchr (parser->line, '\n');
- if (line_end == NULL)
- line_end = parser->line + strlen (parser->line);
-
- p = parser->line;
- key_start = p;
- while (p < line_end &&
- (valid[(guchar)*p] & VALID_KEY_CHAR))
- p++;
- key_end = p;
-
- if (key_start == key_end)
- {
- report_error (parser, "Empty key name", GTK_ICON_THEME_FILE_PARSE_ERROR_INVALID_SYNTAX, error);
- parser_free (parser);
- return FALSE;
- }
-
- if (p < line_end && *p == '[')
- {
- p++;
- locale_start = p;
- while (p < line_end && *p != ']')
- p++;
- locale_end = p;
-
- if (p == line_end)
- {
- report_error (parser, "Unterminated locale specification in key", GTK_ICON_THEME_FILE_PARSE_ERROR_INVALID_SYNTAX, error);
- parser_free (parser);
- return FALSE;
- }
-
- p++;
- }
-
- /* Skip space before '=' */
- while (p < line_end && *p == ' ')
- p++;
-
- if (p < line_end && *p != '=')
- {
- report_error (parser, "Invalid characters in key name", GTK_ICON_THEME_FILE_PARSE_ERROR_INVALID_CHARS, error);
- parser_free (parser);
- return FALSE;
- }
-
- if (p == line_end)
- {
- report_error (parser, "No '=' in key/value pair", GTK_ICON_THEME_FILE_PARSE_ERROR_INVALID_SYNTAX, error);
- parser_free (parser);
- return FALSE;
- }
-
- /* Skip the '=' */
- p++;
-
- /* Skip space after '=' */
- while (p < line_end && *p == ' ')
- p++;
-
- value_start = p;
-
- value = unescape_string (value_start, line_end - value_start);
- if (value == NULL)
- {
- report_error (parser, "Invalid escaping in value", GTK_ICON_THEME_FILE_PARSE_ERROR_INVALID_ESCAPES, error);
- parser_free (parser);
- return FALSE;
- }
-
- line = new_line (parser);
- key = g_strndup (key_start, key_end - key_start);
- line->key = g_quark_from_string (key);
- g_free (key);
- if (locale_start)
- line->locale = g_strndup (locale_start, locale_end - locale_start);
- line->value = value;
-
- parser->line = (line_end) ? line_end + 1 : NULL;
- parser->line_nr++;
-
- return TRUE;
-}
-
-
-static void
-report_error (GtkIconThemeFileParser *parser,
- char *message,
- GtkIconThemeFileParseError error_code,
- GError **error)
-{
- GtkIconThemeFileSection *section;
- const gchar *section_name = NULL;
-
- section = &parser->df->sections[parser->current_section];
-
- if (section->section_name)
- section_name = g_quark_to_string (section->section_name);
-
- if (error)
- {
- if (section_name)
- *error = g_error_new (GTK_ICON_THEME_FILE_PARSE_ERROR,
- error_code,
- "Error in section %s at line %d: %s", section_name, parser->line_nr, message);
- else
- *error = g_error_new (GTK_ICON_THEME_FILE_PARSE_ERROR,
- error_code,
- "Error at line %d: %s", parser->line_nr, message);
- }
-}
-
-
-GtkIconThemeFile *
-_gtk_icon_theme_file_new_from_string (char *data,
- GError **error)
-{
- GtkIconThemeFileParser parser;
-
- parser.df = g_new0 (GtkIconThemeFile, 1);
- parser.current_section = -1;
-
- parser.n_allocated_lines = 0;
- parser.n_allocated_sections = 0;
- parser.line_nr = 1;
-
- parser.line = data;
-
- /* Put any initial comments in a NULL segment */
- open_section (&parser, NULL);
-
- while (parser.line && *parser.line)
- {
- if (*parser.line == '[') {
- if (!parse_section_start (&parser, error))
- return NULL;
- } else if (is_blank_line (&parser) ||
- *parser.line == '#')
- parse_comment_or_blank (&parser);
- else
- {
- if (!parse_key_value (&parser, error))
- return NULL;
- }
- }
-
- return parser.df;
-}
-
-char *
-_gtk_icon_theme_file_to_string (GtkIconThemeFile *df)
-{
- GtkIconThemeFileSection *section;
- GtkIconThemeFileLine *line;
- GString *str;
- char *s;
- int i, j;
-
- str = g_string_sized_new (800);
-
- for (i = 0; i < df->n_sections; i ++)
- {
- section = &df->sections[i];
-
- if (section->section_name)
- {
- g_string_append_c (str, '[');
- s = escape_string (g_quark_to_string (section->section_name), FALSE);
- g_string_append (str, s);
- g_free (s);
- g_string_append (str, "]\n");
- }
-
- for (j = 0; j < section->n_lines; j++)
- {
- line = §ion->lines[j];
-
- if (line->key == 0)
- {
- g_string_append (str, line->value);
- g_string_append_c (str, '\n');
- }
- else
- {
- g_string_append (str, g_quark_to_string (line->key));
- if (line->locale)
- {
- g_string_append_c (str, '[');
- g_string_append (str, line->locale);
- g_string_append_c (str, ']');
- }
- g_string_append_c (str, '=');
- s = escape_string (line->value, TRUE);
- g_string_append (str, s);
- g_free (s);
- g_string_append_c (str, '\n');
- }
- }
- }
-
- return g_string_free (str, FALSE);
-}
-
-static GtkIconThemeFileSection *
-lookup_section (GtkIconThemeFile *df,
- const char *section_name)
-{
- GtkIconThemeFileSection *section;
- GQuark section_quark;
- int i;
-
- section_quark = g_quark_try_string (section_name);
- if (section_quark == 0)
- return NULL;
-
- for (i = 0; i < df->n_sections; i ++)
- {
- section = &df->sections[i];
-
- if (section->section_name == section_quark)
- return section;
- }
- return NULL;
-}
-
-static GtkIconThemeFileLine *
-lookup_line (GtkIconThemeFile *df,
- GtkIconThemeFileSection *section,
- const char *keyname,
- const char *locale)
-{
- GtkIconThemeFileLine *line;
- GQuark key_quark;
- int i;
-
- key_quark = g_quark_try_string (keyname);
- if (key_quark == 0)
- return NULL;
-
- for (i = 0; i < section->n_lines; i++)
- {
- line = §ion->lines[i];
-
- if (line->key == key_quark &&
- ((locale == NULL && line->locale == NULL) ||
- (locale != NULL && line->locale != NULL && strcmp (locale, line->locale) == 0)))
- return line;
- }
-
- return NULL;
-}
-
-gboolean
-_gtk_icon_theme_file_get_raw (GtkIconThemeFile *df,
- const char *section_name,
- const char *keyname,
- const char *locale,
- char **val)
-{
- GtkIconThemeFileSection *section;
- GtkIconThemeFileLine *line;
-
- *val = NULL;
-
- section = lookup_section (df, section_name);
- if (!section)
- return FALSE;
-
- line = lookup_line (df,
- section,
- keyname,
- locale);
-
- if (!line)
- return FALSE;
-
- *val = g_strdup (line->value);
-
- return TRUE;
-}
-
-
-void
-_gtk_icon_theme_file_foreach_section (GtkIconThemeFile *df,
- GtkIconThemeFileSectionFunc func,
- gpointer user_data)
-{
- GtkIconThemeFileSection *section;
- int i;
-
- for (i = 0; i < df->n_sections; i ++)
- {
- section = &df->sections[i];
-
- (*func) (df, g_quark_to_string (section->section_name), user_data);
- }
- return;
-}
-
-void
-_gtk_icon_theme_file_foreach_key (GtkIconThemeFile *df,
- const char *section_name,
- gboolean include_localized,
- GtkIconThemeFileLineFunc func,
- gpointer user_data)
-{
- GtkIconThemeFileSection *section;
- GtkIconThemeFileLine *line;
- int i;
-
- section = lookup_section (df, section_name);
- if (!section)
- return;
-
- for (i = 0; i < section->n_lines; i++)
- {
- line = §ion->lines[i];
-
- (*func) (df, g_quark_to_string (line->key), line->locale, line->value, user_data);
- }
-
- return;
-}
-
-
-static void
-calculate_locale (GtkIconThemeFile *df)
-{
- char *p, *lang;
-
-#ifdef HAVE_LC_MESSAGES
- lang = g_strdup (setlocale (LC_MESSAGES, NULL));
-#else
- lang = g_strdup (setlocale (LC_CTYPE, NULL));
-#endif
-
- if (lang)
- {
- p = strchr (lang, '.');
- if (p)
- *p = '\0';
- p = strchr (lang, '@');
- if (p)
- *p = '\0';
- }
- else
- lang = g_strdup ("C");
-
- p = strchr (lang, '_');
- if (p)
- {
- df->current_locale[0] = g_strdup (lang);
- *p = '\0';
- df->current_locale[1] = lang;
- }
- else
- {
- df->current_locale[0] = lang;
- df->current_locale[1] = NULL;
- }
-}
-
-gboolean
-_gtk_icon_theme_file_get_locale_string (GtkIconThemeFile *df,
- const char *section,
- const char *keyname,
- char **val)
-{
- gboolean res;
-
- if (df->current_locale[0] == NULL)
- calculate_locale (df);
-
- if (df->current_locale[0] != NULL)
- {
- res = _gtk_icon_theme_file_get_raw (df,section, keyname,
- df->current_locale[0], val);
- if (res)
- return TRUE;
- }
-
- if (df->current_locale[1] != NULL)
- {
- res = _gtk_icon_theme_file_get_raw (df,section, keyname,
- df->current_locale[1], val);
- if (res)
- return TRUE;
- }
-
- return _gtk_icon_theme_file_get_raw (df, section, keyname, NULL, val);
-}
-
-gboolean
-_gtk_icon_theme_file_get_string (GtkIconThemeFile *df,
- const char *section,
- const char *keyname,
- char **val)
-{
- return _gtk_icon_theme_file_get_raw (df, section, keyname, NULL, val);
-}
-
-gboolean
-_gtk_icon_theme_file_get_integer (GtkIconThemeFile *df,
- const char *section,
- const char *keyname,
- int *val)
-{
- gboolean res;
- char *str;
-
- *val = 0;
-
- res = _gtk_icon_theme_file_get_raw (df, section, keyname, NULL, &str);
- if (!res)
- return FALSE;
-
-
- *val = atoi (str);
- g_free (str);
-
- return TRUE;
-
-}
-