/* * utils.c - misc. utility functions for Lodju */ #include #include "lodju.h" gint compare_basenames(gconstpointer a, gconstpointer b) { return strcmp(g_basename(a), g_basename(b)); } static gboolean is_image(const gchar *filename) { static const gchar *suffixes[] = { ".jpg", ".JPG", ".jpeg", ".JPEG", ".png", ".PNG", }; static const gint num_suffixes = sizeof(suffixes) / sizeof(suffixes[0]); gint i; size_t namelen; size_t suffixlen; namelen = strlen(filename); for (i = 0; i < num_suffixes; ++i) { suffixlen = strlen(suffixes[i]); if (namelen <= suffixlen) continue; if (strcmp(filename + namelen - suffixlen, suffixes[i]) == 0) return TRUE; } return FALSE; } GList *find_images(const gchar *filename) { DIR *dir; GList *list; gchar *fullname; struct dirent *ent; list = NULL; dir = opendir(filename); if (dir != NULL) { while ((ent = readdir(dir)) != NULL) { fullname = g_strdup_printf("%s/%s", filename, ent->d_name); if (is_image(fullname)) list = g_list_prepend(list, fullname); else g_free(fullname); } closedir(dir); } else if (is_image(filename)) list = g_list_prepend(list, g_strdup(filename)); list = g_list_sort(list, compare_basenames); return list; } #ifndef LODJU_LOCALE_DIR #define LODJU_LOCALE_DIR "." #endif #ifndef LODJU_TEXTDOMAIN #define LODJU_TEXTDOMAIN "lodju" #endif #ifndef LODJU_GLADE #define LODJU_GLADE "lodju.glade" #endif void gettext_init(void) { #if HAVE_LIBINTL_H if (setlocale(LC_ALL, "") == NULL) { g_warning("Lodju: Couldn't set locale."); } if (bindtextdomain(LODJU_TEXTDOMAIN, LODJU_LOCALE_DIR) == NULL) { g_warning("Lodju: Couldn't set message catalog directory"); } else { if (textdomain(LODJU_TEXTDOMAIN) == NULL) { g_warning("Lodju: Couldn't set message domain, using defaults."); } } #endif } static gboolean file_exists(const gchar *filename) { FILE *f; f = fopen(filename, "r"); if (f == NULL) return FALSE; (void) fclose(f); return TRUE; } GladeXML *load_user_interface(const gchar *root_widget) { GladeXML *xml; static const gchar *glade_names[] = { LODJU_GLADE }; static const gint num_names = sizeof(glade_names) / sizeof(glade_names[0]); int i; for (i = 0; i < num_names; ++i) { if (file_exists(glade_names[i])) break; } if (i == num_names) goto error; xml = glade_xml_new(glade_names[i], root_widget); if (i == num_names || xml == NULL) goto error; glade_xml_signal_autoconnect(xml); return xml; error: g_warning(_("Lodju: Couldn't load user interface.")); return NULL; } /*********************************************************************** * XML parsing utilities. */ gchar *node_get_content(xmlNodePtr node) { gchar *str; size_t len; size_t pos; xmlNodePtr child; len = 0; for (child = node->childs; child != NULL; child = child->next) { if (strcmp(child->name, "text") == 0) len += strlen(child->content); } str = g_malloc(len + 1); *str = '\0'; pos = 0; for (child = node->childs; child != NULL; child = child->next) { if (strcmp(child->name, "text") == 0) { strcpy(str + pos, child->content); pos += strlen(child->content); } } return str; } gchar *node_get_attribute(xmlNodePtr node, const gchar *name) { return xmlGetProp(node, name); } /*********************************************************************** * Unit testing. */ static void setup(void) { } static void teardown(void) { } gint utils_unit_test(void) { TEST("compare_basenames", { ASSERT(compare_basenames("aaa", "aaa") == 0); ASSERT(compare_basenames("aaa", "bbb") < 0); ASSERT(compare_basenames("bbb", "aaa") > 0); ASSERT(compare_basenames("foo/aaa", "bar/aaa") == 0); ASSERT(compare_basenames("foo/aaa", "bar/bbb") < 0); ASSERT(compare_basenames("foo/bbb", "foo/aaa") > 0); }); TEST("load_user_interface", { ASSERT(load_user_interface("lodju_window") != NULL); }); return 0; }