--- mc-4.6.1/src/file.c +++ mc-4.6.1/src/file.c @@ -165,15 +165,20 @@ do_transform_source (FileOpContext *ctx, const unsigned char *source) { size_t j, k, l, len; - unsigned const char *fnsource = x_basename (source); + unsigned char *fnsource = g_strdup(x_basename (source)); int next_reg; enum CaseConvs case_conv = NO_CONV; static unsigned 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++) { @@ -217,6 +222,7 @@ || 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]; @@ -231,6 +237,7 @@ } } fntarget[k] = 0; + g_free(fnsource); return fntarget; } @@ -2107,8 +2114,8 @@ static int files_error (const char *format, const char *file1, const char *file2) { - char nfile1[16]; - char nfile2[16]; + char nfile1[16 * MB_LEN_MAX]; + char nfile2[16 * MB_LEN_MAX]; strcpy (nfile1, path_trunc (file1, 15)); strcpy (nfile2, path_trunc (file2, 15)); --- mc-4.6.1/src/filegui.c +++ mc-4.6.1/src/filegui.c @@ -69,6 +69,7 @@ #include "filegui.h" #include "key.h" /* get_event */ #include "util.h" /* strip_password() */ +#include "tty.h" /* }}} */ @@ -856,7 +857,7 @@ char * file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text, - const char *def_text, int only_one, int *do_background) + const char *def_text_orig, int only_one, int *do_background) { int source_easy_patterns = easy_patterns; char *source_mask, *orig_mask, *dest_dir, *tmpdest; @@ -865,12 +866,20 @@ struct stat buf; int val; QuickDialog Quick_input; - + char *def_text; g_return_val_if_fail (ctx != NULL, NULL); + + def_text = g_strdup(def_text_orig); + #if 0 message (1, __FUNCTION__, "text = `%s' \n def_text = `%s'", text, def_text); #endif + +#ifdef UTF8 + fix_utf8(def_text); +#endif + fmd_init_i18n (FALSE); /* Set up the result pointers */ @@ -929,6 +938,7 @@ orig_mask = source_mask; if (!dest_dir || !*dest_dir) { g_free (source_mask); + g_free(def_text); return dest_dir; } if (source_easy_patterns) { @@ -982,5 +992,6 @@ } if (val == B_USER) *do_background = 1; + g_free(def_text); return dest_dir; } --- mc-4.6.1/src/main.c +++ mc-4.6.1/src/main.c @@ -699,7 +699,7 @@ int prompt_len; prompt = strip_ctrl_codes (subshell_prompt); - prompt_len = strlen (prompt); + prompt_len = mbstrlen (prompt); /* Check for prompts too big */ if (COLS > 8 && prompt_len > COLS - 8) { @@ -1609,7 +1609,7 @@ if (xterm_flag && xterm_title) { p = s = g_strdup (strip_home_and_password (current_panel->cwd)); do { - if (!is_printable (*s)) + if (*s < ' ') *s = '?'; } while (*++s); fprintf (stdout, "\33]0;mc - %s\7", p); --- mc-4.6.1/src/menu.c +++ mc-4.6.1/src/menu.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "global.h" #include "tty.h" #include "menu.h" --- mc-4.6.1/src/screen.c +++ mc-4.6.1/src/screen.c @@ -526,6 +526,7 @@ #else char buffer[BUF_MEDIUM]; #endif + int txtwidth; length = 0; empty_line = (file_index >= panel->count); @@ -578,13 +579,18 @@ if (txtlen < 0) { txt = " "; txtlen = 1; - } else + } else { wide = 1; + txtwidth = wcswidth((wchar_t*)buffer, txtlen); + } } else #endif + { txtlen = strlen (txt); + txtwidth = txtlen; + } - over = txtlen > len; + over = txtwidth > len; still = over ? txtlen - len : len - txtlen; switch (HIDE_FIT(format->just_mode)) { @@ -605,19 +611,46 @@ #ifdef UTF8 if (over) { if (IS_FIT (format->just_mode)) { - int len2 = len / 2 - 1 + (len % 2); + 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, - len / 2); + 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 - len2, len2); + + 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 - txtlen - still, ""); + printw ("%*s", len - txtwidth - still, ""); } #endif } else { --- mc-4.6.1/src/util.c +++ mc-4.6.1/src/util.c @@ -89,11 +89,13 @@ if (SLsmg_Is_Unicode) { static mbstate_t s; int len; + const char *str0 = str; len = mbsrtowcs (NULL, &str, -1, &s); if (len < 0) { - memset (&s, 0, sizeof (s)); - return -1; + memset (&s, 0, sizeof (s)); + /* invalid multibyte character, probably not UTF-8 string */ + return strlen (str0); } return len; } else @@ -101,6 +103,33 @@ return strlen (str); } +#ifdef UTF8 + +void +fix_utf8(char *str) +{ + mbstate_t mbs; + + char *p = str; + + while (*p) { + int len; + memset (&mbs, 0, sizeof (mbs)); + len = mbrlen(p, MB_CUR_MAX, &mbs); + if (len == -1) { + *p = '?'; + p++; + } else if (len > 0) { + p += len; + } else { + p++; + } + } +} +#endif + + + int is_printable (int c) { @@ -229,7 +258,24 @@ *d++ = '\\'; break; } +#ifndef UTF8 *d = *s; +#else /* UTF8 */ + { + mbstate_t mbs; + int len; + memset (&mbs, 0, sizeof (mbs)); + len = mbrlen(s, MB_CUR_MAX, &mbs); + if (len > 0) { + while (len-- > 1) + *d++ = *s++; + *d = *s; + } else { + *d = '?'; + } + + } +#endif /* UTF8 */ } *d = '\0'; return ret; @@ -955,10 +1001,27 @@ r++; continue; } - +#ifndef UTF8 if (is_printable(*r)) *w++ = *r; ++r; +#else /* UTF8 */ + { + mbstate_t mbs; + int len; + memset (&mbs, 0, sizeof (mbs)); + len = mbrlen(r, MB_CUR_MAX, &mbs); + + if (len > 0 && (unsigned char)*r >= ' ') + while (len--) + *w++ = *r++; + else { + if (len == -1) + *w++ = '?'; + r++; + } + } +#endif /* UTF8 */ } *w = 0; return s; --- mc-4.6.1/src/util.h +++ mc-4.6.1/src/util.h @@ -93,6 +93,7 @@ char *get_group (int); char *get_owner (int); +void fix_utf8(char *str); int mbstrlen (const char *); #define MAX_I18NTIMELENGTH 14 --- mc-4.6.1/src/widget.c +++ mc-4.6.1/src/widget.c @@ -149,10 +149,11 @@ attrset ((b->selected) ? HOT_FOCUSC : HOT_NORMALC); widget_move (&b->widget, 0, b->hotpos + off); #ifdef UTF8 - SLsmg_write_nwchars (&b->hotwc, 1); -#else - addch ((unsigned char) b->text[b->hotpos]); + if (SLsmg_Is_Unicode) + SLsmg_write_nwchars (&b->hotwc, 1); + else #endif + addch ((unsigned char) b->text[b->hotpos]); } return MSG_HANDLED; @@ -475,10 +476,11 @@ attrset ((msg == WIDGET_FOCUS) ? HOT_FOCUSC : HOT_NORMALC); widget_move (&c->widget, 0, +c->hotpos + 4); #ifdef UTF8 - SLsmg_write_nwchars (&c->hotwc, 1); -#else - addch ((unsigned char) c->text[c->hotpos]); + if (SLsmg_Is_Unicode) + SLsmg_write_nwchars (&c->hotwc, 1); + else #endif + addch ((unsigned char) c->text[c->hotpos]); } return MSG_HANDLED;