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
This commit is contained in:
Enrico Tröger 2006-01-23 17:05:29 +00:00
parent ac282112ba
commit 62ff8ef794
5 changed files with 58 additions and 29 deletions

View File

@ -2310,16 +2310,17 @@ on_comments_function_activate (GtkMenuItem *menuitem,
if (doc_list[idx].file_type->id != GEANY_FILETYPES_JAVA && if (doc_list[idx].file_type->id != GEANY_FILETYPES_JAVA &&
doc_list[idx].file_type->id != GEANY_FILETYPES_ALL) 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); 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); 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) if (line == -1)
{ {
g_free(cur_tag); g_free(cur_tag);
return; cur_tag = g_strdup(_("unknown"));
} }
if (doc_list[idx].file_type->id == GEANY_FILETYPES_PASCAL) if (doc_list[idx].file_type->id == GEANY_FILETYPES_PASCAL)
@ -2487,7 +2488,9 @@ void
on_recent_file_activate (GtkMenuItem *menuitem, on_recent_file_activate (GtkMenuItem *menuitem,
gpointer user_data) 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);
} }

View File

@ -366,11 +366,12 @@ void document_open_file(gint idx, const gchar *filename, gint pos, gboolean read
gboolean reload = (idx == -1) ? FALSE : TRUE; gboolean reload = (idx == -1) ? FALSE : TRUE;
struct stat st; struct stat st;
gchar *enc = NULL; gchar *enc = NULL;
gchar *utf8_filename = NULL;
GError *err = NULL;
#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) #if defined(HAVE_MMAP) && defined(HAVE_MUNMAP)
gint fd; gint fd;
void *map; void *map;
#else #else
GError *err = NULL;
gchar *map; gchar *map;
#endif #endif
//struct timeval tv, tv1; //struct timeval tv, tv1;
@ -383,8 +384,17 @@ void document_open_file(gint idx, const gchar *filename, gint pos, gboolean read
} }
else 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 // 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) if (idx >= 0)
{ {
gtk_notebook_set_current_page(GTK_NOTEBOOK(app->notebook), 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 defined(HAVE_MMAP) && defined(HAVE_MUNMAP)
if ((fd = open(filename, O_RDONLY)) < 0) 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; return;
} }
if ((map = mmap (0, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) 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; return;
} }
size = (gint)st.st_size; size = (gint)st.st_size;
#else #else
// use GLib function to load file on Win32 systems and those w/o mmap() // use GLib function to load file on Win32 systems and those w/o mmap()
if (! g_file_get_contents (filename, &map, NULL, &err) ){ if (! g_file_get_contents(utf8_filename, &map, NULL, &err) ){
msgwin_status_add(_("Could not open file %s (%s)"), filename, err->message); msgwin_status_add(_("Could not open file %s (%s)"), utf8_filename, err->message);
return; return;
} }
size = (gint)strlen(map); 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 // sets editor mode and add the text to the ScintillaObject
sci_add_text_buffer(doc_list[idx].sci, map, size); sci_add_text_buffer(doc_list[idx].sci, map, size);
editor_mode = utils_get_line_endings(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_eol_mode(doc_list[idx].sci, editor_mode);
sci_set_line_numbers(doc_list[idx].sci, TRUE, 0); 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); sci_empty_undo_buffer(doc_list[idx].sci);
doc_list[idx].mtime = time(NULL); doc_list[idx].mtime = time(NULL);
doc_list[idx].changed = FALSE; 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; doc_list[idx].encoding = enc;
if (reload) if (reload)
{ {
sci_goto_pos(doc_list[idx].sci, 0); sci_goto_pos(doc_list[idx].sci, 0);
msgwin_status_add(_("File %s reloaded."), filename); msgwin_status_add(_("File %s reloaded."), utf8_filename);
} }
else else
{ {
@ -482,10 +488,10 @@ void document_open_file(gint idx, const gchar *filename, gint pos, gboolean read
doc_list[idx].readonly = readonly; doc_list[idx].readonly = readonly;
sci_set_readonly(doc_list[idx].sci, 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); utils_build_show_hide(idx);
msgwin_status_add(_("File %s opened(%d%s)."), 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") : ""); (readonly) ? _(", read-only") : "");
} }
//utils_update_tag_list(idx, TRUE); //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 // finally add current file to recent files menu, but not the files from the last session
if (! app->opening_session_files && 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) if (g_queue_get_length(app->recent_queue) > app->mru_length)
{ {
g_free(g_queue_pop_tail(app->recent_queue)); g_free(g_queue_pop_tail(app->recent_queue));
} }
utils_update_recent_menu(); utils_update_recent_menu();
} }
g_free(utf8_filename);
//gettimeofday(&tv1, &tz); //gettimeofday(&tv1, &tz);
//geany_debug("%s: %d", filename, (gint)(tv1.tv_usec - tv.tv_usec)); //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) 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); tm_workspace_add_object(doc_list[idx].tm_file);
// parse the file after setting the filetype // parse the file after setting the filetype
TM_SOURCE_FILE(doc_list[idx].tm_file)->lang = getNamedLanguage((doc_list[idx].file_type)->name); TM_SOURCE_FILE(doc_list[idx].tm_file)->lang = getNamedLanguage((doc_list[idx].file_type)->name);

View File

@ -29,6 +29,7 @@
#include "support.h" #include "support.h"
#include "callbacks.h" #include "callbacks.h"
#include "templates.h" #include "templates.h"
#include "msgwindow.h"
/* inits the filetype array and fill it with the known filetypes /* 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) filetype *filetypes_get_from_filename(const gchar *filename)
{ {
GPatternSpec *pattern; GPatternSpec *pattern;
gchar *base_filename; gchar *base_filename, *utf8_filename;
GError *error = NULL;
gint i, j; gint i, j;
if (filename == NULL) if (filename == NULL)
{ {
return filetypes[GEANY_FILETYPES_C]; 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*) // 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++) for(i = 0; i < GEANY_MAX_FILE_TYPES; i++)
{ {

View File

@ -43,8 +43,6 @@
#define SSM(s, m, w, l) scintilla_send_message(s, m, w, l) #define SSM(s, m, w, l) scintilla_send_message(s, m, w, l)
#define INLINE inline
//#define INLINE
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
# include <windows.h> # include <windows.h>
@ -78,6 +76,7 @@ typedef struct document
{ {
gboolean is_valid; gboolean is_valid;
gboolean has_tags; gboolean has_tags;
// the filename is encoded in UTF-8, but every GLibC function expect the locale representation
gchar *file_name; gchar *file_name;
gchar *encoding; gchar *encoding;
filetype *file_type; filetype *file_type;

View File

@ -364,7 +364,7 @@ gboolean configuration_open_files(void)
{ {
gint i; gint i;
guint x, pos; guint x, pos;
gchar *file, spos[7]; gchar *file, *locale_filename, spos[7];
gboolean ret = FALSE; gboolean ret = FALSE;
for(i = GEANY_SESSION_FILES - 1; i >= 0 ; i--) for(i = GEANY_SESSION_FILES - 1; i >= 0 ; i--)
@ -373,6 +373,10 @@ gboolean configuration_open_files(void)
{ {
x = 0; x = 0;
file = strchr(session_files[i], ':') + 1; 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] != ':') while (session_files[i][x] != ':')
{ {
spos[x] = session_files[i][x]; spos[x] = session_files[i][x];
@ -381,11 +385,12 @@ gboolean configuration_open_files(void)
spos[x] = '\0'; spos[x] = '\0';
pos = atoi(spos); 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; ret = TRUE;
} }
g_free(locale_filename);
} }
g_free(session_files[i]); g_free(session_files[i]);
} }