From 62ff8ef794ef6ed17ba34a311d8016050ddf506d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20Tr=C3=B6ger?= Date: Mon, 23 Jan 2006 17:05:29 +0000 Subject: [PATCH] fixed some bugs when opening files with non UTF-8 filenames git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@148 ea778897-0a13-0410-b9d1-a72fbfd435f5 --- src/callbacks.c | 11 +++++++---- src/document.c | 47 +++++++++++++++++++++++++++++------------------ src/filetypes.c | 15 +++++++++++++-- src/geany.h | 3 +-- src/keyfile.c | 11 ++++++++--- 5 files changed, 58 insertions(+), 29 deletions(-) diff --git a/src/callbacks.c b/src/callbacks.c index be10fcbdc..7048e3f92 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -2310,16 +2310,17 @@ on_comments_function_activate (GtkMenuItem *menuitem, if (doc_list[idx].file_type->id != GEANY_FILETYPES_JAVA && doc_list[idx].file_type->id != GEANY_FILETYPES_ALL) { - //cur_tag = utils_get_current_tag(idx, DOWN); line = utils_get_current_tag(idx, &cur_tag); + // utils_get_current_tag returns -1 on failure, so sci_get_position_from_line + // returns the current position, soit should be safe pos = sci_get_position_from_line(doc_list[idx].sci, line - 1); } - // if function name is unknown, do nothing + // if function name is unknown, set function name to "unknown" if (line == -1) { g_free(cur_tag); - return; + cur_tag = g_strdup(_("unknown")); } if (doc_list[idx].file_type->id == GEANY_FILETYPES_PASCAL) @@ -2487,7 +2488,9 @@ void on_recent_file_activate (GtkMenuItem *menuitem, gpointer user_data) { - document_open_file(-1, (gchar*) user_data, 0, FALSE); + gchar *locale_filename = g_locale_from_utf8((gchar*) user_data, -1, NULL, NULL, NULL); + document_open_file(-1, locale_filename, 0, FALSE); + g_free(locale_filename); } diff --git a/src/document.c b/src/document.c index 3a0a1adf8..95de2c667 100644 --- a/src/document.c +++ b/src/document.c @@ -366,11 +366,12 @@ void document_open_file(gint idx, const gchar *filename, gint pos, gboolean read gboolean reload = (idx == -1) ? FALSE : TRUE; struct stat st; gchar *enc = NULL; + gchar *utf8_filename = NULL; + GError *err = NULL; #if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) gint fd; void *map; #else - GError *err = NULL; gchar *map; #endif //struct timeval tv, tv1; @@ -383,8 +384,17 @@ void document_open_file(gint idx, const gchar *filename, gint pos, gboolean read } else { + // try to get the UTF-8 equivalent for the filename, fallback to filename if error + utf8_filename = g_locale_to_utf8(filename, -1, NULL, NULL, &err); + if (utf8_filename == NULL) + { + msgwin_status_add("Invalid filename (%s)", err->message); + utf8_filename = g_strdup(filename); + err = NULL; // set to NULL for further usage + } + // if file is already open, switch to it and go - idx = document_find_by_filename(filename); + idx = document_find_by_filename(utf8_filename); if (idx >= 0) { gtk_notebook_set_current_page(GTK_NOTEBOOK(app->notebook), @@ -402,19 +412,19 @@ void document_open_file(gint idx, const gchar *filename, gint pos, gboolean read #if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) if ((fd = open(filename, O_RDONLY)) < 0) { - msgwin_status_add(_("Could not open file %s (%s)"), filename, g_strerror(errno)); + msgwin_status_add(_("Could not open file %s (%s)"), utf8_filename, g_strerror(errno)); return; } if ((map = mmap (0, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { - msgwin_status_add(_("Could not open file %s (%s)"), filename, g_strerror(errno)); + msgwin_status_add(_("Could not open file %s (%s)"), utf8_filename, g_strerror(errno)); return; } size = (gint)st.st_size; #else // use GLib function to load file on Win32 systems and those w/o mmap() - if (! g_file_get_contents (filename, &map, NULL, &err) ){ - msgwin_status_add(_("Could not open file %s (%s)"), filename, err->message); + if (! g_file_get_contents(utf8_filename, &map, NULL, &err) ){ + msgwin_status_add(_("Could not open file %s (%s)"), utf8_filename, err->message); return; } size = (gint)strlen(map); @@ -451,15 +461,11 @@ void document_open_file(gint idx, const gchar *filename, gint pos, gboolean read } } - if (! reload) idx = document_create_new_sci(filename); + if (! reload) idx = document_create_new_sci(utf8_filename); // sets editor mode and add the text to the ScintillaObject sci_add_text_buffer(doc_list[idx].sci, map, size); editor_mode = utils_get_line_endings(map, size); - if (editor_mode == SC_EOL_CRLF) - { - geany_debug("%s: windows eol choosed", filename); - } sci_set_eol_mode(doc_list[idx].sci, editor_mode); sci_set_line_numbers(doc_list[idx].sci, TRUE, 0); @@ -467,12 +473,12 @@ void document_open_file(gint idx, const gchar *filename, gint pos, gboolean read sci_empty_undo_buffer(doc_list[idx].sci); doc_list[idx].mtime = time(NULL); doc_list[idx].changed = FALSE; - doc_list[idx].file_name = g_strdup(filename); + doc_list[idx].file_name = g_strdup(utf8_filename); doc_list[idx].encoding = enc; if (reload) { sci_goto_pos(doc_list[idx].sci, 0); - msgwin_status_add(_("File %s reloaded."), filename); + msgwin_status_add(_("File %s reloaded."), utf8_filename); } else { @@ -482,10 +488,10 @@ void document_open_file(gint idx, const gchar *filename, gint pos, gboolean read doc_list[idx].readonly = readonly; sci_set_readonly(doc_list[idx].sci, readonly); - document_set_filetype(idx, filetypes_get_from_filename(filename)); + document_set_filetype(idx, filetypes_get_from_filename(utf8_filename)); utils_build_show_hide(idx); msgwin_status_add(_("File %s opened(%d%s)."), - filename, gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook)), + utf8_filename, gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook)), (readonly) ? _(", read-only") : ""); } //utils_update_tag_list(idx, TRUE); @@ -500,15 +506,17 @@ void document_open_file(gint idx, const gchar *filename, gint pos, gboolean read // finally add current file to recent files menu, but not the files from the last session if (! app->opening_session_files && - g_queue_find_custom(app->recent_queue, filename, (GCompareFunc) strcmp) == NULL) + g_queue_find_custom(app->recent_queue, utf8_filename, (GCompareFunc) strcmp) == NULL) { - g_queue_push_head(app->recent_queue, g_strdup(filename)); + g_queue_push_head(app->recent_queue, g_strdup(utf8_filename)); if (g_queue_get_length(app->recent_queue) > app->mru_length) { g_free(g_queue_pop_tail(app->recent_queue)); } utils_update_recent_menu(); } + + g_free(utf8_filename); //gettimeofday(&tv1, &tz); //geany_debug("%s: %d", filename, (gint)(tv1.tv_usec - tv.tv_usec)); } @@ -798,7 +806,10 @@ void document_update_tag_list(gint idx) if (doc_list[idx].tm_file == NULL) { - doc_list[idx].tm_file = tm_source_file_new(doc_list[idx].file_name, FALSE); + gchar *locale_filename = g_locale_from_utf8(doc_list[idx].file_name, -1, NULL, NULL, NULL); + doc_list[idx].tm_file = tm_source_file_new(locale_filename, FALSE); + g_free(locale_filename); + if (! doc_list[idx].tm_file) return; tm_workspace_add_object(doc_list[idx].tm_file); // parse the file after setting the filetype TM_SOURCE_FILE(doc_list[idx].tm_file)->lang = getNamedLanguage((doc_list[idx].file_type)->name); diff --git a/src/filetypes.c b/src/filetypes.c index 8c7362332..f1344acdc 100644 --- a/src/filetypes.c +++ b/src/filetypes.c @@ -29,6 +29,7 @@ #include "support.h" #include "callbacks.h" #include "templates.h" +#include "msgwindow.h" /* inits the filetype array and fill it with the known filetypes @@ -250,15 +251,25 @@ void filetypes_init_types(void) filetype *filetypes_get_from_filename(const gchar *filename) { GPatternSpec *pattern; - gchar *base_filename; + gchar *base_filename, *utf8_filename; + GError *error = NULL; gint i, j; if (filename == NULL) { return filetypes[GEANY_FILETYPES_C]; } + + // try to get the UTF-8 equivalent for the filename + //utf8_filename = g_filename_to_utf8(filename, -1, NULL, NULL, &error); + utf8_filename = g_locale_to_utf8(filename, -1, NULL, NULL, &error); + if (utf8_filename == NULL) + { + return filetypes[GEANY_FILETYPES_C]; + } + // to match against the basename of the file(because of Makefile*) - base_filename = g_path_get_basename(g_filename_to_utf8(filename, -1, NULL, NULL, NULL)); + base_filename = g_path_get_basename(utf8_filename); for(i = 0; i < GEANY_MAX_FILE_TYPES; i++) { diff --git a/src/geany.h b/src/geany.h index fb46dd769..5a6ed2af4 100644 --- a/src/geany.h +++ b/src/geany.h @@ -43,8 +43,6 @@ #define SSM(s, m, w, l) scintilla_send_message(s, m, w, l) -#define INLINE inline -//#define INLINE #ifdef G_OS_WIN32 # include @@ -78,6 +76,7 @@ typedef struct document { gboolean is_valid; gboolean has_tags; + // the filename is encoded in UTF-8, but every GLibC function expect the locale representation gchar *file_name; gchar *encoding; filetype *file_type; diff --git a/src/keyfile.c b/src/keyfile.c index 23e050400..8b292a123 100644 --- a/src/keyfile.c +++ b/src/keyfile.c @@ -364,7 +364,7 @@ gboolean configuration_open_files(void) { gint i; guint x, pos; - gchar *file, spos[7]; + gchar *file, *locale_filename, spos[7]; gboolean ret = FALSE; for(i = GEANY_SESSION_FILES - 1; i >= 0 ; i--) @@ -373,6 +373,10 @@ gboolean configuration_open_files(void) { x = 0; file = strchr(session_files[i], ':') + 1; + // try to get the locale equivalent for the filename, fallback to filename if error + locale_filename = g_locale_from_utf8(file, -1, NULL, NULL, NULL); + if (locale_filename == NULL) locale_filename = g_strdup(file); + while (session_files[i][x] != ':') { spos[x] = session_files[i][x]; @@ -381,11 +385,12 @@ gboolean configuration_open_files(void) spos[x] = '\0'; pos = atoi(spos); - if (g_file_test(file, G_FILE_TEST_IS_REGULAR || G_FILE_TEST_IS_SYMLINK)) + if (g_file_test(locale_filename, G_FILE_TEST_IS_REGULAR || G_FILE_TEST_IS_SYMLINK)) { - document_open_file(-1, file, pos, FALSE); + document_open_file(-1, locale_filename, pos, FALSE); ret = TRUE; } + g_free(locale_filename); } g_free(session_files[i]); }