/dev/tomkiewicz/new-smileys: 2979d2a75df8: PidginSmileyTheme: in...
Tomasz Wasilczyk
twasilczyk at pidgin.im
Mon Mar 31 15:50:26 EDT 2014
Changeset: 2979d2a75df81c0214f195ad5833438a9a27e321
Author: Tomasz Wasilczyk <twasilczyk at pidgin.im>
Date: 2014-03-31 21:50 +0200
Branch: default
URL: https://hg.pidgin.im/dev/tomkiewicz/new-smileys/rev/2979d2a75df8
Description:
PidginSmileyTheme: index file parsing
diffstat:
pidgin/gtksmiley-theme.c | 241 ++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 236 insertions(+), 5 deletions(-)
diffs (299 lines):
diff --git a/pidgin/gtksmiley-theme.c b/pidgin/gtksmiley-theme.c
--- a/pidgin/gtksmiley-theme.c
+++ b/pidgin/gtksmiley-theme.c
@@ -21,6 +21,9 @@
#include "gtksmiley-theme.h"
+#include "internal.h"
+#include "glibcompat.h"
+
#include "debug.h"
#include <glib/gstdio.h>
@@ -29,11 +32,17 @@
(G_TYPE_INSTANCE_GET_PRIVATE((obj), PIDGIN_TYPE_SMILEY_THEME, \
PidginSmileyThemePrivate))
-#define PIDGIN_SMILEY_THEME_MAX_INDEX_SIZE 102400
+#define PIDGIN_SMILEY_THEME_MAX_LINES 1024
+#define PIDGIN_SMILEY_THEME_MAX_TOKENS 1024
typedef struct
{
gchar *path;
+
+ gchar *name;
+ gchar *desc;
+ gchar *icon;
+ gchar *author;
} PidginSmileyThemePrivate;
static GObjectClass *parent_class;
@@ -41,6 +50,208 @@ static GObjectClass *parent_class;
static gchar **probe_dirs;
static GList *smiley_themes = NULL;
+typedef struct
+{
+ gchar *name;
+ gchar *desc;
+ gchar *icon;
+ gchar *author;
+
+ GList *protocols;
+} PidginSmileyThemeIndex;
+
+typedef struct
+{
+ gchar *name;
+ GList *smileys;
+} PidginSmileyThemeIndexProtocol;
+
+typedef struct
+{
+ gchar *file;
+ gboolean hidden;
+ GList *shortcuts;
+} PidginSmileyThemeIndexSmiley;
+
+/*******************************************************************************
+ * Theme index parsing
+ ******************************************************************************/
+
+static void
+pidgin_smiley_theme_index_free(PidginSmileyThemeIndex *index)
+{
+ GList *it, *it2;
+
+ g_return_if_fail(index != NULL);
+
+ g_free(index->name);
+ g_free(index->desc);
+ g_free(index->icon);
+ g_free(index->author);
+
+ for (it = index->protocols; it; it = g_list_next(it)) {
+ PidginSmileyThemeIndexProtocol *proto = it->data;
+
+ g_free(proto->name);
+ for (it2 = proto->smileys; it2; it2 = g_list_next(it2)) {
+ PidginSmileyThemeIndexSmiley *smiley = it2->data;
+
+ g_free(smiley->file);
+ g_list_free_full(smiley->shortcuts, g_free);
+ g_free(smiley);
+ }
+ g_list_free(proto->smileys);
+ g_free(proto);
+ }
+ g_list_free(index->protocols);
+}
+
+static PidginSmileyThemeIndex *
+pidgin_smiley_theme_index_parse(const gchar *index_path, gboolean load_contents)
+{
+ PidginSmileyThemeIndex *index;
+ PidginSmileyThemeIndexProtocol *proto = NULL;
+ FILE *file;
+ int line_no = 0;
+ gboolean inv_frm = FALSE;
+
+ file = g_fopen(index_path, "r");
+ if (!file) {
+ purple_debug_error("gtksmiley-theme",
+ "Failed to open index file %s", index_path);
+ return NULL;
+ }
+
+ index = g_new0(PidginSmileyThemeIndex, 1);
+
+ while (!feof(file)) {
+ PidginSmileyThemeIndexSmiley *smiley;
+ gchar buff[1024];
+ gchar *line, *eqchr;
+ gchar **split;
+ int i;
+
+ if (++line_no > PIDGIN_SMILEY_THEME_MAX_LINES) {
+ purple_debug_warning("gtksmiley-theme", "file too big");
+ break;
+ }
+
+ if (!fgets(buff, sizeof(buff), file))
+ break;
+
+ /* strip comments */
+ if (buff[0] == '#')
+ continue;
+
+ g_strstrip(buff);
+ if (buff[0] == '\0')
+ continue;
+
+ if (!g_utf8_validate(buff, -1, NULL)) {
+ purple_debug_error("gtksmiley-theme", "%s:%"
+ G_GSIZE_FORMAT " is invalid UTF-8",
+ index_path, line_no);
+ continue;
+ }
+
+ line = buff;
+
+ if (line[0] == '[') {
+ gchar *end;
+
+ if (!load_contents)
+ break;
+ line++;
+ end = strchr(line, ']');
+ if (!end) {
+ inv_frm = TRUE;
+ break;
+ }
+
+ proto = g_new0(PidginSmileyThemeIndexProtocol, 1);
+ proto->name = g_strndup(line, end - line);
+
+ index->protocols =
+ g_list_prepend(index->protocols, proto);
+
+ continue;
+ }
+
+ if ((eqchr = strchr(line, '='))) {
+ *eqchr = '\0';
+ if (g_ascii_strcasecmp(line, "name") == 0) {
+ g_free(index->name);
+ index->name = g_strdup(eqchr + 1);
+ g_strchug(index->name);
+ continue;
+ } else if (g_ascii_strcasecmp(line, "description") == 0) {
+ g_free(index->desc);
+ index->desc = g_strdup(eqchr + 1);
+ g_strchug(index->desc);
+ continue;
+ } else if (g_ascii_strcasecmp(line, "icon") == 0) {
+ g_free(index->icon);
+ index->icon = g_strdup(eqchr + 1);
+ g_strchug(index->icon);
+ continue;
+ } else if (g_ascii_strcasecmp(line, "author") == 0) {
+ g_free(index->author);
+ index->author = g_strdup(eqchr + 1);
+ g_strchug(index->author);
+ continue;
+ }
+ *eqchr = '=';
+ }
+
+ /* parsing section content */
+
+ if (proto == NULL) {
+ inv_frm = FALSE;
+ break;
+ }
+
+ smiley = g_new0(PidginSmileyThemeIndexSmiley, 1);
+ proto->smileys = g_list_prepend(proto->smileys, smiley);
+
+ smiley->hidden = FALSE;
+ if (line[0] == '!') {
+ smiley->hidden = TRUE;
+ line++;
+ }
+
+ split = g_strsplit_set(line, " \t",
+ PIDGIN_SMILEY_THEME_MAX_TOKENS);
+ for (i = 0; split[i]; i++) {
+ gchar *token = split[i];
+
+ if (token[0] == '\0')
+ continue;
+ if (i == PIDGIN_SMILEY_THEME_MAX_TOKENS - 1)
+ break;
+
+ if (!smiley->file) {
+ smiley->file = g_strdup(token);
+ continue;
+ }
+
+ smiley->shortcuts = g_list_prepend(smiley->shortcuts,
+ g_strdup(token));
+ }
+ g_strfreev(split);
+ }
+
+ fclose(file);
+
+ if (inv_frm) {
+ purple_debug_error("gtksmiley-theme", "%s:%" G_GSIZE_FORMAT
+ " invalid format", index_path, line_no);
+ pidgin_smiley_theme_index_free(index);
+ index = NULL;
+ }
+
+ return index;
+}
+
/*******************************************************************************
* Theme loading
******************************************************************************/
@@ -50,6 +261,7 @@ pidgin_smiley_theme_load(const gchar *th
{
PidginSmileyTheme *theme;
PidginSmileyThemePrivate *priv;
+ PidginSmileyThemeIndex *index;
GList *it;
gchar *index_path;
@@ -71,9 +283,29 @@ pidgin_smiley_theme_load(const gchar *th
priv->path = g_strdup(theme_path);
+ index = pidgin_smiley_theme_index_parse(index_path, FALSE);
+
g_free(index_path);
- purple_debug_fatal("tomo", "loading not implemented");
+ if (!index->name || index->name[0] == '\0') {
+ purple_debug_warning("gtksmiley-theme",
+ "incomplete theme %s", theme_path);
+ pidgin_smiley_theme_index_free(index);
+ g_object_unref(theme);
+ return;
+ }
+
+ priv->name = g_strdup(index->name);
+ if (index->desc && index->desc[0])
+ priv->desc = g_strdup(index->desc);
+ if (index->icon && index->icon[0])
+ priv->icon = g_strdup(index->icon);
+ if (index->author && index->author[0])
+ priv->author = g_strdup(index->author);
+
+ pidgin_smiley_theme_index_free(index);
+
+ smiley_themes = g_list_append(smiley_themes, theme);
}
static void
@@ -149,8 +381,7 @@ pidgin_smiley_theme_init(void)
if (!g_file_test(user_smileys_dir, G_FILE_TEST_IS_DIR))
g_mkdir(user_smileys_dir, S_IRUSR | S_IWUSR | S_IXUSR);
- //TODO: remove it
- pidgin_smiley_theme_probe();
+ /* TODO: load configured theme */
}
void
@@ -164,7 +395,7 @@ pidgin_smiley_theme_get_all(void)
{
pidgin_smiley_theme_probe();
- return NULL;
+ return smiley_themes;
}
/*******************************************************************************
More information about the Commits
mailing list