Moved string functions to gm-string, improved file reading

This commit is contained in:
Jesse van den Kieboom 2005-11-15 12:02:38 +00:00
parent 5f77eaba58
commit 56a85b6557
2 changed files with 268 additions and 301 deletions

View File

@ -8,6 +8,8 @@
#include <string.h>
#include <stdio.h>
#include <locale.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <gtk/gtk.h>
#include <regex.h>
@ -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;
}

View File

@ -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__ */