From 420208f38910c28f11a983fd8f4d231d3956e6e7 Mon Sep 17 00:00:00 2001 From: Jindrich Novy Date: Mon, 25 Feb 2008 15:01:14 +0000 Subject: [PATCH] - update to 4.6.2-pre1 - forwardport the UTF-8 patch to 4.6.2-pre1 and convert new functionality to support UTF-8 --- .cvsignore | 1 + mc-utf8.patch | 6286 +++++++++++++++++++++++++------------------------ mc.spec | 16 +- sources | 1 + 4 files changed, 3198 insertions(+), 3106 deletions(-) diff --git a/.cvsignore b/.cvsignore index 7f17af6..4a22503 100644 --- a/.cvsignore +++ b/.cvsignore @@ -9,3 +9,4 @@ mc-2006-12-28-05.tar.gz mc-2007-01-22-13.tar.gz mc-2007-01-24-03.tar.gz mc-2007-06-04-22.tar.gz +mc-4.6.2-pre1.tar.gz diff --git a/mc-utf8.patch b/mc-utf8.patch index 67b1839..6344ab6 100644 --- a/mc-utf8.patch +++ b/mc-utf8.patch @@ -1,387 +1,6 @@ ---- mc/acinclude.m4.utf8 2006-09-09 00:35:29.000000000 +0200 -+++ mc/acinclude.m4 2007-01-04 16:20:56.000000000 +0100 -@@ -399,14 +399,14 @@ AC_DEFUN([MC_WITH_SLANG], [ - fi - - dnl Unless external S-Lang was requested, reject S-Lang with UTF-8 hacks -- if test x$with_screen = xslang; then -- : -- m4_if([$1], strict, , -- [AC_CHECK_LIB([slang], [SLsmg_write_nwchars], -- [AC_MSG_WARN([Rejecting S-Lang with UTF-8 support, \ --it's not fully supported yet]) -- with_screen=mcslang])]) -- fi -+dnl if test x$with_screen = xslang; then -+dnl : -+dnl m4_if([$1], strict, , -+dnl [AC_CHECK_LIB([slang], [SLsmg_write_nwchars], -+dnl [AC_MSG_WARN([Rejecting S-Lang with UTF-8 support, \ -+dnl it's not fully supported yet]) -+dnl with_screen=mcslang])]) -+dnl fi - - if test x$with_screen = xslang; then - AC_DEFINE(HAVE_SYSTEM_SLANG, 1, ---- mc/src/layout.c.utf8 2006-11-10 01:22:30.000000000 +0100 -+++ mc/src/layout.c 2007-01-04 16:20:56.000000000 +0100 -@@ -366,36 +366,36 @@ init_layout (void) - - while (i--) { - s_split_direction[i] = _(s_split_direction[i]); -- l1 = strlen (s_split_direction[i]) + 7; -+ l1 = mbstrlen (s_split_direction[i]) + 7; - if (l1 > first_width) - first_width = l1; - } - - for (i = 0; i <= 8; i++) { - check_options[i].text = _(check_options[i].text); -- l1 = strlen (check_options[i].text) + 7; -+ l1 = mbstrlen (check_options[i].text) + 7; - if (l1 > first_width) - first_width = l1; - } - -- l1 = strlen (title1) + 1; -+ l1 = mbstrlen (title1) + 1; - if (l1 > first_width) - first_width = l1; - -- l1 = strlen (title2) + 1; -+ l1 = mbstrlen (title2) + 1; - if (l1 > first_width) - first_width = l1; - - -- second_width = strlen (title3) + 1; -+ second_width = mbstrlen (title3) + 1; - for (i = 0; i < 6; i++) { - check_options[i].text = _(check_options[i].text); -- l1 = strlen (check_options[i].text) + 7; -+ l1 = mbstrlen (check_options[i].text) + 7; - if (l1 > second_width) - second_width = l1; - } - if (console_flag) { -- l1 = strlen (output_lines_label) + 13; -+ l1 = mbstrlen (output_lines_label) + 13; - if (l1 > second_width) - second_width = l1; - } -@@ -409,14 +409,14 @@ init_layout (void) - * - * Now the last thing to do - properly space buttons... - */ -- l1 = 11 + strlen (ok_button) /* 14 - all brackets and inner space */ -- +strlen (save_button) /* notice: it is 3 char less because */ -- +strlen (cancel_button); /* of '&' char in button text */ -+ l1 = 11 + mbstrlen (ok_button) /* 14 - all brackets and inner space */ -+ +mbstrlen (save_button) /* notice: it is 3 char less because */ -+ +mbstrlen (cancel_button); /* of '&' char in button text */ - - i = (first_width + second_width - l1) / 4; - b1 = 5 + i; -- b2 = b1 + strlen (ok_button) + i + 6; -- b3 = b2 + strlen (save_button) + i + 4; -+ b2 = b1 + mbstrlen (ok_button) + i + 6; -+ b3 = b2 + mbstrlen (save_button) + i + 4; - - i18n_layt_flag = 1; - } -@@ -684,7 +684,7 @@ setup_panels (void) - panel_do_cols (0); - panel_do_cols (1); - -- promptl = strlen (prompt); -+ promptl = mbstrlen (prompt); - - widget_set_size (&the_menubar->widget, 0, 0, 1, COLS); - ---- mc/src/tty.c.utf8 2006-05-23 16:20:39.000000000 +0200 -+++ mc/src/tty.c 2007-01-04 16:20:56.000000000 +0100 -@@ -134,10 +134,12 @@ tty_print_char(int c) - * defined or not. Congratulations! At least, they left the API call - * for SLsmg_write_nchars as it has always been. - */ -- char ch; -- -- ch = c; -- SLsmg_write_nchars(&ch, 1); -+ -+ /* The above comment is a nonsense, SLsmg_write_char(c) works pretty -+ * good for me. So please don't mess with Red Hat people. -+ * Jindrich Novy (jnovy@redhat.com) -+ */ -+ SLsmg_write_char(c); - #else - addch(c); - #endif ---- mc/src/option.c.utf8 2006-02-28 18:44:28.000000000 +0100 -+++ mc/src/option.c 2007-01-04 16:20:56.000000000 +0100 -@@ -123,12 +123,12 @@ init_configure (void) - title2 = _(" Pause after run... "); - title3 = _(" Other options "); - -- first_width = strlen (title1) + 1; -- second_width = strlen (title3) + 1; -+ first_width = mbstrlen (title1) + 1; -+ second_width = mbstrlen (title3) + 1; - - for (i = 0; check_options[i].text; i++) { - check_options[i].text = _(check_options[i].text); -- l1 = strlen (check_options[i].text) + 7; -+ l1 = mbstrlen (check_options[i].text) + 7; - if (i >= OTHER_OPTIONS) { - if (l1 > first_width) - first_width = l1; -@@ -141,23 +141,23 @@ init_configure (void) - i = PAUSE_OPTIONS; - while (i--) { - pause_options[i] = _(pause_options[i]); -- l1 = strlen (pause_options[i]) + 7; -+ l1 = mbstrlen (pause_options[i]) + 7; - if (l1 > first_width) - first_width = l1; - } - -- l1 = strlen (title2) + 1; -+ l1 = mbstrlen (title2) + 1; - if (l1 > first_width) - first_width = l1; - -- l1 = 11 + strlen (ok_button) -- + strlen (save_button) -- + strlen (cancel_button); -+ l1 = 11 + mbstrlen (ok_button) -+ + mbstrlen (save_button) -+ + mbstrlen (cancel_button); - - i = (first_width + second_width - l1) / 4; - b1 = 5 + i; -- b2 = b1 + strlen (ok_button) + i + 6; -- b3 = b2 + strlen (save_button) + i + 4; -+ b2 = b1 + mbstrlen (ok_button) + i + 6; -+ b3 = b2 + mbstrlen (save_button) + i + 4; - - i18n_config_flag = 1; - } ---- mc/src/menu.h.utf8 2004-12-03 20:17:47.000000000 +0100 -+++ mc/src/menu.h 2007-01-04 16:20:56.000000000 +0100 -@@ -21,6 +21,8 @@ typedef struct Menu { - menu_entry *entries; - int start_x; /* position relative to menubar start */ - char *help_node; -+ wchar_t **wentries; -+ wchar_t *wname; - } Menu; - - extern int menubar_visible; ---- mc/src/menu.c.utf8 2005-09-06 22:36:23.000000000 +0200 -+++ mc/src/menu.c 2007-01-04 16:20:56.000000000 +0100 -@@ -22,6 +22,7 @@ - #include - - #include -+#include - - #include "global.h" - #include "tty.h" -@@ -53,35 +54,95 @@ create_menu (const char *name, menu_entr - { - Menu *menu; - const char *cp; -+ int wlen = 0; -+ mbstate_t s; - - menu = (Menu *) g_malloc (sizeof (*menu)); - menu->count = count; - menu->max_entry_len = 20; - menu->entries = entries; -+ menu->name = g_strdup (name); -+ menu_scan_hotkey (menu); -+#ifdef UTF8 -+ menu->wentries = NULL; -+ menu->wname = NULL; -+ if (SLsmg_Is_Unicode) { -+ const char *str = menu->name; -+ memset (&s, 0, sizeof (s)); -+ wlen = mbsrtowcs (NULL, &str, -1, &s); -+ if (wlen > 0) -+ ++wlen; -+ else { -+ wlen = 0; -+ memset (&s, 0, sizeof (s)); -+ } -+ } -+#endif - - if (entries != (menu_entry*) NULL) { - register menu_entry* mp; - for (mp = entries; count--; mp++) { - if (mp->text[0] != '\0') { -+ int len; - #ifdef ENABLE_NLS - mp->text = _(mp->text); - #endif /* ENABLE_NLS */ - cp = strchr (mp->text,'&'); -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode) { -+ len = mbstrlen(mp->text) + 1; -+ wlen += len; -+ menu->max_entry_len = max (len - 1, menu->max_entry_len); -+ } else -+#endif -+ len = strlen (mp->text); - - if (cp != NULL && *(cp+1) != '\0') { - mp->hot_key = tolower ((unsigned char) *(cp+1)); -- menu->max_entry_len = max ((int) (strlen (mp->text) - 1), -- menu->max_entry_len); -+ menu->max_entry_len = max (len - 1, menu->max_entry_len); - } else { -- menu->max_entry_len = max ((int) strlen (mp->text), -- menu->max_entry_len); -+ menu->max_entry_len = max (len, menu->max_entry_len); - } - } - } - } - -- menu->name = g_strdup (name); -- menu_scan_hotkey(menu); -+#ifdef UTF8 -+ if (wlen) { -+ wchar_t *wp; -+ const char *str; -+ int len; -+ -+ menu->wentries = (wchar_t **) -+ g_malloc (sizeof (wchar_t *) * menu->count -+ + wlen * sizeof (wchar_t)); -+ wp = (wchar_t *) (menu->wentries + menu->count); -+ str = menu->name; -+ len = mbsrtowcs (wp, &str, wlen, &s); -+ if (len > 0) { -+ menu->wname = wp; -+ wlen -= len + 1; -+ wp += len + 1; -+ } else -+ memset (&s, 0, sizeof (s)); -+ if (menu->entries != NULL) -+ for (count = 0; count < menu->count; ++count) -+ if (menu->entries[count].text[0] != '\0') { -+ str = menu->entries[count].text; -+ menu->wentries[count] = wp; -+ len = mbsrtowcs (wp, &str, wlen, &s); -+ if (len > 0) { -+ wlen -= len + 1; -+ wp += len + 1; -+ } else { -+ memset (&s, 0, sizeof (s)); -+ *wp++ = L'\0'; -+ --wlen; -+ } -+ } -+ } -+#endif -+ - menu->start_x = 0; - menu->help_node = g_strdup (help_node); - return menu; -@@ -112,8 +173,26 @@ static void menubar_paint_idx (WMenu *me - const char *text; - - addch((unsigned char)menu->entries [idx].first_letter); -- for (text = menu->entries [idx].text; *text; text++) -- { -+#ifdef UTF8 -+ if (menu->wentries) { -+ wchar_t *wtext, *wp; -+ -+ for (wtext = wp = menu->wentries [idx]; *wtext; wtext++) { -+ if (*wtext == L'&') { -+ if (wtext > wp) -+ SLsmg_write_nwchars (wp, wtext - wp); -+ attrset (color == MENU_SELECTED_COLOR ? -+ MENU_HOTSEL_COLOR : MENU_HOT_COLOR); -+ SLsmg_write_nwchars (++wtext, 1); -+ attrset (color); -+ wp = wtext + 1; -+ } -+ } -+ if (wtext > wp) -+ SLsmg_write_nwchars (wp, wtext - wp); -+ } else -+#endif -+ for (text = menu->entries [idx].text; *text; text++) { - if (*text != '&') - addch(*text); - else { -@@ -122,7 +201,7 @@ static void menubar_paint_idx (WMenu *me - addch(*(++text)); - attrset(color); - } -- } -+ } - } - widget_move (&menubar->widget, y, x + 1); - } -@@ -168,6 +247,12 @@ static void menubar_draw (WMenu *menubar - if (menubar->active) - attrset(i == menubar->selected?MENU_SELECTED_COLOR:SELECTED_COLOR); - widget_move (&menubar->widget, 0, menubar->menu [i]->start_x); -+#ifdef UTF8 -+ if (menubar->menu [i]->wname) -+ SLsmg_write_nwchars (menubar->menu [i]->wname, -+ wcslen (menubar->menu [i]->wname)); -+ else -+#endif - tty_printf ("%s", menubar->menu [i]->name); - } - -@@ -493,7 +578,13 @@ menubar_arrange(WMenu* menubar) - - for (i = 0; i < items; i++) - { -- int len = strlen(menubar->menu[i]->name); -+ int len; -+#ifdef UTF8 -+ if (menubar->menu[i]->wname) -+ len = wcslen (menubar->menu[i]->wname); -+ else -+#endif -+ len = strlen(menubar->menu[i]->name); - menubar->menu[i]->start_x = start_x; - start_x += len + gap; - } -@@ -506,7 +597,13 @@ menubar_arrange(WMenu* menubar) - for (i = 0; i < items; i++) - { - /* preserve length here, to be used below */ -- gap -= (menubar->menu[i]->start_x = strlen(menubar->menu[i]->name)); -+#ifdef UTF8 -+ if (menubar->menu[i]->wname) -+ menubar->menu[i]->start_x = wcslen (menubar->menu[i]->wname); -+ else -+#endif -+ menubar->menu[i]->start_x = strlen (menubar->menu[i]->name); -+ gap -= menubar->menu[i]->start_x; - } - - gap /= (items - 1); -@@ -530,6 +627,9 @@ menubar_arrange(WMenu* menubar) - void - destroy_menu (Menu *menu) - { -+#ifdef UTF8 -+ g_free (menu->wentries); -+#endif - g_free (menu->name); - g_free (menu->help_node); - g_free (menu); ---- mc/src/filegui.c.utf8 2006-01-30 18:01:58.000000000 +0100 -+++ mc/src/filegui.c 2007-01-04 16:20:56.000000000 +0100 +diff -up mc-4.6.2-pre1/src/filegui.c.utf8 mc-4.6.2-pre1/src/filegui.c +--- mc-4.6.2-pre1/src/filegui.c.utf8 2007-08-23 15:16:39.000000000 +0200 ++++ mc-4.6.2-pre1/src/filegui.c 2008-02-25 14:56:22.000000000 +0100 @@ -65,6 +65,7 @@ #include "filegui.h" #include "key.h" /* get_event */ @@ -527,635 +146,9 @@ + g_free(def_text); return dest_dir; } ---- mc/src/panelize.c.utf8 2005-05-27 05:35:15.000000000 +0200 -+++ mc/src/panelize.c 2007-01-04 16:20:56.000000000 +0100 -@@ -127,7 +127,7 @@ init_panelize (void) - i = sizeof (panelize_but) / sizeof (panelize_but[0]); - while (i--) { - panelize_but[i].text = _(panelize_but[i].text); -- maxlen += strlen (panelize_but[i].text) + 5; -+ maxlen += mbstrlen (panelize_but[i].text) + 5; - } - maxlen += 10; - -@@ -136,11 +136,11 @@ init_panelize (void) - panelize_cols = max (panelize_cols, maxlen); - - panelize_but[2].x = -- panelize_but[3].x + strlen (panelize_but[3].text) + 7; -+ panelize_but[3].x + mbstrlen (panelize_but[3].text) + 7; - panelize_but[1].x = -- panelize_but[2].x + strlen (panelize_but[2].text) + 5; -+ panelize_but[2].x + mbstrlen (panelize_but[2].text) + 5; - panelize_but[0].x = -- panelize_cols - strlen (panelize_but[0].text) - 8 - BX; -+ panelize_cols - mbstrlen (panelize_but[0].text) - 8 - BX; - - #endif /* ENABLE_NLS */ - ---- mc/src/slint.c.utf8 2005-09-06 22:36:23.000000000 +0200 -+++ mc/src/slint.c 2007-01-04 16:20:56.000000000 +0100 -@@ -141,7 +141,9 @@ void - slang_init (void) - { - SLtt_get_terminfo (); -- -+#if SLANG_VERSION >= 20000 -+ SLutf8_enable (-1); -+#endif - /* - * If the terminal in not in terminfo but begins with a well-known - * string such as "linux" or "xterm" S-Lang will go on, but the ---- mc/src/main.c.utf8 2006-09-25 16:47:34.000000000 +0200 -+++ mc/src/main.c 2007-01-04 16:20:56.000000000 +0100 -@@ -704,7 +704,7 @@ load_prompt (int fd, void *unused) - int prompt_len; - - tmp_prompt = strip_ctrl_codes (subshell_prompt); -- prompt_len = strlen (tmp_prompt); -+ prompt_len = mbstrlen (tmp_prompt); - - /* Check for prompts too big */ - if (COLS > 8 && prompt_len > COLS - 8) { -@@ -1610,7 +1610,11 @@ update_xterm_title_path (void) - if (xterm_flag && xterm_title) { - p = s = g_strdup (strip_home_and_password (current_panel->cwd)); - do { -+#ifndef UTF8 - if (!is_printable ((unsigned char) *s)) -+#else /* UTF8 */ -+ if (*(unsigned char *)s < ' ') -+#endif /* UTF8 */ - *s = '?'; - } while (*++s); - fprintf (stdout, "\33]0;mc - %s\7", p); ---- mc/src/view.c.utf8 2006-12-12 18:39:33.000000000 +0100 -+++ mc/src/view.c 2007-01-04 16:20:56.000000000 +0100 -@@ -43,6 +43,10 @@ - #include - #include - -+#ifdef UTF8 -+#include -+#endif /* UTF8 */ -+ - #include "global.h" - #include "tty.h" - #include "cmd.h" /* For view_other_cmd */ -@@ -1639,7 +1643,7 @@ view_display_status (WView *view) - hline (' ', width); - - file_label = _("File: %s"); -- file_label_width = strlen (file_label) - 2; -+ file_label_width = mbstrlen (file_label) - 2; - file_name = view->filename ? view->filename - : view->command ? view->command - : ""; -@@ -1907,6 +1911,12 @@ view_display_text (WView * view) - offset_type from; - int c; - struct hexedit_change_node *curr = view->change_list; -+#ifdef UTF8 -+ mbstate_t mbs; -+ char mbbuf[MB_LEN_MAX]; -+ int mblen; -+ wchar_t wc; -+#endif /* UTF8 */ - - view_display_clean (view); - view_display_ruler (view); -@@ -1919,8 +1929,37 @@ view_display_text (WView * view) - - tty_setcolor (NORMAL_COLOR); - for (row = 0, col = 0; row < height && (c = get_byte (view, from)) != -1; from++) { -- -+#ifndef UTF8 - if (view->text_nroff_mode && c == '\b') { -+#else /* UTF8 */ -+ mblen = 1; -+ mbbuf[0] = convert_to_display_c (c); -+ -+ while (mblen < MB_LEN_MAX) { -+ int res; -+ memset (&mbs, 0, sizeof (mbs)); -+ res = mbrtowc (&wc, mbbuf, mblen, &mbs); -+ if (res <= 0 && res != -2) { -+ wc = '.'; -+ mblen = 1; -+ break; -+ } -+ if (res == mblen) -+ break; -+ -+ mbbuf[mblen] = convert_to_display_c (get_byte (view, from + mblen)); -+ mblen++; -+ } -+ -+ if (mblen == MB_LEN_MAX) { -+ wc = '.'; -+ mblen = 1; -+ } -+ -+ from += mblen - 1; -+ -+ if (view->text_nroff_mode && wc == '\b') { -+#endif /* UTF8 */ - int c_prev; - int c_next; - -@@ -1985,10 +2024,17 @@ view_display_text (WView * view) - if (col >= view->dpy_text_column - && col - view->dpy_text_column < width) { - widget_move (view, top + row, left + (col - view->dpy_text_column)); -+#ifndef UTF8 - c = convert_to_display_c (c); - if (!is_printable (c)) - c = '.'; - tty_print_char (c); -+#else -+ wc = convert_to_display_c (wc); -+ if (!iswprint (wc)) -+ wc = '.'; -+ tty_print_char (wc); -+#endif - } - col++; - tty_setcolor (NORMAL_COLOR); ---- mc/src/screen.c.utf8 2006-02-09 02:59:16.000000000 +0100 -+++ mc/src/screen.c 2007-01-04 16:20:56.000000000 +0100 -@@ -171,21 +171,56 @@ add_permission_string (char *dest, int w - static const char * - string_file_name (file_entry *fe, int len) - { -- static char buffer [MC_MAXPATHLEN + 1]; - size_t i; - -- for (i = 0; i < sizeof(buffer) - 1; i++) { -- char c; -+#ifdef UTF8 -+ static char buffer [BUF_SMALL * 4]; -+ mbstate_t s; -+ int mbmax = MB_CUR_MAX; -+ const char *str = fe->fname; - -- c = fe->fname[i]; -+ memset (&s, 0, sizeof (s)); -+#else -+ static char buffer [BUF_SMALL]; -+#endif - -- if (!c) -- break; -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode) -+ for (i = 0; i < sizeof (buffer) - 1; i++) { -+ wchar_t wc; -+ int len; - -- if (!is_printable(c)) -- c = '?'; -+ len = mbrtowc (&wc, str, mbmax, &s); -+ if (!len) -+ break; -+ if (len < 0) { -+ memset (&s, 0, sizeof (s)); -+ buffer[i] = '?'; -+ str++; -+ continue; -+ } -+ if (!is_printable (wc)) { -+ buffer[i] = '?'; -+ str++; -+ continue; -+ } -+ if (i >= sizeof (buffer) - len) -+ break; -+ memcpy (buffer + i, str, len); -+ i += len - 1; -+ str += len; -+ } else -+#endif -+ for (i = 0; i < sizeof(buffer) - 1; i++) { -+ char c; -+ -+ c = fe->fname[i]; - -- buffer[i] = c; -+ if (!c) break; -+ -+ if (!is_printable(c)) c = '?'; -+ -+ buffer[i] = c; - } - - buffer[i] = 0; -@@ -450,42 +485,6 @@ static struct { - { "dot", 1, 0, J_RIGHT, " ", 0, string_dot, NULL }, - }; - --static char * --to_buffer (char *dest, int just_mode, int len, const char *txt) --{ -- int txtlen = strlen (txt); -- int still, over; -- -- /* Fill buffer with spaces */ -- memset (dest, ' ', len); -- -- still = (over=(txtlen > len)) ? (txtlen - len) : (len - txtlen); -- -- switch (HIDE_FIT(just_mode)){ -- case J_LEFT: -- still = 0; -- break; -- case J_CENTER: -- still /= 2; -- break; -- case J_RIGHT: -- default: -- break; -- } -- -- if (over){ -- if (IS_FIT(just_mode)) -- strcpy (dest, name_trunc(txt, len)); -- else -- strncpy (dest, txt+still, len); -- } else -- strncpy (dest+still, txt, txtlen); -- -- dest[len] = '\0'; -- -- return (dest + len); --} -- - static int - file_compute_color (int attr, file_entry *fe) - { -@@ -539,14 +538,18 @@ file_compute_color (int attr, file_entry - - /* Formats the file number file_index of panel in the buffer dest */ - static void --format_file (char *dest, int limit, WPanel *panel, int file_index, int width, int attr, int isstatus) -+format_file (WPanel *panel, int file_index, int width, int attr, int isstatus) - { - int color, length, empty_line; - const char *txt; -- char *old_pos; -- char *cdest = dest; - format_e *format, *home; - file_entry *fe; -+#ifdef UTF8 -+ char buffer[BUF_MEDIUM * sizeof (wchar_t)]; -+#else -+ char buffer[BUF_MEDIUM]; -+#endif -+ int txtwidth = 0; - - length = 0; - empty_line = (file_index >= panel->count); -@@ -564,34 +567,137 @@ format_file (char *dest, int limit, WPan - break; - - if (format->string_fn){ -- int len; -+ int len, still, over, perm, txtlen, wide; - - if (empty_line) - txt = " "; - else - txt = (*format->string_fn)(fe, format->field_len); - -- old_pos = cdest; -- - len = format->field_len; - if (len + length > width) - len = width - length; -- if (len + (cdest - dest) > limit) -- len = limit - (cdest - dest); -+ if (len >= BUF_MEDIUM) -+ len = BUF_MEDIUM - 1; - if (len <= 0) - break; -- cdest = to_buffer (cdest, format->just_mode, len, txt); -- length += len; - -- attrset (color); -+ perm = 0; -+ if (permission_mode) { -+ if (!strcmp(format->id, "perm")) -+ perm = 1; -+ else if (!strcmp(format->id, "mode")) -+ perm = 2; -+ } - -- if (permission_mode && !strcmp(format->id, "perm")) -- add_permission_string (old_pos, format->field_len, fe, attr, color, 0); -- else if (permission_mode && !strcmp(format->id, "mode")) -- add_permission_string (old_pos, format->field_len, fe, attr, color, 1); -- else -- addstr (old_pos); -+ wide = 0; -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode && !empty_line && !perm) { -+ mbstate_t s; -+ const char *str = txt; -+ -+ memset (&s, 0, sizeof (s)); -+ txtlen = mbsrtowcs ((wchar_t *) buffer, &str, -+ sizeof (buffer) / sizeof (wchar_t), &s); -+ if (txtlen < 0) { -+ txt = " "; -+ txtlen = 1; -+ } else { -+ wide = 1; -+ txtwidth = wcswidth((wchar_t*)buffer, txtlen); -+ } -+ } else -+#endif -+ { -+ txtlen = mbstrlen (txt); -+ txtwidth = txtlen; -+ } -+ -+ over = txtwidth > len; -+ still = over ? txtlen - len : len - txtlen; -+ -+ switch (HIDE_FIT(format->just_mode)) { -+ case J_LEFT: -+ still = 0; -+ break; -+ case J_CENTER: -+ still /= 2; -+ break; -+ case J_RIGHT: -+ default: -+ break; -+ } -+ -+ attrset (color); -+ -+ if (wide) { -+#ifdef UTF8 -+ if (over) { -+ if (IS_FIT (format->just_mode)) { -+ int n1 = 0; -+ int width1 = 0; -+ int n2 = 0; -+ int width2 = 0; -+ int len1 = len / 2; -+ int len2; -+ -+ while (1) { -+ int w = wcwidth(((wchar_t *) buffer)[n1]); -+ if (width1 + w <= len1) { -+ width1 += w; -+ n1++; -+ } -+ else -+ break; -+ } -+ len2 = len - width1 - 1; -+ -+ while (1) { -+ int w = wcwidth(((wchar_t *) buffer)[txtlen - n2 - 1]); -+ if (width2 + w <= len2) { -+ width2 += w; -+ n2++; -+ } -+ else -+ break; -+ } -+ -+ -+ SLsmg_write_nwchars ((wchar_t *) buffer, n1); -+ SLsmg_write_nwchars (L"~", 1); -+ printw ("%*s", len - width1 - width2 - 1, ""); -+ SLsmg_write_nwchars (((wchar_t *) buffer) -+ + txtlen - n2, n2); -+ } else -+ SLsmg_write_nwchars ((wchar_t *) buffer, len); -+ } else { -+ printw ("%*s", still, ""); -+ SLsmg_write_nwchars ((wchar_t *) buffer, txtlen); -+ printw ("%*s", len - txtwidth - still, ""); -+ } -+#endif -+ } else { -+ if (over) { -+ if (IS_FIT (format->just_mode)) -+ strcpy (buffer, name_trunc(txt, len)); -+ else -+ memcpy (buffer, txt + still, len); -+ } else { -+ memset (buffer, ' ', still); -+ memcpy (buffer + still, txt, txtlen); -+ memset (buffer + still + txtlen, ' ', -+ len - txtlen - still); -+ } -+ buffer[len] = '\0'; - -+ if (perm) -+ add_permission_string (buffer, format->field_len, fe, -+ attr, color, perm - 1); -+ else -+ addstr (buffer); -+ } -+ -+ length += len; - } else { - if (attr == SELECTED || attr == MARKED_SELECTED) - attrset (SELECTED_COLOR); -@@ -614,7 +720,6 @@ repaint_file (WPanel *panel, int file_in - { - int second_column = 0; - int width, offset; -- char buffer [BUF_MEDIUM]; - - offset = 0; - if (!isstatus && panel->split){ -@@ -643,7 +748,7 @@ repaint_file (WPanel *panel, int file_in - widget_move (&panel->widget, file_index - panel->top_file + 2, 1); - } - -- format_file (buffer, sizeof(buffer), panel, file_index, width, attr, isstatus); -+ format_file (panel, file_index, width, attr, isstatus); - - if (!isstatus && panel->split){ - if (second_column) -@@ -692,7 +797,7 @@ display_mini_info (WPanel *panel) - ngettext("%s in %d file", "%s in %d files", panel->marked), - b_bytes, panel->marked); - -- if ((int) strlen (buffer) > cols-2){ -+ if ((int) mbstrlen (buffer) > cols-2){ - buffer [cols] = 0; - p += 2; - } else -@@ -1101,6 +1206,12 @@ paint_frame (WPanel *panel) - int side, width; - - const char *txt; -+#ifdef UTF8 -+ char buffer[30 * sizeof (wchar_t)]; -+ mbstate_t s; -+ -+ memset (&s, 0, sizeof (s)); -+#endif - if (!panel->split) - adjust_top_file (panel); - -@@ -1125,16 +1236,38 @@ paint_frame (WPanel *panel) - if (format->string_fn){ - txt = format->title; - -- header_len = strlen (txt); -+ attrset (MARKED_COLOR); -+ width -= format->field_len; -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode) { -+ const char *str = txt; -+ header_len = mbsrtowcs ((wchar_t *) buffer, &str, -+ sizeof (buffer) / sizeof (wchar_t), -+ &s); -+ if (header_len < 0) { -+ memset (&s, 0, sizeof (s)); -+ printw ("%*s", format->field_len, ""); -+ continue; -+ } -+ if (header_len > format->field_len) -+ header_len = format->field_len; -+ spaces = (format->field_len - header_len) / 2; -+ extra = (format->field_len - header_len) % 2; -+ printw ("%*s", spaces, ""); -+ SLsmg_write_nwchars ((wchar_t *) buffer, header_len); -+ printw ("%*s", spaces + extra, ""); -+ continue; -+ } -+#endif -+ -+ header_len = mbstrlen (txt); - if (header_len > format->field_len) - header_len = format->field_len; - -- attrset (MARKED_COLOR); - spaces = (format->field_len - header_len) / 2; - extra = (format->field_len - header_len) % 2; - tty_printf ("%*s%.*s%*s", spaces, "", - header_len, txt, spaces+extra, ""); -- width -= 2 * spaces + extra + header_len; - } else { - attrset (NORMAL_COLOR); - one_vline (); -@@ -1891,11 +2024,24 @@ do_search (WPanel *panel, int c_code) - int i; - int wrapped = 0; - int found; -+ int prevpos, pos; -+ int j; -+ mbstate_t mbs; - - l = strlen (panel->search_buffer); - if (c_code == KEY_BACKSPACE) { -- if (l) -- panel->search_buffer[--l] = '\0'; -+ if (l) { -+ prevpos = pos = 0; -+ memset (&mbs, 0, sizeof (mbs)); -+ while (pos < l) { -+ prevpos = pos; -+ j = mbrlen (panel->search_buffer + pos, l - pos, &mbs); -+ if (j <= 0) break; -+ pos += j; -+ } -+ --l; -+ panel->search_buffer[prevpos] = 0; -+ } - } else { - if (c_code && l < sizeof (panel->search_buffer)) { - panel->search_buffer[l] = c_code; -@@ -1904,6 +2050,14 @@ do_search (WPanel *panel, int c_code) - } - } - -+ prevpos = pos = 0; -+ memset (&mbs, 0, sizeof (mbs)); -+ while (pos < l) { -+ prevpos = pos; -+ j = mbrlen (panel->search_buffer + pos, l - pos, &mbs); -+ if (j <= 0) break; -+ pos += j; -+ } - found = 0; - for (i = panel->selected; !wrapped || i != panel->selected; i++) { - if (i >= panel->count) { -@@ -1914,9 +2068,9 @@ do_search (WPanel *panel, int c_code) - } - if (panel-> - case_sensitive -- ? (strncmp (panel->dir.list[i].fname, panel->search_buffer, l) -+ ? (strncmp (panel->dir.list[i].fname, panel->search_buffer, pos) - == 0) : (g_strncasecmp (panel->dir.list[i].fname, -- panel->search_buffer, l) == 0)) { -+ panel->search_buffer, pos) == 0)) { - unselect_item (panel); - panel->selected = i; - select_item (panel); -@@ -1925,7 +2079,7 @@ do_search (WPanel *panel, int c_code) - } - } - if (!found) -- panel->search_buffer[--l] = 0; -+ panel->search_buffer[prevpos] = 0; - - paint_panel (panel); - } ---- mc/src/widget.h.utf8 2006-02-28 18:44:28.000000000 +0100 -+++ mc/src/widget.h 2007-01-04 16:20:56.000000000 +0100 -@@ -22,6 +22,7 @@ typedef struct WButton { - char *text; /* text of button */ - int hotkey; /* hot KEY */ - int hotpos; /* offset hot KEY char in text */ -+ wchar_t hotwc; - bcback callback; /* Callback function */ - } WButton; - -@@ -42,6 +43,7 @@ typedef struct WCheck { - char *text; /* text of check button */ - int hotkey; /* hot KEY */ - int hotpos; /* offset hot KEY char in text */ -+ wchar_t hotwc; - } WCheck; - - typedef struct WGauge { -@@ -57,16 +59,20 @@ char *show_hist (GList *history, int wid - - typedef struct { - Widget widget; -- int point; /* cursor position in the input line */ -- int mark; /* The mark position */ -- int first_shown; /* Index of the first shown character */ -- int current_max_len; /* Maximum length of input line */ -- int field_len; /* Length of the editing field */ -+ int point; /* cursor position in the input line (mb chars) */ -+ int mark; /* The mark position (mb chars) */ -+ int first_shown; /* Index of the first shown character (mb chars) */ -+ int current_max_len; /* Maximum length of input line (bytes) */ -+ int field_len; /* Length of the editing field (mb chars) */ - int color; /* color used */ - int first; /* Is first keystroke? */ - int disable_update; /* Do we want to skip updates? */ - int is_password; /* Is this a password input line? */ - char *buffer; /* pointer to editing buffer */ -+#ifdef UTF8 -+ char charbuf[MB_LEN_MAX]; -+#endif /* UTF8 */ -+ int charpoint; - GList *history; /* The history */ - int need_push; /* need to push the current Input on hist? */ - char **completions; /* Possible completions array */ ---- mc/src/tty.h.utf8 2006-05-15 17:46:20.000000000 +0200 -+++ mc/src/tty.h 2007-01-04 16:20:56.000000000 +0100 +diff -up mc-4.6.2-pre1/src/tty.h.utf8 mc-4.6.2-pre1/src/tty.h +--- mc-4.6.2-pre1/src/tty.h.utf8 2006-05-15 15:26:18.000000000 +0200 ++++ mc-4.6.2-pre1/src/tty.h 2008-02-25 14:56:22.000000000 +0100 @@ -8,6 +8,8 @@ of ifdefs in the other files small. */ @@ -1165,191 +158,9 @@ #ifdef HAVE_SLANG # include "myslang.h" #endif ---- mc/src/hotlist.c.utf8 2006-08-08 19:55:46.000000000 +0200 -+++ mc/src/hotlist.c 2007-01-04 16:20:56.000000000 +0100 -@@ -563,7 +563,7 @@ init_i18n_stuff(int list_type, int cols) - - row = hotlist_but [i].y; - ++count [row]; -- len [row] += strlen (hotlist_but [i].text) + 5; -+ len [row] += mbstrlen (hotlist_but [i].text) + 5; - if (hotlist_but [i].flags == DEFPUSH_BUTTON) - len [row] += 2; - } -@@ -588,12 +588,12 @@ init_i18n_stuff(int list_type, int cols) - /* not first int the row */ - if (!strcmp (hotlist_but [i].text, cancel_but)) - hotlist_but [i].x = -- cols - strlen (hotlist_but [i].text) - 13; -+ cols - mbstrlen (hotlist_but [i].text) - 13; - else - hotlist_but [i].x = cur_x [row]; - } - -- cur_x [row] += strlen (hotlist_but [i].text) + 2 -+ cur_x [row] += mbstrlen (hotlist_but [i].text) + 2 - + (hotlist_but [i].flags == DEFPUSH_BUTTON ? 5 : 3); - } - } -@@ -834,7 +834,7 @@ static void add_widgets_i18n(QuickWidget - for (i = 0; i < 3; i++) - { - qw [i].text = _(qw [i].text); -- l[i] = strlen (qw [i].text) + 3; -+ l[i] = mbstrlen (qw [i].text) + 3; - } - space = (len - 4 - l[0] - l[1] - l[2]) / 4; - -@@ -883,7 +883,7 @@ add_new_entry_input (const char *header, - - msglen(text1, &lines1, &cols1); - msglen(text2, &lines2, &cols2); -- len = max ((int) strlen (header), cols1); -+ len = max ((int) mbstrlen (header), cols1); - len = max (len, cols2) + 4; - len = max (len, 64); - -@@ -979,7 +979,7 @@ add_new_group_input (const char *header, - #endif /* ENABLE_NLS */ - - msglen (label, &lines, &cols); -- len = max ((int) strlen (header), cols) + 4; -+ len = max ((int) mbstrlen (header), cols) + 4; - len = max (len, 64); - - #ifdef ENABLE_NLS -@@ -1035,7 +1035,7 @@ void add2hotlist_cmd (void) - { - char *prompt, *label; - const char *cp = _("Label for \"%s\":"); -- int l = strlen (cp); -+ int l = mbstrlen (cp); - char *label_string = g_strdup (current_panel->cwd); - - strip_password (label_string, 1); ---- mc/src/help.c.utf8 2005-07-22 11:29:50.000000000 +0200 -+++ mc/src/help.c 2007-01-04 16:20:56.000000000 +0100 -@@ -449,10 +449,28 @@ static void help_show (Dlg_head *h, cons - #ifndef HAVE_SLANG - addch (acs_map [c]); - #else -+#if defined(UTF8) && SLANG_VERSION < 20000 -+ SLsmg_draw_object (h->y + line + 2, h->x + col + 2, acs_map [c]); -+#else - SLsmg_draw_object (h->y + line + 2, h->x + col + 2, c); -+#endif /* UTF8 */ - #endif -+ } else { -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode) { -+ int len; -+ mbstate_t mbs; -+ wchar_t wc; -+ memset (&mbs, 0, sizeof (mbs)); -+ len = mbrtowc(&wc, p, MB_CUR_MAX, &mbs); -+ if (len <= 0) len = 1; /* skip broken multibyte chars */ -+ -+ SLsmg_write_nwchars(&wc, 1); -+ p += len - 1; - } else -+#endif - addch (c); -+ } - col++; - break; - } -@@ -805,6 +823,12 @@ interactive_display (const char *filenam - message (1, MSG_ERROR, _(" Cannot open file %s \n %s "), filename ? filename : hlpfile, - unix_error_string (errno)); - } -+ else -+ { -+ char *conv = utf8_to_local(data); -+ g_free(data); -+ data = conv; -+ } - - if (!filename) - g_free (hlpfile); ---- mc/src/wtools.c.utf8 2006-09-14 16:16:10.000000000 +0200 -+++ mc/src/wtools.c 2007-01-04 16:20:56.000000000 +0100 -@@ -49,11 +49,11 @@ create_listbox_window (int cols, int lin - /* Adjust sizes */ - lines = (lines > LINES - 6) ? LINES - 6 : lines; - -- if (title && (cols < (len = strlen (title) + 2))) -+ if (title && (cols < (len = mbstrlen (title) + 2))) - cols = len; - - /* no &, but 4 spaces around button for brackets and such */ -- if (cols < (len = strlen (cancel_string) + 3)) -+ if (cols < (len = mbstrlen (cancel_string) + 3)) - cols = len; - - cols = cols > COLS - 6 ? COLS - 6 : cols; -@@ -124,7 +124,7 @@ query_dialog (const char *header, const - va_start (ap, count); - for (i = 0; i < count; i++) { - char *cp = va_arg (ap, char *); -- win_len += strlen (cp) + 6; -+ win_len += mbstrlen (cp) + 6; - if (strchr (cp, '&') != NULL) - win_len--; - } -@@ -133,7 +133,7 @@ query_dialog (const char *header, const - - /* count coordinates */ - msglen (text, &lines, &cols); -- cols = 6 + max (win_len, max ((int) strlen (header), cols)); -+ cols = 6 + max (win_len, max ((int) mbstrlen (header), cols)); - lines += 4 + (count > 0 ? 2 : 0); - xpos = COLS / 2 - cols / 2; - ypos = LINES / 3 - (lines - 3) / 2; -@@ -148,7 +148,7 @@ query_dialog (const char *header, const - va_start (ap, count); - for (i = 0; i < count; i++) { - cur_name = va_arg (ap, char *); -- xpos = strlen (cur_name) + 6; -+ xpos = mbstrlen (cur_name) + 6; - if (strchr (cur_name, '&') != NULL) - xpos--; - -@@ -463,7 +463,7 @@ fg_input_dialog_help (const char *header - quick_widgets[2].histname = histname; - - msglen (text, &lines, &cols); -- len = max ((int) strlen (header), cols) + 4; -+ len = max ((int) mbstrlen (header), cols) + 4; - len = max (len, 64); - - /* The special value of def_text is used to identify password boxes -@@ -485,7 +485,7 @@ fg_input_dialog_help (const char *header - quick_widgets[1].text = _(quick_widgets[1].text); - quick_widgets[0].relative_x = len / 2 + 4; - quick_widgets[1].relative_x = -- len / 2 - (strlen (quick_widgets[1].text) + 9); -+ len / 2 - (mbstrlen (quick_widgets[1].text) + 9); - quick_widgets[0].x_divisions = quick_widgets[1].x_divisions = len; - #endif /* ENABLE_NLS */ - ---- mc/src/util.h.utf8 2006-02-06 17:55:43.000000000 +0100 -+++ mc/src/util.h 2007-01-04 16:20:56.000000000 +0100 -@@ -103,6 +103,13 @@ void init_uid_gid_cache (void); - char *get_group (int); - char *get_owner (int); - -+void fix_utf8(char *str); -+size_t mbstrlen (const char *); -+wchar_t *mbstr_to_wchar (const char *); -+char *wchar_to_mbstr (const wchar_t *); -+char *utf8_to_local(char *str); -+ -+ - #define MAX_I18NTIMELENGTH 14 - #define MIN_I18NTIMELENGTH 10 - #define STD_I18NTIMELENGTH 12 ---- mc/src/widget.c.utf8 2006-05-30 15:46:15.000000000 +0200 -+++ mc/src/widget.c 2007-01-04 16:20:56.000000000 +0100 +diff -up mc-4.6.2-pre1/src/widget.c.utf8 mc-4.6.2-pre1/src/widget.c +--- mc-4.6.2-pre1/src/widget.c.utf8 2006-05-29 13:58:43.000000000 +0200 ++++ mc-4.6.2-pre1/src/widget.c 2008-02-25 14:56:22.000000000 +0100 @@ -36,6 +36,9 @@ #include "global.h" @@ -2065,8 +876,917 @@ return in; } ---- mc/src/util.c.utf8 2005-11-03 03:01:12.000000000 +0100 -+++ mc/src/util.c 2007-01-04 16:20:56.000000000 +0100 +diff -up mc-4.6.2-pre1/src/widget.h.utf8 mc-4.6.2-pre1/src/widget.h +--- mc-4.6.2-pre1/src/widget.h.utf8 2006-02-28 17:15:21.000000000 +0100 ++++ mc-4.6.2-pre1/src/widget.h 2008-02-25 14:56:22.000000000 +0100 +@@ -22,6 +22,7 @@ typedef struct WButton { + char *text; /* text of button */ + int hotkey; /* hot KEY */ + int hotpos; /* offset hot KEY char in text */ ++ wchar_t hotwc; + bcback callback; /* Callback function */ + } WButton; + +@@ -42,6 +43,7 @@ typedef struct WCheck { + char *text; /* text of check button */ + int hotkey; /* hot KEY */ + int hotpos; /* offset hot KEY char in text */ ++ wchar_t hotwc; + } WCheck; + + typedef struct WGauge { +@@ -57,16 +59,20 @@ char *show_hist (GList *history, int wid + + typedef struct { + Widget widget; +- int point; /* cursor position in the input line */ +- int mark; /* The mark position */ +- int first_shown; /* Index of the first shown character */ +- int current_max_len; /* Maximum length of input line */ +- int field_len; /* Length of the editing field */ ++ int point; /* cursor position in the input line (mb chars) */ ++ int mark; /* The mark position (mb chars) */ ++ int first_shown; /* Index of the first shown character (mb chars) */ ++ int current_max_len; /* Maximum length of input line (bytes) */ ++ int field_len; /* Length of the editing field (mb chars) */ + int color; /* color used */ + int first; /* Is first keystroke? */ + int disable_update; /* Do we want to skip updates? */ + int is_password; /* Is this a password input line? */ + char *buffer; /* pointer to editing buffer */ ++#ifdef UTF8 ++ char charbuf[MB_LEN_MAX]; ++#endif /* UTF8 */ ++ int charpoint; + GList *history; /* The history */ + int need_push; /* need to push the current Input on hist? */ + char **completions; /* Possible completions array */ +diff -up mc-4.6.2-pre1/src/menu.c.utf8 mc-4.6.2-pre1/src/menu.c +--- mc-4.6.2-pre1/src/menu.c.utf8 2005-09-05 04:12:09.000000000 +0200 ++++ mc-4.6.2-pre1/src/menu.c 2008-02-25 14:56:22.000000000 +0100 +@@ -22,6 +22,7 @@ + #include + + #include ++#include + + #include "global.h" + #include "tty.h" +@@ -53,35 +54,95 @@ create_menu (const char *name, menu_entr + { + Menu *menu; + const char *cp; ++ int wlen = 0; ++ mbstate_t s; + + menu = (Menu *) g_malloc (sizeof (*menu)); + menu->count = count; + menu->max_entry_len = 20; + menu->entries = entries; ++ menu->name = g_strdup (name); ++ menu_scan_hotkey (menu); ++#ifdef UTF8 ++ menu->wentries = NULL; ++ menu->wname = NULL; ++ if (SLsmg_Is_Unicode) { ++ const char *str = menu->name; ++ memset (&s, 0, sizeof (s)); ++ wlen = mbsrtowcs (NULL, &str, -1, &s); ++ if (wlen > 0) ++ ++wlen; ++ else { ++ wlen = 0; ++ memset (&s, 0, sizeof (s)); ++ } ++ } ++#endif + + if (entries != (menu_entry*) NULL) { + register menu_entry* mp; + for (mp = entries; count--; mp++) { + if (mp->text[0] != '\0') { ++ int len; + #ifdef ENABLE_NLS + mp->text = _(mp->text); + #endif /* ENABLE_NLS */ + cp = strchr (mp->text,'&'); ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ len = mbstrlen(mp->text) + 1; ++ wlen += len; ++ menu->max_entry_len = max (len - 1, menu->max_entry_len); ++ } else ++#endif ++ len = strlen (mp->text); + + if (cp != NULL && *(cp+1) != '\0') { + mp->hot_key = tolower ((unsigned char) *(cp+1)); +- menu->max_entry_len = max ((int) (strlen (mp->text) - 1), +- menu->max_entry_len); ++ menu->max_entry_len = max (len - 1, menu->max_entry_len); + } else { +- menu->max_entry_len = max ((int) strlen (mp->text), +- menu->max_entry_len); ++ menu->max_entry_len = max (len, menu->max_entry_len); + } + } + } + } + +- menu->name = g_strdup (name); +- menu_scan_hotkey(menu); ++#ifdef UTF8 ++ if (wlen) { ++ wchar_t *wp; ++ const char *str; ++ int len; ++ ++ menu->wentries = (wchar_t **) ++ g_malloc (sizeof (wchar_t *) * menu->count ++ + wlen * sizeof (wchar_t)); ++ wp = (wchar_t *) (menu->wentries + menu->count); ++ str = menu->name; ++ len = mbsrtowcs (wp, &str, wlen, &s); ++ if (len > 0) { ++ menu->wname = wp; ++ wlen -= len + 1; ++ wp += len + 1; ++ } else ++ memset (&s, 0, sizeof (s)); ++ if (menu->entries != NULL) ++ for (count = 0; count < menu->count; ++count) ++ if (menu->entries[count].text[0] != '\0') { ++ str = menu->entries[count].text; ++ menu->wentries[count] = wp; ++ len = mbsrtowcs (wp, &str, wlen, &s); ++ if (len > 0) { ++ wlen -= len + 1; ++ wp += len + 1; ++ } else { ++ memset (&s, 0, sizeof (s)); ++ *wp++ = L'\0'; ++ --wlen; ++ } ++ } ++ } ++#endif ++ + menu->start_x = 0; + menu->help_node = g_strdup (help_node); + return menu; +@@ -112,8 +173,26 @@ static void menubar_paint_idx (WMenu *me + const char *text; + + addch((unsigned char)menu->entries [idx].first_letter); +- for (text = menu->entries [idx].text; *text; text++) +- { ++#ifdef UTF8 ++ if (menu->wentries) { ++ wchar_t *wtext, *wp; ++ ++ for (wtext = wp = menu->wentries [idx]; *wtext; wtext++) { ++ if (*wtext == L'&') { ++ if (wtext > wp) ++ SLsmg_write_nwchars (wp, wtext - wp); ++ attrset (color == MENU_SELECTED_COLOR ? ++ MENU_HOTSEL_COLOR : MENU_HOT_COLOR); ++ SLsmg_write_nwchars (++wtext, 1); ++ attrset (color); ++ wp = wtext + 1; ++ } ++ } ++ if (wtext > wp) ++ SLsmg_write_nwchars (wp, wtext - wp); ++ } else ++#endif ++ for (text = menu->entries [idx].text; *text; text++) { + if (*text != '&') + addch(*text); + else { +@@ -122,7 +201,7 @@ static void menubar_paint_idx (WMenu *me + addch(*(++text)); + attrset(color); + } +- } ++ } + } + widget_move (&menubar->widget, y, x + 1); + } +@@ -168,6 +247,12 @@ static void menubar_draw (WMenu *menubar + if (menubar->active) + attrset(i == menubar->selected?MENU_SELECTED_COLOR:SELECTED_COLOR); + widget_move (&menubar->widget, 0, menubar->menu [i]->start_x); ++#ifdef UTF8 ++ if (menubar->menu [i]->wname) ++ SLsmg_write_nwchars (menubar->menu [i]->wname, ++ wcslen (menubar->menu [i]->wname)); ++ else ++#endif + tty_printf ("%s", menubar->menu [i]->name); + } + +@@ -493,7 +578,13 @@ menubar_arrange(WMenu* menubar) + + for (i = 0; i < items; i++) + { +- int len = strlen(menubar->menu[i]->name); ++ int len; ++#ifdef UTF8 ++ if (menubar->menu[i]->wname) ++ len = wcslen (menubar->menu[i]->wname); ++ else ++#endif ++ len = strlen(menubar->menu[i]->name); + menubar->menu[i]->start_x = start_x; + start_x += len + gap; + } +@@ -506,7 +597,13 @@ menubar_arrange(WMenu* menubar) + for (i = 0; i < items; i++) + { + /* preserve length here, to be used below */ +- gap -= (menubar->menu[i]->start_x = strlen(menubar->menu[i]->name)); ++#ifdef UTF8 ++ if (menubar->menu[i]->wname) ++ menubar->menu[i]->start_x = wcslen (menubar->menu[i]->wname); ++ else ++#endif ++ menubar->menu[i]->start_x = strlen (menubar->menu[i]->name); ++ gap -= menubar->menu[i]->start_x; + } + + gap /= (items - 1); +@@ -530,6 +627,9 @@ menubar_arrange(WMenu* menubar) + void + destroy_menu (Menu *menu) + { ++#ifdef UTF8 ++ g_free (menu->wentries); ++#endif + g_free (menu->name); + g_free (menu->help_node); + g_free (menu); +diff -up mc-4.6.2-pre1/src/wtools.c.utf8 mc-4.6.2-pre1/src/wtools.c +--- mc-4.6.2-pre1/src/wtools.c.utf8 2006-09-14 11:12:49.000000000 +0200 ++++ mc-4.6.2-pre1/src/wtools.c 2008-02-25 14:56:22.000000000 +0100 +@@ -49,11 +49,11 @@ create_listbox_window (int cols, int lin + /* Adjust sizes */ + lines = (lines > LINES - 6) ? LINES - 6 : lines; + +- if (title && (cols < (len = strlen (title) + 2))) ++ if (title && (cols < (len = mbstrlen (title) + 2))) + cols = len; + + /* no &, but 4 spaces around button for brackets and such */ +- if (cols < (len = strlen (cancel_string) + 3)) ++ if (cols < (len = mbstrlen (cancel_string) + 3)) + cols = len; + + cols = cols > COLS - 6 ? COLS - 6 : cols; +@@ -124,7 +124,7 @@ query_dialog (const char *header, const + va_start (ap, count); + for (i = 0; i < count; i++) { + char *cp = va_arg (ap, char *); +- win_len += strlen (cp) + 6; ++ win_len += mbstrlen (cp) + 6; + if (strchr (cp, '&') != NULL) + win_len--; + } +@@ -133,7 +133,7 @@ query_dialog (const char *header, const + + /* count coordinates */ + msglen (text, &lines, &cols); +- cols = 6 + max (win_len, max ((int) strlen (header), cols)); ++ cols = 6 + max (win_len, max ((int) mbstrlen (header), cols)); + lines += 4 + (count > 0 ? 2 : 0); + xpos = COLS / 2 - cols / 2; + ypos = LINES / 3 - (lines - 3) / 2; +@@ -148,7 +148,7 @@ query_dialog (const char *header, const + va_start (ap, count); + for (i = 0; i < count; i++) { + cur_name = va_arg (ap, char *); +- xpos = strlen (cur_name) + 6; ++ xpos = mbstrlen (cur_name) + 6; + if (strchr (cur_name, '&') != NULL) + xpos--; + +@@ -463,7 +463,7 @@ fg_input_dialog_help (const char *header + quick_widgets[2].histname = histname; + + msglen (text, &lines, &cols); +- len = max ((int) strlen (header), cols) + 4; ++ len = max ((int) mbstrlen (header), cols) + 4; + len = max (len, 64); + + /* The special value of def_text is used to identify password boxes +@@ -485,7 +485,7 @@ fg_input_dialog_help (const char *header + quick_widgets[1].text = _(quick_widgets[1].text); + quick_widgets[0].relative_x = len / 2 + 4; + quick_widgets[1].relative_x = +- len / 2 - (strlen (quick_widgets[1].text) + 9); ++ len / 2 - (mbstrlen (quick_widgets[1].text) + 9); + quick_widgets[0].x_divisions = quick_widgets[1].x_divisions = len; + #endif /* ENABLE_NLS */ + +diff -up mc-4.6.2-pre1/src/learn.c.utf8 mc-4.6.2-pre1/src/learn.c +--- mc-4.6.2-pre1/src/learn.c.utf8 2005-05-27 05:35:15.000000000 +0200 ++++ mc-4.6.2-pre1/src/learn.c 2008-02-25 14:56:22.000000000 +0100 +@@ -237,7 +237,7 @@ init_learn (void) + learn_but[0].x = 78 / 2 + 4; + + learn_but[1].text = _(learn_but[1].text); +- learn_but[1].x = 78 / 2 - (strlen (learn_but[1].text) + 9); ++ learn_but[1].x = 78 / 2 - (mbstrlen (learn_but[1].text) + 9); + + learn_title = _(learn_title); + i18n_flag = 1; +diff -up mc-4.6.2-pre1/src/slint.c.utf8 mc-4.6.2-pre1/src/slint.c +--- mc-4.6.2-pre1/src/slint.c.utf8 2005-09-05 04:14:29.000000000 +0200 ++++ mc-4.6.2-pre1/src/slint.c 2008-02-25 14:56:22.000000000 +0100 +@@ -141,7 +141,9 @@ void + slang_init (void) + { + SLtt_get_terminfo (); +- ++#if SLANG_VERSION >= 20000 ++ SLutf8_enable (-1); ++#endif + /* + * If the terminal in not in terminfo but begins with a well-known + * string such as "linux" or "xterm" S-Lang will go on, but the +diff -up mc-4.6.2-pre1/src/option.c.utf8 mc-4.6.2-pre1/src/option.c +--- mc-4.6.2-pre1/src/option.c.utf8 2006-02-28 17:15:21.000000000 +0100 ++++ mc-4.6.2-pre1/src/option.c 2008-02-25 14:56:22.000000000 +0100 +@@ -123,12 +123,12 @@ init_configure (void) + title2 = _(" Pause after run... "); + title3 = _(" Other options "); + +- first_width = strlen (title1) + 1; +- second_width = strlen (title3) + 1; ++ first_width = mbstrlen (title1) + 1; ++ second_width = mbstrlen (title3) + 1; + + for (i = 0; check_options[i].text; i++) { + check_options[i].text = _(check_options[i].text); +- l1 = strlen (check_options[i].text) + 7; ++ l1 = mbstrlen (check_options[i].text) + 7; + if (i >= OTHER_OPTIONS) { + if (l1 > first_width) + first_width = l1; +@@ -141,23 +141,23 @@ init_configure (void) + i = PAUSE_OPTIONS; + while (i--) { + pause_options[i] = _(pause_options[i]); +- l1 = strlen (pause_options[i]) + 7; ++ l1 = mbstrlen (pause_options[i]) + 7; + if (l1 > first_width) + first_width = l1; + } + +- l1 = strlen (title2) + 1; ++ l1 = mbstrlen (title2) + 1; + if (l1 > first_width) + first_width = l1; + +- l1 = 11 + strlen (ok_button) +- + strlen (save_button) +- + strlen (cancel_button); ++ l1 = 11 + mbstrlen (ok_button) ++ + mbstrlen (save_button) ++ + mbstrlen (cancel_button); + + i = (first_width + second_width - l1) / 4; + b1 = 5 + i; +- b2 = b1 + strlen (ok_button) + i + 6; +- b3 = b2 + strlen (save_button) + i + 4; ++ b2 = b1 + mbstrlen (ok_button) + i + 6; ++ b3 = b2 + mbstrlen (save_button) + i + 4; + + i18n_config_flag = 1; + } +diff -up mc-4.6.2-pre1/src/menu.h.utf8 mc-4.6.2-pre1/src/menu.h +--- mc-4.6.2-pre1/src/menu.h.utf8 2004-12-03 20:17:47.000000000 +0100 ++++ mc-4.6.2-pre1/src/menu.h 2008-02-25 14:56:22.000000000 +0100 +@@ -21,6 +21,8 @@ typedef struct Menu { + menu_entry *entries; + int start_x; /* position relative to menubar start */ + char *help_node; ++ wchar_t **wentries; ++ wchar_t *wname; + } Menu; + + extern int menubar_visible; +diff -up mc-4.6.2-pre1/src/file.c.utf8 mc-4.6.2-pre1/src/file.c +--- mc-4.6.2-pre1/src/file.c.utf8 2007-02-22 15:29:11.000000000 +0100 ++++ mc-4.6.2-pre1/src/file.c 2008-02-25 14:56:22.000000000 +0100 +@@ -161,15 +161,20 @@ static const char * + do_transform_source (FileOpContext *ctx, const char *source) + { + size_t j, k, l, len; +- const char *fnsource = x_basename (source); ++ char *fnsource = g_strdup (x_basename (source)); + int next_reg; + enum CaseConvs case_conv = NO_CONV; + static char fntarget[MC_MAXPATHLEN]; + ++#ifdef UTF8 ++ fix_utf8(fnsource); ++#endif ++ + len = strlen (fnsource); + j = re_match (&ctx->rx, fnsource, len, 0, &ctx->regs); + if (j != len) { + transform_error = FILE_SKIP; ++ g_free (fnsource); + return NULL; + } + for (next_reg = 1, j = 0, k = 0; j < strlen (ctx->dest_mask); j++) { +@@ -213,6 +218,7 @@ do_transform_source (FileOpContext *ctx, + || ctx->regs.start[next_reg] < 0) { + message (1, MSG_ERROR, _(" Invalid target mask ")); + transform_error = FILE_ABORT; ++ g_free(fnsource); + return NULL; + } + for (l = (size_t) ctx->regs.start[next_reg]; +@@ -227,6 +233,7 @@ do_transform_source (FileOpContext *ctx, + } + } + fntarget[k] = 0; ++ g_free(fnsource); + return fntarget; + } + +@@ -1688,13 +1695,13 @@ panel_operate_generate_prompt (const WPa + *dp = '\0'; + + if (single_source) { +- i = fmd_xlen - strlen (format_string) - 4; ++ i = fmd_xlen - mbstrlen (format_string) - 4; + g_snprintf (cmd_buf, sizeof (cmd_buf), format_string, + name_trunc (single_source, i)); + } else { + g_snprintf (cmd_buf, sizeof (cmd_buf), format_string, + panel->marked); +- i = strlen (cmd_buf) + 6 - fmd_xlen; ++ i = mbstrlen (cmd_buf) + 6 - fmd_xlen; + if (i > 0) { + fmd_xlen += i; + fmd_init_i18n (TRUE); /* to recalculate positions of child widgets */ +diff -up mc-4.6.2-pre1/src/main.c.utf8 mc-4.6.2-pre1/src/main.c +--- mc-4.6.2-pre1/src/main.c.utf8 2006-09-22 17:14:58.000000000 +0200 ++++ mc-4.6.2-pre1/src/main.c 2008-02-25 14:56:22.000000000 +0100 +@@ -704,7 +704,7 @@ load_prompt (int fd, void *unused) + int prompt_len; + + tmp_prompt = strip_ctrl_codes (subshell_prompt); +- prompt_len = strlen (tmp_prompt); ++ prompt_len = mbstrlen (tmp_prompt); + + /* Check for prompts too big */ + if (COLS > 8 && prompt_len > COLS - 8) { +@@ -1610,7 +1610,11 @@ update_xterm_title_path (void) + if (xterm_flag && xterm_title) { + p = s = g_strdup (strip_home_and_password (current_panel->cwd)); + do { ++#ifndef UTF8 + if (!is_printable ((unsigned char) *s)) ++#else /* UTF8 */ ++ if (*(unsigned char *)s < ' ') ++#endif /* UTF8 */ + *s = '?'; + } while (*++s); + fprintf (stdout, "\33]0;mc - %s\7", p); +diff -up mc-4.6.2-pre1/src/find.c.utf8 mc-4.6.2-pre1/src/find.c +--- mc-4.6.2-pre1/src/find.c.utf8 2006-02-04 12:03:35.000000000 +0100 ++++ mc-4.6.2-pre1/src/find.c 2008-02-25 14:56:22.000000000 +0100 +@@ -217,7 +217,7 @@ find_parameters (char **start_dir, char + int l1, maxlen = 0; + + while (i--) { +- l1 = strlen (labs[i] = _(labs[i])); ++ l1 = mbstrlen (labs[i] = _(labs[i])); + if (l1 > maxlen) + maxlen = l1; + } +@@ -226,7 +226,7 @@ find_parameters (char **start_dir, char + FIND_X = i; + + for (i = sizeof (buts) / sizeof (buts[0]), l1 = 0; i--;) { +- l1 += strlen (buts[i] = _(buts[i])); ++ l1 += mbstrlen (buts[i] = _(buts[i])); + } + l1 += 21; + if (l1 > FIND_X) +@@ -235,8 +235,8 @@ find_parameters (char **start_dir, char + ilen = FIND_X - 7 - maxlen; /* for the case of very long buttons :) */ + istart = FIND_X - 3 - ilen; + +- b1 = b0 + strlen (buts[0]) + 7; +- b2 = FIND_X - (strlen (buts[2]) + 6); ++ b1 = b0 + mbstrlen (buts[0]) + 7; ++ b2 = FIND_X - (mbstrlen (buts[2]) + 6); + + i18n_flag = 1; + case_label = _(case_label); +@@ -863,7 +863,7 @@ setup_gui (void) + if (!i18n_flag) { + register int i = sizeof (fbuts) / sizeof (fbuts[0]); + while (i--) +- fbuts[i].len = strlen (fbuts[i].text = _(fbuts[i].text)) + 3; ++ fbuts[i].len = mbstrlen (fbuts[i].text = _(fbuts[i].text)) + 3; + fbuts[2].len += 2; /* DEFPUSH_BUTTON */ + i18n_flag = 1; + } +@@ -1028,7 +1028,7 @@ find_file (char *start_dir, char *patter + + if (!next_free) /* first turn i.e clean old list */ + panel_clean_dir (current_panel); +- list->list[next_free].fnamelen = strlen (name); ++ list->list[next_free].fnamelen = mbstrlen (name); + list->list[next_free].fname = name; + list->list[next_free].f.marked = 0; + list->list[next_free].f.link_to_dir = link_to_dir; +diff -up mc-4.6.2-pre1/src/view.c.utf8 mc-4.6.2-pre1/src/view.c +--- mc-4.6.2-pre1/src/view.c.utf8 2006-12-30 14:16:54.000000000 +0100 ++++ mc-4.6.2-pre1/src/view.c 2008-02-25 14:56:22.000000000 +0100 +@@ -43,6 +43,10 @@ + #include + #include + ++#ifdef UTF8 ++#include ++#endif /* UTF8 */ ++ + #include "global.h" + #include "tty.h" + #include "cmd.h" /* For view_other_cmd */ +@@ -1642,7 +1646,7 @@ view_display_status (WView *view) + hline (' ', width); + + file_label = _("File: %s"); +- file_label_width = strlen (file_label) - 2; ++ file_label_width = mbstrlen (file_label) - 2; + file_name = view->filename ? view->filename + : view->command ? view->command + : ""; +@@ -1910,6 +1914,12 @@ view_display_text (WView * view) + offset_type from; + int c; + struct hexedit_change_node *curr = view->change_list; ++#ifdef UTF8 ++ mbstate_t mbs; ++ char mbbuf[MB_LEN_MAX]; ++ int mblen; ++ wchar_t wc; ++#endif /* UTF8 */ + + view_display_clean (view); + view_display_ruler (view); +@@ -1922,8 +1932,37 @@ view_display_text (WView * view) + + tty_setcolor (NORMAL_COLOR); + for (row = 0, col = 0; row < height && (c = get_byte (view, from)) != -1; from++) { +- ++#ifndef UTF8 + if (view->text_nroff_mode && c == '\b') { ++#else /* UTF8 */ ++ mblen = 1; ++ mbbuf[0] = convert_to_display_c (c); ++ ++ while (mblen < MB_LEN_MAX) { ++ int res; ++ memset (&mbs, 0, sizeof (mbs)); ++ res = mbrtowc (&wc, mbbuf, mblen, &mbs); ++ if (res <= 0 && res != -2) { ++ wc = '.'; ++ mblen = 1; ++ break; ++ } ++ if (res == mblen) ++ break; ++ ++ mbbuf[mblen] = convert_to_display_c (get_byte (view, from + mblen)); ++ mblen++; ++ } ++ ++ if (mblen == MB_LEN_MAX) { ++ wc = '.'; ++ mblen = 1; ++ } ++ ++ from += mblen - 1; ++ ++ if (view->text_nroff_mode && wc == '\b') { ++#endif /* UTF8 */ + int c_prev; + int c_next; + +@@ -1988,10 +2027,17 @@ view_display_text (WView * view) + if (col >= view->dpy_text_column + && col - view->dpy_text_column < width) { + widget_move (view, top + row, left + (col - view->dpy_text_column)); ++#ifndef UTF8 + c = convert_to_display_c (c); + if (!is_printable (c)) + c = '.'; + tty_print_char (c); ++#else ++ wc = convert_to_display_c (wc); ++ if (!iswprint (wc)) ++ wc = '.'; ++ tty_print_char (wc); ++#endif + } + col++; + tty_setcolor (NORMAL_COLOR); +diff -up mc-4.6.2-pre1/src/dialog.c.utf8 mc-4.6.2-pre1/src/dialog.c +--- mc-4.6.2-pre1/src/dialog.c.utf8 2005-09-05 05:20:27.000000000 +0200 ++++ mc-4.6.2-pre1/src/dialog.c 2008-02-25 14:56:22.000000000 +0100 +@@ -166,7 +166,7 @@ common_dialog_repaint (struct Dlg_head * + + if (h->title) { + attrset (DLG_HOT_NORMALC (h)); +- dlg_move (h, space, (h->cols - strlen (h->title)) / 2); ++ dlg_move (h, space, (h->cols - mbstrlen (h->title)) / 2); + addstr (h->title); + } + } +diff -up mc-4.6.2-pre1/src/util.h.utf8 mc-4.6.2-pre1/src/util.h +--- mc-4.6.2-pre1/src/util.h.utf8 2006-02-03 18:04:17.000000000 +0100 ++++ mc-4.6.2-pre1/src/util.h 2008-02-25 14:56:22.000000000 +0100 +@@ -103,6 +103,13 @@ void init_uid_gid_cache (void); + char *get_group (int); + char *get_owner (int); + ++void fix_utf8(char *str); ++size_t mbstrlen (const char *); ++wchar_t *mbstr_to_wchar (const char *); ++char *wchar_to_mbstr (const wchar_t *); ++char *utf8_to_local(char *str); ++ ++ + #define MAX_I18NTIMELENGTH 14 + #define MIN_I18NTIMELENGTH 10 + #define STD_I18NTIMELENGTH 12 +diff -up mc-4.6.2-pre1/src/boxes.c.utf8 mc-4.6.2-pre1/src/boxes.c +--- mc-4.6.2-pre1/src/boxes.c.utf8 2006-02-28 17:15:21.000000000 +0100 ++++ mc-4.6.2-pre1/src/boxes.c 2008-02-25 14:56:22.000000000 +0100 +@@ -153,23 +153,23 @@ display_init (int radio_sel, char *init_ + display_title = _(display_title); + for (i = 0; i < LIST_TYPES; i++) { + displays[i] = _(displays[i]); +- if ((l = strlen (displays[i])) > maxlen) ++ if ((l = mbstrlen (displays[i])) > maxlen) + maxlen = l; + } + +- i = strlen (ok_button) + 5; +- l = strlen (cancel_button) + 3; ++ i = mbstrlen (ok_button) + 5; ++ l = mbstrlen (cancel_button) + 3; + l = max (i, l); + + i = maxlen + l + 16; + if (i > DISPLAY_X) + DISPLAY_X = i; + +- i = strlen (user_mini_status) + 13; ++ i = mbstrlen (user_mini_status) + 13; + if (i > DISPLAY_X) + DISPLAY_X = i; + +- i = strlen (display_title) + 10; ++ i = mbstrlen (display_title) + 10; + if (i > DISPLAY_X) + DISPLAY_X = i; + +@@ -288,20 +288,20 @@ sort_box (sortfn *sort_fn, int *reverse, + int maxlen = 0; + for (i = SORT_TYPES - 1; i >= 0; i--) { + sort_orders_names[i] = _(sort_orders[i].sort_name); +- r = strlen (sort_orders_names[i]); ++ r = mbstrlen (sort_orders_names[i]); + if (r > maxlen) + maxlen = r; + } + + check_pos = maxlen + 9; + +- r = strlen (reverse_label) + 4; +- i = strlen (case_label) + 4; ++ r = mbstrlen (reverse_label) + 4; ++ i = mbstrlen (case_label) + 4; + if (i > r) + r = i; + +- l = strlen (ok_button) + 6; +- i = strlen (cancel_button) + 4; ++ l = mbstrlen (ok_button) + 6; ++ i = mbstrlen (cancel_button) + 4; + if (i > l) + l = i; + +@@ -310,7 +310,7 @@ sort_box (sortfn *sort_fn, int *reverse, + if (i > SORT_X) + SORT_X = i; + +- i = strlen (sort_title) + 6; ++ i = mbstrlen (sort_title) + 6; + if (i > SORT_X) + SORT_X = i; + +@@ -408,7 +408,7 @@ confirm_box (void) + while (i--) + { + conf_widgets [i].text = _(conf_widgets [i].text); +- l1 = strlen (conf_widgets [i].text) + 3; ++ l1 = mbstrlen (conf_widgets [i].text) + 3; + if (l1 > maxlen) + maxlen = l1; + } +@@ -423,8 +423,8 @@ confirm_box (void) + * And this for the case when buttons with some space to the right + * do not fit within 2/6 + */ +- l1 = strlen (conf_widgets [0].text) + 3; +- i = strlen (conf_widgets [1].text) + 5; ++ l1 = mbstrlen (conf_widgets [0].text) + 3; ++ i = mbstrlen (conf_widgets [1].text) + 5; + if (i > l1) + l1 = i; + +@@ -497,11 +497,11 @@ display_bits_box (void) + { + display_widgets [i].text = _(display_widgets[i].text); + display_bits_str [i] = _(display_bits_str [i]); +- l1 = strlen (display_bits_str [i]); ++ l1 = mbstrlen (display_bits_str [i]); + if (l1 > maxlen) + maxlen = l1; + } +- l1 = strlen (display_widgets [2].text); ++ l1 = mbstrlen (display_widgets [2].text); + if (l1 > maxlen) + maxlen = l1; + +@@ -509,8 +509,8 @@ display_bits_box (void) + display_bits.xlen = (maxlen + 5) * 6 / 4; + + /* See above confirm_box */ +- l1 = strlen (display_widgets [0].text) + 3; +- i = strlen (display_widgets [1].text) + 5; ++ l1 = mbstrlen (display_widgets [0].text) + 3; ++ i = mbstrlen (display_widgets [1].text) + 5; + if (i > l1) + l1 = i; + +@@ -605,7 +605,7 @@ init_disp_bits_box (void) + + cpname = _("&Select"); + add_widget (dbits_dlg, +- button_new (4, DISPX - 8 - strlen (cpname), B_USER, ++ button_new (4, DISPX - 8 - mbstrlen (cpname), B_USER, + NORMAL_BUTTON, cpname, sel_charset_button)); + + return dbits_dlg; +@@ -816,7 +816,7 @@ cd_dialog (void) + quick_widgets [1].y_divisions = + quick_widgets [0].y_divisions = Quick_input.ylen = 5; + +- len = strlen (quick_widgets [1].text); ++ len = mbstrlen (quick_widgets [1].text); + + quick_widgets [0].relative_x = + quick_widgets [1].relative_x + len + 1; +@@ -975,7 +975,7 @@ jobs_cmd (void) + { + job_buttons [i].name = _(job_buttons [i].name); + +- len = strlen (job_buttons [i].name) + 4; ++ len = mbstrlen (job_buttons [i].name) + 4; + JOBS_X = max (JOBS_X, startx + len + 3); + + job_buttons [i].xpos = startx; +@@ -984,7 +984,7 @@ jobs_cmd (void) + + /* Last button - Ok a.k.a. Cancel :) */ + job_buttons [n_buttons - 1].xpos = +- JOBS_X - strlen (job_buttons [n_buttons - 1].name) - 7; ++ JOBS_X - mbstrlen (job_buttons [n_buttons - 1].name) - 7; + + i18n_flag = 1; + } +@@ -1042,7 +1042,7 @@ vfs_smb_get_authinfo (const char *host, + + while (i--) + { +- l1 = strlen (labs [i] = _(labs [i])); ++ l1 = mbstrlen (labs [i] = _(labs [i])); + if (l1 > maxlen) + maxlen = l1; + } +@@ -1052,7 +1052,7 @@ vfs_smb_get_authinfo (const char *host, + + for (i = sizeof(buts)/sizeof(buts[0]), l1 = 0; i--; ) + { +- l1 += strlen (buts [i] = _(buts [i])); ++ l1 += mbstrlen (buts [i] = _(buts [i])); + } + l1 += 15; + if (l1 > dialog_x) +@@ -1061,7 +1061,7 @@ vfs_smb_get_authinfo (const char *host, + ilen = dialog_x - 7 - maxlen; /* for the case of very long buttons :) */ + istart = dialog_x - 3 - ilen; + +- b2 = dialog_x - (strlen(buts[1]) + 6); ++ b2 = dialog_x - (mbstrlen(buts[1]) + 6); + + i18n_flag = 1; + } +diff -up mc-4.6.2-pre1/src/help.c.utf8 mc-4.6.2-pre1/src/help.c +--- mc-4.6.2-pre1/src/help.c.utf8 2007-01-20 12:40:45.000000000 +0100 ++++ mc-4.6.2-pre1/src/help.c 2008-02-25 14:56:22.000000000 +0100 +@@ -447,10 +447,28 @@ static void help_show (Dlg_head *h, cons + #ifndef HAVE_SLANG + addch (acs_map [c]); + #else ++#if defined(UTF8) && SLANG_VERSION < 20000 ++ SLsmg_draw_object (h->y + line + 2, h->x + col + 2, acs_map [c]); ++#else + SLsmg_draw_object (h->y + line + 2, h->x + col + 2, c); ++#endif /* UTF8 */ + #endif ++ } else { ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ int len; ++ mbstate_t mbs; ++ wchar_t wc; ++ memset (&mbs, 0, sizeof (mbs)); ++ len = mbrtowc(&wc, p, MB_CUR_MAX, &mbs); ++ if (len <= 0) len = 1; /* skip broken multibyte chars */ ++ ++ SLsmg_write_nwchars(&wc, 1); ++ p += len - 1; + } else ++#endif + addch (c); ++ } + col++; + break; + } +@@ -803,6 +821,12 @@ interactive_display (const char *filenam + message (1, MSG_ERROR, _(" Cannot open file %s \n %s "), filename ? filename : hlpfile, + unix_error_string (errno)); + } ++ else ++ { ++ char *conv = utf8_to_local(data); ++ g_free(data); ++ data = conv; ++ } + + if (!filename) + g_free (hlpfile); +diff -up mc-4.6.2-pre1/src/achown.c.utf8 mc-4.6.2-pre1/src/achown.c +--- mc-4.6.2-pre1/src/achown.c.utf8 2005-09-05 03:36:58.000000000 +0200 ++++ mc-4.6.2-pre1/src/achown.c 2008-02-25 14:56:22.000000000 +0100 +@@ -584,6 +584,12 @@ init_chown_advanced (void) + b_att[2] = button_new (XTRACT (6)); + b_user = button_new (XTRACT (5)); + b_group = button_new (XTRACT (4)); ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ b_user->text = g_realloc (b_user->text, MB_CUR_MAX * 15 + 1); ++ b_group->text = g_realloc (b_group->text, MB_CUR_MAX * 15 + 1); ++ } ++#endif + + add_widget (ch_dlg, b_group); + add_widget (ch_dlg, b_user); +diff -up mc-4.6.2-pre1/src/tty.c.utf8 mc-4.6.2-pre1/src/tty.c +--- mc-4.6.2-pre1/src/tty.c.utf8 2006-05-23 09:38:59.000000000 +0200 ++++ mc-4.6.2-pre1/src/tty.c 2008-02-25 14:56:22.000000000 +0100 +@@ -134,10 +134,12 @@ tty_print_char(int c) + * defined or not. Congratulations! At least, they left the API call + * for SLsmg_write_nchars as it has always been. + */ +- char ch; +- +- ch = c; +- SLsmg_write_nchars(&ch, 1); ++ ++ /* The above comment is a nonsense, SLsmg_write_char(c) works pretty ++ * good for me. So please don't mess with Red Hat people. ++ * Jindrich Novy (jnovy@redhat.com) ++ */ ++ SLsmg_write_char(c); + #else + addch(c); + #endif +diff -up mc-4.6.2-pre1/src/util.c.utf8 mc-4.6.2-pre1/src/util.c +--- mc-4.6.2-pre1/src/util.c.utf8 2005-11-03 03:18:38.000000000 +0100 ++++ mc-4.6.2-pre1/src/util.c 2008-02-25 14:56:22.000000000 +0100 @@ -33,7 +33,11 @@ #include #include @@ -2536,113 +2256,578 @@ } *w = 0; return s; ---- mc/src/file.c.utf8 2006-05-23 16:20:39.000000000 +0200 -+++ mc/src/file.c 2007-01-04 16:20:56.000000000 +0100 -@@ -161,15 +161,20 @@ static const char * - do_transform_source (FileOpContext *ctx, const char *source) +diff -up mc-4.6.2-pre1/src/screen.c.utf8 mc-4.6.2-pre1/src/screen.c +--- mc-4.6.2-pre1/src/screen.c.utf8 2007-08-24 14:22:29.000000000 +0200 ++++ mc-4.6.2-pre1/src/screen.c 2008-02-25 14:56:22.000000000 +0100 +@@ -171,21 +171,56 @@ add_permission_string (char *dest, int w + static const char * + string_file_name (file_entry *fe, int len) { - size_t j, k, l, len; -- const char *fnsource = x_basename (source); -+ char *fnsource = g_strdup (x_basename (source)); - int next_reg; - enum CaseConvs case_conv = NO_CONV; - static char fntarget[MC_MAXPATHLEN]; +- static char buffer [MC_MAXPATHLEN + 1]; + size_t i; +- for (i = 0; i < sizeof(buffer) - 1; i++) { +- char c; +#ifdef UTF8 -+ fix_utf8(fnsource); ++ static char buffer [BUF_SMALL * 4]; ++ mbstate_t s; ++ int mbmax = MB_CUR_MAX; ++ const char *str = fe->fname; + +- c = fe->fname[i]; ++ memset (&s, 0, sizeof (s)); ++#else ++ static char buffer [BUF_SMALL]; ++#endif + +- if (!c) +- break; ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) ++ for (i = 0; i < sizeof (buffer) - 1; i++) { ++ wchar_t wc; ++ int len; + +- if (!is_printable(c)) +- c = '?'; ++ len = mbrtowc (&wc, str, mbmax, &s); ++ if (!len) ++ break; ++ if (len < 0) { ++ memset (&s, 0, sizeof (s)); ++ buffer[i] = '?'; ++ str++; ++ continue; ++ } ++ if (!is_printable (wc)) { ++ buffer[i] = '?'; ++ str++; ++ continue; ++ } ++ if (i >= sizeof (buffer) - len) ++ break; ++ memcpy (buffer + i, str, len); ++ i += len - 1; ++ str += len; ++ } else ++#endif ++ for (i = 0; i < sizeof(buffer) - 1; i++) { ++ char c; ++ ++ c = fe->fname[i]; + +- buffer[i] = c; ++ if (!c) break; ++ ++ if (!is_printable(c)) c = '?'; ++ ++ buffer[i] = c; + } + + buffer[i] = 0; +@@ -450,42 +485,6 @@ static struct { + { "dot", 1, 0, J_RIGHT, " ", 0, string_dot, NULL }, + }; + +-static char * +-to_buffer (char *dest, int just_mode, int len, const char *txt) +-{ +- int txtlen = strlen (txt); +- int still, over; +- +- /* Fill buffer with spaces */ +- memset (dest, ' ', len); +- +- still = (over=(txtlen > len)) ? (txtlen - len) : (len - txtlen); +- +- switch (HIDE_FIT(just_mode)){ +- case J_LEFT: +- still = 0; +- break; +- case J_CENTER: +- still /= 2; +- break; +- case J_RIGHT: +- default: +- break; +- } +- +- if (over){ +- if (IS_FIT(just_mode)) +- strcpy (dest, name_trunc(txt, len)); +- else +- strncpy (dest, txt+still, len); +- } else +- strncpy (dest+still, txt, txtlen); +- +- dest[len] = '\0'; +- +- return (dest + len); +-} +- + static int + file_compute_color (int attr, file_entry *fe) + { +@@ -539,14 +538,18 @@ file_compute_color (int attr, file_entry + + /* Formats the file number file_index of panel in the buffer dest */ + static void +-format_file (char *dest, int limit, WPanel *panel, int file_index, int width, int attr, int isstatus) ++format_file (WPanel *panel, int file_index, int width, int attr, int isstatus) + { + int color, length, empty_line; + const char *txt; +- char *old_pos; +- char *cdest = dest; + format_e *format, *home; + file_entry *fe; ++#ifdef UTF8 ++ char buffer[BUF_MEDIUM * sizeof (wchar_t)]; ++#else ++ char buffer[BUF_MEDIUM]; ++#endif ++ int txtwidth = 0; + + length = 0; + empty_line = (file_index >= panel->count); +@@ -564,34 +567,137 @@ format_file (char *dest, int limit, WPan + break; + + if (format->string_fn){ +- int len; ++ int len, still, over, perm, txtlen, wide; + + if (empty_line) + txt = " "; + else + txt = (*format->string_fn)(fe, format->field_len); + +- old_pos = cdest; +- + len = format->field_len; + if (len + length > width) + len = width - length; +- if (len + (cdest - dest) > limit) +- len = limit - (cdest - dest); ++ if (len >= BUF_MEDIUM) ++ len = BUF_MEDIUM - 1; + if (len <= 0) + break; +- cdest = to_buffer (cdest, format->just_mode, len, txt); +- length += len; + +- attrset (color); ++ perm = 0; ++ if (permission_mode) { ++ if (!strcmp(format->id, "perm")) ++ perm = 1; ++ else if (!strcmp(format->id, "mode")) ++ perm = 2; ++ } + +- if (permission_mode && !strcmp(format->id, "perm")) +- add_permission_string (old_pos, format->field_len, fe, attr, color, 0); +- else if (permission_mode && !strcmp(format->id, "mode")) +- add_permission_string (old_pos, format->field_len, fe, attr, color, 1); +- else +- addstr (old_pos); ++ wide = 0; ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode && !empty_line && !perm) { ++ mbstate_t s; ++ const char *str = txt; ++ ++ memset (&s, 0, sizeof (s)); ++ txtlen = mbsrtowcs ((wchar_t *) buffer, &str, ++ sizeof (buffer) / sizeof (wchar_t), &s); ++ if (txtlen < 0) { ++ txt = " "; ++ txtlen = 1; ++ } else { ++ wide = 1; ++ txtwidth = wcswidth((wchar_t*)buffer, txtlen); ++ } ++ } else ++#endif ++ { ++ txtlen = mbstrlen (txt); ++ txtwidth = txtlen; ++ } ++ ++ over = txtwidth > len; ++ still = over ? txtlen - len : len - txtlen; ++ ++ switch (HIDE_FIT(format->just_mode)) { ++ case J_LEFT: ++ still = 0; ++ break; ++ case J_CENTER: ++ still /= 2; ++ break; ++ case J_RIGHT: ++ default: ++ break; ++ } ++ ++ attrset (color); ++ ++ if (wide) { ++#ifdef UTF8 ++ if (over) { ++ if (IS_FIT (format->just_mode)) { ++ int n1 = 0; ++ int width1 = 0; ++ int n2 = 0; ++ int width2 = 0; ++ int len1 = len / 2; ++ int len2; ++ ++ while (1) { ++ int w = wcwidth(((wchar_t *) buffer)[n1]); ++ if (width1 + w <= len1) { ++ width1 += w; ++ n1++; ++ } ++ else ++ break; ++ } ++ len2 = len - width1 - 1; ++ ++ while (1) { ++ int w = wcwidth(((wchar_t *) buffer)[txtlen - n2 - 1]); ++ if (width2 + w <= len2) { ++ width2 += w; ++ n2++; ++ } ++ else ++ break; ++ } ++ ++ ++ SLsmg_write_nwchars ((wchar_t *) buffer, n1); ++ SLsmg_write_nwchars (L"~", 1); ++ printw ("%*s", len - width1 - width2 - 1, ""); ++ SLsmg_write_nwchars (((wchar_t *) buffer) ++ + txtlen - n2, n2); ++ } else ++ SLsmg_write_nwchars ((wchar_t *) buffer, len); ++ } else { ++ printw ("%*s", still, ""); ++ SLsmg_write_nwchars ((wchar_t *) buffer, txtlen); ++ printw ("%*s", len - txtwidth - still, ""); ++ } ++#endif ++ } else { ++ if (over) { ++ if (IS_FIT (format->just_mode)) ++ strcpy (buffer, name_trunc(txt, len)); ++ else ++ memcpy (buffer, txt + still, len); ++ } else { ++ memset (buffer, ' ', still); ++ memcpy (buffer + still, txt, txtlen); ++ memset (buffer + still + txtlen, ' ', ++ len - txtlen - still); ++ } ++ buffer[len] = '\0'; + ++ if (perm) ++ add_permission_string (buffer, format->field_len, fe, ++ attr, color, perm - 1); ++ else ++ addstr (buffer); ++ } ++ ++ length += len; + } else { + if (attr == SELECTED || attr == MARKED_SELECTED) + attrset (SELECTED_COLOR); +@@ -614,7 +720,6 @@ repaint_file (WPanel *panel, int file_in + { + int second_column = 0; + int width, offset; +- char buffer [BUF_MEDIUM]; + + offset = 0; + if (!isstatus && panel->split){ +@@ -643,7 +748,7 @@ repaint_file (WPanel *panel, int file_in + widget_move (&panel->widget, file_index - panel->top_file + 2, 1); + } + +- format_file (buffer, sizeof(buffer), panel, file_index, width, attr, isstatus); ++ format_file (panel, file_index, width, attr, isstatus); + + if (!isstatus && panel->split){ + if (second_column) +@@ -692,7 +797,7 @@ display_mini_info (WPanel *panel) + ngettext("%s in %d file", "%s in %d files", panel->marked), + b_bytes, panel->marked); + +- if ((int) strlen (buffer) > cols-2){ ++ if ((int) mbstrlen (buffer) > cols-2){ + buffer [cols] = 0; + p += 2; + } else +@@ -1104,6 +1209,12 @@ paint_frame (WPanel *panel) + int side, width; + + const char *txt; ++#ifdef UTF8 ++ char buffer[30 * sizeof (wchar_t)]; ++ mbstate_t s; ++ ++ memset (&s, 0, sizeof (s)); ++#endif + if (!panel->split) + adjust_top_file (panel); + +@@ -1128,16 +1239,38 @@ paint_frame (WPanel *panel) + if (format->string_fn){ + txt = format->title; + +- header_len = strlen (txt); ++ attrset (MARKED_COLOR); ++ width -= format->field_len; ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ const char *str = txt; ++ header_len = mbsrtowcs ((wchar_t *) buffer, &str, ++ sizeof (buffer) / sizeof (wchar_t), ++ &s); ++ if (header_len < 0) { ++ memset (&s, 0, sizeof (s)); ++ printw ("%*s", format->field_len, ""); ++ continue; ++ } ++ if (header_len > format->field_len) ++ header_len = format->field_len; ++ spaces = (format->field_len - header_len) / 2; ++ extra = (format->field_len - header_len) % 2; ++ printw ("%*s", spaces, ""); ++ SLsmg_write_nwchars ((wchar_t *) buffer, header_len); ++ printw ("%*s", spaces + extra, ""); ++ continue; ++ } +#endif + - len = strlen (fnsource); - j = re_match (&ctx->rx, fnsource, len, 0, &ctx->regs); - if (j != len) { - transform_error = FILE_SKIP; -+ g_free (fnsource); - return NULL; - } - for (next_reg = 1, j = 0, k = 0; j < strlen (ctx->dest_mask); j++) { -@@ -213,6 +218,7 @@ do_transform_source (FileOpContext *ctx, - || ctx->regs.start[next_reg] < 0) { - message (1, MSG_ERROR, _(" Invalid target mask ")); - transform_error = FILE_ABORT; -+ g_free(fnsource); - return NULL; - } - for (l = (size_t) ctx->regs.start[next_reg]; -@@ -227,6 +233,7 @@ do_transform_source (FileOpContext *ctx, ++ header_len = mbstrlen (txt); + if (header_len > format->field_len) + header_len = format->field_len; + +- attrset (MARKED_COLOR); + spaces = (format->field_len - header_len) / 2; + extra = (format->field_len - header_len) % 2; + tty_printf ("%*s%.*s%*s", spaces, "", + header_len, txt, spaces+extra, ""); +- width -= 2 * spaces + extra + header_len; + } else { + attrset (NORMAL_COLOR); + one_vline (); +@@ -1894,11 +2027,24 @@ do_search (WPanel *panel, int c_code) + int i; + int wrapped = 0; + int found; ++ int prevpos, pos; ++ int j; ++ mbstate_t mbs; + + l = strlen (panel->search_buffer); + if (c_code == KEY_BACKSPACE) { +- if (l) +- panel->search_buffer[--l] = '\0'; ++ if (l) { ++ prevpos = pos = 0; ++ memset (&mbs, 0, sizeof (mbs)); ++ while (pos < l) { ++ prevpos = pos; ++ j = mbrlen (panel->search_buffer + pos, l - pos, &mbs); ++ if (j <= 0) break; ++ pos += j; ++ } ++ --l; ++ panel->search_buffer[prevpos] = 0; ++ } + } else { + if (c_code && l < sizeof (panel->search_buffer)) { + panel->search_buffer[l] = c_code; +@@ -1907,6 +2053,14 @@ do_search (WPanel *panel, int c_code) } } - fntarget[k] = 0; -+ g_free(fnsource); - return fntarget; + ++ prevpos = pos = 0; ++ memset (&mbs, 0, sizeof (mbs)); ++ while (pos < l) { ++ prevpos = pos; ++ j = mbrlen (panel->search_buffer + pos, l - pos, &mbs); ++ if (j <= 0) break; ++ pos += j; ++ } + found = 0; + for (i = panel->selected; !wrapped || i != panel->selected; i++) { + if (i >= panel->count) { +@@ -1917,9 +2071,9 @@ do_search (WPanel *panel, int c_code) + } + if (panel-> + case_sensitive +- ? (strncmp (panel->dir.list[i].fname, panel->search_buffer, l) ++ ? (strncmp (panel->dir.list[i].fname, panel->search_buffer, pos) + == 0) : (g_strncasecmp (panel->dir.list[i].fname, +- panel->search_buffer, l) == 0)) { ++ panel->search_buffer, pos) == 0)) { + unselect_item (panel); + panel->selected = i; + select_item (panel); +@@ -1928,7 +2082,7 @@ do_search (WPanel *panel, int c_code) + } + } + if (!found) +- panel->search_buffer[--l] = 0; ++ panel->search_buffer[prevpos] = 0; + + paint_panel (panel); } - -@@ -1688,13 +1695,13 @@ panel_operate_generate_prompt (const WPa - *dp = '\0'; - - if (single_source) { -- i = fmd_xlen - strlen (format_string) - 4; -+ i = fmd_xlen - mbstrlen (format_string) - 4; - g_snprintf (cmd_buf, sizeof (cmd_buf), format_string, - name_trunc (single_source, i)); - } else { - g_snprintf (cmd_buf, sizeof (cmd_buf), format_string, - panel->marked); -- i = strlen (cmd_buf) + 6 - fmd_xlen; -+ i = mbstrlen (cmd_buf) + 6 - fmd_xlen; - if (i > 0) { - fmd_xlen += i; - fmd_init_i18n (TRUE); /* to recalculate positions of child widgets */ ---- mc/src/find.c.utf8 2006-02-06 17:55:43.000000000 +0100 -+++ mc/src/find.c 2007-01-04 16:20:56.000000000 +0100 -@@ -217,7 +217,7 @@ find_parameters (char **start_dir, char - int l1, maxlen = 0; +diff -up mc-4.6.2-pre1/src/layout.c.utf8 mc-4.6.2-pre1/src/layout.c +--- mc-4.6.2-pre1/src/layout.c.utf8 2006-11-08 14:37:25.000000000 +0100 ++++ mc-4.6.2-pre1/src/layout.c 2008-02-25 14:56:22.000000000 +0100 +@@ -366,36 +366,36 @@ init_layout (void) while (i--) { -- l1 = strlen (labs[i] = _(labs[i])); -+ l1 = mbstrlen (labs[i] = _(labs[i])); - if (l1 > maxlen) - maxlen = l1; + s_split_direction[i] = _(s_split_direction[i]); +- l1 = strlen (s_split_direction[i]) + 7; ++ l1 = mbstrlen (s_split_direction[i]) + 7; + if (l1 > first_width) + first_width = l1; } -@@ -226,7 +226,7 @@ find_parameters (char **start_dir, char - FIND_X = i; - for (i = sizeof (buts) / sizeof (buts[0]), l1 = 0; i--;) { -- l1 += strlen (buts[i] = _(buts[i])); -+ l1 += mbstrlen (buts[i] = _(buts[i])); + for (i = 0; i <= 8; i++) { + check_options[i].text = _(check_options[i].text); +- l1 = strlen (check_options[i].text) + 7; ++ l1 = mbstrlen (check_options[i].text) + 7; + if (l1 > first_width) + first_width = l1; } - l1 += 21; - if (l1 > FIND_X) -@@ -235,8 +235,8 @@ find_parameters (char **start_dir, char - ilen = FIND_X - 7 - maxlen; /* for the case of very long buttons :) */ - istart = FIND_X - 3 - ilen; -- b1 = b0 + strlen (buts[0]) + 7; -- b2 = FIND_X - (strlen (buts[2]) + 6); -+ b1 = b0 + mbstrlen (buts[0]) + 7; -+ b2 = FIND_X - (mbstrlen (buts[2]) + 6); +- l1 = strlen (title1) + 1; ++ l1 = mbstrlen (title1) + 1; + if (l1 > first_width) + first_width = l1; - i18n_flag = 1; - case_label = _(case_label); -@@ -863,7 +863,7 @@ setup_gui (void) - if (!i18n_flag) { - register int i = sizeof (fbuts) / sizeof (fbuts[0]); - while (i--) -- fbuts[i].len = strlen (fbuts[i].text = _(fbuts[i].text)) + 3; -+ fbuts[i].len = mbstrlen (fbuts[i].text = _(fbuts[i].text)) + 3; - fbuts[2].len += 2; /* DEFPUSH_BUTTON */ - i18n_flag = 1; +- l1 = strlen (title2) + 1; ++ l1 = mbstrlen (title2) + 1; + if (l1 > first_width) + first_width = l1; + + +- second_width = strlen (title3) + 1; ++ second_width = mbstrlen (title3) + 1; + for (i = 0; i < 6; i++) { + check_options[i].text = _(check_options[i].text); +- l1 = strlen (check_options[i].text) + 7; ++ l1 = mbstrlen (check_options[i].text) + 7; + if (l1 > second_width) + second_width = l1; + } + if (console_flag) { +- l1 = strlen (output_lines_label) + 13; ++ l1 = mbstrlen (output_lines_label) + 13; + if (l1 > second_width) + second_width = l1; + } +@@ -409,14 +409,14 @@ init_layout (void) + * + * Now the last thing to do - properly space buttons... + */ +- l1 = 11 + strlen (ok_button) /* 14 - all brackets and inner space */ +- +strlen (save_button) /* notice: it is 3 char less because */ +- +strlen (cancel_button); /* of '&' char in button text */ ++ l1 = 11 + mbstrlen (ok_button) /* 14 - all brackets and inner space */ ++ +mbstrlen (save_button) /* notice: it is 3 char less because */ ++ +mbstrlen (cancel_button); /* of '&' char in button text */ + + i = (first_width + second_width - l1) / 4; + b1 = 5 + i; +- b2 = b1 + strlen (ok_button) + i + 6; +- b3 = b2 + strlen (save_button) + i + 4; ++ b2 = b1 + mbstrlen (ok_button) + i + 6; ++ b3 = b2 + mbstrlen (save_button) + i + 4; + + i18n_layt_flag = 1; } -@@ -1028,7 +1028,7 @@ find_file (char *start_dir, char *patter +@@ -684,7 +684,7 @@ setup_panels (void) + panel_do_cols (0); + panel_do_cols (1); - if (!next_free) /* first turn i.e clean old list */ - panel_clean_dir (current_panel); -- list->list[next_free].fnamelen = strlen (name); -+ list->list[next_free].fnamelen = mbstrlen (name); - list->list[next_free].fname = name; - list->list[next_free].f.marked = 0; - list->list[next_free].f.link_to_dir = link_to_dir; ---- mc/src/myslang.h.utf8 2005-09-06 22:36:23.000000000 +0200 -+++ mc/src/myslang.h 2007-01-04 16:20:56.000000000 +0100 +- promptl = strlen (prompt); ++ promptl = mbstrlen (prompt); + + widget_set_size (&the_menubar->widget, 0, 0, 1, COLS); + +diff -up mc-4.6.2-pre1/src/hotlist.c.utf8 mc-4.6.2-pre1/src/hotlist.c +--- mc-4.6.2-pre1/src/hotlist.c.utf8 2006-08-08 14:17:14.000000000 +0200 ++++ mc-4.6.2-pre1/src/hotlist.c 2008-02-25 14:56:22.000000000 +0100 +@@ -563,7 +563,7 @@ init_i18n_stuff(int list_type, int cols) + + row = hotlist_but [i].y; + ++count [row]; +- len [row] += strlen (hotlist_but [i].text) + 5; ++ len [row] += mbstrlen (hotlist_but [i].text) + 5; + if (hotlist_but [i].flags == DEFPUSH_BUTTON) + len [row] += 2; + } +@@ -588,12 +588,12 @@ init_i18n_stuff(int list_type, int cols) + /* not first int the row */ + if (!strcmp (hotlist_but [i].text, cancel_but)) + hotlist_but [i].x = +- cols - strlen (hotlist_but [i].text) - 13; ++ cols - mbstrlen (hotlist_but [i].text) - 13; + else + hotlist_but [i].x = cur_x [row]; + } + +- cur_x [row] += strlen (hotlist_but [i].text) + 2 ++ cur_x [row] += mbstrlen (hotlist_but [i].text) + 2 + + (hotlist_but [i].flags == DEFPUSH_BUTTON ? 5 : 3); + } + } +@@ -834,7 +834,7 @@ static void add_widgets_i18n(QuickWidget + for (i = 0; i < 3; i++) + { + qw [i].text = _(qw [i].text); +- l[i] = strlen (qw [i].text) + 3; ++ l[i] = mbstrlen (qw [i].text) + 3; + } + space = (len - 4 - l[0] - l[1] - l[2]) / 4; + +@@ -883,7 +883,7 @@ add_new_entry_input (const char *header, + + msglen(text1, &lines1, &cols1); + msglen(text2, &lines2, &cols2); +- len = max ((int) strlen (header), cols1); ++ len = max ((int) mbstrlen (header), cols1); + len = max (len, cols2) + 4; + len = max (len, 64); + +@@ -979,7 +979,7 @@ add_new_group_input (const char *header, + #endif /* ENABLE_NLS */ + + msglen (label, &lines, &cols); +- len = max ((int) strlen (header), cols) + 4; ++ len = max ((int) mbstrlen (header), cols) + 4; + len = max (len, 64); + + #ifdef ENABLE_NLS +@@ -1035,7 +1035,7 @@ void add2hotlist_cmd (void) + { + char *prompt, *label; + const char *cp = _("Label for \"%s\":"); +- int l = strlen (cp); ++ int l = mbstrlen (cp); + char *label_string = g_strdup (current_panel->cwd); + + strip_password (label_string, 1); +diff -up mc-4.6.2-pre1/src/myslang.h.utf8 mc-4.6.2-pre1/src/myslang.h +--- mc-4.6.2-pre1/src/myslang.h.utf8 2005-09-05 05:22:04.000000000 +0200 ++++ mc-4.6.2-pre1/src/myslang.h 2008-02-25 14:56:22.000000000 +0100 @@ -11,6 +11,16 @@ #endif /* HAVE_SLANG_SLANG_H */ #endif @@ -2660,1414 +2845,36 @@ enum { KEY_BACKSPACE = 400, KEY_END, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, ---- mc/src/achown.c.utf8 2005-09-06 22:36:23.000000000 +0200 -+++ mc/src/achown.c 2007-01-04 16:20:56.000000000 +0100 -@@ -584,6 +584,12 @@ init_chown_advanced (void) - b_att[2] = button_new (XTRACT (6)); - b_user = button_new (XTRACT (5)); - b_group = button_new (XTRACT (4)); -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode) { -+ b_user->text = g_realloc (b_user->text, MB_CUR_MAX * 15 + 1); -+ b_group->text = g_realloc (b_group->text, MB_CUR_MAX * 15 + 1); -+ } -+#endif - - add_widget (ch_dlg, b_group); - add_widget (ch_dlg, b_user); ---- mc/src/dialog.c.utf8 2005-09-06 22:36:23.000000000 +0200 -+++ mc/src/dialog.c 2007-01-04 16:20:56.000000000 +0100 -@@ -166,7 +166,7 @@ common_dialog_repaint (struct Dlg_head * - - if (h->title) { - attrset (DLG_HOT_NORMALC (h)); -- dlg_move (h, space, (h->cols - strlen (h->title)) / 2); -+ dlg_move (h, space, (h->cols - mbstrlen (h->title)) / 2); - addstr (h->title); - } - } ---- mc/src/boxes.c.utf8 2006-02-28 18:44:28.000000000 +0100 -+++ mc/src/boxes.c 2007-01-04 16:20:56.000000000 +0100 -@@ -153,23 +153,23 @@ display_init (int radio_sel, char *init_ - display_title = _(display_title); - for (i = 0; i < LIST_TYPES; i++) { - displays[i] = _(displays[i]); -- if ((l = strlen (displays[i])) > maxlen) -+ if ((l = mbstrlen (displays[i])) > maxlen) - maxlen = l; +diff -up mc-4.6.2-pre1/src/panelize.c.utf8 mc-4.6.2-pre1/src/panelize.c +--- mc-4.6.2-pre1/src/panelize.c.utf8 2005-05-27 05:35:15.000000000 +0200 ++++ mc-4.6.2-pre1/src/panelize.c 2008-02-25 14:56:22.000000000 +0100 +@@ -127,7 +127,7 @@ init_panelize (void) + i = sizeof (panelize_but) / sizeof (panelize_but[0]); + while (i--) { + panelize_but[i].text = _(panelize_but[i].text); +- maxlen += strlen (panelize_but[i].text) + 5; ++ maxlen += mbstrlen (panelize_but[i].text) + 5; } - -- i = strlen (ok_button) + 5; -- l = strlen (cancel_button) + 3; -+ i = mbstrlen (ok_button) + 5; -+ l = mbstrlen (cancel_button) + 3; - l = max (i, l); - - i = maxlen + l + 16; - if (i > DISPLAY_X) - DISPLAY_X = i; - -- i = strlen (user_mini_status) + 13; -+ i = mbstrlen (user_mini_status) + 13; - if (i > DISPLAY_X) - DISPLAY_X = i; - -- i = strlen (display_title) + 10; -+ i = mbstrlen (display_title) + 10; - if (i > DISPLAY_X) - DISPLAY_X = i; - -@@ -288,20 +288,20 @@ sort_box (sortfn *sort_fn, int *reverse, - int maxlen = 0; - for (i = SORT_TYPES - 1; i >= 0; i--) { - sort_orders_names[i] = _(sort_orders[i].sort_name); -- r = strlen (sort_orders_names[i]); -+ r = mbstrlen (sort_orders_names[i]); - if (r > maxlen) - maxlen = r; - } - - check_pos = maxlen + 9; - -- r = strlen (reverse_label) + 4; -- i = strlen (case_label) + 4; -+ r = mbstrlen (reverse_label) + 4; -+ i = mbstrlen (case_label) + 4; - if (i > r) - r = i; - -- l = strlen (ok_button) + 6; -- i = strlen (cancel_button) + 4; -+ l = mbstrlen (ok_button) + 6; -+ i = mbstrlen (cancel_button) + 4; - if (i > l) - l = i; - -@@ -310,7 +310,7 @@ sort_box (sortfn *sort_fn, int *reverse, - if (i > SORT_X) - SORT_X = i; - -- i = strlen (sort_title) + 6; -+ i = mbstrlen (sort_title) + 6; - if (i > SORT_X) - SORT_X = i; - -@@ -408,7 +408,7 @@ confirm_box (void) - while (i--) - { - conf_widgets [i].text = _(conf_widgets [i].text); -- l1 = strlen (conf_widgets [i].text) + 3; -+ l1 = mbstrlen (conf_widgets [i].text) + 3; - if (l1 > maxlen) - maxlen = l1; - } -@@ -423,8 +423,8 @@ confirm_box (void) - * And this for the case when buttons with some space to the right - * do not fit within 2/6 - */ -- l1 = strlen (conf_widgets [0].text) + 3; -- i = strlen (conf_widgets [1].text) + 5; -+ l1 = mbstrlen (conf_widgets [0].text) + 3; -+ i = mbstrlen (conf_widgets [1].text) + 5; - if (i > l1) - l1 = i; - -@@ -497,11 +497,11 @@ display_bits_box (void) - { - display_widgets [i].text = _(display_widgets[i].text); - display_bits_str [i] = _(display_bits_str [i]); -- l1 = strlen (display_bits_str [i]); -+ l1 = mbstrlen (display_bits_str [i]); - if (l1 > maxlen) - maxlen = l1; - } -- l1 = strlen (display_widgets [2].text); -+ l1 = mbstrlen (display_widgets [2].text); - if (l1 > maxlen) - maxlen = l1; - -@@ -509,8 +509,8 @@ display_bits_box (void) - display_bits.xlen = (maxlen + 5) * 6 / 4; - - /* See above confirm_box */ -- l1 = strlen (display_widgets [0].text) + 3; -- i = strlen (display_widgets [1].text) + 5; -+ l1 = mbstrlen (display_widgets [0].text) + 3; -+ i = mbstrlen (display_widgets [1].text) + 5; - if (i > l1) - l1 = i; - -@@ -605,7 +605,7 @@ init_disp_bits_box (void) - - cpname = _("&Select"); - add_widget (dbits_dlg, -- button_new (4, DISPX - 8 - strlen (cpname), B_USER, -+ button_new (4, DISPX - 8 - mbstrlen (cpname), B_USER, - NORMAL_BUTTON, cpname, sel_charset_button)); - - return dbits_dlg; -@@ -816,7 +816,7 @@ cd_dialog (void) - quick_widgets [1].y_divisions = - quick_widgets [0].y_divisions = Quick_input.ylen = 5; - -- len = strlen (quick_widgets [1].text); -+ len = mbstrlen (quick_widgets [1].text); - - quick_widgets [0].relative_x = - quick_widgets [1].relative_x + len + 1; -@@ -975,7 +975,7 @@ jobs_cmd (void) - { - job_buttons [i].name = _(job_buttons [i].name); - -- len = strlen (job_buttons [i].name) + 4; -+ len = mbstrlen (job_buttons [i].name) + 4; - JOBS_X = max (JOBS_X, startx + len + 3); - - job_buttons [i].xpos = startx; -@@ -984,7 +984,7 @@ jobs_cmd (void) - - /* Last button - Ok a.k.a. Cancel :) */ - job_buttons [n_buttons - 1].xpos = -- JOBS_X - strlen (job_buttons [n_buttons - 1].name) - 7; -+ JOBS_X - mbstrlen (job_buttons [n_buttons - 1].name) - 7; - - i18n_flag = 1; - } -@@ -1042,7 +1042,7 @@ vfs_smb_get_authinfo (const char *host, - - while (i--) - { -- l1 = strlen (labs [i] = _(labs [i])); -+ l1 = mbstrlen (labs [i] = _(labs [i])); - if (l1 > maxlen) - maxlen = l1; - } -@@ -1052,7 +1052,7 @@ vfs_smb_get_authinfo (const char *host, - - for (i = sizeof(buts)/sizeof(buts[0]), l1 = 0; i--; ) - { -- l1 += strlen (buts [i] = _(buts [i])); -+ l1 += mbstrlen (buts [i] = _(buts [i])); - } - l1 += 15; - if (l1 > dialog_x) -@@ -1061,7 +1061,7 @@ vfs_smb_get_authinfo (const char *host, - ilen = dialog_x - 7 - maxlen; /* for the case of very long buttons :) */ - istart = dialog_x - 3 - ilen; - -- b2 = dialog_x - (strlen(buts[1]) + 6); -+ b2 = dialog_x - (mbstrlen(buts[1]) + 6); - - i18n_flag = 1; - } ---- mc/src/learn.c.utf8 2005-05-27 05:35:15.000000000 +0200 -+++ mc/src/learn.c 2007-01-04 16:20:56.000000000 +0100 -@@ -237,7 +237,7 @@ init_learn (void) - learn_but[0].x = 78 / 2 + 4; - - learn_but[1].text = _(learn_but[1].text); -- learn_but[1].x = 78 / 2 - (strlen (learn_but[1].text) + 9); -+ learn_but[1].x = 78 / 2 - (mbstrlen (learn_but[1].text) + 9); - - learn_title = _(learn_title); - i18n_flag = 1; ---- mc/edit/edit-widget.h.utf8 2006-03-20 17:44:32.000000000 +0100 -+++ mc/edit/edit-widget.h 2007-01-04 16:20:56.000000000 +0100 -@@ -30,6 +30,11 @@ typedef struct edit_key_map_type { - long command; - } edit_key_map_type; - -+struct action { -+ mc_wchar_t ch; -+ long flags; -+}; -+ - struct WEdit { - Widget widget; - -@@ -42,8 +47,17 @@ struct WEdit { - /* dynamic buffers and cursor position for editor: */ - long curs1; /* position of the cursor from the beginning of the file. */ - long curs2; /* position from the end of the file */ -+#ifndef UTF8 - unsigned char *buffers1[MAXBUFF + 1]; /* all data up to curs1 */ - unsigned char *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */ -+#else /* UTF8 */ -+ mc_wchar_t *buffers1[MAXBUFF + 1]; /* all data up to curs1 */ -+ mc_wchar_t *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */ -+ -+ unsigned char charbuf[MB_LEN_MAX]; -+ int charpoint; -+#endif /* UTF8 */ -+ - - /* search variables */ - long search_start; /* First character to start searching from */ -@@ -87,7 +101,7 @@ struct WEdit { - - /* undo stack and pointers */ - unsigned long stack_pointer; -- long *undo_stack; -+ struct action *undo_stack; - unsigned long stack_size; - unsigned long stack_size_mask; - unsigned long stack_bottom; ---- mc/edit/editkeys.c.utf8 2006-02-02 00:05:15.000000000 +0100 -+++ mc/edit/editkeys.c 2007-01-04 16:20:56.000000000 +0100 -@@ -182,10 +182,10 @@ static const edit_key_map_type common_ke - * 'command' is one of the editor commands from editcmddef.h. - */ - int --edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch) -+edit_translate_key (WEdit *edit, long x_key, int *cmd, mc_wint_t *ch) - { - int command = CK_Insert_Char; -- int char_for_insertion = -1; -+ mc_wint_t char_for_insertion = -1; - int i = 0; - int extmod = 0; - const edit_key_map_type *key_map = NULL; -@@ -242,9 +242,30 @@ edit_translate_key (WEdit *edit, long x_ - /* an ordinary insertable character */ - if (x_key < 256 && !extmod) { - int c = convert_from_input_c (x_key); -- -+#ifdef UTF8 -+ mbstate_t mbs; -+ int res; -+ mc_wchar_t wc; -+ -+ memset (&mbs, 0, sizeof (mbs)); -+ -+ if (edit->charpoint >= MB_CUR_MAX) edit->charpoint = 0; -+ -+ edit->charbuf[edit->charpoint++] = c; -+ -+ res = mbrtowc(&wc, (char *)edit->charbuf, edit->charpoint, &mbs); -+ if (res < 0) { -+ if (res != -2) edit->charpoint = 0; /* broken multibyte char, skip */ -+ return 0; -+ } -+ edit->charpoint = 0; -+ -+ if (iswprint (wc)) { -+ char_for_insertion = wc; -+#else - if (is_printable (c)) { - char_for_insertion = c; -+#endif /* UTF8 */ - goto fin; - } - } -@@ -283,7 +304,7 @@ edit_translate_key (WEdit *edit, long x_ - *cmd = command; - *ch = char_for_insertion; - -- if (command == CK_Insert_Char && char_for_insertion == -1) { -+ if (command == CK_Insert_Char && char_for_insertion == (mc_wint_t)-1) { - /* unchanged, key has no function here */ - return 0; - } ---- mc/edit/editwidget.c.utf8 2006-12-12 18:39:33.000000000 +0100 -+++ mc/edit/editwidget.c 2007-01-04 16:20:56.000000000 +0100 -@@ -331,7 +331,8 @@ edit_callback (Widget *w, widget_msg_t m - - case WIDGET_KEY: - { -- int cmd, ch; -+ int cmd; -+ mc_wint_t ch; - - /* The user may override the access-keys for the menu bar. */ - if (edit_translate_key (e, parm, &cmd, &ch)) { ---- mc/edit/editcmd.c.utf8 2006-11-27 15:19:29.000000000 +0100 -+++ mc/edit/editcmd.c 2007-01-04 16:20:56.000000000 +0100 -@@ -61,7 +61,7 @@ - #define edit_get_save_file(f,h) input_expand_dialog (h, _(" Enter file name: "), f) - - struct selection { -- unsigned char * text; -+ mc_wchar_t *text; - int len; - }; - -@@ -84,12 +84,16 @@ int edit_confirm_save = 1; - #define MAX_REPL_LEN 1024 - - static int edit_save_cmd (WEdit *edit); --static unsigned char *edit_get_block (WEdit *edit, long start, -+static mc_wchar_t *edit_get_block (WEdit *edit, long start, - long finish, int *l); - --static inline int my_lower_case (int c) -+static inline mc_wchar_t my_lower_case (mc_wchar_t c) - { -+#ifndef UTF8 - return tolower(c & 0xFF); -+#else -+ return towlower(c); -+#endif - } - - static const char * -@@ -124,11 +128,11 @@ static void *memmove (void *dest, const - #endif /* !HAVE_MEMMOVE */ - - /* #define itoa MY_itoa <---- this line is now in edit.h */ --static char * -+static mc_wchar_t * - MY_itoa (int i) - { -- static char t[14]; -- char *s = t + 13; -+ static mc_wchar_t t[14]; -+ mc_wchar_t *s = t + 13; - int j = i; - *s-- = 0; - do { -@@ -213,6 +217,48 @@ void edit_refresh_cmd (WEdit * edit) - doupdate(); - } - -+#ifdef UTF8 -+ -+static size_t -+wchar_write(int fd, mc_wchar_t *buf, size_t len) -+{ -+ char *tmpbuf = g_malloc(len + MB_LEN_MAX); -+ mbstate_t mbs; -+ size_t i; -+ size_t outlen = 0; -+ size_t res; -+ -+ for (i = 0; i < len; i++) { -+ if (outlen >= len) { -+ if ((res = mc_write(fd, tmpbuf, outlen)) != outlen) { -+ g_free(tmpbuf); -+ return -1; -+ } -+ outlen = 0; -+ } -+ memset (&mbs, 0, sizeof (mbs)); -+#ifdef __STDC_ISO_10646__ -+ if (buf[i] >= BINARY_CHAR_OFFSET && buf[i] < (BINARY_CHAR_OFFSET + 256)) { -+ res = 1; -+ tmpbuf[outlen] = (char) (buf[i] - BINARY_CHAR_OFFSET); -+ -+ } else -+#endif -+ res = wcrtomb(tmpbuf + outlen, buf[i], &mbs); -+ if (res > 0) { -+ outlen += res; -+ } -+ } -+ if ((res = mc_write(fd, tmpbuf, outlen)) != outlen) { -+ g_free(tmpbuf); -+ return -1; -+ } -+ g_free(tmpbuf); -+ return len; -+} -+ -+#endif /* UTF8 */ -+ - /* If 0 (quick save) then a) create/truncate file, - b) save to ; - if 1 (safe save) then a) save to , -@@ -360,32 +406,48 @@ edit_save_file (WEdit *edit, const char - buf = 0; - filelen = edit->last_byte; - while (buf <= (edit->curs1 >> S_EDIT_BUF_SIZE) - 1) { -+#ifndef UTF8 - if (mc_write (fd, (char *) edit->buffers1[buf], EDIT_BUF_SIZE) -+#else /* UTF8 */ -+ if (wchar_write (fd, edit->buffers1[buf], EDIT_BUF_SIZE) -+#endif /* UTF8 */ - != EDIT_BUF_SIZE) { - mc_close (fd); - goto error_save; - } - buf++; - } -+#ifndef UTF8 - if (mc_write - (fd, (char *) edit->buffers1[buf], -+#else /* UTF8 */ -+ if (wchar_write -+ (fd, edit->buffers1[buf], -+#endif /* UTF8 */ - edit->curs1 & M_EDIT_BUF_SIZE) != - (edit->curs1 & M_EDIT_BUF_SIZE)) { - filelen = -1; - } else if (edit->curs2) { - edit->curs2--; - buf = (edit->curs2 >> S_EDIT_BUF_SIZE); -- if (mc_write -- (fd, -- (char *) edit->buffers2[buf] + EDIT_BUF_SIZE - -+#ifndef UTF8 -+ if (mc_write(fd, (char *) edit->buffers2[buf] + EDIT_BUF_SIZE - -+#else /* UTF8 */ -+ if (wchar_write(fd, edit->buffers2[buf] + EDIT_BUF_SIZE - -+#endif /* UTF8 */ - (edit->curs2 & M_EDIT_BUF_SIZE) - 1, - 1 + (edit->curs2 & M_EDIT_BUF_SIZE)) != - 1 + (edit->curs2 & M_EDIT_BUF_SIZE)) { - filelen = -1; - } else { - while (--buf >= 0) { -+#ifndef UTF8 - if (mc_write - (fd, (char *) edit->buffers2[buf], -+#else /* UTF8 */ -+ if (wchar_write -+ (fd, edit->buffers2[buf], -+#endif /* UTF8 */ - EDIT_BUF_SIZE) != EDIT_BUF_SIZE) { - filelen = -1; - break; -@@ -705,13 +767,21 @@ edit_delete_macro (WEdit * edit, int k) - if (!n || n == EOF) - break; - n = 0; -+#ifndef UTF8 - while (fscanf (f, "%hd %hd, ", ¯o[n].command, ¯o[n].ch)) -+#else /* UTF8 */ -+ while (fscanf (f, "%hd %lu, ", ¯o[n].command, ¯o[n].ch)) -+#endif /* UTF8 */ - n++; - fscanf (f, ";\n"); - if (s != k) { - fprintf (g, ("key '%d 0': "), s); - for (i = 0; i < n; i++) -+#ifndef UTF8 - fprintf (g, "%hd %hd, ", macro[i].command, macro[i].ch); -+#else /* UTF8 */ -+ fprintf (g, "%hd %lu, ", macro[i].command, macro[i].ch); -+#endif /* UTF8 */ - fprintf (g, ";\n"); - } - } -@@ -744,7 +814,11 @@ int edit_save_macro_cmd (WEdit * edit, s - if (f) { - fprintf (f, ("key '%d 0': "), s); - for (i = 0; i < n; i++) -+#ifndef UTF8 - fprintf (f, "%hd %hd, ", macro[i].command, macro[i].ch); -+#else /* UTF8 */ -+ fprintf (f, "%hd %lu, ", macro[i].command, macro[i].ch); -+#endif /* UTF8 */ - fprintf (f, ";\n"); - fclose (f); - if (saved_macros_loaded) { -@@ -794,10 +868,18 @@ int edit_load_macro_cmd (WEdit * edit, s - saved_macro[i++] = s; - if (!found) { - *n = 0; -+#ifndef UTF8 - while (*n < MAX_MACRO_LENGTH && 2 == fscanf (f, "%hd %hd, ", ¯o[*n].command, ¯o[*n].ch)) -+#else /* UTF8 */ -+ while (*n < MAX_MACRO_LENGTH && 2 == fscanf (f, "%hd %lu, ", ¯o[*n].command, ¯o[*n].ch)) -+#endif /* UTF8 */ - (*n)++; - } else { -+#ifndef UTF8 - while (2 == fscanf (f, "%hd %hd, ", &dummy.command, &dummy.ch)); -+#else /* UTF8 */ -+ while (2 == fscanf (f, "%hd %lu, ", &dummy.command, &dummy.ch)); -+#endif /* UTF8 */ - } - fscanf (f, ";\n"); - if (s == k) -@@ -944,7 +1026,7 @@ int eval_marks (WEdit * edit, long *star - #define space_width 1 - - static void --edit_insert_column_of_text (WEdit * edit, unsigned char *data, int size, int width) -+edit_insert_column_of_text (WEdit * edit, mc_wchar_t *data, int size, int width) - { - long cursor; - int i, col; -@@ -992,7 +1074,7 @@ edit_block_copy_cmd (WEdit *edit) - { - long start_mark, end_mark, current = edit->curs1; - int size; -- unsigned char *copy_buf; -+ mc_wchar_t *copy_buf; - - edit_update_curs_col (edit); - if (eval_marks (edit, &start_mark, &end_mark)) -@@ -1032,7 +1114,7 @@ edit_block_move_cmd (WEdit *edit) - { - long count; - long current; -- unsigned char *copy_buf; -+ mc_wchar_t *copy_buf; - long start_mark, end_mark; - int deleted = 0; - int x = 0; -@@ -1093,7 +1175,7 @@ edit_block_move_cmd (WEdit *edit) - edit_push_action (edit, COLUMN_ON); - column_highlighting = 0; - } else { -- copy_buf = g_malloc (end_mark - start_mark); -+ copy_buf = g_malloc ((end_mark - start_mark) * sizeof(mc_wchar_t)); - edit_cursor_move (edit, start_mark - edit->curs1); - edit_scroll_screen_over_cursor (edit); - count = start_mark; -@@ -1432,7 +1514,11 @@ static long sargs[NUM_REPL_ARGS][256 / s - /* This function is a modification of mc-3.2.10/src/view.c:regexp_view_search() */ - /* returns -3 on error in pattern, -1 on not found, found_len = 0 if either */ - static int -+#ifndef UTF8 - string_regexp_search (char *pattern, char *string, int match_type, -+#else /* UTF8 */ -+string_regexp_search (char *pattern, mc_wchar_t *wstring, int match_type, -+#endif /* UTF8 */ - int match_bol, int icase, int *found_len, void *d) - { - static regex_t r; -@@ -1441,6 +1527,11 @@ string_regexp_search (char *pattern, cha - regmatch_t *pmatch; - static regmatch_t s[1]; - -+#ifdef UTF8 -+ char *string; -+ int i; -+#endif /* UTF8 */ -+ - pmatch = (regmatch_t *) d; - if (!pmatch) - pmatch = s; -@@ -1460,13 +1551,51 @@ string_regexp_search (char *pattern, cha - old_type = match_type; - old_icase = icase; - } -+ -+#ifdef UTF8 -+ string = wchar_to_mbstr(wstring); -+ if (string == NULL) -+ return -1; -+#endif /* UTF8 */ -+ - if (regexec - (&r, string, d ? NUM_REPL_ARGS : 1, pmatch, - ((match_bol - || match_type != match_normal) ? 0 : REG_NOTBOL)) != 0) { - *found_len = 0; -+ -+#ifdef UTF8 -+ g_free(string); -+#endif /* UTF8 */ -+ - return -1; - } -+ -+#ifdef UTF8 -+ for (i = 0; i < (d ? NUM_REPL_ARGS : 1); i++) { -+ char tmp; -+ int new_o; -+ -+ if (pmatch[i].rm_so < 0) -+ continue; -+ tmp = string[pmatch[i].rm_so]; -+ string[pmatch[i].rm_so] = 0; -+ new_o = mbstrlen(string); -+ string[pmatch[i].rm_so] = tmp; -+ pmatch[i].rm_so = new_o; -+ -+ if (pmatch[i].rm_eo < 0) -+ continue; -+ tmp = string[pmatch[i].rm_eo]; -+ string[pmatch[i].rm_eo] = 0; -+ new_o = mbstrlen(string); -+ string[pmatch[i].rm_eo] = tmp; -+ pmatch[i].rm_eo = new_o; -+ } -+ -+ g_free(string); -+#endif /* UTF8 */ -+ - *found_len = pmatch[0].rm_eo - pmatch[0].rm_so; - return (pmatch[0].rm_so); - } -@@ -1474,13 +1603,29 @@ string_regexp_search (char *pattern, cha - /* thanks to Liviu Daia for getting this - (and the above) routines to work properly - paul */ - -+#ifndef UTF8 - typedef int (*edit_getbyte_fn) (WEdit *, long); -+#else /* UTF8 */ -+typedef mc_wchar_t (*edit_getbyte_fn) (WEdit *, long); -+#endif /* UTF8 */ - - static long -+#ifndef UTF8 - edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit_getbyte_fn get_byte, void *data, int once_only, void *d) -+#else /* UTF8 */ -+edit_find_string (long start, unsigned char *exp_mb, int *len, long last_byte, edit_getbyte_fn get_byte, void *data, int once_only, void *d) -+#endif /* UTF8 */ - { - long p, q = 0; -- long l = strlen ((char *) exp), f = 0; -+ long f = 0; -+ -+#ifndef UTF8 -+ long l = strlen ((char *) exp); -+#else /* UTF8 */ -+ mc_wchar_t *exp = mbstr_to_wchar((char *)exp_mb); -+ mc_wchar_t *exp_backup = exp; -+ long l = wcslen(exp); -+#endif /* UTF8 */ - int n = 0; - - for (p = 0; p < l; p++) /* count conversions... */ -@@ -1489,19 +1634,22 @@ edit_find_string (long start, unsigned c - n++; - - if (replace_scanf || replace_regexp) { -- int c; -- unsigned char *buf; -- unsigned char mbuf[MAX_REPL_LEN * 2 + 3]; -+ mc_wint_t c; -+ mc_wchar_t *buf; -+ mc_wchar_t mbuf[MAX_REPL_LEN * 2 + 3]; - - replace_scanf = (!replace_regexp); /* can't have both */ - - buf = mbuf; - - if (replace_scanf) { -- unsigned char e[MAX_REPL_LEN]; -- if (n >= NUM_REPL_ARGS) -- return -3; -- -+ mc_wchar_t e[MAX_REPL_LEN]; -+ if (n >= NUM_REPL_ARGS) { -+#ifdef UTF8 -+ g_free(exp_backup); -+#endif /* UTF8 */ -+ return -3; -+ } - if (replace_case) { - for (p = start; p < last_byte && p < start + MAX_REPL_LEN; p++) - buf[p - start] = (*get_byte) (data, p); -@@ -1515,20 +1663,36 @@ edit_find_string (long start, unsigned c - } - - buf[(q = p - start)] = 0; -+#ifndef UTF8 - strcpy ((char *) e, (char *) exp); - strcat ((char *) e, "%n"); -+#else /* UTF8 */ -+ wcscpy (e, exp); -+ wcscat (e, L"%n"); -+#endif /* UTF8 */ - exp = e; - - while (q) { - *((int *) sargs[n]) = 0; /* --> here was the problem - now fixed: good */ -+#ifndef UTF8 - if (n == sscanf ((char *) buf, (char *) exp, SCANF_ARGS)) { -+#else /* UTF8 */ -+ if (n == swscanf (buf, exp, SCANF_ARGS)) { -+#endif /* UTF8 */ - if (*((int *) sargs[n])) { - *len = *((int *) sargs[n]); -+#ifdef UTF8 -+ g_free(exp_backup); -+#endif /* UTF8 */ - return start; - } - } -- if (once_only) -+ if (once_only) { -+#ifdef UTF8 -+ g_free(exp_backup); -+#endif /* UTF8 */ - return -2; -+ } - if (q + start < last_byte) { - if (replace_case) { - buf[q] = (*get_byte) (data, q + start); -@@ -1542,7 +1706,11 @@ edit_find_string (long start, unsigned c - start++; - buf++; /* move the window along */ - if (buf == mbuf + MAX_REPL_LEN) { /* the window is about to go past the end of array, so... */ -+#ifndef UTF8 - memmove (mbuf, buf, strlen ((char *) buf) + 1); /* reset it */ -+#else /* UTF8 */ -+ wmemmove (mbuf, buf, (wcslen (buf) + 1)); /* reset it */ -+#endif /* UTF8 */ - buf = mbuf; - } - q--; -@@ -1568,10 +1736,16 @@ edit_find_string (long start, unsigned c - - buf = mbuf; - while (q) { -+#ifndef UTF8 - found_start = string_regexp_search ((char *) exp, (char *) buf, match_normal, match_bol, !replace_case, len, d); -- -+#else /* UTF8 */ -+ found_start = string_regexp_search ((char *) exp_mb, buf, match_normal, match_bol, !replace_case, len, d); -+#endif /* UTF8 */ - if (found_start <= -2) { /* regcomp/regexec error */ - *len = 0; -+#ifdef UTF8 -+ g_free (exp_backup); -+#endif /* UTF8 */ - return -3; - } - else if (found_start == -1) /* not found: try next line */ -@@ -1582,15 +1756,27 @@ edit_find_string (long start, unsigned c - match_bol = 0; - continue; - } -- else /* found */ -+ else { /* found */ -+#ifdef UTF8 -+ g_free(exp_backup); -+#endif /* UTF8 */ - return (start + offset - q + found_start); -+ } - } -- if (once_only) -+ if (once_only) { -+#ifdef UTF8 -+ g_free(exp_backup); -+#endif /* UTF8 */ - return -2; -+ } - - if (buf[q - 1] != '\n') { /* incomplete line: try to recover */ - buf = mbuf + MAX_REPL_LEN / 2; -+#ifndef UTF8 - q = strlen ((const char *) buf); -+#else /* UTF8 */ -+ q = wcslen (buf); -+#endif /* UTF8 */ - memmove (mbuf, buf, q); - p = start + q; - move_win = 1; -@@ -1600,36 +1786,59 @@ edit_find_string (long start, unsigned c - } - } - } else { -+#ifndef UTF8 - *len = strlen ((const char *) exp); -+#else /* UTF8 */ -+ *len = wcslen (exp); -+#endif /* UTF8 */ - if (replace_case) { - for (p = start; p <= last_byte - l; p++) { -- if ((*get_byte) (data, p) == (unsigned char)exp[0]) { /* check if first char matches */ -+ if ((*get_byte) (data, p) == exp[0]) { /* check if first char matches */ - for (f = 0, q = 0; q < l && f < 1; q++) -- if ((*get_byte) (data, q + p) != (unsigned char)exp[q]) -+ if ((*get_byte) (data, q + p) != exp[q]) - f = 1; -- if (f == 0) -+ if (f == 0) { -+#ifdef UTF8 -+ g_free (exp_backup); -+#endif /* UTF8 */ - return p; -+ } - } -- if (once_only) -+ if (once_only) { -+#ifdef UTF8 -+ g_free(exp_backup); -+#endif /* UTF8 */ - return -2; -+ } - } - } else { - for (p = 0; exp[p] != 0; p++) - exp[p] = my_lower_case (exp[p]); - - for (p = start; p <= last_byte - l; p++) { -- if (my_lower_case ((*get_byte) (data, p)) == (unsigned char)exp[0]) { -+ if (my_lower_case ((*get_byte) (data, p)) == exp[0]) { - for (f = 0, q = 0; q < l && f < 1; q++) -- if (my_lower_case ((*get_byte) (data, q + p)) != (unsigned char)exp[q]) -+ if (my_lower_case ((*get_byte) (data, q + p)) != exp[q]) - f = 1; -- if (f == 0) -+ if (f == 0) { -+#ifdef UTF8 -+ g_free (exp_backup); -+#endif /* UTF8 */ - return p; -+ } - } -- if (once_only) -+ if (once_only) { -+#ifdef UTF8 -+ g_free (exp_backup); -+#endif /* UTF8 */ - return -2; -+ } - } - } - } -+#ifdef UTF8 -+ g_free (exp_backup); -+#endif /* UTF8 */ - return -2; - } - -@@ -1643,9 +1852,14 @@ edit_find_forwards (long search_start, u - - while ((p = edit_find_string (p, exp, len, last_byte, get_byte, data, once_only, d)) >= 0) { - if (replace_whole) { -+#ifndef UTF8 - /*If the bordering chars are not in option_whole_chars_search then word is whole */ - if (!strcasechr (option_whole_chars_search, (*get_byte) (data, p - 1)) - && !strcasechr (option_whole_chars_search, (*get_byte) (data, p + *len))) -+#else /* UTF8 */ -+ if (!iswalnum((*get_byte) (data, p - 1)) -+ && !iswalnum((*get_byte) (data, p + *len))) -+#endif /* UTF8 */ - return p; - if (once_only) - return -2; -@@ -1677,6 +1891,7 @@ edit_find (long search_start, unsigned c - - #define is_digit(x) ((x) >= '0' && (x) <= '9') - -+#ifndef UTF8 - #define snprint(v) { \ - *p1++ = *p++; \ - *p1 = '\0'; \ -@@ -1684,33 +1899,48 @@ edit_find (long search_start, unsigned c - if (n >= (size_t) (e - s)) goto nospc; \ - s += n; \ - } -+#else /* UTF8 */ -+#define snprint(v) { \ -+ *p1++ = *p++; \ -+ *p1 = '\0'; \ -+ n = swprintf(s, e-s, q1,v); \ -+ if (n >= (size_t) (e - s)) goto nospc; \ -+ s += n; \ -+ } -+#endif /* UTF8 */ - - /* this function uses the sprintf command to do a vprintf */ - /* it takes pointers to arguments instead of the arguments themselves */ - /* The return value is the number of bytes written excluding '\0' - if successfull, -1 if the resulting string would be too long and - -2 if the format string is errorneous. */ --static int snprintf_p (char *str, size_t size, const char *fmt,...) -- __attribute__ ((format (printf, 3, 4))); -- --static int snprintf_p (char *str, size_t size, const char *fmt,...) -+static int snprintf_p (mc_wchar_t *str, size_t size, const mc_wchar_t *fmt,...) - { - va_list ap; - size_t n; -- const char *q, *p; -- char *s = str, *e = str + size; -- char q1[40]; -- char *p1; -+ const mc_wchar_t *q, *p; -+ mc_wchar_t *s = str, *e = str + size; -+ mc_wchar_t q1[40]; -+ -+ mc_wchar_t *p1; - int nargs = 0; - - va_start (ap, fmt); - p = q = fmt; - -+#ifndef UTF8 - while ((p = strchr (p, '%'))) { -+#else /* UTF8 */ -+ while ((p = wcschr (p, L'%'))) { -+#endif /* UTF8 */ - n = p - q; - if (n >= (size_t) (e - s)) - goto nospc; -+#ifndef UTF8 - memcpy (s, q, n); /* copy stuff between format specifiers */ -+#else /* UTF8 */ -+ wmemcpy (s, q, n); /* copy stuff between format specifiers */ -+#endif /* UTF8 */ - s += n; - q = p; - p1 = q1; -@@ -1738,45 +1968,78 @@ static int snprintf_p (char *str, size_t - *p1++ = *p++; - if (*p == '*') { - p++; -+#ifndef UTF8 - strcpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace field width with a number */ - p1 += strlen (p1); -+#else /* UTF8 */ -+ wcscpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace field width with a number */ -+ p1 += wcslen (p1); -+#endif /* UTF8 */ - } else { -- while (is_digit (*p) && p1 < q1 + 20) -+#ifndef UTF8 -+ while (is_digit (*p) -+#else /* UTF8 */ -+ while (iswdigit (*p) -+#endif /* UTF8 */ -+ && p1 < q1 + 20) - *p1++ = *p++; -- if (is_digit (*p)) -+#ifndef UTF8 -+ if (is_digit (*p)) -+#else /* UTF8 */ -+ if (iswdigit (*p)) -+#endif /* UTF8 */ - goto err; - } - if (*p == '.') - *p1++ = *p++; - if (*p == '*') { - p++; -+#ifndef UTF8 - strcpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace precision with a number */ - p1 += strlen (p1); -+#else /* UTF8 */ -+ wcscpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace precision with a number */ -+ p1 += wcslen (p1); -+#endif /* UTF8 */ - } else { -- while (is_digit (*p) && p1 < q1 + 32) -+#ifndef UTF8 -+ while (is_digit (*p) -+#else /* UTF8 */ -+ while (iswdigit (*p) -+#endif /* UTF8 */ -+ && p1 < q1 + 32) - *p1++ = *p++; -- if (is_digit (*p)) -+#ifndef UTF8 -+ if (is_digit (*p)) -+#else /* UTF8 */ -+ if (iswdigit (*p)) -+#endif /* UTF8 */ - goto err; - } - /* flags done, now get argument */ - if (*p == 's') { -+#ifndef UTF8 - snprint (va_arg (ap, char *)); -+#else /* UTF8 */ -+ *p1++ = 'l'; -+ snprint (va_arg (ap, mc_wchar_t *)); -+#endif /* UTF8 */ - } else if (*p == 'h') { -- if (strchr ("diouxX", *p)) -+ if (*p < 128 && strchr ("diouxX", *p)) - snprint (*va_arg (ap, short *)); - } else if (*p == 'l') { - *p1++ = *p++; -- if (strchr ("diouxX", *p)) -+ if (*p < 128 && strchr ("diouxX", *p)) - snprint (*va_arg (ap, long *)); -- } else if (strchr ("cdiouxX", *p)) { -+ } else if (*p < 128 && strchr ("cdiouxX", *p)) { - snprint (*va_arg (ap, int *)); - } else if (*p == 'L') { - *p1++ = *p++; -- if (strchr ("EefgG", *p)) -+ if (*p < 128 && strchr ("EefgG", *p)) - snprint (*va_arg (ap, double *)); /* should be long double */ -- } else if (strchr ("EefgG", *p)) { -+ } else if (*p < 128 && strchr ("EefgG", *p)) { - snprint (*va_arg (ap, double *)); -- } else if (strchr ("DOU", *p)) { -+ } else if (*p < 128 && strchr ("DOU", *p)) { - snprint (*va_arg (ap, long *)); - } else if (*p == 'p') { - snprint (*va_arg (ap, void **)); -@@ -1785,10 +2048,17 @@ static int snprintf_p (char *str, size_t - q = p; - } - va_end (ap); -+#ifndef UTF8 - n = strlen (q); - if (n >= (size_t) (e - s)) - return -1; - memcpy (s, q, n + 1); -+#else /* UTF8 */ -+ n = wcslen (q); -+ if (n >= (size_t) (e - s)) -+ return -1; -+ wmemcpy (s, q, n + 1); -+#endif /* UTF8 */ - return s + n - str; - nospc: - va_end (ap); -@@ -1967,8 +2237,11 @@ edit_replace_cmd (WEdit *edit, int again - } - } - if (replace_yes) { /* delete then insert new */ -+#ifdef UTF8 -+ mc_wchar_t *winput2 = mbstr_to_wchar(input2); -+#endif /* UTF8 */ - if (replace_scanf) { -- char repl_str[MAX_REPL_LEN + 2]; -+ mc_wchar_t repl_str[MAX_REPL_LEN + 2]; - int ret = 0; - - /* we need to fill in sargs just like with scanf */ -@@ -1977,17 +2250,25 @@ edit_replace_cmd (WEdit *edit, int again - for (k = 1; - k < NUM_REPL_ARGS && pmatch[k].rm_eo >= 0; - k++) { -+#ifndef UTF8 - unsigned char *t; -+#else /* UTF8 */ -+ mc_wchar_t *t; -+#endif - - if (pmatch[k].rm_eo - pmatch[k].rm_so > 255) { - ret = -1; - break; - } -+#ifndef UTF8 - t = (unsigned char *) &sargs[k - 1][0]; -+#else /* UTF8 */ -+ t = (mc_wchar_t *) &sargs[k - 1][0]; -+#endif /* UTF8 */ - for (j = 0; - j < pmatch[k].rm_eo - pmatch[k].rm_so - && j < 255; j++, t++) -- *t = (unsigned char) edit_get_byte (edit, -+ *t = edit_get_byte (edit, - edit-> - search_start - - -@@ -2005,14 +2286,23 @@ edit_replace_cmd (WEdit *edit, int again - } - if (!ret) - ret = -+#ifndef UTF8 - snprintf_p (repl_str, MAX_REPL_LEN + 2, input2, -+#else /* UTF8 */ -+ snprintf_p (repl_str, MAX_REPL_LEN + 2, winput2, -+#endif /* UTF8 */ - PRINTF_ARGS); - if (ret >= 0) { - times_replaced++; - while (i--) - edit_delete (edit); -+#ifndef UTF8 - while (repl_str[++i]) - edit_insert (edit, repl_str[i]); -+#else /* UTF8 */ -+ while (winput2[++i]) -+ edit_insert (edit, winput2[i]); -+#endif /* UTF8 */ - } else { - edit_error_dialog (_(" Replace "), - ret == -@@ -2026,10 +2316,18 @@ edit_replace_cmd (WEdit *edit, int again - times_replaced++; - while (i--) - edit_delete (edit); -+#ifndef UTF8 - while (input2[++i]) - edit_insert (edit, input2[i]); -+#else /* UTF8 */ -+ while (winput2[++i]) -+ edit_insert (edit, winput2[i]); -+#endif /* UTF8 */ - } - edit->found_len = i; -+#ifdef UTF8 -+ g_free (winput2); -+#endif /* UTF8 */ - } - /* so that we don't find the same string again */ - if (replace_backwards) { -@@ -2202,16 +2500,17 @@ edit_ok_to_exit (WEdit *edit) - #define TEMP_BUF_LEN 1024 - - /* Return a null terminated length of text. Result must be g_free'd */ --static unsigned char * -+static mc_wchar_t * - edit_get_block (WEdit *edit, long start, long finish, int *l) - { -- unsigned char *s, *r; -- r = s = g_malloc (finish - start + 1); -+ mc_wchar_t *s, *r; -+ r = s = g_malloc ((finish - start + 1) * sizeof(mc_wchar_t)); - if (column_highlighting) { - *l = 0; - /* copy from buffer, excluding chars that are out of the column 'margins' */ - while (start < finish) { -- int c, x; -+ mc_wchar_t c; -+ int x; - x = edit_move_forward3 (edit, edit_bol (edit, start), 0, - start); - c = edit_get_byte (edit, start); -@@ -2244,11 +2543,15 @@ edit_save_block (WEdit * edit, const cha - return 0; - - if (column_highlighting) { -- unsigned char *block, *p; -+ mc_wchar_t *block, *p; - int r; - p = block = edit_get_block (edit, start, finish, &len); - while (len) { -+#ifndef UTF8 - r = mc_write (file, p, len); -+#else /* UTF8 */ -+ r = wchar_write (file, p, len); -+#endif /* UTF8 */ - if (r < 0) - break; - p += r; -@@ -2256,15 +2559,19 @@ edit_save_block (WEdit * edit, const cha - } - g_free (block); - } else { -- unsigned char *buf; -+ mc_wchar_t *buf; - int i = start, end; - len = finish - start; -- buf = g_malloc (TEMP_BUF_LEN); -+ buf = g_malloc (TEMP_BUF_LEN * sizeof(mc_wchar_t)); - while (start != finish) { - end = min (finish, start + TEMP_BUF_LEN); - for (; i < end; i++) - buf[i - start] = edit_get_byte (edit, i); -+#ifndef UTF8 - len -= mc_write (file, (char *) buf, end - start); -+#else /* UTF8 */ -+ len -= wchar_write (file, buf, end - start); -+#endif /* UTF8 */ - start = end; - } - g_free (buf); -@@ -2602,17 +2909,20 @@ edit_block_process_cmd (WEdit *edit, con - - /* prints at the cursor */ - /* returns the number of chars printed */ -+#ifndef UTF8 - int edit_print_string (WEdit * e, const char *s) -+#else /* UTF8 */ -+int edit_print_wstring (WEdit * e, mc_wchar_t *s) -+#endif /* UTF8 */ - { - int i = 0; - while (s[i]) -- edit_execute_cmd (e, -1, (unsigned char) s[i++]); -+ edit_execute_cmd (e, -1, s[i++]); - e->force |= REDRAW_COMPLETELY; - edit_update_screen (e); - return i; - } - -- - static void pipe_mail (WEdit *edit, char *to, char *subject, char *cc) - { - FILE *p = 0; -@@ -2706,15 +3016,20 @@ void edit_mail_dialog (WEdit * edit) - /* find first character of current word */ - static int edit_find_word_start (WEdit *edit, long *word_start, int *word_len) - { -- int i, c, last; -+ int i; -+ mc_wint_t c, last; - - /* return if at begin of file */ - if (edit->curs1 <= 0) - return 0; - -- c = (unsigned char) edit_get_byte (edit, edit->curs1 - 1); -+ c = edit_get_byte (edit, edit->curs1 - 1); - /* return if not at end or in word */ -+#ifndef UTF8 - if (isspace (c) || !(isalnum (c) || c == '_')) -+#else /* UTF8 */ -+ if (iswspace (c) || !(iswalnum (c) || c == '_')) -+#endif /* UTF8 */ - return 0; - - /* search start of word to be completed */ -@@ -2724,11 +3039,19 @@ static int edit_find_word_start (WEdit * - return 0; - - last = c; -- c = (unsigned char) edit_get_byte (edit, edit->curs1 - i); -+ c = edit_get_byte (edit, edit->curs1 - i); - -+#ifndef UTF8 - if (!(isalnum (c) || c == '_')) { -+#else /* UTF8 */ -+ if (!(iswalnum (c) || c == '_')) { -+#endif /* UTF8 */ - /* return if word starts with digit */ -+#ifndef UTF8 - if (isdigit (last)) -+#else /* UTF8 */ -+ if (iswdigit (last)) -+#endif /* UTF8 */ - return 0; - - *word_start = edit->curs1 - (i - 1); /* start found */ -@@ -2761,7 +3084,7 @@ edit_collect_completions (WEdit *edit, l - int *num) - { - int len, max_len = 0, i, skip; -- unsigned char *bufpos; -+ mc_wchar_t *bufpos; - - /* collect max MAX_WORD_COMPLETIONS completions */ - while (*num < MAX_WORD_COMPLETIONS) { -@@ -2780,11 +3103,16 @@ edit_collect_completions (WEdit *edit, l - buffers1[start >> S_EDIT_BUF_SIZE][start & M_EDIT_BUF_SIZE]; - skip = 0; - for (i = 0; i < *num; i++) { -+#ifndef UTF8 - if (strncmp - ((char *) &compl[i].text[word_len], -- (char *) &bufpos[word_len], max (len, -- compl[i].len) - -- word_len) == 0) { -+ (char *) &bufpos[word_len], -+#else /* UTF8 */ -+ if (wcsncmp -+ ((wchar_t *) &compl[i].text[word_len], -+ (wchar_t *) &bufpos[word_len], -+#endif /* UTF8 */ -+ max (len, compl[i].len) - word_len) == 0) { - skip = 1; - break; /* skip it, already added */ - } -@@ -2792,7 +3120,7 @@ edit_collect_completions (WEdit *edit, l - if (skip) - continue; - -- compl[*num].text = g_malloc (len + 1); -+ compl[*num].text = g_malloc ((len + 1) * sizeof(mc_wchar_t)); - compl[*num].len = len; - for (i = 0; i < len; i++) - compl[*num].text[i] = *(bufpos + i); -@@ -2806,6 +3134,18 @@ edit_collect_completions (WEdit *edit, l - return max_len; - } - -+#ifdef UTF8 -+int edit_print_string (WEdit * e, const char *s) -+{ -+ int i; -+ mc_wchar_t *ws = mbstr_to_wchar(s); -+ i = edit_print_wstring (e, ws); -+ g_free(ws); -+ return i; -+} -+ -+#endif /* UTF8 */ -+ - - /* let the user select its preferred completion */ - static void -@@ -2818,6 +3158,9 @@ edit_completion_dialog (WEdit * edit, in - WListbox *compl_list; - int compl_dlg_h; /* completion dialog height */ - int compl_dlg_w; /* completion dialog width */ -+#ifdef UTF8 -+ char *mbtext; -+#endif /* UTF8 */ - - /* calculate the dialog metrics */ - compl_dlg_h = num_compl + 2; -@@ -2853,9 +3196,18 @@ edit_completion_dialog (WEdit * edit, in - add_widget (compl_dlg, compl_list); - - /* fill the listbox with the completions */ -+#ifndef UTF8 - for (i = 0; i < num_compl; i++) - listbox_add_item (compl_list, LISTBOX_APPEND_AT_END, 0, - (char *) compl[i].text, NULL); -+#else /* UTF8 */ -+ for (i = 0; i < num_compl; i++) { -+ mbtext = wchar_to_mbstr(compl[i].text); -+ listbox_add_item (compl_list, LISTBOX_APPEND_AT_END, 0, -+ mbtext, NULL); -+ g_free(mbtext); -+ } -+#endif /* UTF8 */ - - /* pop up the dialog */ - run_dlg (compl_dlg); -@@ -2863,9 +3215,17 @@ edit_completion_dialog (WEdit * edit, in - /* apply the choosen completion */ - if (compl_dlg->ret_value == B_ENTER) { - listbox_get_current (compl_list, &curr, NULL); -- if (curr) -+ if (curr){ -+#ifndef UTF8 - for (curr += word_len; *curr; curr++) - edit_insert (edit, *curr); -+#else /* UTF8 */ -+ mc_wchar_t *wc, *wccurr = mbstr_to_wchar(curr); -+ for (wc = wccurr + word_len; *wc; wc++) -+ edit_insert (edit, *wc); -+ g_free(wccurr); -+#endif /* UTF8 */ -+ } - } - - /* destroy dialog before return */ -@@ -2882,8 +3242,9 @@ edit_complete_word_cmd (WEdit *edit) - { - int word_len = 0, i, num_compl = 0, max_len; - long word_start = 0; -- unsigned char *bufpos; -- char *match_expr; -+ mc_wchar_t *bufpos; -+ mc_wchar_t *match_expr; -+ char *mbmatch_expr; - struct selection compl[MAX_WORD_COMPLETIONS]; /* completions */ - - /* don't want to disturb another search */ -@@ -2900,16 +3261,32 @@ edit_complete_word_cmd (WEdit *edit) - /* prepare match expression */ - bufpos = &edit->buffers1[word_start >> S_EDIT_BUF_SIZE] - [word_start & M_EDIT_BUF_SIZE]; -+ -+ match_expr = g_malloc((word_len + 14) * sizeof(mc_wchar_t)); -+#ifndef UTF8 - match_expr = g_strdup_printf ("%.*s[a-zA-Z_0-9]+", word_len, bufpos); -+#else /* UTF8 */ -+ wcsncpy (match_expr, bufpos, word_len); -+ match_expr[word_len] = '\0'; -+ wcscat (match_expr, L"[a-zA-Z_0-9]+"); -+#endif /* UTF8 */ - - /* init search: backward, regexp, whole word, case sensitive */ - edit_set_search_parameters (0, 1, 1, 1, 1); - - /* collect the possible completions */ - /* start search from curs1 down to begin of file */ -+#ifndef UTF8 - max_len = - edit_collect_completions (edit, word_start, word_len, match_expr, - (struct selection *) &compl, &num_compl); -+#else /* UTF8 */ -+ mbmatch_expr = wchar_to_mbstr(match_expr); -+ max_len = -+ edit_collect_completions (edit, word_start, word_len, mbmatch_expr, -+ (struct selection *) &compl, &num_compl); -+ g_free(mbmatch_expr); -+#endif /* UTF8 */ - - if (num_compl > 0) { - /* insert completed word if there is only one match */ ---- mc/edit/wordproc.c.utf8 2006-06-17 04:55:41.000000000 +0200 -+++ mc/edit/wordproc.c 2007-01-04 16:20:56.000000000 +0100 + maxlen += 10; + +@@ -136,11 +136,11 @@ init_panelize (void) + panelize_cols = max (panelize_cols, maxlen); + + panelize_but[2].x = +- panelize_but[3].x + strlen (panelize_but[3].text) + 7; ++ panelize_but[3].x + mbstrlen (panelize_but[3].text) + 7; + panelize_but[1].x = +- panelize_but[2].x + strlen (panelize_but[2].text) + 5; ++ panelize_but[2].x + mbstrlen (panelize_but[2].text) + 5; + panelize_but[0].x = +- panelize_cols - strlen (panelize_but[0].text) - 8 - BX; ++ panelize_cols - mbstrlen (panelize_but[0].text) - 8 - BX; + + #endif /* ENABLE_NLS */ + +diff -up mc-4.6.2-pre1/edit/wordproc.c.utf8 mc-4.6.2-pre1/edit/wordproc.c +--- mc-4.6.2-pre1/edit/wordproc.c.utf8 2006-06-16 22:01:29.000000000 +0200 ++++ mc-4.6.2-pre1/edit/wordproc.c 2008-02-25 14:56:22.000000000 +0100 @@ -40,7 +40,12 @@ #define tab_width option_tab_spacing @@ -4287,317 +3094,9 @@ g_free (t); return; } ---- mc/edit/edit.h.utf8 2006-12-12 18:39:33.000000000 +0100 -+++ mc/edit/edit.h 2007-01-04 16:20:56.000000000 +0100 -@@ -25,6 +25,27 @@ - - #include - -+#include "src/tty.h" -+ -+#ifdef UTF8 -+#include -+#include -+ -+#define mc_wchar_t wchar_t -+#define mc_wint_t wint_t -+ -+#else -+ -+#define mc_wchar_t unsigned char -+#define mc_wint_t int -+ -+#endif -+ -+ -+/* unicode private use area */ -+#define BINARY_CHAR_OFFSET 0xFFE00 -+ -+ - #define N_menus 5 - - #define SEARCH_DIALOG_OPTION_NO_SCANF (1 << 0) -@@ -86,6 +107,8 @@ - #define START_STACK_SIZE 32 - - /* Some codes that may be pushed onto or returned from the undo stack */ -+#define CHAR_INSERT 65 -+#define CHAR_INSERT_AHEAD 66 - #define CURS_LEFT 601 - #define CURS_RIGHT 602 - #define DELCHAR 603 -@@ -105,7 +128,7 @@ - - struct macro { - short command; -- short ch; -+ mc_wchar_t ch; - }; - - struct WEdit; -@@ -120,8 +143,12 @@ void edit_reload_menu (void); - void menu_save_mode_cmd (void); - int edit_raw_key_query (const char *heading, const char *query, int cancel); - int edit_file (const char *_file, int line); --int edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch); -+int edit_translate_key (WEdit *edit, long x_key, int *cmd, mc_wint_t *ch); -+#ifndef UTF8 - int edit_get_byte (WEdit * edit, long byte_index); -+#else /* UTF8 */ -+mc_wchar_t edit_get_byte (WEdit * edit, long byte_index); -+#endif /* UTF8 */ - int edit_count_lines (WEdit * edit, long current, int upto); - long edit_move_forward (WEdit * edit, long current, int lines, long upto); - long edit_move_forward3 (WEdit * edit, long current, int cols, long upto); -@@ -148,11 +175,11 @@ int edit_block_delete_cmd (WEdit * edit) - void edit_delete_line (WEdit * edit); - - int edit_delete (WEdit * edit); --void edit_insert (WEdit * edit, int c); -+void edit_insert (WEdit * edit, mc_wchar_t c); - int edit_cursor_move (WEdit * edit, long increment); - void edit_push_action (WEdit * edit, long c, ...); - void edit_push_key_press (WEdit * edit); --void edit_insert_ahead (WEdit * edit, int c); -+void edit_insert_ahead (WEdit * edit, mc_wchar_t c); - long edit_write_stream (WEdit * edit, FILE * f); - char *edit_get_write_filter (const char *writename, const char *filename); - int edit_save_confirm_cmd (WEdit * edit); -@@ -183,7 +210,7 @@ void edit_goto_cmd (WEdit * edit); - int eval_marks (WEdit * edit, long *start_mark, long *end_mark); - void edit_status (WEdit * edit); - void edit_execute_key_command (WEdit *edit, int command, -- int char_for_insertion); -+ mc_wint_t char_for_insertion); - void edit_update_screen (WEdit * edit); - int edit_print_string (WEdit * e, const char *s); - void edit_move_to_line (WEdit * e, long line); -@@ -233,7 +260,7 @@ void edit_mail_dialog (WEdit *edit); - void format_paragraph (WEdit *edit, int force); - - /* either command or char_for_insertion must be passed as -1 */ --void edit_execute_cmd (WEdit *edit, int command, int char_for_insertion); -+void edit_execute_cmd (WEdit *edit, int command, mc_wint_t char_for_insertion); - - #define get_sys_error(s) (s) - ---- mc/edit/editdraw.c.utf8 2006-12-09 16:19:48.000000000 +0100 -+++ mc/edit/editdraw.c 2007-01-04 16:20:56.000000000 +0100 -@@ -69,11 +69,16 @@ static void status_string (WEdit * edit, - * as decimal and as hex. - */ - if (edit->curs1 < edit->last_byte) { -- unsigned char cur_byte = edit_get_byte (edit, edit->curs1); -+ mc_wchar_t cur_byte = edit_get_byte (edit, edit->curs1); -+#ifndef UTF8 - g_snprintf (byte_str, sizeof (byte_str), "%c %3d 0x%02X", - is_printable (cur_byte) ? cur_byte : '.', -- (int) cur_byte, -- (unsigned) cur_byte); -+#else /* UTF8 */ -+ g_snprintf (byte_str, sizeof(byte_str), "%lc %3d 0x%02X", -+ iswprint(cur_byte) ? cur_byte : '.', -+#endif /* UTF8 */ -+ (int) cur_byte, -+ (unsigned) cur_byte); - } else { - strcpy (byte_str, ""); - } -@@ -205,11 +210,16 @@ void edit_scroll_screen_over_cursor (WEd - #define lowlevel_set_color(x) attrset(MY_COLOR_PAIR(color)) - #endif - -+struct line_s { -+ mc_wchar_t ch; -+ unsigned int style; -+}; -+ - static void - print_to_widget (WEdit *edit, long row, int start_col, int start_col_real, -- long end_col, unsigned int line[]) -+ long end_col, struct line_s line[]) - { -- unsigned int *p; -+ struct line_s *p; - - int x = start_col_real + EDIT_TEXT_HORIZONTAL_OFFSET; - int x1 = start_col + EDIT_TEXT_HORIZONTAL_OFFSET; -@@ -223,9 +233,9 @@ print_to_widget (WEdit *edit, long row, - edit_move (x1 + FONT_OFFSET_X, y + FONT_OFFSET_Y); - p = line; - -- while (*p) { -+ while (p->ch) { - int style; -- int textchar; -+ mc_wchar_t textchar; - int color; - - if (cols_to_skip) { -@@ -234,9 +244,9 @@ print_to_widget (WEdit *edit, long row, - continue; - } - -- style = *p & 0xFF00; -- textchar = *p & 0xFF; -- color = *p >> 16; -+ style = p->style & 0xFF00; -+ textchar = p->ch; -+ color = p->style >> 16; - - if (style & MOD_ABNORMAL) { - /* Non-printable - use black background */ -@@ -250,8 +260,11 @@ print_to_widget (WEdit *edit, long row, - } else { - lowlevel_set_color (color); - } -- -+#ifdef UTF8 -+ SLsmg_write_nwchars(&textchar, 1); -+#else - addch (textchar); -+#endif - p++; - } - } -@@ -261,11 +274,11 @@ static void - edit_draw_this_line (WEdit *edit, long b, long row, long start_col, - long end_col) - { -- static unsigned int line[MAX_LINE_LEN]; -- unsigned int *p = line; -+ struct line_s line[MAX_LINE_LEN]; -+ struct line_s *p = line; - long m1 = 0, m2 = 0, q, c1, c2; - int col, start_col_real; -- unsigned int c; -+ mc_wint_t c; - int color; - int i; - -@@ -282,62 +295,92 @@ edit_draw_this_line (WEdit *edit, long b - - if (row <= edit->total_lines - edit->start_line) { - while (col <= end_col - edit->start_col) { -- *p = 0; -+ p->ch = 0; -+ p->style = 0; - if (q == edit->curs1) -- *p |= MOD_CURSOR; -+ p->style |= MOD_CURSOR; - if (q >= m1 && q < m2) { - if (column_highlighting) { - int x; - x = edit_move_forward3 (edit, b, 0, q); - if (x >= c1 && x < c2) -- *p |= MOD_MARKED; -+ p->style |= MOD_MARKED; - } else -- *p |= MOD_MARKED; -+ p->style |= MOD_MARKED; - } - if (q == edit->bracket) -- *p |= MOD_BOLD; -+ p->style |= MOD_BOLD; - if (q >= edit->found_start - && q < edit->found_start + edit->found_len) -- *p |= MOD_BOLD; -+ p->style |= MOD_BOLD; - c = edit_get_byte (edit, q); - /* we don't use bg for mc - fg contains both */ - edit_get_syntax_color (edit, q, &color); -- *p |= color << 16; -+ p->style |= color << 16; - q++; - switch (c) { - case '\n': - col = end_col - edit->start_col + 1; /* quit */ -- *(p++) |= ' '; -+ p->ch = ' '; -+ p++; - break; - case '\t': - i = TAB_SIZE - ((int) col % TAB_SIZE); -- *p |= ' '; -- c = *(p++) & ~MOD_CURSOR; -+ p->ch = ' '; -+ c = p->style & ~MOD_CURSOR; -+ p++; - col += i; -- while (--i) -- *(p++) = c; -+ while (--i) { -+ p->ch = ' '; p->style = c; -+ p++; -+ } - break; - default: - c = convert_to_display_c (c); - - /* Caret notation for control characters */ - if (c < 32) { -- *(p++) = '^' | MOD_ABNORMAL; -- *(p++) = (c + 0x40) | MOD_ABNORMAL; -+ p->ch = '^'; -+ p->style = MOD_ABNORMAL; -+ p++; -+ p->ch = c + 0x40; -+ p->style = MOD_ABNORMAL; - col += 2; - break; - } - if (c == 127) { -- *(p++) = '^' | MOD_ABNORMAL; -- *(p++) = '?' | MOD_ABNORMAL; -+ p->ch = '^'; -+ p->style = MOD_ABNORMAL; -+ p++; -+ p->ch = '?'; -+ p->style = MOD_ABNORMAL; -+ p++; - col += 2; - break; - } - -- if (is_printable (c)) { -- *(p++) |= c; -+#ifndef UTF8 -+ if (is_printable (c) -+#else /* UTF8 */ -+ if (iswprint (c) -+#ifdef __STDC_ISO_10646__ -+ && (c < BINARY_CHAR_OFFSET || c >= (BINARY_CHAR_OFFSET + 256)) -+#endif -+#endif /* UTF8 */ -+ ) { -+ p->ch = c; -+ p++; -+ -+#ifdef UTF8 -+ i = wcwidth(c); -+ if (i > 1) { -+ col += i - 1; -+ } -+#endif /* UTF8 */ - } else { -- *(p++) = '.' | MOD_ABNORMAL; -+ p->ch = '.'; -+ p->style = MOD_ABNORMAL; -+ p++; - } - col++; - break; -@@ -347,7 +390,7 @@ edit_draw_this_line (WEdit *edit, long b - } else { - start_col_real = start_col = 0; - } -- *p = 0; -+ p->ch = 0; - - print_to_widget (edit, row, start_col, start_col_real, end_col, line); - } ---- mc/edit/edit.c.utf8 2006-12-12 18:39:33.000000000 +0100 -+++ mc/edit/edit.c 2007-01-04 16:20:56.000000000 +0100 +diff -up mc-4.6.2-pre1/edit/edit.c.utf8 mc-4.6.2-pre1/edit/edit.c +--- mc-4.6.2-pre1/edit/edit.c.utf8 2007-01-04 16:37:23.000000000 +0100 ++++ mc-4.6.2-pre1/edit/edit.c 2008-02-25 14:56:22.000000000 +0100 @@ -102,7 +102,11 @@ char *option_backup_ext = NULL; static void user_menu (WEdit *edit); @@ -5101,7 +3600,7 @@ } return col; } -@@ -1399,7 +1521,7 @@ static int +@@ -1399,12 +1521,16 @@ static int is_blank (WEdit *edit, long offset) { long s, f; @@ -5110,7 +3609,105 @@ s = edit_bol (edit, offset); f = edit_eol (edit, offset) - 1; while (s <= f) { -@@ -1771,13 +1893,13 @@ static void edit_left_delete_word (WEdit + c = edit_get_byte (edit, s++); ++#ifndef UTF8 + if (!isspace (c)) ++#else ++ if (!iswspace (c)) ++#endif /* UTF8 */ + return 0; + } + return 1; +@@ -1659,6 +1785,7 @@ my_type_of (int c) + return 2; + return 0x80000000UL; + } ++#ifndef UTF8 + if (isupper (c)) + c = 'A'; + else if (islower (c)) +@@ -1669,6 +1796,18 @@ my_type_of (int c) + c = '0'; + else if (isspace (c)) + c = ' '; ++#else ++ if (iswupper (c)) ++ c = 'A'; ++ else if (iswlower (c)) ++ c = 'a'; ++ else if (iswalpha (c)) ++ c = 'a'; ++ else if (iswdigit (c)) ++ c = '0'; ++ else if (iswspace (c)) ++ c = ' '; ++#endif /* UTF8 */ + q = strchr (option_chars_move_whole_word, c); + if (!q) + return 0xFFFFFFFFUL; +@@ -1693,10 +1832,18 @@ edit_left_word_move (WEdit *edit, int s) + c2 = edit_get_byte (edit, edit->curs1); + if (!(my_type_of (c1) & my_type_of (c2))) + break; ++#ifndef UTF8 + if (isspace (c1) && !isspace (c2)) ++#else ++ if (iswspace (c1) && !iswspace (c2)) ++#endif /* UTF8 */ + break; + if (s) ++#ifndef UTF8 + if (!isspace (c1) && isspace (c2)) ++#else ++ if (!iswspace (c1) && iswspace (c2)) ++#endif /* UTF8 */ + break; + } + } +@@ -1719,10 +1866,18 @@ edit_right_word_move (WEdit *edit, int s + c2 = edit_get_byte (edit, edit->curs1); + if (!(my_type_of (c1) & my_type_of (c2))) + break; ++#ifndef UTF8 + if (isspace (c1) && !isspace (c2)) ++#else ++ if (iswspace (c1) && !iswspace (c2)) ++#endif /* UTF8 */ + break; + if (s) ++#ifndef UTF8 + if (!isspace (c1) && isspace (c2)) ++#else ++ if (!iswspace (c1) && iswspace (c2)) ++#endif /* UTF8 */ + break; + } + } +@@ -1742,7 +1897,11 @@ static void edit_right_delete_word (WEdi + break; + c1 = edit_delete (edit); + c2 = edit_get_byte (edit, edit->curs1); ++#ifndef UTF8 + if ((isspace (c1) == 0) != (isspace (c2) == 0)) ++#else ++ if ((iswspace (c1) == 0) != (iswspace (c2) == 0)) ++#endif /* UTF8 */ + break; + if (!(my_type_of (c1) & my_type_of (c2))) + break; +@@ -1757,7 +1916,11 @@ static void edit_left_delete_word (WEdit + break; + c1 = edit_backspace (edit); + c2 = edit_get_byte (edit, edit->curs1 - 1); ++#ifndef UTF8 + if ((isspace (c1) == 0) != (isspace (c2) == 0)) ++#else ++ if ((iswspace (c1) == 0) != (iswspace (c2) == 0)) ++#endif /* UTF8 */ + break; + if (!(my_type_of (c1) & my_type_of (c2))) + break; +@@ -1771,13 +1934,13 @@ static void edit_left_delete_word (WEdit static void edit_do_undo (WEdit * edit) { @@ -5127,7 +3724,7 @@ case STACK_BOTTOM: goto done_undo; case CURS_RIGHT: -@@ -1798,31 +1920,33 @@ edit_do_undo (WEdit * edit) +@@ -1798,31 +1961,33 @@ edit_do_undo (WEdit * edit) case COLUMN_OFF: column_highlighting = 0; break; @@ -5174,7 +3771,7 @@ edit_update_curs_row (edit); done_undo:; -@@ -2102,7 +2226,7 @@ static void edit_goto_matching_bracket ( +@@ -2102,7 +2267,7 @@ static void edit_goto_matching_bracket ( * passed as -1. Commands are executed, and char_for_insertion is * inserted at the cursor. */ @@ -5183,7 +3780,7 @@ { if (command == CK_Begin_Record_Macro) { edit->macro_i = 0; -@@ -2137,7 +2261,7 @@ static const char * const shell_cmd[] = +@@ -2137,7 +2302,7 @@ static const char * const shell_cmd[] = all of them. It also does not check for the Undo command. */ void @@ -5192,7 +3789,7 @@ { edit->force |= REDRAW_LINE; -@@ -2170,7 +2294,7 @@ edit_execute_cmd (WEdit *edit, int comma +@@ -2170,7 +2335,7 @@ edit_execute_cmd (WEdit *edit, int comma } /* An ordinary key press */ @@ -5201,106 +3798,1597 @@ if (edit->overwrite) { if (edit_get_byte (edit, edit->curs1) != '\n') edit_delete (edit); ---- mc/edit/edit.c.jn 2007-04-16 18:14:22.000000000 +0200 -+++ mc/edit/edit.c 2007-04-16 18:26:25.000000000 +0200 -@@ -1526,7 +1526,11 @@ - f = edit_eol (edit, offset) - 1; - while (s <= f) { - c = edit_get_byte (edit, s++); +diff -up mc-4.6.2-pre1/edit/editcmd.c.utf8 mc-4.6.2-pre1/edit/editcmd.c +--- mc-4.6.2-pre1/edit/editcmd.c.utf8 2007-05-02 13:22:01.000000000 +0200 ++++ mc-4.6.2-pre1/edit/editcmd.c 2008-02-25 14:56:22.000000000 +0100 +@@ -61,7 +61,7 @@ + #define edit_get_save_file(f,h) input_expand_dialog (h, _(" Enter file name: "), f) + + struct selection { +- unsigned char * text; ++ mc_wchar_t *text; + int len; + }; + +@@ -84,12 +84,16 @@ int edit_confirm_save = 1; + #define MAX_REPL_LEN 1024 + + static int edit_save_cmd (WEdit *edit); +-static unsigned char *edit_get_block (WEdit *edit, long start, ++static mc_wchar_t *edit_get_block (WEdit *edit, long start, + long finish, int *l); + +-static inline int my_lower_case (int c) ++static inline mc_wchar_t my_lower_case (mc_wchar_t c) + { +#ifndef UTF8 - if (!isspace (c)) + return tolower(c & 0xFF); +#else -+ if (!iswspace (c)) ++ return towlower(c); ++#endif + } + + static const char * +@@ -124,11 +128,11 @@ static void *memmove (void *dest, const + #endif /* !HAVE_MEMMOVE */ + + /* #define itoa MY_itoa <---- this line is now in edit.h */ +-static char * ++static mc_wchar_t * + MY_itoa (int i) + { +- static char t[14]; +- char *s = t + 13; ++ static mc_wchar_t t[14]; ++ mc_wchar_t *s = t + 13; + int j = i; + *s-- = 0; + do { +@@ -213,6 +217,48 @@ void edit_refresh_cmd (WEdit * edit) + doupdate(); + } + ++#ifdef UTF8 ++ ++static size_t ++wchar_write(int fd, mc_wchar_t *buf, size_t len) ++{ ++ char *tmpbuf = g_malloc(len + MB_LEN_MAX); ++ mbstate_t mbs; ++ size_t i; ++ size_t outlen = 0; ++ size_t res; ++ ++ for (i = 0; i < len; i++) { ++ if (outlen >= len) { ++ if ((res = mc_write(fd, tmpbuf, outlen)) != outlen) { ++ g_free(tmpbuf); ++ return -1; ++ } ++ outlen = 0; ++ } ++ memset (&mbs, 0, sizeof (mbs)); ++#ifdef __STDC_ISO_10646__ ++ if (buf[i] >= BINARY_CHAR_OFFSET && buf[i] < (BINARY_CHAR_OFFSET + 256)) { ++ res = 1; ++ tmpbuf[outlen] = (char) (buf[i] - BINARY_CHAR_OFFSET); ++ ++ } else ++#endif ++ res = wcrtomb(tmpbuf + outlen, buf[i], &mbs); ++ if (res > 0) { ++ outlen += res; ++ } ++ } ++ if ((res = mc_write(fd, tmpbuf, outlen)) != outlen) { ++ g_free(tmpbuf); ++ return -1; ++ } ++ g_free(tmpbuf); ++ return len; ++} ++ +#endif /* UTF8 */ ++ + /* If 0 (quick save) then a) create/truncate file, + b) save to ; + if 1 (safe save) then a) save to , +@@ -360,32 +406,48 @@ edit_save_file (WEdit *edit, const char + buf = 0; + filelen = edit->last_byte; + while (buf <= (edit->curs1 >> S_EDIT_BUF_SIZE) - 1) { ++#ifndef UTF8 + if (mc_write (fd, (char *) edit->buffers1[buf], EDIT_BUF_SIZE) ++#else /* UTF8 */ ++ if (wchar_write (fd, edit->buffers1[buf], EDIT_BUF_SIZE) ++#endif /* UTF8 */ + != EDIT_BUF_SIZE) { + mc_close (fd); + goto error_save; + } + buf++; + } ++#ifndef UTF8 + if (mc_write + (fd, (char *) edit->buffers1[buf], ++#else /* UTF8 */ ++ if (wchar_write ++ (fd, edit->buffers1[buf], ++#endif /* UTF8 */ + edit->curs1 & M_EDIT_BUF_SIZE) != + (edit->curs1 & M_EDIT_BUF_SIZE)) { + filelen = -1; + } else if (edit->curs2) { + edit->curs2--; + buf = (edit->curs2 >> S_EDIT_BUF_SIZE); +- if (mc_write +- (fd, +- (char *) edit->buffers2[buf] + EDIT_BUF_SIZE - ++#ifndef UTF8 ++ if (mc_write(fd, (char *) edit->buffers2[buf] + EDIT_BUF_SIZE - ++#else /* UTF8 */ ++ if (wchar_write(fd, edit->buffers2[buf] + EDIT_BUF_SIZE - ++#endif /* UTF8 */ + (edit->curs2 & M_EDIT_BUF_SIZE) - 1, + 1 + (edit->curs2 & M_EDIT_BUF_SIZE)) != + 1 + (edit->curs2 & M_EDIT_BUF_SIZE)) { + filelen = -1; + } else { + while (--buf >= 0) { ++#ifndef UTF8 + if (mc_write + (fd, (char *) edit->buffers2[buf], ++#else /* UTF8 */ ++ if (wchar_write ++ (fd, edit->buffers2[buf], ++#endif /* UTF8 */ + EDIT_BUF_SIZE) != EDIT_BUF_SIZE) { + filelen = -1; + break; +@@ -705,13 +767,21 @@ edit_delete_macro (WEdit * edit, int k) + if (!n || n == EOF) + break; + n = 0; ++#ifndef UTF8 + while (fscanf (f, "%hd %hd, ", ¯o[n].command, ¯o[n].ch)) ++#else /* UTF8 */ ++ while (fscanf (f, "%hd %lu, ", ¯o[n].command, ¯o[n].ch)) ++#endif /* UTF8 */ + n++; + fscanf (f, ";\n"); + if (s != k) { + fprintf (g, ("key '%d 0': "), s); + for (i = 0; i < n; i++) ++#ifndef UTF8 + fprintf (g, "%hd %hd, ", macro[i].command, macro[i].ch); ++#else /* UTF8 */ ++ fprintf (g, "%hd %lu, ", macro[i].command, macro[i].ch); ++#endif /* UTF8 */ + fprintf (g, ";\n"); + } + } +@@ -744,7 +814,11 @@ int edit_save_macro_cmd (WEdit * edit, s + if (f) { + fprintf (f, ("key '%d 0': "), s); + for (i = 0; i < n; i++) ++#ifndef UTF8 + fprintf (f, "%hd %hd, ", macro[i].command, macro[i].ch); ++#else /* UTF8 */ ++ fprintf (f, "%hd %lu, ", macro[i].command, macro[i].ch); ++#endif /* UTF8 */ + fprintf (f, ";\n"); + fclose (f); + if (saved_macros_loaded) { +@@ -794,10 +868,18 @@ int edit_load_macro_cmd (WEdit * edit, s + saved_macro[i++] = s; + if (!found) { + *n = 0; ++#ifndef UTF8 + while (*n < MAX_MACRO_LENGTH && 2 == fscanf (f, "%hd %hd, ", ¯o[*n].command, ¯o[*n].ch)) ++#else /* UTF8 */ ++ while (*n < MAX_MACRO_LENGTH && 2 == fscanf (f, "%hd %lu, ", ¯o[*n].command, ¯o[*n].ch)) ++#endif /* UTF8 */ + (*n)++; + } else { ++#ifndef UTF8 + while (2 == fscanf (f, "%hd %hd, ", &dummy.command, &dummy.ch)); ++#else /* UTF8 */ ++ while (2 == fscanf (f, "%hd %lu, ", &dummy.command, &dummy.ch)); ++#endif /* UTF8 */ + } + fscanf (f, ";\n"); + if (s == k) +@@ -944,7 +1026,7 @@ int eval_marks (WEdit * edit, long *star + #define space_width 1 + + static void +-edit_insert_column_of_text (WEdit * edit, unsigned char *data, int size, int width) ++edit_insert_column_of_text (WEdit * edit, mc_wchar_t *data, int size, int width) + { + long cursor; + int i, col; +@@ -992,7 +1074,7 @@ edit_block_copy_cmd (WEdit *edit) + { + long start_mark, end_mark, current = edit->curs1; + int size; +- unsigned char *copy_buf; ++ mc_wchar_t *copy_buf; + + edit_update_curs_col (edit); + if (eval_marks (edit, &start_mark, &end_mark)) +@@ -1032,7 +1114,7 @@ edit_block_move_cmd (WEdit *edit) + { + long count; + long current; +- unsigned char *copy_buf; ++ mc_wchar_t *copy_buf; + long start_mark, end_mark; + int deleted = 0; + int x = 0; +@@ -1093,7 +1175,7 @@ edit_block_move_cmd (WEdit *edit) + edit_push_action (edit, COLUMN_ON); + column_highlighting = 0; + } else { +- copy_buf = g_malloc (end_mark - start_mark); ++ copy_buf = g_malloc ((end_mark - start_mark) * sizeof(mc_wchar_t)); + edit_cursor_move (edit, start_mark - edit->curs1); + edit_scroll_screen_over_cursor (edit); + count = start_mark; +@@ -1432,7 +1514,11 @@ static long sargs[NUM_REPL_ARGS][256 / s + /* This function is a modification of mc-3.2.10/src/view.c:regexp_view_search() */ + /* returns -3 on error in pattern, -1 on not found, found_len = 0 if either */ + static int ++#ifndef UTF8 + string_regexp_search (char *pattern, char *string, int match_type, ++#else /* UTF8 */ ++string_regexp_search (char *pattern, mc_wchar_t *wstring, int match_type, ++#endif /* UTF8 */ + int match_bol, int icase, int *found_len, void *d) + { + static regex_t r; +@@ -1441,6 +1527,11 @@ string_regexp_search (char *pattern, cha + regmatch_t *pmatch; + static regmatch_t s[1]; + ++#ifdef UTF8 ++ char *string; ++ int i; ++#endif /* UTF8 */ ++ + pmatch = (regmatch_t *) d; + if (!pmatch) + pmatch = s; +@@ -1460,13 +1551,51 @@ string_regexp_search (char *pattern, cha + old_type = match_type; + old_icase = icase; + } ++ ++#ifdef UTF8 ++ string = wchar_to_mbstr(wstring); ++ if (string == NULL) ++ return -1; ++#endif /* UTF8 */ ++ + if (regexec + (&r, string, d ? NUM_REPL_ARGS : 1, pmatch, + ((match_bol + || match_type != match_normal) ? 0 : REG_NOTBOL)) != 0) { + *found_len = 0; ++ ++#ifdef UTF8 ++ g_free(string); ++#endif /* UTF8 */ ++ + return -1; + } ++ ++#ifdef UTF8 ++ for (i = 0; i < (d ? NUM_REPL_ARGS : 1); i++) { ++ char tmp; ++ int new_o; ++ ++ if (pmatch[i].rm_so < 0) ++ continue; ++ tmp = string[pmatch[i].rm_so]; ++ string[pmatch[i].rm_so] = 0; ++ new_o = mbstrlen(string); ++ string[pmatch[i].rm_so] = tmp; ++ pmatch[i].rm_so = new_o; ++ ++ if (pmatch[i].rm_eo < 0) ++ continue; ++ tmp = string[pmatch[i].rm_eo]; ++ string[pmatch[i].rm_eo] = 0; ++ new_o = mbstrlen(string); ++ string[pmatch[i].rm_eo] = tmp; ++ pmatch[i].rm_eo = new_o; ++ } ++ ++ g_free(string); ++#endif /* UTF8 */ ++ + *found_len = pmatch[0].rm_eo - pmatch[0].rm_so; + return (pmatch[0].rm_so); + } +@@ -1474,13 +1603,29 @@ string_regexp_search (char *pattern, cha + /* thanks to Liviu Daia for getting this + (and the above) routines to work properly - paul */ + ++#ifndef UTF8 + typedef int (*edit_getbyte_fn) (WEdit *, long); ++#else /* UTF8 */ ++typedef mc_wchar_t (*edit_getbyte_fn) (WEdit *, long); ++#endif /* UTF8 */ + + static long ++#ifndef UTF8 + edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit_getbyte_fn get_byte, void *data, int once_only, void *d) ++#else /* UTF8 */ ++edit_find_string (long start, unsigned char *exp_mb, int *len, long last_byte, edit_getbyte_fn get_byte, void *data, int once_only, void *d) ++#endif /* UTF8 */ + { + long p, q = 0; +- long l = strlen ((char *) exp), f = 0; ++ long f = 0; ++ ++#ifndef UTF8 ++ long l = strlen ((char *) exp); ++#else /* UTF8 */ ++ mc_wchar_t *exp = mbstr_to_wchar((char *)exp_mb); ++ mc_wchar_t *exp_backup = exp; ++ long l = wcslen(exp); ++#endif /* UTF8 */ + int n = 0; + + for (p = 0; p < l; p++) /* count conversions... */ +@@ -1489,19 +1634,22 @@ edit_find_string (long start, unsigned c + n++; + + if (replace_scanf || replace_regexp) { +- int c; +- unsigned char *buf; +- unsigned char mbuf[MAX_REPL_LEN * 2 + 3]; ++ mc_wint_t c; ++ mc_wchar_t *buf; ++ mc_wchar_t mbuf[MAX_REPL_LEN * 2 + 3]; + + replace_scanf = (!replace_regexp); /* can't have both */ + + buf = mbuf; + + if (replace_scanf) { +- unsigned char e[MAX_REPL_LEN]; +- if (n >= NUM_REPL_ARGS) +- return -3; +- ++ mc_wchar_t e[MAX_REPL_LEN]; ++ if (n >= NUM_REPL_ARGS) { ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ ++ return -3; ++ } + if (replace_case) { + for (p = start; p < last_byte && p < start + MAX_REPL_LEN; p++) + buf[p - start] = (*get_byte) (data, p); +@@ -1515,20 +1663,36 @@ edit_find_string (long start, unsigned c + } + + buf[(q = p - start)] = 0; ++#ifndef UTF8 + strcpy ((char *) e, (char *) exp); + strcat ((char *) e, "%n"); ++#else /* UTF8 */ ++ wcscpy (e, exp); ++ wcscat (e, L"%n"); ++#endif /* UTF8 */ + exp = e; + + while (q) { + *((int *) sargs[n]) = 0; /* --> here was the problem - now fixed: good */ ++#ifndef UTF8 + if (n == sscanf ((char *) buf, (char *) exp, SCANF_ARGS)) { ++#else /* UTF8 */ ++ if (n == swscanf (buf, exp, SCANF_ARGS)) { ++#endif /* UTF8 */ + if (*((int *) sargs[n])) { + *len = *((int *) sargs[n]); ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ + return start; + } + } +- if (once_only) ++ if (once_only) { ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ + return -2; ++ } + if (q + start < last_byte) { + if (replace_case) { + buf[q] = (*get_byte) (data, q + start); +@@ -1542,7 +1706,11 @@ edit_find_string (long start, unsigned c + start++; + buf++; /* move the window along */ + if (buf == mbuf + MAX_REPL_LEN) { /* the window is about to go past the end of array, so... */ ++#ifndef UTF8 + memmove (mbuf, buf, strlen ((char *) buf) + 1); /* reset it */ ++#else /* UTF8 */ ++ wmemmove (mbuf, buf, (wcslen (buf) + 1)); /* reset it */ ++#endif /* UTF8 */ + buf = mbuf; + } + q--; +@@ -1569,10 +1737,16 @@ edit_find_string (long start, unsigned c + + buf = mbuf; + while (q) { ++#ifndef UTF8 + found_start = string_regexp_search ((char *) exp, (char *) buf, match_normal, match_bol, !replace_case, len, d); +- ++#else /* UTF8 */ ++ found_start = string_regexp_search ((char *) exp_mb, buf, match_normal, match_bol, !replace_case, len, d); ++#endif /* UTF8 */ + if (found_start <= -2) { /* regcomp/regexec error */ + *len = 0; ++#ifdef UTF8 ++ g_free (exp_backup); ++#endif /* UTF8 */ + return -3; + } + else if (found_start == -1) /* not found: try next line */ +@@ -1583,15 +1757,27 @@ edit_find_string (long start, unsigned c + match_bol = 0; + continue; + } +- else /* found */ ++ else { /* found */ ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ + return (start + offset - q + found_start); ++ } + } +- if (once_only) ++ if (once_only) { ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ + return -2; ++ } + + if (buf[q - 1] != '\n') { /* incomplete line: try to recover */ + buf = mbuf + MAX_REPL_LEN / 2; ++#ifndef UTF8 + q = strlen ((const char *) buf); ++#else /* UTF8 */ ++ q = wcslen (buf); ++#endif /* UTF8 */ + memmove (mbuf, buf, q); + p = start + q; + move_win = 1; +@@ -1601,36 +1787,59 @@ edit_find_string (long start, unsigned c + } + } + } else { ++#ifndef UTF8 + *len = strlen ((const char *) exp); ++#else /* UTF8 */ ++ *len = wcslen (exp); ++#endif /* UTF8 */ + if (replace_case) { + for (p = start; p <= last_byte - l; p++) { +- if ((*get_byte) (data, p) == (unsigned char)exp[0]) { /* check if first char matches */ ++ if ((*get_byte) (data, p) == exp[0]) { /* check if first char matches */ + for (f = 0, q = 0; q < l && f < 1; q++) +- if ((*get_byte) (data, q + p) != (unsigned char)exp[q]) ++ if ((*get_byte) (data, q + p) != exp[q]) + f = 1; +- if (f == 0) ++ if (f == 0) { ++#ifdef UTF8 ++ g_free (exp_backup); ++#endif /* UTF8 */ + return p; ++ } + } +- if (once_only) ++ if (once_only) { ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ + return -2; ++ } + } + } else { + for (p = 0; exp[p] != 0; p++) + exp[p] = my_lower_case (exp[p]); + + for (p = start; p <= last_byte - l; p++) { +- if (my_lower_case ((*get_byte) (data, p)) == (unsigned char)exp[0]) { ++ if (my_lower_case ((*get_byte) (data, p)) == exp[0]) { + for (f = 0, q = 0; q < l && f < 1; q++) +- if (my_lower_case ((*get_byte) (data, q + p)) != (unsigned char)exp[q]) ++ if (my_lower_case ((*get_byte) (data, q + p)) != exp[q]) + f = 1; +- if (f == 0) ++ if (f == 0) { ++#ifdef UTF8 ++ g_free (exp_backup); ++#endif /* UTF8 */ + return p; ++ } + } +- if (once_only) ++ if (once_only) { ++#ifdef UTF8 ++ g_free (exp_backup); ++#endif /* UTF8 */ + return -2; ++ } + } + } + } ++#ifdef UTF8 ++ g_free (exp_backup); ++#endif /* UTF8 */ + return -2; + } + +@@ -1644,9 +1853,14 @@ edit_find_forwards (long search_start, u + + while ((p = edit_find_string (p, exp, len, last_byte, get_byte, data, once_only, d)) >= 0) { + if (replace_whole) { ++#ifndef UTF8 + /*If the bordering chars are not in option_whole_chars_search then word is whole */ + if (!strcasechr (option_whole_chars_search, (*get_byte) (data, p - 1)) + && !strcasechr (option_whole_chars_search, (*get_byte) (data, p + *len))) ++#else /* UTF8 */ ++ if (!iswalnum((*get_byte) (data, p - 1)) ++ && !iswalnum((*get_byte) (data, p + *len))) ++#endif /* UTF8 */ + return p; + if (once_only) + return -2; +@@ -1678,6 +1892,7 @@ edit_find (long search_start, unsigned c + + #define is_digit(x) ((x) >= '0' && (x) <= '9') + ++#ifndef UTF8 + #define snprint(v) { \ + *p1++ = *p++; \ + *p1 = '\0'; \ +@@ -1685,33 +1900,48 @@ edit_find (long search_start, unsigned c + if (n >= (size_t) (e - s)) goto nospc; \ + s += n; \ + } ++#else /* UTF8 */ ++#define snprint(v) { \ ++ *p1++ = *p++; \ ++ *p1 = '\0'; \ ++ n = swprintf(s, e-s, q1,v); \ ++ if (n >= (size_t) (e - s)) goto nospc; \ ++ s += n; \ ++ } ++#endif /* UTF8 */ + + /* this function uses the sprintf command to do a vprintf */ + /* it takes pointers to arguments instead of the arguments themselves */ + /* The return value is the number of bytes written excluding '\0' + if successfull, -1 if the resulting string would be too long and + -2 if the format string is errorneous. */ +-static int snprintf_p (char *str, size_t size, const char *fmt,...) +- __attribute__ ((format (printf, 3, 4))); +- +-static int snprintf_p (char *str, size_t size, const char *fmt,...) ++static int snprintf_p (mc_wchar_t *str, size_t size, const mc_wchar_t *fmt,...) + { + va_list ap; + size_t n; +- const char *q, *p; +- char *s = str, *e = str + size; +- char q1[40]; +- char *p1; ++ const mc_wchar_t *q, *p; ++ mc_wchar_t *s = str, *e = str + size; ++ mc_wchar_t q1[40]; ++ ++ mc_wchar_t *p1; + int nargs = 0; + + va_start (ap, fmt); + p = q = fmt; + ++#ifndef UTF8 + while ((p = strchr (p, '%'))) { ++#else /* UTF8 */ ++ while ((p = wcschr (p, L'%'))) { ++#endif /* UTF8 */ + n = p - q; + if (n >= (size_t) (e - s)) + goto nospc; ++#ifndef UTF8 + memcpy (s, q, n); /* copy stuff between format specifiers */ ++#else /* UTF8 */ ++ wmemcpy (s, q, n); /* copy stuff between format specifiers */ ++#endif /* UTF8 */ + s += n; + q = p; + p1 = q1; +@@ -1739,45 +1969,78 @@ static int snprintf_p (char *str, size_t + *p1++ = *p++; + if (*p == '*') { + p++; ++#ifndef UTF8 + strcpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace field width with a number */ + p1 += strlen (p1); ++#else /* UTF8 */ ++ wcscpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace field width with a number */ ++ p1 += wcslen (p1); ++#endif /* UTF8 */ + } else { +- while (is_digit (*p) && p1 < q1 + 20) ++#ifndef UTF8 ++ while (is_digit (*p) ++#else /* UTF8 */ ++ while (iswdigit (*p) ++#endif /* UTF8 */ ++ && p1 < q1 + 20) + *p1++ = *p++; +- if (is_digit (*p)) ++#ifndef UTF8 ++ if (is_digit (*p)) ++#else /* UTF8 */ ++ if (iswdigit (*p)) ++#endif /* UTF8 */ + goto err; + } + if (*p == '.') + *p1++ = *p++; + if (*p == '*') { + p++; ++#ifndef UTF8 + strcpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace precision with a number */ + p1 += strlen (p1); ++#else /* UTF8 */ ++ wcscpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace precision with a number */ ++ p1 += wcslen (p1); ++#endif /* UTF8 */ + } else { +- while (is_digit (*p) && p1 < q1 + 32) ++#ifndef UTF8 ++ while (is_digit (*p) ++#else /* UTF8 */ ++ while (iswdigit (*p) ++#endif /* UTF8 */ ++ && p1 < q1 + 32) + *p1++ = *p++; +- if (is_digit (*p)) ++#ifndef UTF8 ++ if (is_digit (*p)) ++#else /* UTF8 */ ++ if (iswdigit (*p)) ++#endif /* UTF8 */ + goto err; + } + /* flags done, now get argument */ + if (*p == 's') { ++#ifndef UTF8 + snprint (va_arg (ap, char *)); ++#else /* UTF8 */ ++ *p1++ = 'l'; ++ snprint (va_arg (ap, mc_wchar_t *)); ++#endif /* UTF8 */ + } else if (*p == 'h') { +- if (strchr ("diouxX", *p)) ++ if (*p < 128 && strchr ("diouxX", *p)) + snprint (*va_arg (ap, short *)); + } else if (*p == 'l') { + *p1++ = *p++; +- if (strchr ("diouxX", *p)) ++ if (*p < 128 && strchr ("diouxX", *p)) + snprint (*va_arg (ap, long *)); +- } else if (strchr ("cdiouxX", *p)) { ++ } else if (*p < 128 && strchr ("cdiouxX", *p)) { + snprint (*va_arg (ap, int *)); + } else if (*p == 'L') { + *p1++ = *p++; +- if (strchr ("EefgG", *p)) ++ if (*p < 128 && strchr ("EefgG", *p)) + snprint (*va_arg (ap, double *)); /* should be long double */ +- } else if (strchr ("EefgG", *p)) { ++ } else if (*p < 128 && strchr ("EefgG", *p)) { + snprint (*va_arg (ap, double *)); +- } else if (strchr ("DOU", *p)) { ++ } else if (*p < 128 && strchr ("DOU", *p)) { + snprint (*va_arg (ap, long *)); + } else if (*p == 'p') { + snprint (*va_arg (ap, void **)); +@@ -1786,10 +2049,17 @@ static int snprintf_p (char *str, size_t + q = p; + } + va_end (ap); ++#ifndef UTF8 + n = strlen (q); + if (n >= (size_t) (e - s)) + return -1; + memcpy (s, q, n + 1); ++#else /* UTF8 */ ++ n = wcslen (q); ++ if (n >= (size_t) (e - s)) ++ return -1; ++ wmemcpy (s, q, n + 1); ++#endif /* UTF8 */ + return s + n - str; + nospc: + va_end (ap); +@@ -1968,8 +2238,11 @@ edit_replace_cmd (WEdit *edit, int again + } + } + if (replace_yes) { /* delete then insert new */ ++#ifdef UTF8 ++ mc_wchar_t *winput2 = mbstr_to_wchar(input2); ++#endif /* UTF8 */ + if (replace_scanf) { +- char repl_str[MAX_REPL_LEN + 2]; ++ mc_wchar_t repl_str[MAX_REPL_LEN + 2]; + int ret = 0; + + /* we need to fill in sargs just like with scanf */ +@@ -1978,17 +2251,25 @@ edit_replace_cmd (WEdit *edit, int again + for (k = 1; + k < NUM_REPL_ARGS && pmatch[k].rm_eo >= 0; + k++) { ++#ifndef UTF8 + unsigned char *t; ++#else /* UTF8 */ ++ mc_wchar_t *t; ++#endif + + if (pmatch[k].rm_eo - pmatch[k].rm_so > 255) { + ret = -1; + break; + } ++#ifndef UTF8 + t = (unsigned char *) &sargs[k - 1][0]; ++#else /* UTF8 */ ++ t = (mc_wchar_t *) &sargs[k - 1][0]; ++#endif /* UTF8 */ + for (j = 0; + j < pmatch[k].rm_eo - pmatch[k].rm_so + && j < 255; j++, t++) +- *t = (unsigned char) edit_get_byte (edit, ++ *t = edit_get_byte (edit, + edit-> + search_start + - +@@ -2006,14 +2287,23 @@ edit_replace_cmd (WEdit *edit, int again + } + if (!ret) + ret = ++#ifndef UTF8 + snprintf_p (repl_str, MAX_REPL_LEN + 2, input2, ++#else /* UTF8 */ ++ snprintf_p (repl_str, MAX_REPL_LEN + 2, winput2, ++#endif /* UTF8 */ + PRINTF_ARGS); + if (ret >= 0) { + times_replaced++; + while (i--) + edit_delete (edit); ++#ifndef UTF8 + while (repl_str[++i]) + edit_insert (edit, repl_str[i]); ++#else /* UTF8 */ ++ while (winput2[++i]) ++ edit_insert (edit, winput2[i]); ++#endif /* UTF8 */ + } else { + edit_error_dialog (_(" Replace "), + ret == +@@ -2027,10 +2317,18 @@ edit_replace_cmd (WEdit *edit, int again + times_replaced++; + while (i--) + edit_delete (edit); ++#ifndef UTF8 + while (input2[++i]) + edit_insert (edit, input2[i]); ++#else /* UTF8 */ ++ while (winput2[++i]) ++ edit_insert (edit, winput2[i]); ++#endif /* UTF8 */ + } + edit->found_len = i; ++#ifdef UTF8 ++ g_free (winput2); ++#endif /* UTF8 */ + } + /* so that we don't find the same string again */ + if (replace_backwards) { +@@ -2203,16 +2501,17 @@ edit_ok_to_exit (WEdit *edit) + #define TEMP_BUF_LEN 1024 + + /* Return a null terminated length of text. Result must be g_free'd */ +-static unsigned char * ++static mc_wchar_t * + edit_get_block (WEdit *edit, long start, long finish, int *l) + { +- unsigned char *s, *r; +- r = s = g_malloc (finish - start + 1); ++ mc_wchar_t *s, *r; ++ r = s = g_malloc ((finish - start + 1) * sizeof(mc_wchar_t)); + if (column_highlighting) { + *l = 0; + /* copy from buffer, excluding chars that are out of the column 'margins' */ + while (start < finish) { +- int c, x; ++ mc_wchar_t c; ++ int x; + x = edit_move_forward3 (edit, edit_bol (edit, start), 0, + start); + c = edit_get_byte (edit, start); +@@ -2245,11 +2544,15 @@ edit_save_block (WEdit * edit, const cha + return 0; + + if (column_highlighting) { +- unsigned char *block, *p; ++ mc_wchar_t *block, *p; + int r; + p = block = edit_get_block (edit, start, finish, &len); + while (len) { ++#ifndef UTF8 + r = mc_write (file, p, len); ++#else /* UTF8 */ ++ r = wchar_write (file, p, len); ++#endif /* UTF8 */ + if (r < 0) + break; + p += r; +@@ -2257,15 +2560,19 @@ edit_save_block (WEdit * edit, const cha + } + g_free (block); + } else { +- unsigned char *buf; ++ mc_wchar_t *buf; + int i = start, end; + len = finish - start; +- buf = g_malloc (TEMP_BUF_LEN); ++ buf = g_malloc (TEMP_BUF_LEN * sizeof(mc_wchar_t)); + while (start != finish) { + end = min (finish, start + TEMP_BUF_LEN); + for (; i < end; i++) + buf[i - start] = edit_get_byte (edit, i); ++#ifndef UTF8 + len -= mc_write (file, (char *) buf, end - start); ++#else /* UTF8 */ ++ len -= wchar_write (file, buf, end - start); ++#endif /* UTF8 */ + start = end; + } + g_free (buf); +@@ -2603,17 +2910,20 @@ edit_block_process_cmd (WEdit *edit, con + + /* prints at the cursor */ + /* returns the number of chars printed */ ++#ifndef UTF8 + int edit_print_string (WEdit * e, const char *s) ++#else /* UTF8 */ ++int edit_print_wstring (WEdit * e, mc_wchar_t *s) ++#endif /* UTF8 */ + { + int i = 0; + while (s[i]) +- edit_execute_cmd (e, -1, (unsigned char) s[i++]); ++ edit_execute_cmd (e, -1, s[i++]); + e->force |= REDRAW_COMPLETELY; + edit_update_screen (e); + return i; + } + +- + static void pipe_mail (WEdit *edit, char *to, char *subject, char *cc) + { + FILE *p = 0; +@@ -2707,15 +3017,20 @@ void edit_mail_dialog (WEdit * edit) + /* find first character of current word */ + static int edit_find_word_start (WEdit *edit, long *word_start, int *word_len) + { +- int i, c, last; ++ int i; ++ mc_wint_t c, last; + + /* return if at begin of file */ + if (edit->curs1 <= 0) + return 0; + +- c = (unsigned char) edit_get_byte (edit, edit->curs1 - 1); ++ c = edit_get_byte (edit, edit->curs1 - 1); + /* return if not at end or in word */ ++#ifndef UTF8 + if (isspace (c) || !(isalnum (c) || c == '_')) ++#else /* UTF8 */ ++ if (iswspace (c) || !(iswalnum (c) || c == '_')) ++#endif /* UTF8 */ + return 0; + + /* search start of word to be completed */ +@@ -2725,11 +3040,19 @@ static int edit_find_word_start (WEdit * return 0; + + last = c; +- c = (unsigned char) edit_get_byte (edit, edit->curs1 - i); ++ c = edit_get_byte (edit, edit->curs1 - i); + ++#ifndef UTF8 + if (!(isalnum (c) || c == '_')) { ++#else /* UTF8 */ ++ if (!(iswalnum (c) || c == '_')) { ++#endif /* UTF8 */ + /* return if word starts with digit */ ++#ifndef UTF8 + if (isdigit (last)) ++#else /* UTF8 */ ++ if (iswdigit (last)) ++#endif /* UTF8 */ + return 0; + + *word_start = edit->curs1 - (i - 1); /* start found */ +@@ -2762,7 +3085,7 @@ edit_collect_completions (WEdit *edit, l + int *num) + { + int len, max_len = 0, i, skip; +- unsigned char *bufpos; ++ mc_wchar_t *bufpos; + + /* collect max MAX_WORD_COMPLETIONS completions */ + while (*num < MAX_WORD_COMPLETIONS) { +@@ -2781,11 +3104,16 @@ edit_collect_completions (WEdit *edit, l + buffers1[start >> S_EDIT_BUF_SIZE][start & M_EDIT_BUF_SIZE]; + skip = 0; + for (i = 0; i < *num; i++) { ++#ifndef UTF8 + if (strncmp + ((char *) &compl[i].text[word_len], +- (char *) &bufpos[word_len], max (len, +- compl[i].len) - +- word_len) == 0) { ++ (char *) &bufpos[word_len], ++#else /* UTF8 */ ++ if (wcsncmp ++ ((wchar_t *) &compl[i].text[word_len], ++ (wchar_t *) &bufpos[word_len], ++#endif /* UTF8 */ ++ max (len, compl[i].len) - word_len) == 0) { + skip = 1; + break; /* skip it, already added */ + } +@@ -2793,7 +3121,7 @@ edit_collect_completions (WEdit *edit, l + if (skip) + continue; + +- compl[*num].text = g_malloc (len + 1); ++ compl[*num].text = g_malloc ((len + 1) * sizeof(mc_wchar_t)); + compl[*num].len = len; + for (i = 0; i < len; i++) + compl[*num].text[i] = *(bufpos + i); +@@ -2807,6 +3135,18 @@ edit_collect_completions (WEdit *edit, l + return max_len; + } + ++#ifdef UTF8 ++int edit_print_string (WEdit * e, const char *s) ++{ ++ int i; ++ mc_wchar_t *ws = mbstr_to_wchar(s); ++ i = edit_print_wstring (e, ws); ++ g_free(ws); ++ return i; ++} ++ ++#endif /* UTF8 */ ++ + + /* let the user select its preferred completion */ + static void +@@ -2819,6 +3159,9 @@ edit_completion_dialog (WEdit * edit, in + WListbox *compl_list; + int compl_dlg_h; /* completion dialog height */ + int compl_dlg_w; /* completion dialog width */ ++#ifdef UTF8 ++ char *mbtext; ++#endif /* UTF8 */ + + /* calculate the dialog metrics */ + compl_dlg_h = num_compl + 2; +@@ -2854,9 +3197,18 @@ edit_completion_dialog (WEdit * edit, in + add_widget (compl_dlg, compl_list); + + /* fill the listbox with the completions */ ++#ifndef UTF8 + for (i = 0; i < num_compl; i++) + listbox_add_item (compl_list, LISTBOX_APPEND_AT_END, 0, + (char *) compl[i].text, NULL); ++#else /* UTF8 */ ++ for (i = 0; i < num_compl; i++) { ++ mbtext = wchar_to_mbstr(compl[i].text); ++ listbox_add_item (compl_list, LISTBOX_APPEND_AT_END, 0, ++ mbtext, NULL); ++ g_free(mbtext); ++ } ++#endif /* UTF8 */ + + /* pop up the dialog */ + run_dlg (compl_dlg); +@@ -2864,9 +3216,17 @@ edit_completion_dialog (WEdit * edit, in + /* apply the choosen completion */ + if (compl_dlg->ret_value == B_ENTER) { + listbox_get_current (compl_list, &curr, NULL); +- if (curr) ++ if (curr){ ++#ifndef UTF8 + for (curr += word_len; *curr; curr++) + edit_insert (edit, *curr); ++#else /* UTF8 */ ++ mc_wchar_t *wc, *wccurr = mbstr_to_wchar(curr); ++ for (wc = wccurr + word_len; *wc; wc++) ++ edit_insert (edit, *wc); ++ g_free(wccurr); ++#endif /* UTF8 */ ++ } } - return 1; -@@ -1781,6 +1785,7 @@ - return 2; - return 0x80000000UL; + + /* destroy dialog before return */ +@@ -2883,8 +3243,9 @@ edit_complete_word_cmd (WEdit *edit) + { + int word_len = 0, i, num_compl = 0, max_len; + long word_start = 0; +- unsigned char *bufpos; +- char *match_expr; ++ mc_wchar_t *bufpos; ++ mc_wchar_t *match_expr; ++ char *mbmatch_expr; + struct selection compl[MAX_WORD_COMPLETIONS]; /* completions */ + + /* don't want to disturb another search */ +@@ -2901,16 +3262,32 @@ edit_complete_word_cmd (WEdit *edit) + /* prepare match expression */ + bufpos = &edit->buffers1[word_start >> S_EDIT_BUF_SIZE] + [word_start & M_EDIT_BUF_SIZE]; ++ ++ match_expr = g_malloc((word_len + 14) * sizeof(mc_wchar_t)); ++#ifndef UTF8 + match_expr = g_strdup_printf ("%.*s[a-zA-Z_0-9]+", word_len, bufpos); ++#else /* UTF8 */ ++ wcsncpy (match_expr, bufpos, word_len); ++ match_expr[word_len] = '\0'; ++ wcscat (match_expr, L"[a-zA-Z_0-9]+"); ++#endif /* UTF8 */ + + /* init search: backward, regexp, whole word, case sensitive */ + edit_set_search_parameters (0, 1, 1, 1, 1); + + /* collect the possible completions */ + /* start search from curs1 down to begin of file */ ++#ifndef UTF8 + max_len = + edit_collect_completions (edit, word_start, word_len, match_expr, + (struct selection *) &compl, &num_compl); ++#else /* UTF8 */ ++ mbmatch_expr = wchar_to_mbstr(match_expr); ++ max_len = ++ edit_collect_completions (edit, word_start, word_len, mbmatch_expr, ++ (struct selection *) &compl, &num_compl); ++ g_free(mbmatch_expr); ++#endif /* UTF8 */ + + if (num_compl > 0) { + /* insert completed word if there is only one match */ +diff -up mc-4.6.2-pre1/edit/editdraw.c.utf8 mc-4.6.2-pre1/edit/editdraw.c +--- mc-4.6.2-pre1/edit/editdraw.c.utf8 2007-08-27 14:06:03.000000000 +0200 ++++ mc-4.6.2-pre1/edit/editdraw.c 2008-02-25 15:35:11.000000000 +0100 +@@ -70,11 +70,16 @@ static void status_string (WEdit * edit, + * as decimal and as hex. + */ + if (edit->curs1 < edit->last_byte) { +- unsigned char cur_byte = edit_get_byte (edit, edit->curs1); ++ mc_wchar_t cur_byte = edit_get_byte (edit, edit->curs1); ++#ifndef UTF8 + g_snprintf (byte_str, sizeof (byte_str), "%c %3d 0x%02X", + is_printable (cur_byte) ? cur_byte : '.', +- (int) cur_byte, +- (unsigned) cur_byte); ++#else /* UTF8 */ ++ g_snprintf (byte_str, sizeof(byte_str), "%lc %3d 0x%02X", ++ iswprint(cur_byte) ? cur_byte : '.', ++#endif /* UTF8 */ ++ (int) cur_byte, ++ (unsigned) cur_byte); + } else { + strcpy (byte_str, ""); } -+#ifndef UTF8 - if (isupper (c)) - c = 'A'; - else if (islower (c)) -@@ -1791,6 +1796,18 @@ - c = '0'; - else if (isspace (c)) - c = ' '; +@@ -206,11 +211,16 @@ void edit_scroll_screen_over_cursor (WEd + #define lowlevel_set_color(x) attrset(MY_COLOR_PAIR(color)) + #endif + ++struct line_s { ++ mc_wchar_t ch; ++ unsigned int style; ++}; ++ + static void + print_to_widget (WEdit *edit, long row, int start_col, int start_col_real, +- long end_col, unsigned int line[]) ++ long end_col, struct line_s line[]) + { +- unsigned int *p; ++ struct line_s *p; + + int x = start_col_real + EDIT_TEXT_HORIZONTAL_OFFSET; + int x1 = start_col + EDIT_TEXT_HORIZONTAL_OFFSET; +@@ -224,9 +234,9 @@ print_to_widget (WEdit *edit, long row, + edit_move (x1 + FONT_OFFSET_X, y + FONT_OFFSET_Y); + p = line; + +- while (*p) { ++ while (p->ch) { + int style; +- int textchar; ++ mc_wchar_t textchar; + int color; + + if (cols_to_skip) { +@@ -235,9 +245,9 @@ print_to_widget (WEdit *edit, long row, + continue; + } + +- style = *p & 0xFF00; +- textchar = *p & 0xFF; +- color = *p >> 16; ++ style = p->style & 0xFF00; ++ textchar = p->ch; ++ color = p->style >> 16; + + if (style & MOD_ABNORMAL) { + /* Non-printable - use black background */ +@@ -266,8 +276,11 @@ print_to_widget (WEdit *edit, long row, + lowlevel_set_color (color); + } + } +- ++#ifdef UTF8 ++ SLsmg_write_nwchars(&textchar, 1); +#else -+ if (iswupper (c)) -+ c = 'A'; -+ else if (iswlower (c)) -+ c = 'a'; -+ else if (iswalpha (c)) -+ c = 'a'; -+ else if (iswdigit (c)) -+ c = '0'; -+ else if (iswspace (c)) -+ c = ' '; -+#endif /* UTF8 */ - q = strchr (option_chars_move_whole_word, c); - if (!q) - return 0xFFFFFFFFUL; -@@ -1815,10 +1832,18 @@ - c2 = edit_get_byte (edit, edit->curs1); - if (!(my_type_of (c1) & my_type_of (c2))) - break; -+#ifndef UTF8 - if (isspace (c1) && !isspace (c2)) -+#else -+ if (iswspace (c1) && !iswspace (c2)) -+#endif /* UTF8 */ - break; - if (s) -+#ifndef UTF8 - if (!isspace (c1) && isspace (c2)) -+#else -+ if (!iswspace (c1) && iswspace (c2)) -+#endif /* UTF8 */ - break; + addch (textchar); ++#endif + p++; } } -@@ -1841,10 +1866,18 @@ - c2 = edit_get_byte (edit, edit->curs1); - if (!(my_type_of (c1) & my_type_of (c2))) - break; +@@ -279,11 +292,11 @@ static void + edit_draw_this_line (WEdit *edit, long b, long row, long start_col, + long end_col) + { +- static unsigned int line[MAX_LINE_LEN]; +- unsigned int *p = line; ++ struct line_s line[MAX_LINE_LEN]; ++ struct line_s *p = line; + long m1 = 0, m2 = 0, q, c1, c2, tws; + int col, start_col_real; +- unsigned int c; ++ mc_wint_t c; + int color; + int i; + +@@ -307,62 +320,88 @@ edit_draw_this_line (WEdit *edit, long b + } + + while (col <= end_col - edit->start_col) { +- *p = 0; ++ p->ch = 0; ++ p->style = 0; + if (q == edit->curs1) +- *p |= MOD_CURSOR; ++ p->style |= MOD_CURSOR; + if (q >= m1 && q < m2) { + if (column_highlighting) { + int x; + x = edit_move_forward3 (edit, b, 0, q); + if (x >= c1 && x < c2) +- *p |= MOD_MARKED; ++ p->style |= MOD_MARKED; + } else +- *p |= MOD_MARKED; ++ p->style |= MOD_MARKED; + } + if (q == edit->bracket) +- *p |= MOD_BOLD; ++ p->style |= MOD_BOLD; + if (q >= edit->found_start + && q < edit->found_start + edit->found_len) +- *p |= MOD_BOLD; ++ p->style |= MOD_BOLD; + c = edit_get_byte (edit, q); + /* we don't use bg for mc - fg contains both */ + edit_get_syntax_color (edit, q, &color); +- *p |= color << 16; ++ p->style |= color << 16; + switch (c) { + case '\n': + col = end_col - edit->start_col + 1; /* quit */ +- *(p++) |= ' '; ++ p->ch = ' '; ++ p++; + break; + case '\t': + i = TAB_SIZE - ((int) col % TAB_SIZE); + col += i; + if (use_colors && visible_tabs) { +- c = (*p & ~MOD_CURSOR) | MOD_WHITESPACE; ++// c = (p->style & ~MOD_CURSOR) | MOD_WHITESPACE; ++ c = 0; + if (i > 2) { +- *(p++) |= '<' | MOD_WHITESPACE; +- while (--i > 1) +- *(p++) = c | '-'; +- *(p++) = c | '>'; ++ p->ch |= '<'; ++ p->style = MOD_WHITESPACE; ++ p++; ++ while (--i > 1) { ++ p->ch = c | '-'; ++ p->style = MOD_WHITESPACE; ++ p++; ++ } ++ p->ch = c | '>'; ++ p->style = MOD_WHITESPACE; ++ p++; + } else if (i > 1) { +- *(p++) |= '<' | MOD_WHITESPACE; +- *(p++) = c | '>'; +- } else +- *(p++) |= '>' | MOD_WHITESPACE; ++ p->ch |= '<'; ++ p->style = MOD_WHITESPACE; ++ p++; ++ p->ch = c | '>'; ++ p->style = MOD_WHITESPACE; ++ p++; ++ } else { ++ p->ch |= '>'; ++ p->style = MOD_WHITESPACE; ++ p++; ++ } + } else if (use_colors && visible_tws && q >= tws) { +- *p |= '.' | MOD_WHITESPACE; +- c = *(p++) & ~MOD_CURSOR; +- while (--i) +- *(p++) = c; ++ p->ch |= '.'; ++ p->style = MOD_WHITESPACE; ++ c = p->style & ~MOD_CURSOR; ++ p++; ++ while (--i) { ++ p->ch = c; ++ p++; ++ } + } else { +- *p |= ' '; +- c = *(p++) & ~MOD_CURSOR; +- while (--i) +- *(p++) = c; ++ p->ch |= ' '; ++ c = p->style & ~MOD_CURSOR; ++ p++; ++ while (--i) { ++ p->ch = c; ++ p++; ++ } + } + break; + case ' ': + if (use_colors && visible_tws && q >= tws) { +- *(p++) |= '.' | MOD_WHITESPACE; ++ p->ch |= '.'; ++ p->style = MOD_WHITESPACE; ++ p++; + col++; + break; + } +@@ -372,22 +411,47 @@ edit_draw_this_line (WEdit *edit, long b + + /* Caret notation for control characters */ + if (c < 32) { +- *(p++) = '^' | MOD_ABNORMAL; +- *(p++) = (c + 0x40) | MOD_ABNORMAL; ++ p->ch = '^'; ++ p->style = MOD_ABNORMAL; ++ p++; ++ p->ch = c + 0x40; ++ p->style = MOD_ABNORMAL; ++ p++; + col += 2; + break; + } + if (c == 127) { +- *(p++) = '^' | MOD_ABNORMAL; +- *(p++) = '?' | MOD_ABNORMAL; ++ p->ch = '^'; ++ p->style = MOD_ABNORMAL; ++ p++; ++ p->ch = '?'; ++ p->style = MOD_ABNORMAL; ++ p++; + col += 2; + break; + } + +- if (is_printable (c)) { +- *(p++) |= c; +#ifndef UTF8 - if (isspace (c1) && !isspace (c2)) -+#else -+ if (iswspace (c1) && !iswspace (c2)) ++ if (is_printable (c) ++#else /* UTF8 */ ++ if (iswprint (c) ++#ifdef __STDC_ISO_10646__ ++ && (c < BINARY_CHAR_OFFSET || c >= (BINARY_CHAR_OFFSET + 256)) ++#endif +#endif /* UTF8 */ - break; - if (s) -+#ifndef UTF8 - if (!isspace (c1) && isspace (c2)) -+#else -+ if (!iswspace (c1) && iswspace (c2)) ++ ) { ++ p->ch = c; ++ p++; ++#ifdef UTF8 ++ i = wcwidth(c); ++ if (i > 1) { ++ col += i - 1; ++ } +#endif /* UTF8 */ - break; + } else { +- *(p++) = '.' | MOD_ABNORMAL; ++ p->ch = '.'; ++ p->style = MOD_ABNORMAL; ++ p++; + } + col++; + break; +@@ -398,7 +462,7 @@ edit_draw_this_line (WEdit *edit, long b + } else { + start_col_real = start_col = 0; } +- *p = 0; ++ p->ch = 0; + + print_to_widget (edit, row, start_col, start_col_real, end_col, line); } -@@ -1864,7 +1897,11 @@ - break; - c1 = edit_delete (edit); - c2 = edit_get_byte (edit, edit->curs1); +diff -up mc-4.6.2-pre1/edit/editwidget.c.utf8 mc-4.6.2-pre1/edit/editwidget.c +--- mc-4.6.2-pre1/edit/editwidget.c.utf8 2006-12-10 23:07:28.000000000 +0100 ++++ mc-4.6.2-pre1/edit/editwidget.c 2008-02-25 14:56:22.000000000 +0100 +@@ -331,7 +331,8 @@ edit_callback (Widget *w, widget_msg_t m + + case WIDGET_KEY: + { +- int cmd, ch; ++ int cmd; ++ mc_wint_t ch; + + /* The user may override the access-keys for the menu bar. */ + if (edit_translate_key (e, parm, &cmd, &ch)) { +diff -up mc-4.6.2-pre1/edit/edit-widget.h.utf8 mc-4.6.2-pre1/edit/edit-widget.h +--- mc-4.6.2-pre1/edit/edit-widget.h.utf8 2007-02-03 02:03:53.000000000 +0100 ++++ mc-4.6.2-pre1/edit/edit-widget.h 2008-02-25 14:56:22.000000000 +0100 +@@ -30,6 +30,11 @@ typedef struct edit_key_map_type { + long command; + } edit_key_map_type; + ++struct action { ++ mc_wchar_t ch; ++ long flags; ++}; ++ + struct WEdit { + Widget widget; + +@@ -42,8 +47,17 @@ struct WEdit { + /* dynamic buffers and cursor position for editor: */ + long curs1; /* position of the cursor from the beginning of the file. */ + long curs2; /* position from the end of the file */ +#ifndef UTF8 - if ((isspace (c1) == 0) != (isspace (c2) == 0)) -+#else -+ if ((iswspace (c1) == 0) != (iswspace (c2) == 0)) + unsigned char *buffers1[MAXBUFF + 1]; /* all data up to curs1 */ + unsigned char *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */ ++#else /* UTF8 */ ++ mc_wchar_t *buffers1[MAXBUFF + 1]; /* all data up to curs1 */ ++ mc_wchar_t *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */ ++ ++ unsigned char charbuf[MB_LEN_MAX]; ++ int charpoint; +#endif /* UTF8 */ - break; - if (!(my_type_of (c1) & my_type_of (c2))) - break; -@@ -1879,7 +1916,11 @@ - break; - c1 = edit_backspace (edit); - c2 = edit_get_byte (edit, edit->curs1 - 1); ++ + + /* search variables */ + long search_start; /* First character to start searching from */ +@@ -87,7 +101,7 @@ struct WEdit { + + /* undo stack and pointers */ + unsigned long stack_pointer; +- long *undo_stack; ++ struct action *undo_stack; + unsigned long stack_size; + unsigned long stack_size_mask; + unsigned long stack_bottom; +diff -up mc-4.6.2-pre1/edit/edit.h.utf8 mc-4.6.2-pre1/edit/edit.h +--- mc-4.6.2-pre1/edit/edit.h.utf8 2006-12-10 23:07:28.000000000 +0100 ++++ mc-4.6.2-pre1/edit/edit.h 2008-02-25 14:56:22.000000000 +0100 +@@ -25,6 +25,27 @@ + + #include + ++#include "src/tty.h" ++ ++#ifdef UTF8 ++#include ++#include ++ ++#define mc_wchar_t wchar_t ++#define mc_wint_t wint_t ++ ++#else ++ ++#define mc_wchar_t unsigned char ++#define mc_wint_t int ++ ++#endif ++ ++ ++/* unicode private use area */ ++#define BINARY_CHAR_OFFSET 0xFFE00 ++ ++ + #define N_menus 5 + + #define SEARCH_DIALOG_OPTION_NO_SCANF (1 << 0) +@@ -86,6 +107,8 @@ + #define START_STACK_SIZE 32 + + /* Some codes that may be pushed onto or returned from the undo stack */ ++#define CHAR_INSERT 65 ++#define CHAR_INSERT_AHEAD 66 + #define CURS_LEFT 601 + #define CURS_RIGHT 602 + #define DELCHAR 603 +@@ -105,7 +128,7 @@ + + struct macro { + short command; +- short ch; ++ mc_wchar_t ch; + }; + + struct WEdit; +@@ -120,8 +143,12 @@ void edit_reload_menu (void); + void menu_save_mode_cmd (void); + int edit_raw_key_query (const char *heading, const char *query, int cancel); + int edit_file (const char *_file, int line); +-int edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch); ++int edit_translate_key (WEdit *edit, long x_key, int *cmd, mc_wint_t *ch); +#ifndef UTF8 - if ((isspace (c1) == 0) != (isspace (c2) == 0)) -+#else -+ if ((iswspace (c1) == 0) != (iswspace (c2) == 0)) + int edit_get_byte (WEdit * edit, long byte_index); ++#else /* UTF8 */ ++mc_wchar_t edit_get_byte (WEdit * edit, long byte_index); +#endif /* UTF8 */ - break; - if (!(my_type_of (c1) & my_type_of (c2))) - break; + int edit_count_lines (WEdit * edit, long current, int upto); + long edit_move_forward (WEdit * edit, long current, int lines, long upto); + long edit_move_forward3 (WEdit * edit, long current, int cols, long upto); +@@ -148,11 +175,11 @@ int edit_block_delete_cmd (WEdit * edit) + void edit_delete_line (WEdit * edit); + + int edit_delete (WEdit * edit); +-void edit_insert (WEdit * edit, int c); ++void edit_insert (WEdit * edit, mc_wchar_t c); + int edit_cursor_move (WEdit * edit, long increment); + void edit_push_action (WEdit * edit, long c, ...); + void edit_push_key_press (WEdit * edit); +-void edit_insert_ahead (WEdit * edit, int c); ++void edit_insert_ahead (WEdit * edit, mc_wchar_t c); + long edit_write_stream (WEdit * edit, FILE * f); + char *edit_get_write_filter (const char *writename, const char *filename); + int edit_save_confirm_cmd (WEdit * edit); +@@ -183,7 +210,7 @@ void edit_goto_cmd (WEdit * edit); + int eval_marks (WEdit * edit, long *start_mark, long *end_mark); + void edit_status (WEdit * edit); + void edit_execute_key_command (WEdit *edit, int command, +- int char_for_insertion); ++ mc_wint_t char_for_insertion); + void edit_update_screen (WEdit * edit); + int edit_print_string (WEdit * e, const char *s); + void edit_move_to_line (WEdit * e, long line); +@@ -233,7 +260,7 @@ void edit_mail_dialog (WEdit *edit); + void format_paragraph (WEdit *edit, int force); + + /* either command or char_for_insertion must be passed as -1 */ +-void edit_execute_cmd (WEdit *edit, int command, int char_for_insertion); ++void edit_execute_cmd (WEdit *edit, int command, mc_wint_t char_for_insertion); + + #define get_sys_error(s) (s) + +diff -up mc-4.6.2-pre1/edit/editkeys.c.utf8 mc-4.6.2-pre1/edit/editkeys.c +--- mc-4.6.2-pre1/edit/editkeys.c.utf8 2006-02-01 18:07:11.000000000 +0100 ++++ mc-4.6.2-pre1/edit/editkeys.c 2008-02-25 14:56:22.000000000 +0100 +@@ -182,10 +182,10 @@ static const edit_key_map_type common_ke + * 'command' is one of the editor commands from editcmddef.h. + */ + int +-edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch) ++edit_translate_key (WEdit *edit, long x_key, int *cmd, mc_wint_t *ch) + { + int command = CK_Insert_Char; +- int char_for_insertion = -1; ++ mc_wint_t char_for_insertion = -1; + int i = 0; + int extmod = 0; + const edit_key_map_type *key_map = NULL; +@@ -242,9 +242,30 @@ edit_translate_key (WEdit *edit, long x_ + /* an ordinary insertable character */ + if (x_key < 256 && !extmod) { + int c = convert_from_input_c (x_key); +- ++#ifdef UTF8 ++ mbstate_t mbs; ++ int res; ++ mc_wchar_t wc; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ ++ if (edit->charpoint >= MB_CUR_MAX) edit->charpoint = 0; ++ ++ edit->charbuf[edit->charpoint++] = c; ++ ++ res = mbrtowc(&wc, (char *)edit->charbuf, edit->charpoint, &mbs); ++ if (res < 0) { ++ if (res != -2) edit->charpoint = 0; /* broken multibyte char, skip */ ++ return 0; ++ } ++ edit->charpoint = 0; ++ ++ if (iswprint (wc)) { ++ char_for_insertion = wc; ++#else + if (is_printable (c)) { + char_for_insertion = c; ++#endif /* UTF8 */ + goto fin; + } + } +@@ -283,7 +304,7 @@ edit_translate_key (WEdit *edit, long x_ + *cmd = command; + *ch = char_for_insertion; + +- if (command == CK_Insert_Char && char_for_insertion == -1) { ++ if (command == CK_Insert_Char && char_for_insertion == (mc_wint_t)-1) { + /* unchanged, key has no function here */ + return 0; + } +diff -up mc-4.6.2-pre1/acinclude.m4.utf8 mc-4.6.2-pre1/acinclude.m4 +--- mc-4.6.2-pre1/acinclude.m4.utf8 2006-09-07 17:59:51.000000000 +0200 ++++ mc-4.6.2-pre1/acinclude.m4 2008-02-25 14:56:22.000000000 +0100 +@@ -399,14 +399,14 @@ AC_DEFUN([MC_WITH_SLANG], [ + fi + + dnl Unless external S-Lang was requested, reject S-Lang with UTF-8 hacks +- if test x$with_screen = xslang; then +- : +- m4_if([$1], strict, , +- [AC_CHECK_LIB([slang], [SLsmg_write_nwchars], +- [AC_MSG_WARN([Rejecting S-Lang with UTF-8 support, \ +-it's not fully supported yet]) +- with_screen=mcslang])]) +- fi ++dnl if test x$with_screen = xslang; then ++dnl : ++dnl m4_if([$1], strict, , ++dnl [AC_CHECK_LIB([slang], [SLsmg_write_nwchars], ++dnl [AC_MSG_WARN([Rejecting S-Lang with UTF-8 support, \ ++dnl it's not fully supported yet]) ++dnl with_screen=mcslang])]) ++dnl fi + + if test x$with_screen = xslang; then + AC_DEFINE(HAVE_SYSTEM_SLANG, 1, diff --git a/mc.spec b/mc.spec index 1223273..887673d 100644 --- a/mc.spec +++ b/mc.spec @@ -1,13 +1,11 @@ -%define date 2007-06-04-22 - Summary: User-friendly text console file manager and visual shell Name: mc -Version: 4.6.1a -Release: 52.20070604cvs%{?dist} +Version: 4.6.2 +Release: 1.pre1%{?dist} Epoch: 1 License: GPLv2 Group: System Environment/Shells -Source0: http://www.ibiblio.org/pub/Linux/utils/file/managers/mc/snapshots/mc-%{date}.tar.gz +Source0: http://www.ibiblio.org/pub/Linux/utils/file/managers/mc/snapshots/mc-%{version}-pre1.tar.gz URL: http://www.ibiblio.org/mc/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: glib2-devel e2fsprogs-devel slang-devel @@ -40,8 +38,7 @@ ability to FTP, view tar and zip files, and to poke into RPMs for specific files. %prep -%setup -q -n %{name}-%{date} - +%setup -q -n %{name}-%{version}-pre1 %patch0 -p1 -b .utf8 %patch1 -p1 -b .extensions %patch2 -p1 -b .userhost @@ -198,6 +195,11 @@ rm -rf $RPM_BUILD_ROOT %dir %{_libexecdir}/mc %changelog +* Mon Feb 25 2008 Jindrich Novy 4.6.2-1.pre1 +- update to 4.6.2-pre1 +- forwardport the UTF-8 patch to 4.6.2-pre1 and convert new + functionality to support UTF-8 + * Tue Feb 19 2008 Fedora Release Engineering - 1:4.6.1a-52.20070604cvs - Autorebuild for GCC 4.3 diff --git a/sources b/sources index 26d6b4f..459d63a 100644 --- a/sources +++ b/sources @@ -1 +1,2 @@ f5b70d9409ac7885c50cdf388b15721e mc-2007-06-04-22.tar.gz +7626c446f016b09fd1210f00b9d0c292 mc-4.6.2-pre1.tar.gz