From 56a85b65575a1b0311d94860e5d8560f46c4a65b Mon Sep 17 00:00:00 2001 From: Jesse van den Kieboom Date: Tue, 15 Nov 2005 12:02:38 +0000 Subject: [PATCH] Moved string functions to gm-string, improved file reading --- gnoemoe/gm-support.c | 551 ++++++++++++++++++++----------------------- gnoemoe/gm-support.h | 18 +- 2 files changed, 268 insertions(+), 301 deletions(-) diff --git a/gnoemoe/gm-support.c b/gnoemoe/gm-support.c index 1a7f3b1..1589490 100644 --- a/gnoemoe/gm-support.c +++ b/gnoemoe/gm-support.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include @@ -43,16 +45,16 @@ gm_fix_decimal_point(gchar *line, int len) { gchar * gm_fix_decimal_point_rev(gchar *line, int len) { - int i; - struct lconv *l = localeconv(); + int i; + struct lconv *l = localeconv(); - for (i = 0; i < len; i++) { - if (line[i] == l->decimal_point[0]) { - line[i] = '.'; - } - } + for (i = 0; i < len; i++) { + if (line[i] == l->decimal_point[0]) { + line[i] = '.'; + } + } - return line; + return line; } gchar * @@ -76,133 +78,104 @@ gm_ansi_strip(gchar * s) { } int -garray_length(gchar **s) { - int i = 0; - - while (s[i] != NULL) { - i++; - } - - return i; +gm_garray_length(gchar **s) { + gchar **iter = s; + + while (*iter++ != NULL) + ; + + return *iter - *s - 1; } -void g_list_free_simple(GList *s) { - GList *tmp; +void gm_g_list_free_simple(GList *s) { + GList *tmp; - for (tmp = s; tmp; tmp = tmp->next) { - g_free(tmp->data); - } + for (tmp = s; tmp; tmp = tmp->next) { + g_free(tmp->data); + } - g_list_free(s); + g_list_free(s); } gchar * -g_list_find_simple(GList *s, gchar *f) { - GList *tmp; +gm_g_list_find_simple(GList *s, gchar *f) { + GList *tmp; - for (tmp = s; tmp; tmp = tmp->next) { - if (strcmp(tmp->data, f) == 0) { - return tmp->data; - } - } + for (tmp = s; tmp; tmp = tmp->next) { + if (strcmp(tmp->data, f) == 0) { + return tmp->data; + } + } - return NULL; + return NULL; } void gm_dialog(gchar * message, GtkMessageType messagebox_type, GtkWindow * parent) { - GtkWidget *dlg; + GtkWidget *dlg; - if (parent == NULL) { - //parent = GTK_WINDOW(if_main_get_widget("wndMain")); - } + if (parent == NULL) { + //parent = GTK_WINDOW(if_main_get_widget("wndMain")); + } - dlg = - gtk_message_dialog_new(parent, - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - messagebox_type, GTK_BUTTONS_OK, message, NULL); - gtk_dialog_run(GTK_DIALOG(dlg)); - gtk_widget_destroy(dlg); + dlg = gtk_message_dialog_new(parent, + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + messagebox_type, GTK_BUTTONS_OK, message, NULL); + gtk_dialog_run(GTK_DIALOG(dlg)); + gtk_widget_destroy(dlg); } void gm_error_dialog(gchar * message, GtkWindow * parent) { - gm_dialog(message, GTK_MESSAGE_ERROR, parent); + gm_dialog(message, GTK_MESSAGE_ERROR, parent); } void gm_warning_dialog(gchar * message, GtkWindow * parent) { - gm_dialog(message, GTK_MESSAGE_WARNING, parent); + gm_dialog(message, GTK_MESSAGE_WARNING, parent); } void gm_info_dialog(gchar * message, GtkWindow * parent) { - gm_dialog(message, GTK_MESSAGE_INFO, parent); + gm_dialog(message, GTK_MESSAGE_INFO, parent); } void gm_question_dialog(gchar * message, GtkWindow * parent) { - gm_dialog(message, GTK_MESSAGE_QUESTION, parent); + gm_dialog(message, GTK_MESSAGE_QUESTION, parent); } void gm_do_events() { - while (gtk_events_pending()) { - gtk_main_iteration(); - } -} - -gchar * -gm_str_escape(gchar * line) { - gchar *newLine; - int i, j = 0; - - if (strlen(line) == 0) { - return g_strdup(""); - } - - if (strstr(line, "\"") || strstr(line, "\\")) { - newLine = g_new(gchar, (strlen(line) * 2) + 1); - - for (i = 0; i < (int)strlen(line); i++) { - if (line[i] == '"' || line[i] == '\\') { - newLine[j] = '\\'; - j++; - } - newLine[j] = line[i]; - j++; - } - - newLine[j] = '\0'; - return newLine; - } else { - return g_strdup(line); - } + while (gtk_events_pending()) { + gtk_main_iteration(); + } } void gm_directory_remove_all(const gchar * path, gboolean remove_self) { - GDir *cDir; - gchar *name; - gchar *newPath; + GDir *cDir; + gchar *name; + gchar *newPath; - if (g_file_test(path, G_FILE_TEST_IS_DIR)) { - // Iterate through the files and do the right thingie - if ((cDir = g_dir_open(path, 0, NULL))) { - while ((name = (gchar *) (g_dir_read_name(cDir))) != NULL) { - newPath = g_strconcat(path, "/", name, NULL); - gm_directory_remove_all(newPath, TRUE); - g_free(newPath); - } - g_dir_close(cDir); - } - } + if (g_file_test(path, G_FILE_TEST_IS_DIR)) { + // Iterate through the files and do the right thingie + if ((cDir = g_dir_open(path, 0, NULL))) { + while ((name = (gchar *) (g_dir_read_name(cDir))) != NULL) { + newPath = g_strconcat(path, "/", name, NULL); + gm_directory_remove_all(newPath, TRUE); + g_free(newPath); + } + + g_dir_close(cDir); + } + } - if (remove_self) { - // Its a file, or just empty! MUST...BE...REMOVEEEED! - remove(path); - } + if (remove_self) { + // Its a file, or just empty! MUST...BE...REMOVEEEED! + remove(path); + } } gint @@ -245,24 +218,24 @@ gm_url_regex_match(const gchar *msg, int len, GArray *start, GArray *end) { } void -gm_open_url (const gchar *url) { - if (!url || strlen (url) == 0) { +gm_open_url(const gchar *url) { + if (url == NULL || *url == '\0') { return; } /* gnome_url_show doesn't work when there's no protocol, so we might * need to add one. */ - if (strstr (url, "://") == NULL) { + if (strstr(url, "://") == NULL) { gchar *tmp; - tmp = g_strconcat ("http://", url, NULL); + tmp = g_strconcat("http://", url, NULL); gnome_url_show(tmp, NULL); - g_free (tmp); + g_free(tmp); return; } - gnome_url_show (url, NULL); + gnome_url_show(url, NULL); } void @@ -310,8 +283,8 @@ gint gm_fetch_progress(GnomeVFSAsyncHandle *handle, GnomeVFSXferProgressInfo *info, GmFetchHandle *g) { - gchar *name; - const gchar *err; + gchar *name; + gchar const *err; g->cur_phase = info->phase; g->cur_file = info->file_index; @@ -320,190 +293,196 @@ gm_fetch_progress(GnomeVFSAsyncHandle *handle, g->file_size = info->file_size; g->bytes_copied = info->bytes_copied; g->total_bytes_copied = info->total_bytes_copied; - g->status = info->status; + g->status = info->status; - if (g->aborted) { - g->cb(g, g->user_data); - gm_fetch_handle_free(g); - return FALSE; - } + if (g->aborted) { + g->cb(g, g->user_data); + gm_fetch_handle_free(g); + return FALSE; + } - if (info->target_name != NULL) { - if (g->cur_file_name && strcmp(g->cur_file_name, info->target_name) != 0) { - g->cur_phase = GNOME_VFS_XFER_PHASE_FILECOMPLETED; - g->cb(g, g->user_data); - g->cur_phase = info->phase; - - g_free(g->cur_file_name); - g->cur_file_name = NULL; - } + if (info->target_name != NULL) { + if (g->cur_file_name && strcmp(g->cur_file_name, info->target_name) != 0) { + g->cur_phase = GNOME_VFS_XFER_PHASE_FILECOMPLETED; + g->cb(g, g->user_data); + g->cur_phase = info->phase; - if (!g->cur_file_name) { - g->cur_file_name = g_strdup(info->target_name); - } - } + g_free(g->cur_file_name); + g->cur_file_name = NULL; + } + + if (!g->cur_file_name) { + g->cur_file_name = g_strdup(info->target_name); + } + } - if (info->status == GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE) { - name = gnome_vfs_get_local_path_from_uri(info->target_name); - gm_debug_msg(DEBUG_DEFAULT, "gnoemoe_fetch_progress: asking for overwriting %s: yes", name); + if (info->status == GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE) { + name = gnome_vfs_get_local_path_from_uri(info->target_name); + gm_debug_msg(DEBUG_DEFAULT, "GmFetchProgress: asking for overwriting " + "%s: yes", name); - g->prev_status = GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE; - return GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE; - } else if (info->status == GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR) { - name = gnome_vfs_get_local_path_from_uri(info->target_name); - err = gnome_vfs_result_to_string(info->vfs_status); + g->prev_status = GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE; + return GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE; + } else if (info->status == GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR) { + name = gnome_vfs_get_local_path_from_uri(info->target_name); + err = gnome_vfs_result_to_string(info->vfs_status); - gdk_threads_enter(); - gm_debug_msg(DEBUG_DEFAULT, "gnoemoe_fetch_progress: error for %s: %s", name, err); - g->cb(g, g->user_data); - gdk_threads_leave(); + gdk_threads_enter(); + gm_debug_msg(DEBUG_DEFAULT, "GmFetchProgress: error for %s: %s", name, + err); + g->cb(g, g->user_data); + gdk_threads_leave(); - g_free(g->cur_file_name); - g->cur_file_name = NULL; + g_free(g->cur_file_name); + g->cur_file_name = NULL; - g->prev_status = GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR; - g_free(name); + g->prev_status = GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR; + g_free(name); - return GNOME_VFS_XFER_ERROR_ACTION_SKIP; - } + return GNOME_VFS_XFER_ERROR_ACTION_SKIP; + } - if (info->phase == GNOME_VFS_XFER_PHASE_COMPLETED) { - if (g->cur_file_name != NULL) { - g->cur_phase = GNOME_VFS_XFER_PHASE_FILECOMPLETED; - g->cb(g, g->user_data); - g->cur_phase = info->phase; - } + if (info->phase == GNOME_VFS_XFER_PHASE_COMPLETED) { + if (g->cur_file_name != NULL) { + g->cur_phase = GNOME_VFS_XFER_PHASE_FILECOMPLETED; + g->cb(g, g->user_data); + g->cur_phase = info->phase; + } - g->done = TRUE; - g->cb(g, g->user_data); - gm_fetch_handle_free(g); - return TRUE; - } + g->done = TRUE; + g->cb(g, g->user_data); + gm_fetch_handle_free(g); + + return TRUE; + } - g->prev_status = info->status; + g->prev_status = info->status; - return TRUE; + return TRUE; } gint gm_fetch_interact(GnomeVFSXferProgressInfo *info, gpointer user_data) { - return 1; + return 1; } GmFetchHandle * gm_fetch(const GList *source, const GList *dest, GFunc cb, gpointer user_data) { - GmFetchHandle *g = gm_fetch_handle_create(cb, user_data); - gchar *uri; - - for (; source; source = source->next) { - uri = (gchar *)(source->data); - g->source_uri = g_list_append(g->source_uri, gnome_vfs_uri_new(uri)); - } - - for (; dest; dest = dest->next) { - uri = (gchar *)(dest->data); - g->dest_uri = g_list_append(g->dest_uri, gnome_vfs_uri_new(uri)); - } - - gnome_vfs_async_xfer(&(g->handle), g->source_uri, g->dest_uri, - GNOME_VFS_XFER_DEFAULT|GNOME_VFS_XFER_RECURSIVE, - GNOME_VFS_XFER_ERROR_MODE_QUERY, - GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE, - GNOME_VFS_PRIORITY_DEFAULT, - (GnomeVFSAsyncXferProgressCallback)gm_fetch_progress, - g, gm_fetch_interact, g); - return g; + GmFetchHandle *g = gm_fetch_handle_create(cb, user_data); + gchar *uri; + GnomeVFSResult ret; + + for (; source; source = source->next) { + uri = (gchar *)(source->data); + g->source_uri = g_list_append(g->source_uri, gnome_vfs_uri_new(uri)); + } + + for (; dest; dest = dest->next) { + uri = (gchar *)(dest->data); + g->dest_uri = g_list_append(g->dest_uri, gnome_vfs_uri_new(uri)); + } + + ret = gnome_vfs_async_xfer(&(g->handle), g->source_uri, g->dest_uri, + GNOME_VFS_XFER_DEFAULT|GNOME_VFS_XFER_RECURSIVE, + GNOME_VFS_XFER_ERROR_MODE_QUERY, + GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE, + GNOME_VFS_PRIORITY_DEFAULT, + (GnomeVFSAsyncXferProgressCallback)gm_fetch_progress, + g, gm_fetch_interact, g); + + return g; } gboolean gm_is_end_scrolled(GtkScrolledWindow *wnd, guint charHeight) { - GtkAdjustment *ad = gtk_scrolled_window_get_vadjustment(wnd); - - return ((ad->page_size + ad->value) >= ad->upper - (double)charHeight); + GtkAdjustment *ad = gtk_scrolled_window_get_vadjustment(wnd); + + return ((ad->page_size + ad->value) >= ad->upper - (double)charHeight); } void gm_scroll_end(GtkTextView *view, gboolean needs) { - GtkTextBuffer *buf; - GtkTextMark *mark; - GtkTextIter iter; - - if (!needs) { - return; - } - - buf = gtk_text_view_get_buffer(view); - mark = gtk_text_buffer_get_mark(buf, "end-of-buffer"); - - if (mark == NULL) { - gtk_text_buffer_get_end_iter(buf, &iter); - mark = gtk_text_buffer_create_mark(buf, "end-of-buffer", &iter, FALSE); - } - - gtk_text_view_scroll_to_mark(view, mark, 0.0, TRUE, 1.0, 1.0); + GtkTextBuffer *buf; + GtkTextMark *mark; + GtkTextIter iter; + + if (!needs) { + return; + } + + buf = gtk_text_view_get_buffer(view); + mark = gtk_text_buffer_get_mark(buf, "end-of-buffer"); + + if (mark == NULL) { + gtk_text_buffer_get_end_iter(buf, &iter); + mark = gtk_text_buffer_create_mark(buf, "end-of-buffer", &iter, FALSE); + } + + gtk_text_view_scroll_to_mark(view, mark, 0.0, TRUE, 1.0, 1.0); } #define MAX_BUF 1024 -GString * -gm_read_file(const gchar *fname, gboolean readall, OpenLogProgress func, gpointer user_data) { - FILE *f; - gchar line[MAX_BUF], *tmp; - GString *str = NULL; - long bytes_read = 0, bytes_total = 0; +gchar * +gm_read_file(const gchar *fname) { + int fd; + gchar *tmp, *mapped; + long bytes_total = 0; - if (!fname) { - return NULL; - } + if (!fname) { + return NULL; + } - f = fopen(fname, "r"); + fd = open(fname, O_RDONLY); - if (f) { - fseek(f, 0, SEEK_END); - bytes_total = ftell(f); - rewind(f); - - str = g_string_new(""); + if (fd == -1) { + gm_debug_msg(DEBUG_DEFAULT, "GmReadFile: file (%s) could not be read: " + "%s", fname, strerror(errno)); + return NULL; + } + + bytes_total = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + + if (bytes_total == (off_t)-1) { + close(fd); + return NULL; + } + + mapped = mmap(0, bytes_total, PROT_READ, MAP_PRIVATE, fd, 0); + + if (mapped == MAP_FAILED) { + close(fd); - while (fgets((char *) &line, MAX_BUF, f) != NULL) { - bytes_read += strlen((char *)&line); - tmp = NULL; - if (g_utf8_validate(line, -1, NULL)) { - if (readall) { - str = g_string_append(str, line); - } - tmp = g_strdup(line); - } else { - tmp = g_locale_to_utf8(line, -1, NULL, NULL, NULL); - - if (!tmp) { - tmp = g_convert(line, -1, "UTF-8", "ISO-8859-15", NULL, NULL, NULL); - } - if (!tmp) { - tmp = g_convert(line, -1, "UTF-8", "ISO-8859-15", NULL, NULL, NULL); - } - - if (readall) { - str = g_string_append(str, tmp); - } - } - - if (func != NULL) { - func(bytes_read, bytes_total, tmp, user_data); - } else { - g_free(tmp); - } - } - - fclose(f); - - return str; - } else { - gm_debug_msg(DEBUG_DEFAULT, "support_read_file: file (%s) could not be read: %s", - fname, strerror(errno)); - return NULL; - } + gm_debug_msg(DEBUG_DEFAULT, "GmReadFile: error while mapping file: %s", + strerror(errno)); + return NULL; + } + + if (g_utf8_validate(mapped, bytes_total, NULL)) { + // Easy, this is utf8! + tmp = g_strndup(mapped, bytes_total); + } else { + // Try locale + tmp = g_locale_to_utf8(mapped, bytes_total, NULL, NULL, NULL); + + if (!tmp) { + // Now we're getting desperate... try ISO-8859-15 + tmp = g_convert(mapped, bytes_total, "UTF-8", "ISO-8859-15", NULL, + NULL, NULL); + } + + if (!tmp) { + // OMG try one last conversion to ISO-8859-1 + tmp = g_convert(mapped, bytes_total, "UTF-8", "ISO-8859-1", NULL, + NULL, NULL); + } + } + + munmap(mapped, bytes_total); + close(fd); + return tmp; } GtkWidget * @@ -551,21 +530,24 @@ gm_create_tab_label(const gchar *icon, const gchar *caption, gboolean has_exit, void gm_widget_destroy_data(GtkWidget *caller, GtkWidget *destroyer) { - if (GTK_IS_WIDGET(destroyer)) { - gtk_widget_destroy(destroyer); - } + if (GTK_IS_WIDGET(destroyer)) { + gtk_widget_destroy(destroyer); + } } const gchar * gm_default_charset() { - const gchar *loc = NULL; - g_get_charset(&loc); - - if (loc == NULL || strlen(loc) == 0) { - loc = "ISO-8859-15"; - } + static const gchar *loc = NULL; + + if (loc == NULL) { + g_get_charset(&loc); + } - return loc; + if (loc == NULL || *loc == 0) { + loc = "ISO-8859-15"; + } + + return loc; } void @@ -584,39 +566,6 @@ gm_notebook_focus_from_label(GtkNotebook *note, gchar *caption) { } } -void -gm_string_skip_space(gchar **ptr) { - while (**ptr != '\0' && g_unichar_isspace(g_utf8_get_char(*ptr))) { - *ptr = g_utf8_next_char(*ptr); - } -} - -void -gm_string_skip_nonspace(gchar **ptr) { - while (**ptr != '\0' && !g_unichar_isspace(g_utf8_get_char(*ptr))) { - *ptr = g_utf8_next_char(*ptr); - } -} - -void -gm_string_skip_till(gchar **ptr, gchar const *find) { - gchar const *fptr; - gunichar check; - - while (**ptr != '\0') { - check = g_utf8_get_char(*ptr); - - for (fptr = find; *fptr; ++fptr) { - // CHECK: find should also be treated as utf8! - if (check == (gunichar)(*fptr)) { - return; - } - } - - *ptr = g_utf8_next_char(*ptr); - } -} - gchar * gm_to_utf8_with_fallback(gchar const *text, gssize len, gchar const *from, gchar const *fallback) { @@ -645,3 +594,25 @@ gm_to_utf8_with_fallback(gchar const *text, gssize len, gchar const *from, g_string_free(str, FALSE); return res; } + +GtkWidget * +gm_container_item(GtkContainer *cnt, GType type) { + GList *child_first = gtk_container_get_children(cnt); + GList *child; + GtkWidget *result = NULL; + + for (child = child_first; child; child = child->next) { + if (G_TYPE_CHECK_INSTANCE_TYPE(child->data, type)) { + result = GTK_WIDGET(child->data); + break; + } else if (GTK_IS_CONTAINER(child->data)) { + if ((result = gm_container_item( + GTK_CONTAINER(child->data), type))) { + break; + } + } + } + + g_list_free(child_first); + return result; +} diff --git a/gnoemoe/gm-support.h b/gnoemoe/gm-support.h index ba7fb24..628fcca 100644 --- a/gnoemoe/gm-support.h +++ b/gnoemoe/gm-support.h @@ -114,8 +114,8 @@ gchar *gm_fix_decimal_point(gchar *line, int len); gchar *gm_fix_decimal_point_rev(gchar *line, int len); gchar *gm_ansi_strip(gchar * s); int garray_length(gchar **s); -void g_list_free_simple(GList *s); -gchar *g_list_find_simple(GList *s, gchar *f); +void gm_g_list_free_simple(GList *s); +gchar *gm_g_list_find_simple(GList *s, gchar *f); void gm_error_dialog(gchar * message, GtkWindow * parent); void gm_warning_dialog(gchar * message, GtkWindow * parent); @@ -124,11 +124,10 @@ void gm_question_dialog(gchar * message, GtkWindow * parent); void gm_do_events(); -gchar *gm_str_escape(gchar * line); void gm_directory_remove_all(const gchar * path, gboolean remove_self); gint gm_url_regex_match(const gchar *msg, int len, GArray *start, GArray *end); -void gm_open_url (const gchar *url); +void gm_open_url(const gchar *url); GmFetchHandle * gm_fetch(const GList *source, const GList *dest, GFunc cb, gpointer user_data); @@ -137,20 +136,17 @@ void gm_fetch_handle_free(GmFetchHandle *g); gboolean gm_is_end_scrolled(GtkScrolledWindow *wnd, guint charHeight); void gm_scroll_end(GtkTextView *view, gboolean needs); -typedef void (*OpenLogProgress) (long, long, gchar *, gpointer); -GString *gm_read_file(const gchar *fname, gboolean readall, - OpenLogProgress func, gpointer user_data); +typedef gboolean (*ReadProgressFunc) (long, long, gchar *, gpointer); + +gchar *gm_read_file(gchar const *fname); GtkWidget *gm_create_tab_label(const gchar *icon, const gchar *caption, gboolean has_exit, GmLabelInfo *info); void gm_widget_destroy_data(GtkWidget *caller, GtkWidget *destroyer); const gchar *gm_default_charset(); void gm_notebook_focus_from_label(GtkNotebook *note, gchar *caption); -void gm_string_skip_space(gchar **ptr); -void gm_string_skip_nonspace(gchar **ptr); -void gm_string_skip_till(gchar **ptr, gchar const *find); - gchar *gm_to_utf8_with_fallback(gchar const *text, gssize len, gchar const *from, gchar const *fallback); +GtkWidget *gm_container_item(GtkContainer *cnt, GType type); #endif /* __GM_SUPPORT_H__ */