Submitted By: Alexander E. Patrakov Date: 2007-01-19 Initial Package Version: 4.6.1 Origin: Debian Upstream Status: partially applied Description: This patch adds UTF-8 support to MC, enables recoding of FTP filenames, fixes 64-bit issues, mcedit segfaults, moves configuration files to /etc/mc, and contains other changes from the Debian mc package. diff -urN mc-4.6.1.orig/doc/mc.1.in mc-4.6.1/doc/mc.1.in --- mc-4.6.1.orig/doc/mc.1.in 2005-06-08 18:27:06.000000000 +0600 +++ mc-4.6.1/doc/mc.1.in 2007-01-19 18:33:58.000000000 +0500 @@ -1377,7 +1377,7 @@ but only if it is owned by user or root and is not world-writable. If no such file found, ~/.mc/menu is tried in the same way, and otherwise mc uses the default system-wide menu -@prefix@/share/mc/mc.menu. +/etc/mc/mc.menu. .PP The format of the menu file is very simple. Lines that start with anything but space or tab are considered entries for the menu (in @@ -1903,7 +1903,7 @@ At startup the Midnight Commander will try to load initialization information from the ~/.mc/ini file. If this file doesn't exist, it will load the information from the system-wide configuration file, located in -@prefix@/share/mc/mc.ini. If the system-wide configuration file doesn't +/etc/mc/mc.ini. If the system-wide configuration file doesn't exist, MC uses the default settings. .PP The @@ -3235,7 +3235,7 @@ .IP The help file for the program. .PP -.I @prefix@/share/mc/mc.ext +.I /etc/mc/mc.ext .IP The default system-wide extensions file. .PP @@ -3244,12 +3244,12 @@ User's own extension, view configuration and edit configuration file. They override the contents of the system wide files if present. .PP -.I @prefix@/share/mc/mc.ini +.I /etc/mc/mc.ini .IP The default system-wide setup for the Midnight Commander, used only if the user doesn't have his own ~/.mc/ini file. .PP -.I @prefix@/share/mc/mc.lib +.I /etc/mc/mc.lib .IP Global settings for the Midnight Commander. Settings in this file affect all users, whether they have ~/.mc/ini or not. Currently, only @@ -3267,7 +3267,7 @@ .IP This file contains the hints displayed by the program. .PP -.I @prefix@/share/mc/mc.menu +.I /etc/mc/mc.menu .IP This file contains the default system-wide applications menu. .PP diff -urN mc-4.6.1.orig/doc/mcedit.1.in mc-4.6.1/doc/mcedit.1.in --- mc-4.6.1.orig/doc/mcedit.1.in 2005-06-08 18:27:07.000000000 +0600 +++ mc-4.6.1/doc/mcedit.1.in 2007-01-19 18:33:58.000000000 +0500 @@ -464,12 +464,12 @@ .IP The help file for the program. .PP -.I @prefix@/share/mc/mc.ini +.I /etc/mc/mc.ini .IP The default system-wide setup for GNU Midnight Commander, used only if the user's own ~/.mc/ini file is missing. .PP -.I @prefix@/share/mc/mc.lib +.I /etc/mc/mc.lib .IP Global settings for the Midnight Commander. Settings in this file affect all users, whether they have ~/.mc/ini or not. diff -urN mc-4.6.1.orig/doc/mcview.1.in mc-4.6.1/doc/mcview.1.in --- mc-4.6.1.orig/doc/mcview.1.in 2005-06-08 18:27:07.000000000 +0600 +++ mc-4.6.1/doc/mcview.1.in 2007-01-19 18:33:58.000000000 +0500 @@ -65,12 +65,12 @@ .IP The help file for the program. .PP -.I @prefix@/share/mc/mc.ini +.I /etc/mc/mc.ini .IP The default system-wide setup for GNU Midnight Commander, used only if the user's own ~/.mc/ini file is missing. .PP -.I @prefix@/share/mc/mc.lib +.I /etc/mc/mc.lib .IP Global settings for the Midnight Commander. Settings in this file affect all users, whether they have ~/.mc/ini or not. diff -urN mc-4.6.1.orig/edit/edit.c mc-4.6.1/edit/edit.c --- mc-4.6.1.orig/edit/edit.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/edit/edit.c 2007-01-19 18:33:58.000000000 +0500 @@ -93,7 +93,7 @@ #ifndef NO_INLINE_GETBYTE -int edit_get_byte (WEdit * edit, long byte_index) +mc_wchar_t edit_get_byte (WEdit * edit, long byte_index) { unsigned long p; if (byte_index >= (edit->curs1 + edit->curs2) || byte_index < 0) @@ -125,7 +125,7 @@ edit->curs1 = 0; edit->curs2 = 0; - edit->buffers2[0] = g_malloc (EDIT_BUF_SIZE); + edit->buffers2[0] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); } /* @@ -152,7 +152,7 @@ } if (!edit->buffers2[buf2]) - edit->buffers2[buf2] = g_malloc (EDIT_BUF_SIZE); + edit->buffers2[buf2] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); mc_read (file, (char *) edit->buffers2[buf2] + EDIT_BUF_SIZE - @@ -162,7 +162,7 @@ for (buf = buf2 - 1; buf >= 0; buf--) { /* edit->buffers2[0] is already allocated */ if (!edit->buffers2[buf]) - edit->buffers2[buf] = g_malloc (EDIT_BUF_SIZE); + edit->buffers2[buf] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); mc_read (file, (char *) edit->buffers2[buf], EDIT_BUF_SIZE); } @@ -242,9 +242,44 @@ { int c; long i = 0; - while ((c = fgetc (f)) >= 0) { +#ifndef UTF8 + while ((c = fgetc (f)) != EOF) { edit_insert (edit, c); i++; +#else /* UTF8 */ + unsigned char buf[MB_LEN_MAX]; + int charpos = 0; + mbstate_t mbs; + + while ((c = fgetc (f)) != EOF) { + mc_wchar_t wc; + int size; + int j; + + buf[charpos++] = c; + + memset (&mbs, 0, sizeof (mbs)); + size = mbrtowc(&wc, (char *)buf, charpos, &mbs); + + if (size == -2) + continue; /* incomplete */ + + else if (size >= 0) { + edit_insert (edit, wc); + i++; + charpos = 0; + continue; + } + else { + + /* invalid */ +#ifdef __STDC_ISO_10646__ + for (j=0; jlast_byte; i++) if (fputc (edit_get_byte (edit, i), f) < 0) break; +#else /* UTF8 */ + for (i = 0; i < edit->last_byte; i++) { + mc_wchar_t wc = edit_get_byte (edit, i); + int res; + char tmpbuf[MB_LEN_MAX]; + mbstate_t mbs; + + memset (&mbs, 0, sizeof (mbs)); + +#ifdef __STDC_ISO_10646__ + if (wc >= BINARY_CHAR_OFFSET && wc < (BINARY_CHAR_OFFSET + 256)) { + res = 1; + tmpbuf[0] = (char) (wc - BINARY_CHAR_OFFSET); + } else +#endif + res = wcrtomb(tmpbuf, wc, &mbs); + if (res > 0) { + if (fwrite(tmpbuf, res, 1, f) != 1) + break; + } + } +#endif /* UTF8 */ return i; } @@ -294,12 +352,46 @@ int i, file, blocklen; long current = edit->curs1; unsigned char *buf; +#ifdef UTF8 + mbstate_t mbs; + int bufstart = 0; + + memset (&mbs, 0, sizeof (mbs)); +#endif /* UTF8 */ if ((file = mc_open (filename, O_RDONLY | O_BINARY)) == -1) return 0; buf = g_malloc (TEMP_BUF_LEN); +#ifndef UTF8 while ((blocklen = mc_read (file, (char *) buf, TEMP_BUF_LEN)) > 0) { for (i = 0; i < blocklen; i++) edit_insert (edit, buf[i]); +#else /* UTF8 */ + while ((blocklen = mc_read (file, (char *) buf + bufstart, TEMP_BUF_LEN - bufstart)) > 0) { + blocklen += bufstart; + bufstart = 0; + for (i = 0; i < blocklen; ) { + mc_wchar_t wc; + int j; + int size = mbrtowc(&wc, (char *)buf + i, blocklen - i, &mbs); + if (size == -2) { /*incomplete char*/ + bufstart = blocklen - i; + memcpy(buf, buf+i, bufstart); + i = blocklen; + memset (&mbs, 0, sizeof (mbs)); + } + else if (size <= 0) { +#ifdef __STDC_ISO_10646__ + edit_insert (edit, BINARY_CHAR_OFFSET + (mc_wchar_t)buf[i]); +#endif + memset (&mbs, 0, sizeof (mbs)); + i++; /* skip broken char */ + } + else { + edit_insert (edit, wc); + i+=size; + } + } +#endif /* UTF8 */ } edit_cursor_move (edit, current - edit->curs1); g_free (buf); @@ -393,7 +485,11 @@ static int edit_load_file (WEdit *edit) { +#ifndef UTF8 int fast_load = 1; +#else /* UTF8 */ + int fast_load = 0; /* can't be used with multibyte characters */ +#endif /* UTF8 */ /* Cannot do fast load if a filter is used */ if (edit_find_filter (edit->filename) >= 0) @@ -540,7 +636,7 @@ edit_set_filename (edit, filename); edit->stack_size = START_STACK_SIZE; edit->stack_size_mask = START_STACK_SIZE - 1; - edit->undo_stack = g_malloc ((edit->stack_size + 10) * sizeof (long)); + edit->undo_stack = g_malloc ((edit->stack_size + 10) * sizeof (struct action)); if (edit_load_file (edit)) { /* edit_load_file already gives an error message */ if (to_free) @@ -565,7 +661,9 @@ edit_move_display (edit, line - 1); edit_move_to_line (edit, line - 1); } - +#ifdef UTF8 + edit->charpoint = 0; +#endif return edit; } @@ -693,13 +791,23 @@ { unsigned long sp = edit->stack_pointer; unsigned long spm1; - long *t; + + struct action *t; + mc_wchar_t ch = 0; + + if (c == CHAR_INSERT || c == CHAR_INSERT_AHEAD) { + va_list ap; + va_start (ap, c); + ch = va_arg (ap, mc_wint_t); + va_end (ap); + } + /* first enlarge the stack if necessary */ if (sp > edit->stack_size - 10) { /* say */ if (option_max_undo < 256) option_max_undo = 256; if (edit->stack_size < (unsigned long) option_max_undo) { - t = g_realloc (edit->undo_stack, (edit->stack_size * 2 + 10) * sizeof (long)); + t = g_realloc (edit->undo_stack, (edit->stack_size * 2 + 10) * sizeof (struct action)); if (t) { edit->undo_stack = t; edit->stack_size <<= 1; @@ -714,7 +822,7 @@ #ifdef FAST_MOVE_CURSOR if (c == CURS_LEFT_LOTS || c == CURS_RIGHT_LOTS) { va_list ap; - edit->undo_stack[sp] = c == CURS_LEFT_LOTS ? CURS_LEFT : CURS_RIGHT; + edit->undo_stack[sp].flags = c == CURS_LEFT_LOTS ? CURS_LEFT : CURS_RIGHT; edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask; va_start (ap, c); c = -(va_arg (ap, int)); @@ -725,12 +833,14 @@ && spm1 != edit->stack_bottom && ((sp - 2) & edit->stack_size_mask) != edit->stack_bottom) { int d; - if (edit->undo_stack[spm1] < 0) { - d = edit->undo_stack[(sp - 2) & edit->stack_size_mask]; - if (d == c) { - if (edit->undo_stack[spm1] > -1000000000) { + mc_wchar_t d_ch; + if (edit->undo_stack[spm1].flags < 0) { + d = edit->undo_stack[(sp - 2) & edit->stack_size_mask].flags; + d_ch = edit->undo_stack[(sp - 2) & edit->stack_size_mask].ch; + if (d == c && d_ch == ch) { + if (edit->undo_stack[spm1].flags > -1000000000) { if (c < KEY_PRESS) /* --> no need to push multiple do-nothings */ - edit->undo_stack[spm1]--; + edit->undo_stack[spm1].flags--; return; } } @@ -738,19 +848,20 @@ #ifndef NO_STACK_CURSMOVE_ANIHILATION else if ((c == CURS_LEFT && d == CURS_RIGHT) || (c == CURS_RIGHT && d == CURS_LEFT)) { /* a left then a right anihilate each other */ - if (edit->undo_stack[spm1] == -2) + if (edit->undo_stack[spm1].flags == -2) edit->stack_pointer = spm1; else - edit->undo_stack[spm1]++; + edit->undo_stack[spm1].flags++; return; } #endif } else { - d = edit->undo_stack[spm1]; - if (d == c) { + d = edit->undo_stack[spm1].flags; + d_ch = edit->undo_stack[spm1].ch; + if (d == c && d_ch == ch) { if (c >= KEY_PRESS) return; /* --> no need to push multiple do-nothings */ - edit->undo_stack[sp] = -2; + edit->undo_stack[sp].flags = -2; goto check_bottom; } #ifndef NO_STACK_CURSMOVE_ANIHILATION @@ -762,7 +873,9 @@ #endif } } - edit->undo_stack[sp] = c; + edit->undo_stack[sp].flags = c; + edit->undo_stack[sp].ch = ch; + check_bottom: edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask; @@ -775,10 +888,10 @@ (((unsigned long) c + 1) & edit->stack_size_mask) == edit->stack_bottom) do { edit->stack_bottom = (edit->stack_bottom + 1) & edit->stack_size_mask; - } while (edit->undo_stack[edit->stack_bottom] < KEY_PRESS && edit->stack_bottom != edit->stack_pointer); + } while (edit->undo_stack[edit->stack_bottom].flags < KEY_PRESS && edit->stack_bottom != edit->stack_pointer); /*If a single key produced enough pushes to wrap all the way round then we would notice that the [stack_bottom] does not contain KEY_PRESS. The stack is then initialised: */ - if (edit->stack_pointer != edit->stack_bottom && edit->undo_stack[edit->stack_bottom] < KEY_PRESS) + if (edit->stack_pointer != edit->stack_bottom && edit->undo_stack[edit->stack_bottom].flags < KEY_PRESS) edit->stack_bottom = edit->stack_pointer = 0; } @@ -787,30 +900,30 @@ then the file should be as it was when he loaded up. Then set edit->modified to 0. */ static long -pop_action (WEdit * edit) +pop_action (WEdit * edit, struct action *c) { - long c; unsigned long sp = edit->stack_pointer; if (sp == edit->stack_bottom) { - return STACK_BOTTOM; + c->flags = STACK_BOTTOM; + return c->flags; } sp = (sp - 1) & edit->stack_size_mask; - if ((c = edit->undo_stack[sp]) >= 0) { -/* edit->undo_stack[sp] = '@'; */ + *c = edit->undo_stack[sp]; + if (edit->undo_stack[sp].flags >= 0) { edit->stack_pointer = (edit->stack_pointer - 1) & edit->stack_size_mask; - return c; + return c->flags; } if (sp == edit->stack_bottom) { return STACK_BOTTOM; } - c = edit->undo_stack[(sp - 1) & edit->stack_size_mask]; - if (edit->undo_stack[sp] == -2) { -/* edit->undo_stack[sp] = '@'; */ + *c = edit->undo_stack[(sp - 1) & edit->stack_size_mask]; + + if (edit->undo_stack[sp].flags == -2) { edit->stack_pointer = sp; } else - edit->undo_stack[sp]++; + edit->undo_stack[sp].flags++; - return c; + return c->flags; } /* is called whenever a modification is made by one of the four routines below */ @@ -831,7 +944,7 @@ */ void -edit_insert (WEdit *edit, int c) +edit_insert (WEdit *edit, mc_wchar_t c) { /* check if file has grown to large */ if (edit->last_byte >= SIZE_LIMIT) @@ -869,12 +982,11 @@ /* add a new buffer if we've reached the end of the last one */ if (!(edit->curs1 & M_EDIT_BUF_SIZE)) edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = - g_malloc (EDIT_BUF_SIZE); + g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); /* perform the insertion */ - edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE][edit-> - curs1 & M_EDIT_BUF_SIZE] - = (unsigned char) c; + edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] + [edit->curs1 & M_EDIT_BUF_SIZE] = c; /* update file length */ edit->last_byte++; @@ -885,7 +997,7 @@ /* same as edit_insert and move left */ -void edit_insert_ahead (WEdit * edit, int c) +void edit_insert_ahead (WEdit * edit, mc_wchar_t c) { if (edit->last_byte >= SIZE_LIMIT) return; @@ -908,7 +1020,7 @@ edit->last_get_rule += (edit->last_get_rule >= edit->curs1); if (!((edit->curs2 + 1) & M_EDIT_BUF_SIZE)) - edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE); + edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE) - 1] = c; edit->last_byte++; @@ -918,7 +1030,7 @@ int edit_delete (WEdit * edit) { - int p; + mc_wint_t p; if (!edit->curs2) return 0; @@ -942,7 +1054,7 @@ edit->total_lines--; edit->force |= REDRAW_AFTER_CURSOR; } - edit_push_action (edit, p + 256); + edit_push_action (edit, CHAR_INSERT_AHEAD, p); if (edit->curs1 < edit->start_display) { edit->start_display--; if (p == '\n') @@ -956,7 +1068,7 @@ static int edit_backspace (WEdit * edit) { - int p; + mc_wint_t p; if (!edit->curs1) return 0; @@ -980,7 +1092,7 @@ edit->total_lines--; edit->force |= REDRAW_AFTER_CURSOR; } - edit_push_action (edit, p); + edit_push_action (edit, CHAR_INSERT, p); if (edit->curs1 < edit->start_display) { edit->start_display--; @@ -993,10 +1105,18 @@ #ifdef FAST_MOVE_CURSOR -static void memqcpy (WEdit * edit, unsigned char *dest, unsigned char *src, int n) +static void memqcpy (WEdit * edit, mc_wchar_t *dest, mc_wchar_t *src, int n) { unsigned long next; +#ifndef UTF8 while ((next = (unsigned long) memccpy (dest, src, '\n', n))) { +#else /* UTF8 */ + while (n) { + next = 0; + while (next < n && src[next]!='\n') next++; + if (next < n) next++; + wmemcpy (dest, src, next) +#endif /* UTF8 */ edit->curs_line--; next -= (unsigned long) dest; n -= next; @@ -1009,7 +1129,7 @@ edit_move_backward_lots (WEdit *edit, long increment) { int r, s, t; - unsigned char *p; + mc_wchar_t *p; if (increment > edit->curs1) increment = edit->curs1; @@ -1049,7 +1169,7 @@ edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = p; else edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = - g_malloc (EDIT_BUF_SIZE); + g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); } else { g_free (p); } @@ -1087,7 +1207,7 @@ edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = p; else edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = - g_malloc (EDIT_BUF_SIZE); + g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); } else { g_free (p); } @@ -1119,7 +1239,7 @@ c = edit_get_byte (edit, edit->curs1 - 1); if (!((edit->curs2 + 1) & M_EDIT_BUF_SIZE)) - edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE); + edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE) - 1] = c; edit->curs2++; c = edit->buffers1[(edit->curs1 - 1) >> S_EDIT_BUF_SIZE][(edit->curs1 - 1) & M_EDIT_BUF_SIZE]; @@ -1144,7 +1264,7 @@ c = edit_get_byte (edit, edit->curs1); if (!(edit->curs1 & M_EDIT_BUF_SIZE)) - edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE); + edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE][edit->curs1 & M_EDIT_BUF_SIZE] = c; edit->curs1++; c = edit->buffers2[(edit->curs2 - 1) >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - ((edit->curs2 - 1) & M_EDIT_BUF_SIZE) - 1]; @@ -1251,7 +1371,7 @@ q = edit->last_byte + 2; for (col = 0, p = current; p < q; p++) { - int c; + mc_wchar_t c; if (cols != -10) { if (col == cols) return p; @@ -1269,7 +1389,7 @@ } else if (c < 32 || c == 127) col += 2; /* Caret notation for control characters */ else - col++; + col += wcwidth(c); } return col; } @@ -1402,7 +1522,7 @@ is_blank (WEdit *edit, long offset) { long s, f; - int c; + mc_wchar_t c; s = edit_bol (edit, offset); f = edit_eol (edit, offset) - 1; while (s <= f) { @@ -1774,13 +1894,13 @@ static void edit_do_undo (WEdit * edit) { - long ac; + struct action ac; long count = 0; edit->stack_disable = 1; /* don't record undo's onto undo stack! */ - while ((ac = pop_action (edit)) < KEY_PRESS) { - switch ((int) ac) { + while (pop_action (edit, &ac) < KEY_PRESS) { + switch ((int) ac.flags) { case STACK_BOTTOM: goto done_undo; case CURS_RIGHT: @@ -1801,31 +1921,33 @@ case COLUMN_OFF: column_highlighting = 0; break; + case CHAR_INSERT: + edit_insert (edit, ac.ch); + break; + case CHAR_INSERT_AHEAD: + edit_insert_ahead (edit, ac.ch); + break; } - if (ac >= 256 && ac < 512) - edit_insert_ahead (edit, ac - 256); - if (ac >= 0 && ac < 256) - edit_insert (edit, ac); - if (ac >= MARK_1 - 2 && ac < MARK_2 - 2) { - edit->mark1 = ac - MARK_1; + if (ac.flags >= MARK_1 - 2 && ac.flags < MARK_2 - 2) { + edit->mark1 = ac.flags - MARK_1; edit->column1 = edit_move_forward3 (edit, edit_bol (edit, edit->mark1), 0, edit->mark1); - } else if (ac >= MARK_2 - 2 && ac < KEY_PRESS) { - edit->mark2 = ac - MARK_2; + } else if (ac.flags >= MARK_2 - 2 && ac.flags < KEY_PRESS) { + edit->mark2 = ac.flags - MARK_2; edit->column2 = edit_move_forward3 (edit, edit_bol (edit, edit->mark2), 0, edit->mark2); } if (count++) edit->force |= REDRAW_PAGE; /* more than one pop usually means something big */ } - if (edit->start_display > ac - KEY_PRESS) { - edit->start_line -= edit_count_lines (edit, ac - KEY_PRESS, edit->start_display); + if (edit->start_display > ac.flags - KEY_PRESS) { + edit->start_line -= edit_count_lines (edit, ac.flags - KEY_PRESS, edit->start_display); edit->force |= REDRAW_PAGE; - } else if (edit->start_display < ac - KEY_PRESS) { - edit->start_line += edit_count_lines (edit, edit->start_display, ac - KEY_PRESS); + } else if (edit->start_display < ac.flags - KEY_PRESS) { + edit->start_line += edit_count_lines (edit, edit->start_display, ac.flags - KEY_PRESS); edit->force |= REDRAW_PAGE; } - edit->start_display = ac - KEY_PRESS; /* see push and pop above */ + edit->start_display = ac.flags - KEY_PRESS; /* see push and pop above */ edit_update_curs_row (edit); done_undo:; @@ -2102,7 +2224,7 @@ * passed as -1. Commands are executed, and char_for_insertion is * inserted at the cursor. */ -void edit_execute_key_command (WEdit *edit, int command, int char_for_insertion) +void edit_execute_key_command (WEdit *edit, int command, mc_wint_t char_for_insertion) { if (command == CK_Begin_Record_Macro) { edit->macro_i = 0; @@ -2137,7 +2259,7 @@ all of them. It also does not check for the Undo command. */ void -edit_execute_cmd (WEdit *edit, int command, int char_for_insertion) +edit_execute_cmd (WEdit *edit, int command, mc_wint_t char_for_insertion) { edit->force |= REDRAW_LINE; @@ -2170,7 +2292,7 @@ } /* An ordinary key press */ - if (char_for_insertion >= 0) { + if (char_for_insertion != (mc_wint_t) -1) { if (edit->overwrite) { if (edit_get_byte (edit, edit->curs1) != '\n') edit_delete (edit); diff -urN mc-4.6.1.orig/edit/editcmd.c mc-4.6.1/edit/editcmd.c --- mc-4.6.1.orig/edit/editcmd.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/edit/editcmd.c 2007-01-19 18:33:58.000000000 +0500 @@ -24,7 +24,6 @@ /* #define PIPE_BLOCKS_SO_READ_BYTE_BY_BYTE */ #include -#include #include "edit.h" #include "editlock.h" @@ -46,7 +45,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; }; @@ -69,12 +68,16 @@ #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 *strcasechr (const unsigned char *s, int c) @@ -108,11 +111,11 @@ #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 { @@ -196,6 +199,48 @@ 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 , @@ -225,7 +270,7 @@ } if (!vfs_file_is_local (filename) || - (fd = mc_open (filename, O_WRONLY | O_BINARY)) == -1) { + (fd = mc_open (filename, O_RDONLY | O_BINARY)) == -1) { /* * The file does not exists yet, so no safe save or * backup are necessary. @@ -303,32 +348,48 @@ 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; @@ -643,13 +704,21 @@ 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"); } } @@ -685,7 +754,11 @@ 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) { @@ -734,10 +807,18 @@ 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) @@ -886,7 +967,7 @@ #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; @@ -934,7 +1015,7 @@ { long start_mark, end_mark, current = edit->curs1; int size, x; - unsigned char *copy_buf; + mc_wchar_t *copy_buf; edit_update_curs_col (edit); x = edit->curs_col; @@ -979,7 +1060,7 @@ { long count; long current; - unsigned char *copy_buf; + mc_wchar_t *copy_buf; long start_mark, end_mark; int deleted = 0; int x = 0; @@ -1040,7 +1121,7 @@ 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; @@ -1371,7 +1452,11 @@ /* 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 len, 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; @@ -1380,6 +1465,11 @@ regmatch_t *pmatch; static regmatch_t s[1]; +#ifdef UTF8 + char *string; + int i; +#endif /* UTF8 */ + pmatch = (regmatch_t *) d; if (!pmatch) pmatch = s; @@ -1399,13 +1489,51 @@ 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); } @@ -1413,13 +1541,29 @@ /* 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... */ @@ -1428,19 +1572,22 @@ 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); @@ -1454,20 +1601,36 @@ } 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); @@ -1481,7 +1644,11 @@ 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--; @@ -1507,10 +1674,17 @@ buf = mbuf; while (q) { +#ifndef UTF8 found_start = string_regexp_search ((char *) exp, (char *) buf, q, 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 */ @@ -1521,15 +1695,27 @@ 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; @@ -1539,36 +1725,59 @@ } } } 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; } @@ -1582,9 +1791,14 @@ 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; @@ -1616,6 +1830,7 @@ #define is_digit(x) ((x) >= '0' && (x) <= '9') +#ifndef UTF8 #define snprint(v) { \ *p1++ = *p++; \ *p1 = '\0'; \ @@ -1623,33 +1838,48 @@ 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; @@ -1677,45 +1907,78 @@ *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 **)); @@ -1724,10 +1987,17 @@ 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); @@ -1902,8 +2172,11 @@ } } if (replace_yes) { /* delete then insert new */ +#ifdef UTF8 + mc_wchar_t *winput2 = mbstr_to_wchar(exp2); +#endif /* UTF8 */ if (replace_scanf || replace_regexp) { - 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 */ @@ -1912,17 +2185,25 @@ 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 - @@ -1939,13 +2220,22 @@ sargs[k - 1][0] = 0; } if (!ret) +#ifndef UTF8 ret = snprintf_p (repl_str, MAX_REPL_LEN + 2, exp2, PRINTF_ARGS); +#else /* UTF8 */ + ret = snprintf_p (repl_str, MAX_REPL_LEN + 2, winput2, PRINTF_ARGS); +#endif /* UTF8 */ 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 == -2 @@ -1957,10 +2247,18 @@ times_replaced++; while (i--) edit_delete (edit); +#ifndef UTF8 while (exp2[++i]) edit_insert (edit, exp2[i]); +#else /* UTF8 */ + while (winput2[++i]) + edit_insert (edit, winput2[i]); +#endif } edit->found_len = i; +#ifdef UTF8 + g_free (winput2); +#endif /* UTF8 */ } /* so that we don't find the same string again */ if (replace_backwards) { @@ -2132,16 +2430,17 @@ #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); @@ -2174,11 +2473,15 @@ 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; @@ -2186,15 +2489,19 @@ } 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); @@ -2531,17 +2838,20 @@ /* 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; @@ -2635,15 +2945,20 @@ /* 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 */ @@ -2653,11 +2968,19 @@ 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 */ @@ -2690,7 +3013,7 @@ int *num) { int len, max_len = 0, i, skip; - char *bufpos; + mc_wchar_t *bufpos; /* collect max MAX_WORD_COMPLETIONS completions */ while (*num < MAX_WORD_COMPLETIONS) { @@ -2711,9 +3034,16 @@ buffers1[start >> S_EDIT_BUF_SIZE][start & M_EDIT_BUF_SIZE]; skip = 0; for (i = 0; i < *num; i++) { +#ifndef UTF8 if (strncmp (&compl[i].text[word_len], &bufpos[word_len], - max (len, compl[i].len) - word_len) == 0) { + max (len, +#else /* UTF8 */ + if (wcsncmp + ((wchar_t *) &compl[i].text[word_len], + (wchar_t *) &bufpos[word_len], max (len, +#endif /* UTF8 */ + compl[i].len) - word_len) == 0) { skip = 1; break; /* skip it, already added */ } @@ -2721,7 +3051,7 @@ 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); @@ -2735,6 +3065,18 @@ 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 @@ -2747,6 +3089,10 @@ 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; @@ -2782,8 +3128,16 @@ 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, 0, 0, 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, 0, 0, mbtext, NULL); + g_free(mbtext); + } +#endif /* UTF8 */ /* pop up the dialog */ run_dlg (compl_dlg); @@ -2791,9 +3145,17 @@ /* 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 */ @@ -2810,8 +3172,9 @@ { int word_len = 0, i, num_compl = 0, max_len; long word_start = 0; - 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 */ @@ -2828,16 +3191,32 @@ /* 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 -urN mc-4.6.1.orig/edit/editdraw.c mc-4.6.1/edit/editdraw.c --- mc-4.6.1.orig/edit/editdraw.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/edit/editdraw.c 2007-01-19 18:33:59.000000000 +0500 @@ -48,7 +48,7 @@ static void status_string (WEdit * edit, char *s, int w) { - char byte_str[16]; + char byte_str[32]; /* * If we are at the end of file, print , @@ -56,11 +56,16 @@ * 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, ""); } @@ -183,11 +188,16 @@ #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; @@ -201,9 +211,9 @@ 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) { @@ -212,9 +222,9 @@ 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 */ @@ -228,8 +238,11 @@ } else { lowlevel_set_color (color); } - +#ifdef UTF8 + SLsmg_write_nwchars(&textchar, 1); +#else addch (textchar); +#endif p++; } } @@ -239,11 +252,11 @@ 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, book_mark = -1; @@ -265,66 +278,96 @@ 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 */ if (book_mark == -1) { edit_get_syntax_color (edit, q, &color); - *p |= color << 16; + p->style |= color << 16; } else { - *p |= book_mark << 16; + p->style |= book_mark << 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; @@ -334,7 +377,7 @@ } 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); } diff -urN mc-4.6.1.orig/edit/edit.h mc-4.6.1/edit/edit.h --- mc-4.6.1.orig/edit/edit.h 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/edit/edit.h 2007-01-19 18:33:58.000000000 +0500 @@ -39,6 +39,27 @@ #include "../src/global.h" +#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 @@ -99,6 +120,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 @@ -118,7 +141,7 @@ struct macro { short command; - short ch; + mc_wchar_t ch; }; struct WEdit; @@ -132,26 +155,8 @@ 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); - -#ifndef NO_INLINE_GETBYTE -int edit_get_byte (WEdit * edit, long byte_index); -#else -static inline int edit_get_byte (WEdit * edit, long byte_index) -{ - unsigned long p; - if (byte_index >= (edit->curs1 + edit->curs2) || byte_index < 0) - return '\n'; - - if (byte_index >= edit->curs1) { - p = edit->curs1 + edit->curs2 - byte_index - 1; - return edit->buffers2[p >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (p & M_EDIT_BUF_SIZE) - 1]; - } else { - return edit->buffers1[byte_index >> S_EDIT_BUF_SIZE][byte_index & M_EDIT_BUF_SIZE]; - } -} -#endif - +int edit_translate_key (WEdit *edit, long x_key, int *cmd, mc_wint_t *ch); +mc_wchar_t edit_get_byte (WEdit * edit, long byte_index); 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); @@ -176,11 +181,11 @@ 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); @@ -212,7 +217,7 @@ 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); @@ -256,7 +261,7 @@ 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 -urN mc-4.6.1.orig/edit/editkeys.c mc-4.6.1/edit/editkeys.c --- mc-4.6.1.orig/edit/editkeys.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/edit/editkeys.c 2007-01-19 18:33:59.000000000 +0500 @@ -162,10 +162,10 @@ * '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; static const long *key_map; @@ -205,7 +205,7 @@ #ifdef HAVE_CHARSET if (x_key == XCTRL ('t')) { - do_select_codepage (); + do_select_codepage (_(" Choose codepage ")); edit->force = REDRAW_COMPLETELY; command = CK_Refresh; @@ -242,9 +242,30 @@ /* an ordinary insertable character */ if (x_key < 256) { 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; } } @@ -285,7 +306,7 @@ *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 -urN mc-4.6.1.orig/edit/editwidget.c mc-4.6.1/edit/editwidget.c --- mc-4.6.1.orig/edit/editwidget.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/edit/editwidget.c 2007-01-19 18:33:58.000000000 +0500 @@ -337,7 +337,8 @@ case WIDGET_KEY: { - int cmd, ch; + int cmd; + mc_wint_t ch; /* first check alt-f, alt-e, alt-s, etc for drop menus */ if (edit_drop_hotkey_menu (e, parm)) diff -urN mc-4.6.1.orig/edit/edit-widget.h mc-4.6.1/edit/edit-widget.h --- mc-4.6.1.orig/edit/edit-widget.h 2003-10-29 13:54:47.000000000 +0500 +++ mc-4.6.1/edit/edit-widget.h 2007-01-19 18:33:58.000000000 +0500 @@ -24,6 +24,11 @@ unsigned char border; }; +struct action { + mc_wchar_t ch; + long flags; +}; + struct WEdit { Widget widget; @@ -36,8 +41,17 @@ /* 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 */ @@ -81,7 +95,7 @@ /* 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; @@ -92,6 +106,7 @@ /* syntax higlighting */ struct _syntax_marker *syntax_marker; struct context_rule **rules; + size_t rules_count; /* number of rules that are defined */ long last_get_rule; struct syntax_rule rule; char *syntax_type; /* description of syntax highlighting type being used */ diff -urN mc-4.6.1.orig/edit/syntax.c mc-4.6.1/edit/syntax.c --- mc-4.6.1.orig/edit/syntax.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/edit/syntax.c 2007-01-19 18:33:58.000000000 +0500 @@ -662,6 +662,7 @@ strcpy (whole_right, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890"); r = edit->rules = g_malloc (alloc_contexts * sizeof (struct context_rule *)); + edit->rules_count = 0; if (!edit->defines) edit->defines = g_tree_new ((GCompareFunc) strcmp); @@ -892,6 +893,7 @@ if (num_contexts == -1) { return line; } + edit->rules_count = num_contexts; { char *first_chars, *p; @@ -916,17 +918,18 @@ void edit_free_syntax_rules (WEdit * edit) { - int i, j; + size_t i, j; if (!edit) return; if (edit->defines) destroy_defines (&edit->defines); if (!edit->rules) return; - edit_get_rule (edit, -1); + if (edit->rules_count > 0) + edit_get_rule (edit, -1); syntax_g_free (edit->syntax_type); edit->syntax_type = 0; - for (i = 0; edit->rules[i]; i++) { + for (i = 0; i < edit->rules_count; i++) { if (edit->rules[i]->keyword) { for (j = 0; edit->rules[i]->keyword[j]; j++) { syntax_g_free (edit->rules[i]->keyword[j]->keyword); diff -urN mc-4.6.1.orig/edit/wordproc.c mc-4.6.1/edit/wordproc.c --- mc-4.6.1.orig/edit/wordproc.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/edit/wordproc.c 2007-01-19 18:33:58.000000000 +0500 @@ -24,7 +24,12 @@ #define tab_width option_tab_spacing +#ifndef UTF8 #define NO_FORMAT_CHARS_START "-+*\\,.;:&>" +#else /* UTF8 */ +#define NO_FORMAT_CHARS_START L"-+*\\,.;:&>" +#endif /* UTF8 */ + #define FONT_MEAN_WIDTH 1 static long @@ -41,14 +46,21 @@ p = edit_move_forward (edit, p, line - l, 0); p = edit_bol (edit, p); + +#ifndef UTF8 while (strchr ("\t ", edit_get_byte (edit, p))) +#else /* UTF8 */ + while (wcschr (L"\t ", edit_get_byte (edit, p))) +#endif /* UTF8 */ + p++; return p; } static int bad_line_start (WEdit * edit, long p) { - int c; + mc_wint_t c; + c = edit_get_byte (edit, p); if (c == '.') { /* `...' is acceptable */ if (edit_get_byte (edit, p + 1) == '.') @@ -62,7 +74,13 @@ return 0; /* `---' is acceptable */ return 1; } + +#ifndef UTF8 if (strchr (NO_FORMAT_CHARS_START, c)) +#else /* UTF8 */ + if (wcschr (NO_FORMAT_CHARS_START, c)) +#endif /* UTF8 */ + return 1; return 0; } @@ -115,33 +133,37 @@ i - edit->curs_line, 0)); } -static unsigned char * +static mc_wchar_t * get_paragraph (WEdit *edit, long p, long q, int indent, int *size) { - unsigned char *s, *t; + mc_wchar_t *s, *t; #if 0 - t = g_malloc ((q - p) + 2 * (q - p) / option_word_wrap_line_length + - 10); + t = g_malloc (((q - p) + 2 * (q - p) / option_word_wrap_line_length + + 10) * sizeof(mc_wchar_t)); #else - t = g_malloc (2 * (q - p) + 100); + t = g_malloc ((2 * (q - p) + 100) * sizeof(mc_wchar_t)); #endif if (!t) return 0; for (s = t; p < q; p++, s++) { if (indent) if (edit_get_byte (edit, p - 1) == '\n') +#ifndef UTF8 while (strchr ("\t ", edit_get_byte (edit, p))) +#else /* UTF8 */ + while (wcschr (L"\t ", edit_get_byte (edit, p))) +#endif /* UTF8 */ p++; *s = edit_get_byte (edit, p); } - *size = (unsigned long) s - (unsigned long) t; + *size = s - t; t[*size] = '\n'; return t; } -static void strip_newlines (unsigned char *t, int size) +static void strip_newlines (mc_wchar_t *t, int size) { - unsigned char *p = t; + mc_wchar_t *p = t; while (size--) { *p = *p == '\n' ? ' ' : *p; p++; @@ -158,7 +180,7 @@ { return x += tab_width - x % tab_width; } -static int line_pixel_length (unsigned char *t, long b, int l) +static int line_pixel_length (mc_wchar_t *t, long b, int l) { int x = 0, c, xn = 0; for (;;) { @@ -182,7 +204,7 @@ } /* find the start of a word */ -static int next_word_start (unsigned char *t, int q, int size) +static int next_word_start (mc_wchar_t *t, int q, int size) { int i; for (i = q;; i++) { @@ -203,7 +225,7 @@ } /* find the start of a word */ -static int word_start (unsigned char *t, int q, int size) +static int word_start (mc_wchar_t *t, int q, int size) { int i = q; if (t[q] == ' ' || t[q] == '\t') @@ -222,7 +244,7 @@ } /* replaces ' ' with '\n' to properly format a paragraph */ -static void format_this (unsigned char *t, int size, int indent) +static void format_this (mc_wchar_t *t, int size, int indent) { int q = 0, ww; strip_newlines (t, size); @@ -250,7 +272,7 @@ } } -static void replace_at (WEdit * edit, long q, int c) +static void replace_at (WEdit * edit, long q, mc_wint_t c) { edit_cursor_move (edit, q - edit->curs1); edit_delete (edit); @@ -258,18 +280,27 @@ } /* replaces a block of text */ -static void put_paragraph (WEdit * edit, unsigned char *t, long p, long q, int indent, int size) +static void put_paragraph (WEdit * edit, mc_wchar_t *t, long p, long q, int indent, int size) { long cursor; - int i, c = 0; + int i; + mc_wchar_t c = 0; cursor = edit->curs1; if (indent) +#ifndef UTF8 while (strchr ("\t ", edit_get_byte (edit, p))) +#else /* UTF8 */ + while (wcschr (L"\t ", edit_get_byte (edit, p))) +#endif /* UTF8 */ p++; for (i = 0; i < size; i++, p++) { if (i && indent) { if (t[i - 1] == '\n' && c == '\n') { +#ifndef UTF8 while (strchr ("\t ", edit_get_byte (edit, p))) +#else /* UTF8 */ + while (wcschr (L"\t ", edit_get_byte (edit, p))) +#endif /* UTF8 */ p++; } else if (t[i - 1] == '\n') { long curs; @@ -281,7 +312,11 @@ p = edit->curs1; } else if (c == '\n') { edit_cursor_move (edit, p - edit->curs1); +#ifndef UTF8 while (strchr ("\t ", edit_get_byte (edit, p))) { +#else /* UTF8 */ + while (wcschr (L"\t ", edit_get_byte (edit, p))) { +#endif /* UTF8 */ edit_delete (edit); if (cursor > edit->curs1) cursor--; @@ -314,7 +349,7 @@ { long p, q; int size; - unsigned char *t; + mc_wchar_t *t; int indent = 0; if (option_word_wrap_line_length < 2) return; @@ -324,17 +359,25 @@ q = end_paragraph (edit, force); indent = test_indent (edit, p, q); t = get_paragraph (edit, p, q, indent, &size); - if (!t) + if (!t) return; if (!force) { int i; +#ifndef UTF8 if (strchr (NO_FORMAT_CHARS_START, *t)) { +#else /* UTF8 */ + if (wcschr (NO_FORMAT_CHARS_START, *t)) { +#endif /* UTF8 */ g_free (t); return; } for (i = 0; i < size - 1; i++) { if (t[i] == '\n') { +#ifndef UTF8 if (strchr (NO_FORMAT_CHARS_START "\t ", t[i + 1])) { +#else /* UTF8 */ + if (wcschr (NO_FORMAT_CHARS_START "\t", t[i + 1])) { +#endif /* UTF8 */ g_free (t); return; } diff -urN mc-4.6.1.orig/lib/mc.menu mc-4.6.1/lib/mc.menu --- mc-4.6.1.orig/lib/mc.menu 2004-08-17 14:31:16.000000000 +0600 +++ mc-4.6.1/lib/mc.menu 2007-01-19 18:33:58.000000000 +0500 @@ -15,7 +15,7 @@ 0 Edit a bug report and send it to root I=`mktemp ${MC_TMPDIR:-/tmp}/mail.XXXXXX` || exit 1 - ${EDITOR-vi} $I + ${EDITOR-editor} $I test -r $I && mail root < $I rm -f $I @@ -330,3 +330,7 @@ o Open next a free console open -s -- sh +=+ f \.dsc$ & t r +x Extract the contents of a Debian source package + dpkg-source -x %f + diff -urN mc-4.6.1.orig/po/de.po mc-4.6.1/po/de.po --- mc-4.6.1.orig/po/de.po 2005-07-23 22:53:27.000000000 +0600 +++ mc-4.6.1/po/de.po 2007-01-19 18:33:58.000000000 +0500 @@ -1412,7 +1412,7 @@ #: src/cmd.c:988 #, c-format msgid " edit symlink: %s " -msgstr " symbolschen Link barbeiten: %s" +msgstr " symbolschen Link bearbeiten: %s" #: src/cmd.c:999 #, c-format @@ -1562,7 +1562,7 @@ " Cannot create temporary command file \n" " %s " msgstr "" -" Kann temporre Befehlsdaei nicht anlegen \n" +" Kann temporre Befehlsdatei nicht anlegen \n" " %s " #: src/ext.c:117 src/user.c:606 @@ -1670,7 +1670,7 @@ " Cannot stat source file \"%s\" \n" " %s " msgstr "" -" Kann Quelldaei \"%s\" nicht untersuchen \n" +" Kann Quelldatei \"%s\" nicht untersuchen \n" " %s " #: src/file.c:517 src/file.c:1058 @@ -2576,7 +2576,7 @@ #: src/learn.c:115 #, c-format msgid " You have entered \"%s\"" -msgstr " Sie haben \"%s\" einggeben" +msgstr " Sie haben \"%s\" eingegeben" #. TRANSLATORS: This label appears near learned keys. Keep it short. #: src/learn.c:164 @@ -2668,7 +2668,7 @@ #: src/main.c:811 src/main.c:835 msgid "S&hell link..." -msgstr "Shell-Verbindung..." +msgstr "S&hell-Verbindung..." #: src/main.c:813 src/main.c:837 msgid "SM&B link..." @@ -4200,7 +4200,7 @@ #: vfs/ftpfs.c:684 #, c-format msgid "ftpfs: connection to server failed: %s" -msgstr "ftpfs: Verbindung zum Server fehlgeschlgen: %s" +msgstr "ftpfs: Verbindung zum Server fehlgeschlagen: %s" #: vfs/ftpfs.c:725 #, c-format diff -urN mc-4.6.1.orig/po/it.po mc-4.6.1/po/it.po --- mc-4.6.1.orig/po/it.po 2005-07-23 22:53:28.000000000 +0600 +++ mc-4.6.1/po/it.po 2007-01-19 18:33:58.000000000 +0500 @@ -2098,7 +2098,7 @@ #: src/filegui.c:524 msgid "A&ppend" -msgstr "Atta&cca" +msgstr "atta&Cca" #: src/filegui.c:527 msgid "Overwrite this target?" diff -urN mc-4.6.1.orig/po/ru.po mc-4.6.1/po/ru.po --- mc-4.6.1.orig/po/ru.po 2005-07-23 22:53:30.000000000 +0600 +++ mc-4.6.1/po/ru.po 2007-01-19 18:33:59.000000000 +0500 @@ -4503,3 +4503,32 @@ #: vfs/vfs.c:894 msgid "Changes to file lost" msgstr " " + +#: messages for recode patch +msgid "Panel &codepage" +msgstr " " + +msgid " Choose codepage " +msgstr " " + +msgid " Choose panel codepage " +msgstr " " + +msgid " Choose default FTP codepage " +msgstr " FTP " + +msgid "FTP default codepage:" +msgstr " FTP :" + +msgid "Recode file names:" +msgstr " :" + +msgid "Recoding works only with COPY/MOVE operation" +msgstr " /" + +msgid " Choose \"FROM\" codepage for COPY/MOVE operaion " +msgstr" / " + +msgid " Choose \"TO\" codepage for COPY/MOVE operaion " +msgstr" / " + diff -urN mc-4.6.1.orig/po/vi.po mc-4.6.1/po/vi.po --- mc-4.6.1.orig/po/vi.po 1970-01-01 05:00:00.000000000 +0500 +++ mc-4.6.1/po/vi.po 2007-01-19 18:33:58.000000000 +0500 @@ -0,0 +1,4456 @@ +# Vietnamese translation of Midnight Commander +# Copyright (C) 1998-2003, 2005 Free Software Foundation, Inc. +# First translator(s): Phan Vinh Thinh , 2005. +# +# +msgid "" +msgstr "" +"Project-Id-Version: mc 4.6.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2003-12-24 12:16-0500\n" +"PO-Revision-Date: 2005-03-29 01:20+0300\n" +"Last-Translator: Phan Vinh Thinh \n" +"Language-Team: Vietnamese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.9.1\n" + +#: edit/edit.c:146 edit/edit.c:277 edit/edit.c:285 edit/edit.c:333 +#: edit/edit.c:348 edit/edit.c:359 edit/edit.c:375 edit/edit.c:2665 +#: edit/editcmd.c:282 edit/editcmd.c:290 edit/editcmd.c:1719 src/wtools.c:120 +#: src/wtools.c:275 +msgid "Error" +msgstr "Lỗi" + +#: edit/edit.c:149 edit/edit.c:336 +msgid " Cannot open file for reading: " +msgstr " Không thể mở tập tin để đọc: " + +#: edit/edit.c:279 +msgid " Error reading from pipe: " +msgstr " Lỗi đọc từ đường ống (pipe): " + +#: edit/edit.c:288 +msgid " Cannot open pipe for reading: " +msgstr " Không thể mở đường ống để đọc: " + +#: edit/edit.c:351 +msgid " Cannot get size/permissions info for file: " +msgstr " Không lấy được thông tin kích thước/quyền hạn của tập tin: " + +#: edit/edit.c:360 +msgid " Not an ordinary file: " +msgstr " Tập tin không thông thường: " + +#: edit/edit.c:376 +msgid " File is too large: " +msgstr " Tập tin quá lớn: " + +#: edit/edit.c:2665 +msgid "Macro recursion is too deep" +msgstr "Đệ qui của macro quá sâu" + +#: edit/edit.h:262 +msgid "&Dismiss" +msgstr "Đó&ng" + +#: edit/edit.h:264 edit/editcmd.c:382 edit/editcmd.c:1228 edit/editcmd.c:1310 +#: edit/editcmd.c:2569 edit/editmenu.c:37 edit/editoptions.c:71 +#: src/boxes.c:139 src/boxes.c:276 src/boxes.c:372 src/boxes.c:464 +#: src/boxes.c:590 src/boxes.c:713 src/boxes.c:835 src/boxes.c:945 +#: src/boxes.c:1013 src/filegui.c:763 src/find.c:184 src/layout.c:348 +#: src/option.c:113 src/subshell.c:323 src/view.c:2107 src/wtools.c:441 +msgid "&OK" +msgstr "Đồng ý &=" + +#: edit/editcmd.c:45 edit/editcmd.c:46 +msgid " Enter file name: " +msgstr " Hãy nhập tên tập tin: " + +#: edit/editcmd.c:283 +msgid " Error writing to pipe: " +msgstr " Lỗi ghi vào đường ống: " + +#: edit/editcmd.c:293 +msgid " Cannot open pipe for writing: " +msgstr " Không thể mở đường ống để ghi: " + +#: edit/editcmd.c:375 +msgid "Quick save " +msgstr "&Lưu nhanh" + +#: edit/editcmd.c:376 +msgid "Safe save " +msgstr "Lưu &an toàn" + +#: edit/editcmd.c:377 +msgid "Do backups -->" +msgstr "&Sao lưu -->" + +#: edit/editcmd.c:380 edit/editcmd.c:1169 edit/editcmd.c:1226 +#: edit/editcmd.c:1308 edit/editcmd.c:2567 edit/editoptions.c:68 +#: src/achown.c:68 src/boxes.c:140 src/boxes.c:277 src/boxes.c:370 +#: src/boxes.c:462 src/boxes.c:588 src/boxes.c:711 src/boxes.c:833 +#: src/boxes.c:1013 src/chmod.c:96 src/chown.c:72 src/cmd.c:856 +#: src/filegui.c:745 src/find.c:184 src/hotlist.c:121 src/hotlist.c:523 +#: src/hotlist.c:830 src/hotlist.c:926 src/layout.c:349 src/learn.c:58 +#: src/option.c:114 src/panelize.c:66 src/view.c:441 src/view.c:2104 +#: src/wtools.c:46 src/wtools.c:439 +msgid "&Cancel" +msgstr "Đóng hộp thoại &-" + +#: edit/editcmd.c:386 +msgid "Extension:" +msgstr "&Mở rộng:" + +#: edit/editcmd.c:392 +msgid " Edit Save Mode " +msgstr " Chế độ ghi nhớ " + +#: edit/editcmd.c:465 edit/editcmd.c:524 +msgid " Save As " +msgstr " Ghi như " + +#: edit/editcmd.c:482 edit/editcmd.c:804 edit/editcmd.c:841 +#: edit/editcmd.c:1000 edit/editcmd.c:1113 src/file.c:599 src/help.c:318 +#: src/main.c:424 src/screen.c:1415 src/selcodepage.c:105 src/subshell.c:319 +#: src/subshell.c:653 src/utilunix.c:401 src/utilunix.c:405 src/utilunix.c:427 +#: vfs/mcfs.c:138 +msgid "Warning" +msgstr "Cảnh báo" + +#: edit/editcmd.c:483 +msgid " A file already exists with this name. " +msgstr " Tập tin có tên như vậy đã tồn tại. " + +#: edit/editcmd.c:484 +msgid "Overwrite" +msgstr "Ghi chèn" + +#: edit/editcmd.c:484 edit/editcmd.c:569 edit/editcmd.c:768 edit/editcmd.c:804 +#: edit/editcmd.c:844 edit/editcmd.c:1003 edit/editcmd.c:1116 +msgid "Cancel" +msgstr "Hủy bỏ" + +#: edit/editcmd.c:526 edit/editcmd.c:2293 src/view.c:440 +msgid " Cannot save file. " +msgstr " Không thể ghi nhớ tập tin. " + +#: edit/editcmd.c:626 edit/editcmd.c:634 edit/editcmd.c:659 edit/editcmd.c:706 +msgid " Delete macro " +msgstr " Xóa macro " + +#: edit/editcmd.c:628 +msgid " Cannot open temp file " +msgstr " Không thể mở tập tin tạm thời " + +#: edit/editcmd.c:636 edit/editcmd.c:697 edit/editcmd.c:754 +msgid " Cannot open macro file " +msgstr " Không thể mở tập tin chứa các macro " + +#: edit/editcmd.c:660 +msgid " Cannot overwrite macro file " +msgstr " Không thể ghi chèn lên tập tin chứa các macro " + +#: edit/editcmd.c:676 edit/editcmd.c:697 +msgid " Save macro " +msgstr " Ghi nhớ macro " + +#: edit/editcmd.c:678 +msgid " Press the macro's new hotkey: " +msgstr " Hãy nhấn phím tắt mới của macro: " + +#: edit/editcmd.c:707 edit/editkeys.c:195 edit/editkeys.c:225 +msgid " Press macro hotkey: " +msgstr " Hãy nhấn phím tắt của macro: " + +#: edit/editcmd.c:753 +msgid " Load macro " +msgstr " Nạp macro " + +#: edit/editcmd.c:766 +msgid " Confirm save file? : " +msgstr " Phê chuẩn việc ghi nhớ tập tin?: " + +#: edit/editcmd.c:768 src/view.c:439 +msgid " Save file " +msgstr " Ghi nhớ tập tin " + +#: edit/editcmd.c:768 edit/editwidget.c:288 src/view.c:2220 +msgid "Save" +msgstr "Ghinhớ" + +#: edit/editcmd.c:804 edit/editcmd.c:842 +msgid "" +" Current text was modified without a file save. \n" +" Continue discards these changes. " +msgstr "" +" Văn bản hiện thời đã thay đổi và chưa được ghi nhớ. \n" +" Tiếp tục thao tác sẽ làm mất những thay đổi này. " + +#: edit/editcmd.c:804 edit/editcmd.c:843 edit/editcmd.c:1003 +#: edit/editcmd.c:1116 +msgid "Continue" +msgstr "Tiếp tục" + +#: edit/editcmd.c:850 +msgid " Load " +msgstr " Nạp " + +#: edit/editcmd.c:1002 edit/editcmd.c:1115 +msgid " Block is large, you may not be able to undo this action. " +msgstr " Khối quá lớn, có thể bạn sẽ không hủy bỏ được bước này. " + +#: edit/editcmd.c:1171 +msgid "O&ne" +msgstr "&Một" + +#: edit/editcmd.c:1173 src/file.c:2210 src/filegui.c:521 +msgid "A&ll" +msgstr "&Tất cả" + +#: edit/editcmd.c:1175 src/file.c:2147 src/filegui.c:210 +msgid "&Skip" +msgstr "&Bỏ qua" + +#: edit/editcmd.c:1177 +msgid "&Replace" +msgstr "&Thay thế" + +#: edit/editcmd.c:1184 edit/editcmd.c:1191 +msgid " Replace with: " +msgstr " Thay thế bằng: " + +#: edit/editcmd.c:1196 +msgid " Confirm replace " +msgstr " Phê chuẩn thay thế " + +#: edit/editcmd.c:1230 edit/editcmd.c:1312 +msgid "scanf &Expression" +msgstr "biểu thức &Scanf" + +#: edit/editcmd.c:1232 +msgid "replace &All" +msgstr "&Thay thế tất cả" + +#: edit/editcmd.c:1234 +msgid "pr&Ompt on replace" +msgstr "&Hỏi trước khi thay" + +#: edit/editcmd.c:1236 edit/editcmd.c:1314 src/view.c:2110 +msgid "&Backwards" +msgstr "&Tìm ngược lại" + +#: edit/editcmd.c:1238 edit/editcmd.c:1316 +msgid "&Regular expression" +msgstr "&Biểu thức chính quy" + +#: edit/editcmd.c:1240 edit/editcmd.c:1318 +msgid "&Whole words only" +msgstr "&Chỉ những từ đầy đủ" + +#: edit/editcmd.c:1242 edit/editcmd.c:1320 src/find.c:176 +msgid "case &Sensitive" +msgstr "có tính &Kiểu chữ" + +#: edit/editcmd.c:1246 +msgid " Enter replacement argument order eg. 3,2,1,4 " +msgstr " Hãy nhập thứ tự của tham số thay thế, ví dụ 3,2,1,4 " + +#: edit/editcmd.c:1250 +msgid " Enter replacement string:" +msgstr " Nhập chuỗi thay thế:" + +#: edit/editcmd.c:1254 edit/editcmd.c:1324 src/view.c:2115 +msgid " Enter search string:" +msgstr " Nhập chuỗi tìm kiếm:" + +#: edit/editcmd.c:1273 edit/editcmd.c:1925 edit/editcmd.c:1949 +msgid " Replace " +msgstr " Thay thế " + +#: edit/editcmd.c:1338 edit/editcmd.c:2036 edit/editcmd.c:2038 +#: edit/editcmd.c:2066 edit/editwidget.c:293 src/view.c:1594 src/view.c:1673 +#: src/view.c:1826 src/view.c:1838 src/view.c:2060 src/view.c:2113 +#: src/view.c:2120 src/view.c:2236 +msgid "Search" +msgstr "Tìm" + +#: edit/editcmd.c:1719 +msgid " Invalid regular expression, or scanf expression with to many conversions " +msgstr " Biểu thức chính quy không đúng, hoặc biểu thức scanf có quá nhiều biến đổi " + +#: edit/editcmd.c:1927 +msgid " Error in replacement format string. " +msgstr " Lỗi trong định dạng chuỗi thay thế. " + +#: edit/editcmd.c:1957 +#, c-format +msgid " %ld replacements made. " +msgstr " %ld thay thế được thực hiện. " + +#: edit/editcmd.c:1960 edit/editcmd.c:2038 edit/editcmd.c:2066 src/view.c:1673 +#: src/view.c:1838 +msgid " Search string not found " +msgstr " Không tìm thấy chuỗi tìm kiếm " + +#: edit/editcmd.c:2036 +#, c-format +msgid " %d finds made, %d bookmarks added " +msgstr " tìm thấy %d , thêm %d thẻ đánh dấu (bookmark) " + +#: edit/editcmd.c:2088 edit/editwidget.c:296 src/help.c:826 src/main.c:1208 +#: src/view.c:456 src/view.c:2215 src/view.c:2246 +msgid "Quit" +msgstr "Thoát" + +#: edit/editcmd.c:2088 src/view.c:457 +msgid " File was modified, Save with exit? " +msgstr "Tập tin đã thay đổi, ghi nhớ khi thoát? " + +#: edit/editcmd.c:2089 src/view.c:458 +msgid "Cancel quit" +msgstr "Không thoát" + +#: edit/editcmd.c:2089 src/cmd.c:195 src/file.c:1837 src/file.c:2209 +#: src/filegui.c:526 src/hotlist.c:1049 src/main.c:471 src/screen.c:1952 +#: src/subshell.c:654 src/tree.c:708 src/view.c:458 vfs/mcfs.c:143 +msgid "&Yes" +msgstr "&Có" + +#: edit/editcmd.c:2089 src/cmd.c:195 src/file.c:1837 src/file.c:2209 +#: src/filegui.c:525 src/hotlist.c:1049 src/main.c:471 src/screen.c:1953 +#: src/subshell.c:654 src/tree.c:708 src/view.c:458 vfs/mcfs.c:143 +msgid "&No" +msgstr "&Không" + +#: edit/editcmd.c:2202 +msgid " Copy to clipboard " +msgstr "Sao chép vào bộ đệm " + +#: edit/editcmd.c:2202 edit/editcmd.c:2215 +msgid " Unable to save to file. " +msgstr "Không ghi nhớ được tập tin. " + +#: edit/editcmd.c:2215 +msgid " Cut to clipboard " +msgstr "Cắt vào bộ đệm " + +#: edit/editcmd.c:2243 src/view.c:2005 +msgid " Goto line " +msgstr "Chuyển tới dòng " + +#: edit/editcmd.c:2243 +msgid " Enter line: " +msgstr "Hãy nhập số thứ tự dòng: " + +#: edit/editcmd.c:2278 edit/editcmd.c:2291 +msgid " Save Block " +msgstr "Ghi nhớ khối " + +#: edit/editcmd.c:2307 edit/editcmd.c:2320 +msgid " Insert File " +msgstr "Chèn tập tin " + +#: edit/editcmd.c:2322 +msgid " Cannot insert file. " +msgstr "Không chèn được tập tin. " + +#: edit/editcmd.c:2339 +msgid " Sort block " +msgstr "Sắp xếp khối " + +#: edit/editcmd.c:2339 edit/editcmd.c:2465 +msgid " You must first highlight a block of text. " +msgstr "Đầu tiên bạn phải chọn một khối văn bản. " + +#: edit/editcmd.c:2346 +msgid " Run Sort " +msgstr "Thực hiện sắp xếp " + +#: edit/editcmd.c:2347 +msgid " Enter sort options (see manpage) separated by whitespace: " +msgstr "Nhập tùy chọn sắp xếp (xem trang man), phân cách nhau bởi khoảng trắng: " + +#: edit/editcmd.c:2358 edit/editcmd.c:2363 +msgid " Sort " +msgstr "Sắp xếp " + +#: edit/editcmd.c:2359 +msgid " Cannot execute sort command " +msgstr "Không thể thực hiện câu lệnh sort " + +#: edit/editcmd.c:2364 +msgid " Sort returned non-zero: " +msgstr "Sắp xếp trả lại giá trị khác không: " + +#: edit/editcmd.c:2388 +msgid "Paste output of external command" +msgstr "Dán kết quả của lệnh ngoại trú" + +#: edit/editcmd.c:2389 +msgid "Enter shell command(s):" +msgstr "Nhập (các) câu lệnh shell:" + +#: edit/editcmd.c:2398 +msgid "External command" +msgstr "Lệnh ngoại trú" + +#: edit/editcmd.c:2399 +msgid "Cannot execute command" +msgstr "Không thực hiện được câu lệnh" + +#: edit/editcmd.c:2433 +msgid "Error creating script:" +msgstr "Lỗi tạo script:" + +#: edit/editcmd.c:2441 +msgid "Error reading script:" +msgstr "Lỗi đọc script:" + +#: edit/editcmd.c:2450 +msgid "Error closing script:" +msgstr "Lỗi đóng script:" + +#: edit/editcmd.c:2456 +msgid "Script created:" +msgstr "Đã tạo script:" + +#: edit/editcmd.c:2463 +msgid "Process block" +msgstr "Xử lý khối" + +#: edit/editcmd.c:2562 +msgid " Mail " +msgstr " Thư " + +#: edit/editcmd.c:2573 +msgid " Copies to" +msgstr " Sao chép tới" + +#: edit/editcmd.c:2577 +msgid " Subject" +msgstr " Tên thư" + +#: edit/editcmd.c:2581 +msgid " To" +msgstr " Người nhận" + +#: edit/editcmd.c:2583 +msgid " mail -s -c " +msgstr " mail -s -c " + +#: edit/editkeys.c:180 +msgid " Emacs key: " +msgstr "Phím Emacs: " + +#: edit/editkeys.c:194 edit/editkeys.c:225 +msgid " Execute Macro " +msgstr "Thực hiện Macro " + +#: edit/editkeys.c:217 +msgid " Insert Literal " +msgstr " Chèn văn bản thuần túy " + +#: edit/editkeys.c:218 +msgid " Press any key: " +msgstr " Nhấn phím bất kỳ: " + +#: edit/editlock.c:148 +#, c-format +msgid "" +"File \"%s\" is already being edited\n" +"User: %s\n" +"Process ID: %d" +msgstr "" +"Tập tin \"%s\" đang được soạn thảo\n" +"Ngưòi dùng: %s\n" +"ID tiến trình: %d" + +#: edit/editlock.c:153 +msgid "File locked" +msgstr "Tập tin bị khóa" + +#: edit/editlock.c:153 +msgid "&Grab lock" +msgstr "&Chiếm đoạt khóa" + +#: edit/editlock.c:154 +msgid "&Ignore lock" +msgstr "&Lời đi khóa" + +#: edit/editmenu.c:55 +msgid " About " +msgstr " Về chương trình " + +#: edit/editmenu.c:56 +msgid "" +"\n" +" Cooledit v3.11.5\n" +"\n" +" Copyright (C) 1996 the Free Software Foundation\n" +"\n" +" A user friendly text editor written\n" +" for the Midnight Commander.\n" +msgstr "" +"\n" +" Cooledit v3.11.5\n" +"\n" +" Copyright (C) 1996 the Free Software Foundation\n" +"\n" +" Trình soạn thảo với giao diện người dùng thân thiện.\n" +" Được viết cho Midnight Commander.\n" + +#: edit/editmenu.c:283 edit/editmenu.c:301 +msgid "&Open file..." +msgstr "&Mở tập tin..." + +#: edit/editmenu.c:284 +msgid "&New C-n" +msgstr "&Tập tin mới C-n" + +#: edit/editmenu.c:286 edit/editmenu.c:304 +msgid "&Save F2" +msgstr "&Ghi nhớ F2" + +#: edit/editmenu.c:287 edit/editmenu.c:305 +msgid "Save &as... F12" +msgstr "Ghi &như... F12" + +#: edit/editmenu.c:289 edit/editmenu.c:307 +msgid "&Insert file... F15" +msgstr "&Chèn tập tin... F15" + +#: edit/editmenu.c:290 +msgid "Copy to &file... C-f" +msgstr "Ché&p vào tập tin... C-f" + +#: edit/editmenu.c:292 edit/editmenu.c:310 +msgid "&User menu... F11" +msgstr "Trình đơn người &dùng... F11" + +#: edit/editmenu.c:294 edit/editmenu.c:312 +msgid "A&bout... " +msgstr "&Về chương trình... " + +#: edit/editmenu.c:296 edit/editmenu.c:314 +msgid "&Quit F10" +msgstr "T&hoát F10" + +#: edit/editmenu.c:302 +msgid "&New C-x k" +msgstr "&Tập tin mới C-x k" + +#: edit/editmenu.c:308 +msgid "Copy to &file... " +msgstr "S&ao chép vào tập tin... " + +#: edit/editmenu.c:319 +msgid "&Toggle Mark F3" +msgstr "&Bật/tắt bôi đen F3" + +#: edit/editmenu.c:320 +msgid "&Mark Columns S-F3" +msgstr "Bôi đen &cột S-F3" + +#: edit/editmenu.c:322 +msgid "Toggle &ins/overw Ins" +msgstr "Chế độ chèn/&thay thế Ins" + +#: edit/editmenu.c:324 +msgid "&Copy F5" +msgstr "&Sao chép F5" + +#: edit/editmenu.c:325 +msgid "&Move F6" +msgstr "&Di chuyển F6" + +#: edit/editmenu.c:326 +msgid "&Delete F8" +msgstr "&Xóa F8" + +#: edit/editmenu.c:328 +msgid "&Undo C-u" +msgstr "&Hủy bước C-u" + +#: edit/editmenu.c:330 +msgid "&Beginning C-PgUp" +msgstr "Đầ&u tập tin C-PgUp" + +#: edit/editmenu.c:331 +msgid "&End C-PgDn" +msgstr "Cuố&i tập tin C-PgDn" + +#: edit/editmenu.c:338 +msgid "&Search... F7" +msgstr "Tìm &kiếm... F7" + +#: edit/editmenu.c:339 +msgid "Search &again F17" +msgstr "&Tìm kiếm lại lần nữa F17" + +#: edit/editmenu.c:340 +msgid "&Replace... F4" +msgstr "Th&ay thế... F4" + +#: edit/editmenu.c:347 edit/editmenu.c:371 +msgid "&Go to line... M-l" +msgstr "&Chuyển tới dòng... M-l" + +#: edit/editmenu.c:348 edit/editmenu.c:372 +msgid "Go to matching &bracket M-b" +msgstr "Chuyển &tới dấu ngoặc tạo cặp M-b" + +#: edit/editmenu.c:350 edit/editmenu.c:374 +msgid "Insert &literal... C-q" +msgstr "Chèn &văn bản thuần túy... C-q" + +#: edit/editmenu.c:352 edit/editmenu.c:376 +msgid "&Refresh screen C-l" +msgstr "&Làm mới màn hình C-l" + +#: edit/editmenu.c:354 edit/editmenu.c:378 +msgid "&Start record macro C-r" +msgstr "&Bắt đầu ghi macro C-r" + +#: edit/editmenu.c:355 edit/editmenu.c:379 +msgid "&Finish record macro... C-r" +msgstr "&Kết thúc ghi macro... C-r" + +#: edit/editmenu.c:356 +msgid "&Execute macro... C-a, KEY" +msgstr "Chạy ¯o... C-a, KEY" + +#: edit/editmenu.c:357 edit/editmenu.c:381 +msgid "Delete macr&o... " +msgstr "&Xóa macro... " + +#: edit/editmenu.c:359 edit/editmenu.c:383 +msgid "Insert &date/time " +msgstr "Chèn &ngày/giờ " + +#: edit/editmenu.c:361 edit/editmenu.c:385 +msgid "Format p&aragraph M-p" +msgstr "Định &dạng đoạn văn M-p" + +#: edit/editmenu.c:362 +msgid "'ispell' s&pell check C-p" +msgstr "Kiểm tra chính tả '&ispell' C-p" + +#: edit/editmenu.c:363 edit/editmenu.c:387 +msgid "Sor&t... M-t" +msgstr "&Sắp xếp... M-t" + +#: edit/editmenu.c:364 edit/editmenu.c:388 +msgid "Paste o&utput of... M-u" +msgstr "Dán &kết quả của lệnh... M-u" + +#: edit/editmenu.c:365 edit/editmenu.c:389 +msgid "E&xternal Formatter F19" +msgstr "T&rình định dạng ngoài F19" + +#: edit/editmenu.c:366 edit/editmenu.c:390 +msgid "&Mail... " +msgstr "T&hư điện tử... " + +#: edit/editmenu.c:380 +msgid "&Execute macro... C-x e, KEY" +msgstr "Thực hiện ¯o... C-x e, KEY" + +#: edit/editmenu.c:386 +msgid "'ispell' s&pell check M-$" +msgstr "Kiểm tra chính tả '&ispell' M-$" + +#: edit/editmenu.c:395 +msgid "&General... " +msgstr "Ch&ung... " + +#: edit/editmenu.c:396 +msgid "&Save mode..." +msgstr "&Chế độ ghi nhớ..." + +#: edit/editmenu.c:397 src/main.c:909 +msgid "learn &Keys..." +msgstr "&Tạo phím tắt... " + +#: edit/editmenu.c:408 edit/editmenu.c:422 src/chmod.c:146 src/chown.c:119 +msgid " File " +msgstr " Tập tin " + +#: edit/editmenu.c:410 edit/editmenu.c:424 +msgid " Edit " +msgstr " Soạn thảo " + +#: edit/editmenu.c:412 edit/editmenu.c:426 +msgid " Sear/Repl " +msgstr " Tìm kiếm/Thay thế " + +#: edit/editmenu.c:414 edit/editmenu.c:428 +msgid " Command " +msgstr " Câu lệnh " + +#: edit/editmenu.c:416 edit/editmenu.c:430 +msgid " Options " +msgstr " Tùy chọn " + +#: edit/editoptions.c:36 +msgid "Intuitive" +msgstr "T&rực giác" + +#: edit/editoptions.c:36 +msgid "Emacs" +msgstr "&Emacs" + +#: edit/editoptions.c:39 +msgid "None" +msgstr "&Không" + +#: edit/editoptions.c:39 +msgid "Dynamic paragraphing" +msgstr "Định &dạng đoạn văn động" + +#: edit/editoptions.c:39 +msgid "Type writer wrap" +msgstr "Tự độ&ng chuyển dòng" + +#: edit/editoptions.c:75 +msgid "Word wrap line length: " +msgstr "Vị trí chuyển dòng: " + +#: edit/editoptions.c:81 +msgid "Tab spacing: " +msgstr "Độ rộng tab: " + +#: edit/editoptions.c:88 +msgid "Synta&x highlighting" +msgstr "&Chiếu sáng cú pháp" + +#: edit/editoptions.c:91 +msgid "Save file &position" +msgstr "&Ghi nhớ vị trí trong tập tin" + +#: edit/editoptions.c:94 +msgid "Confir&m before saving" +msgstr "&Hỏi lại trước khi ghi nhớ" + +#: edit/editoptions.c:97 +msgid "Fill tabs with &spaces" +msgstr "&Làm đầy tab bằng khoảng trắng" + +#: edit/editoptions.c:100 +msgid "&Return does autoindent" +msgstr "&Enter tự động thụt dòng" + +#: edit/editoptions.c:103 +msgid "&Backspace through tabs" +msgstr "&Backpace xóa hết tab" + +#: edit/editoptions.c:106 +msgid "&Fake half tabs" +msgstr "&Tạo một nửa tab" + +#: edit/editoptions.c:112 +msgid "Wrap mode" +msgstr "Chế độ chuyển dòng" + +#: edit/editoptions.c:119 +msgid "Key emulation" +msgstr "Giả tạo phím" + +#: edit/editoptions.c:124 +msgid " Editor options " +msgstr " Cấu hình trình soạn thảo " + +#: edit/editwidget.c:287 src/help.c:793 src/help.c:814 src/main.c:1205 +#: src/screen.c:2184 src/tree.c:970 src/view.c:2213 +msgid "Help" +msgstr "Giúpđỡ" + +#: edit/editwidget.c:289 +msgid "Mark" +msgstr "Bôiđen" + +#: edit/editwidget.c:290 +msgid "Replac" +msgstr "Thayth" + +#: edit/editwidget.c:291 src/file.c:803 src/screen.c:2188 src/tree.c:975 +msgid "Copy" +msgstr "Cópi " + +#: edit/editwidget.c:292 +msgid "Move" +msgstr "Chuyển" + +#: edit/editwidget.c:294 src/screen.c:2191 +msgid "Delete" +msgstr "Xóa " + +#: edit/editwidget.c:295 src/main.c:1207 +msgid "PullDn" +msgstr "GọiTĐ " + +#: edit/syntax.c:1100 edit/syntax.c:1107 +msgid " Load syntax file " +msgstr " Nạp tập tin cú pháp " + +#: edit/syntax.c:1101 src/help.c:764 src/user.c:711 +#, c-format +msgid "" +" Cannot open file %s \n" +" %s " +msgstr "" +" Không mở được tập tin %s \n" +" %s " + +#: edit/syntax.c:1108 +#, c-format +msgid " Error in file %s on line %d " +msgstr " Lỗi trong tập tin %s trên dòng %d " + +#: src/achown.c:69 src/chmod.c:97 src/chown.c:73 +msgid "&Set" +msgstr "Đồ&ng ý" + +#: src/achown.c:70 +msgid "S&kip" +msgstr "&Bỏ qua" + +#: src/achown.c:71 src/chmod.c:101 src/chown.c:76 +msgid "Set &all" +msgstr "Đặt &tất cả" + +#: src/achown.c:250 src/achown.c:338 src/achown.c:345 +msgid "owner" +msgstr "sở hữu" + +#: src/achown.c:250 src/achown.c:340 src/achown.c:347 +msgid "group" +msgstr "nhóm" + +#: src/achown.c:342 +msgid "other" +msgstr "khác" + +#: src/achown.c:350 +msgid "On" +msgstr "Trên" + +#: src/achown.c:352 +msgid "Flag" +msgstr "Cờ" + +#: src/achown.c:354 +msgid "Mode" +msgstr "Chếđộ" + +#: src/achown.c:358 +#, c-format +msgid "%6d of %d" +msgstr "%6d của %d" + +#: src/achown.c:549 +msgid " Chown advanced command " +msgstr " Câu lệnh chown mở rộng" + +#: src/achown.c:607 src/achown.c:623 src/achown.c:669 src/chmod.c:241 +#: src/chmod.c:311 +#, c-format +msgid "" +" Cannot chmod \"%s\" \n" +" %s " +msgstr "" +" Không chmod được \"%s\" \n" +" %s " + +#: src/achown.c:612 src/achown.c:627 src/achown.c:673 src/chown.c:214 +#: src/chown.c:322 +#, c-format +msgid "" +" Cannot chown \"%s\" \n" +" %s " +msgstr "" +" Không thay thế được chủ sở hữu \"%s\" \n" +" %s " + +#: src/background.c:205 src/file.c:2145 +msgid " Background process error " +msgstr " Lỗi của tiến trình nền sau " + +#: src/background.c:211 +msgid " Unknown error in child " +msgstr " Lỗi không rõ trong tiến trình con " + +#: src/background.c:219 +msgid " Child died unexpectedly " +msgstr " Tiến trình con bất đắc kỳ tử " + +#: src/background.c:226 +msgid " Background protocol error " +msgstr " Lỗi giao thức nền sau " + +#: src/background.c:227 +msgid "" +" Background process sent us a request for more arguments \n" +" than we can handle. \n" +msgstr "" +" Tiến trình nền sau yêu cầu nhiều tham số hơn, \n" +" số chúng ta có thể điều khiển. \n" + +#: src/boxes.c:75 +msgid "&Full file list" +msgstr "&Danh sách đầy đủ" + +#: src/boxes.c:76 +msgid "&Brief file list" +msgstr "&Thu gọn" + +#: src/boxes.c:77 +msgid "&Long file list" +msgstr "&Mở rộng" + +#: src/boxes.c:78 +msgid "&User defined:" +msgstr "&Người dùng tự xác định:" + +#: src/boxes.c:136 +msgid "Listing mode" +msgstr "Dạng danh sách" + +#: src/boxes.c:138 +msgid "user &Mini status" +msgstr "t&Rạng thái mini" + +#: src/boxes.c:278 +msgid "&Reverse" +msgstr "&Ngược lại" + +#: src/boxes.c:279 +msgid "case sensi&tive" +msgstr "tính đến kiể&U chữ" + +#: src/boxes.c:280 +msgid "Sort order" +msgstr "Thứ tự sắp xếp" + +#: src/boxes.c:375 +msgid " confirm &Exit " +msgstr " trước khi th&Oát " + +#: src/boxes.c:377 +msgid " confirm e&Xecute " +msgstr " trước &Khi thực hiện " + +#: src/boxes.c:379 +msgid " confirm o&Verwrite " +msgstr " &Trước khi ghi chèn " + +#: src/boxes.c:381 +msgid " confirm &Delete " +msgstr " hỏi lại trước khi &Xóa " + +#: src/boxes.c:387 src/cmd.c:194 +msgid " Confirmation " +msgstr " Hỏi xác nhận " + +#: src/boxes.c:459 +msgid "Full 8 bits output" +msgstr "Đầu ra 8 bit đầy đủ" + +#: src/boxes.c:459 +msgid "ISO 8859-1" +msgstr "ISO.8859-1" + +#: src/boxes.c:459 +msgid "7 bits" +msgstr "7 bit" + +#: src/boxes.c:466 src/boxes.c:594 +msgid "F&ull 8 bits input" +msgstr "Đầ&u vào 8 bit đầy đủ" + +#: src/boxes.c:474 src/boxes.c:575 +msgid " Display bits " +msgstr " Ký tự hiển thị " + +#: src/boxes.c:556 src/boxes.c:581 src/selcodepage.c:70 +msgid "Other 8 bit" +msgstr "8 bit khác" + +#: src/boxes.c:578 +msgid "Input / display codepage:" +msgstr "Bảng mã đầu vào / hiển thị:" + +#: src/boxes.c:597 +msgid "&Select" +msgstr "&Lựa chọn" + +#: src/boxes.c:716 +msgid "Use &passive mode" +msgstr "Sử &dụng chế độ thụ động" + +#: src/boxes.c:718 +msgid "&Use ~/.netrc" +msgstr "&Sử dụng ~/.netrc" + +#: src/boxes.c:722 +msgid "&Always use ftp proxy" +msgstr "&Luôn luôn sử dụng ftp proxy" + +#: src/boxes.c:724 +msgid "sec" +msgstr "giây" + +#: src/boxes.c:728 +msgid "ftpfs directory cache timeout:" +msgstr "Thời gian chờ của cache thư mục ftp:" + +#: src/boxes.c:732 +msgid "ftp anonymous password:" +msgstr "Mật khẩu ftp nặc danh:" + +#: src/boxes.c:739 +msgid "Timeout for freeing VFSs:" +msgstr "Thời gian chờ giải phóng VFS:" + +#: src/boxes.c:745 +msgid " Virtual File System Setting " +msgstr " Thiết lập hệ thống tập tin ảo " + +#: src/boxes.c:799 +msgid "Quick cd" +msgstr "cd nhanh" + +#: src/boxes.c:802 +msgid "cd" +msgstr "cd" + +#: src/boxes.c:837 +msgid "Symbolic link filename:" +msgstr "Tên của liên kết mềm:" + +#: src/boxes.c:841 +msgid "Existing filename (filename symlink will point to):" +msgstr "Tên tập tin đã có (liên kết mềm sẽ chỉ đến):" + +#: src/boxes.c:848 +msgid "Symbolic link" +msgstr "Liên kết mềm" + +#: src/boxes.c:881 +msgid "Running " +msgstr "Đang chạy " + +#: src/boxes.c:882 src/find.c:721 +msgid "Stopped" +msgstr "Đã dừng" + +#: src/boxes.c:942 +msgid "&Stop" +msgstr "&Dừng" + +#: src/boxes.c:943 +msgid "&Resume" +msgstr "&Phục hồi" + +#: src/boxes.c:944 +msgid "&Kill" +msgstr "&Diệt" + +#: src/boxes.c:981 +msgid "Background Jobs" +msgstr " Công việc nền sau" + +#: src/boxes.c:1012 +msgid "Domain:" +msgstr "Miền (domain):" + +#: src/boxes.c:1012 +msgid "Username:" +msgstr "Tên người dùng:" + +#: src/boxes.c:1012 +msgid "Password:" +msgstr "Mật khẩu:" + +#: src/boxes.c:1063 +#, c-format +msgid "Password for \\\\%s\\%s" +msgstr "Mật khẩu cho \\\\%s\\%s" + +#: src/charsets.c:51 vfs/extfs.c:1260 vfs/sfs.c:318 +#, c-format +msgid "Warning: file %s not found\n" +msgstr "Cảnh báo: không tìm thấy tập tin %s\n" + +#: src/charsets.c:198 src/charsets.c:212 +#, c-format +msgid "Cannot translate from %s to %s" +msgstr "Không chuyển được bảng mã từ %s thành %s" + +#: src/chmod.c:77 +msgid "execute/search by others" +msgstr "người khác có quyền chạy/tìm" + +#: src/chmod.c:78 +msgid "write by others" +msgstr "người khác có quyền ghi nhớ" + +#: src/chmod.c:79 +msgid "read by others" +msgstr "người khác có quyền đọc" + +#: src/chmod.c:80 +msgid "execute/search by group" +msgstr "nhóm có quyền chạy/tìm kiếm" + +#: src/chmod.c:81 +msgid "write by group" +msgstr "nhóm có quyền ghi nhớ" + +#: src/chmod.c:82 +msgid "read by group" +msgstr "nhóm có quyền đọc" + +#: src/chmod.c:83 +msgid "execute/search by owner" +msgstr "chủ sở hữu có quyền chạy/tìm" + +#: src/chmod.c:84 +msgid "write by owner" +msgstr "chủ sở hữu có quyền ghi nhớ" + +#: src/chmod.c:85 +msgid "read by owner" +msgstr "chủ sở hữu có quyền đọc" + +#: src/chmod.c:86 +msgid "sticky bit" +msgstr "bit dính (sticky)" + +#: src/chmod.c:87 +msgid "set group ID on execution" +msgstr "đặt ID nhóm khi chạy" + +#: src/chmod.c:88 +msgid "set user ID on execution" +msgstr "đặt ID người dùng khi chạy" + +#: src/chmod.c:98 +msgid "C&lear marked" +msgstr "&Xóa đánh dấu" + +#: src/chmod.c:99 +msgid "S&et marked" +msgstr "Đá&nh dấu" + +#: src/chmod.c:100 +msgid "&Marked all" +msgstr "Đánh &dấu tất cả" + +#: src/chmod.c:124 src/screen.c:405 +msgid "Name" +msgstr "Tên" + +#: src/chmod.c:126 +msgid "Permissions (Octal)" +msgstr "Quyền hạn (Hệ tám)" + +#: src/chmod.c:128 +msgid "Owner name" +msgstr "Tên chủ sở hữu" + +#: src/chmod.c:130 +msgid "Group name" +msgstr "Tên nhóm" + +#: src/chmod.c:133 +msgid "Use SPACE to change" +msgstr "Dùng PHÍM TRẮNG để thay đổi" + +#: src/chmod.c:135 +msgid "an option, ARROW KEYS" +msgstr "tùy chọn, PHÍM MŨI TÊN" + +#: src/chmod.c:137 +msgid "to move between options" +msgstr "để di chuyển giữa các tùy chọn" + +#: src/chmod.c:139 +msgid "and T or INS to mark" +msgstr "và T hoặc INS để đánh dấu" + +#: src/chmod.c:144 src/chown.c:111 +msgid " Permission " +msgstr " Quyền truy cập " + +#: src/chmod.c:196 +msgid "Chmod command" +msgstr " Câu lệnh chmod " + +#: src/chown.c:74 +msgid "Set &users" +msgstr "Đặt &người dùng" + +#: src/chown.c:75 +msgid "Set &groups" +msgstr "Đặt &nhóm" + +#: src/chown.c:103 +msgid " Name " +msgstr " Tên " + +#: src/chown.c:105 +msgid " Owner name " +msgstr " Tên chủ sở hữu " + +#: src/chown.c:107 src/chown.c:117 +msgid " Group name " +msgstr " Tên nhóm " + +#: src/chown.c:109 +msgid " Size " +msgstr " Kích thước " + +#: src/chown.c:115 +msgid " User name " +msgstr " Tên người dùng " + +#: src/chown.c:158 +msgid " Chown command " +msgstr " Câu lệnh chown " + +#: src/chown.c:178 +msgid "" +msgstr "" + +#: src/chown.c:179 +msgid "" +msgstr "" + +#: src/cmd.c:194 +msgid "Files tagged, want to cd?" +msgstr "Đã đánh dấu các tập tin, chuyển thư mục?" + +#: src/cmd.c:200 src/cmd.c:670 src/cmd.c:727 src/main.c:681 src/screen.c:1933 +msgid "Cannot change directory" +msgstr "Không thay đổi được thư mục" + +#: src/cmd.c:233 +msgid " View file " +msgstr " Xem tập tin " + +#: src/cmd.c:233 +msgid " Filename:" +msgstr " Tên tập tin:" + +#: src/cmd.c:255 +msgid " Filtered view " +msgstr " Lọc rồi xem " + +#: src/cmd.c:256 +msgid " Filter command and arguments:" +msgstr " Lệnh lọc và tham số:" + +#: src/cmd.c:355 +msgid "Create a new Directory" +msgstr "Tạo thư mục mới" + +#: src/cmd.c:356 +msgid " Enter directory name:" +msgstr " Hãy nhập tên thư mục:" + +#: src/cmd.c:428 +msgid " Filter " +msgstr " Đầu lọc " + +#: src/cmd.c:429 +msgid " Set expression for filtering filenames" +msgstr " Đặt biểu thức để lọc tên tập tin (nhấn F1 để xem trợ giúp)" + +#: src/cmd.c:482 +msgid " Select " +msgstr " Chọn " + +#: src/cmd.c:510 src/cmd.c:555 src/find.c:147 +msgid " Malformed regular expression " +msgstr " Biểu thức chính quy không đúng " + +#: src/cmd.c:528 +msgid " Unselect " +msgstr " Bỏ chọn " + +#: src/cmd.c:596 +msgid "Extension file edit" +msgstr "Soạn thảo phần mở rộng tập tin" + +#: src/cmd.c:597 +msgid " Which extension file you want to edit? " +msgstr " Soạn thảo phần mở rộng tập tin nào? " + +#: src/cmd.c:598 src/cmd.c:701 +msgid "&User" +msgstr "&Người dùng" + +#: src/cmd.c:598 src/cmd.c:627 src/cmd.c:701 +msgid "&System Wide" +msgstr "&Hệ thống" + +#: src/cmd.c:624 +msgid " Menu edit " +msgstr " Soạn thảo tập tin trình đơn " + +#: src/cmd.c:625 +msgid " Which menu file do you want to edit? " +msgstr " Soạn thảo tập tin trình đơn nào? " + +#: src/cmd.c:627 +msgid "&Local" +msgstr "&Nội bộ máy" + +#: src/cmd.c:627 +msgid "&Home" +msgstr "&Cá nhân" + +#: src/cmd.c:699 +msgid "Syntax file edit" +msgstr "Soạn thảo tập tin cú pháp" + +#: src/cmd.c:700 +msgid " Which syntax file you want to edit? " +msgstr " Soạn thảo tập tin cú pháp nào? " + +#: src/cmd.c:854 +msgid " Compare directories " +msgstr " So sánh thư mục " + +#: src/cmd.c:855 +msgid " Select compare method: " +msgstr " Chọn phương pháp so sánh: " + +#: src/cmd.c:855 +msgid "&Quick" +msgstr "&Nhanh" + +#: src/cmd.c:856 +msgid "&Size only" +msgstr "&Chỉ theo kích thước" + +#: src/cmd.c:856 +msgid "&Thorough" +msgstr "&Theo từng byte" + +#: src/cmd.c:869 +msgid " Both panels should be in the listing mode to use this command " +msgstr "Để thực hiện câu lệnh này cả hai bảng phải ở trong chế độ danh sách " + +#: src/cmd.c:885 +msgid " The command history is empty " +msgstr " Lịch sử dòng lệnh rỗng " + +#: src/cmd.c:889 +msgid " Command history " +msgstr " Lịch sử dòng lệnh " + +#: src/cmd.c:925 +msgid "" +" Not an xterm or Linux console; \n" +" the panels cannot be toggled. " +msgstr "" +" Đây không phải là xterm hay kênh giao tác Linux; \n" +" bảng sẽ không thể bị tắt. " + +#: src/cmd.c:939 +#, c-format +msgid "Link %s to:" +msgstr "Tạo liên kết tới %s:" + +#: src/cmd.c:940 +msgid " Link " +msgstr " Liên kết " + +#: src/cmd.c:950 +#, c-format +msgid " link: %s " +msgstr " liên kết: %s " + +#: src/cmd.c:978 +#, c-format +msgid " symlink: %s " +msgstr " liên kết mềm: %s " + +#: src/cmd.c:1012 +#, c-format +msgid " Symlink `%s' points to: " +msgstr " Liên kết mềm %s chỉ tới: " + +#: src/cmd.c:1017 +msgid " Edit symlink " +msgstr " Sửa liên kết mềm " + +#: src/cmd.c:1022 +#, c-format +msgid " edit symlink, unable to remove %s: %s " +msgstr " sửa liên kết mềm, không thể xóa %s: %s " + +#: src/cmd.c:1026 +#, c-format +msgid " edit symlink: %s " +msgstr " sửa liên kết mềm: %s " + +#: src/cmd.c:1037 +#, c-format +msgid "`%s' is not a symbolic link" +msgstr "`%s' không phải là một liên kết mềm" + +#: src/cmd.c:1155 +#, c-format +msgid " Cannot chdir to %s " +msgstr " Không thể chdir vào %s " + +#: src/cmd.c:1164 +msgid " Enter machine name (F1 for details): " +msgstr " Hãy nhập tên máy (nhấn F1 để biết chi tiết): " + +#: src/cmd.c:1169 src/widget.c:1051 +msgid " Link to a remote machine " +msgstr " Kiết nối tới máy ở xa " + +#: src/cmd.c:1176 src/widget.c:1052 +msgid " FTP to machine " +msgstr " FTP tới máy ở xa " + +#: src/cmd.c:1182 +msgid " Shell link to machine " +msgstr " Kết nối shell tới máy ở xa" + +#: src/cmd.c:1189 src/widget.c:1053 +msgid " SMB link to machine " +msgstr " Kết nối SMB tới máy ở xa" + +#: src/cmd.c:1198 +msgid " Undelete files on an ext2 file system " +msgstr " Phục hồi tập tin trên hệ thống tập tin ext2 sau khi xóa " + +#: src/cmd.c:1199 +msgid "" +" Enter device (without /dev/) to undelete\n" +" files on: (F1 for details)" +msgstr "" +" Nhập tên thiết bị (không có /dev/), để\n" +" phục hồi tập tin của nó: (nhấn F1 để biết chi tiết)" + +#: src/cmd.c:1249 +msgid " Setup saved to ~/" +msgstr " Tham số ghi nhớ trong ~/" + +#: src/cmd.c:1251 +msgid " Setup " +msgstr " Cấu hình " + +#: src/command.c:177 src/screen.c:2174 src/tree.c:823 +#, c-format +msgid "" +" Cannot chdir to \"%s\" \n" +" %s " +msgstr "" +" Không chdir được tới \"%s\" \n" +" %s " + +#: src/command.c:210 src/user.c:694 +msgid " Cannot execute commands on non-local filesystems" +msgstr " Chỉ có thể thực hiện câu lệnh trên hệ thống tập tin nội bộ" + +#: src/command.c:219 src/execute.c:183 +msgid " The shell is already running a command " +msgstr " shell đang chạy một câu lệnh" + +#: src/dir.c:49 +msgid "&Unsorted" +msgstr "không &Sắp xếp" + +#: src/dir.c:50 +msgid "&Name" +msgstr "th&Eo tên" + +#: src/dir.c:51 +msgid "&Extension" +msgstr "&Phần mở rộng" + +#: src/dir.c:52 +msgid "&Modify time" +msgstr "&Thời gian sửa đổi" + +#: src/dir.c:53 +msgid "&Access time" +msgstr "thời &Gian truy cập" + +#: src/dir.c:54 +msgid "&Change time" +msgstr "thời gi&An thay đổi" + +#: src/dir.c:55 +msgid "&Size" +msgstr "&Kích thước" + +#: src/dir.c:56 +msgid "&Inode" +msgstr "&Chỉ mục inode" + +#: src/dir.c:59 +msgid "&Type" +msgstr "&Loại" + +#: src/dir.c:60 +msgid "&Links" +msgstr "&Liên kết" + +#: src/dir.c:61 +msgid "N&GID" +msgstr "N&GID" + +#: src/dir.c:62 +msgid "N&UID" +msgstr "N&UID" + +#: src/dir.c:63 +msgid "&Owner" +msgstr "&Chủ sở hữu" + +#: src/dir.c:64 +msgid "&Group" +msgstr "&Nhóm" + +#: src/dir.c:475 src/dir.c:577 +msgid "Cannot read directory contents" +msgstr "Không đọc được nội dung thư mục" + +#: src/execute.c:133 src/utilunix.c:380 +msgid "Press any key to continue..." +msgstr "Để tiếp tục nhấn phím bất kỳ..." + +#: src/execute.c:235 +msgid "Type `exit' to return to the Midnight Commander" +msgstr "Hãy gõ \"exit\" để quay trở lại Midnight Commander" + +#: src/execute.c:343 +#, c-format +msgid " Cannot fetch a local copy of %s " +msgstr " Không thể lấy được bản sao nội bộ của %s " + +#: src/ext.c:106 src/user.c:566 +#, c-format +msgid "" +" Cannot create temporary command file \n" +" %s " +msgstr "" +" Không tạo được tập tin câu lệnh tạm thời\n" +" %s " + +#: src/ext.c:119 src/user.c:589 +msgid " Parameter " +msgstr " Tham số " + +#: src/ext.c:462 src/ext.c:481 +msgid " file error " +msgstr " lỗi tập tin " + +#: src/ext.c:464 src/ext.c:483 +msgid "Format of the " +msgstr "Định dạng của " + +#: src/ext.c:465 +msgid "" +"mc.ext file has changed\n" +"with version 3.0. It seems that installation\n" +"failed. Please fetch a fresh new copy from the\n" +"Midnight Commander package." +msgstr "" +"Tập tin mc.ext đã thay đổi\n" +"từ phiên bản 3.0. Rất có thể có sự cố khi cài đặt.\n" +"Xin hãy lấy bản sao mới nhất từ gói \n" +"Midnight Commander." + +#: src/ext.c:484 +msgid "" +" file has changed\n" +"with version 3.0. You may want either to\n" +"copy it from " +msgstr "" +" tập tin đã thay đổi\n" +"trong phiên bản 3.0. Có thể nên sao\n" +"chép nó từ " + +#: src/ext.c:487 +msgid "" +"mc.ext or use that\n" +"file as an example of how to write it.\n" +msgstr "" +"mc.ext, hoặc sử dụng tập tin này làm\n" +"ví dụ để biết cách viết.\n" + +#: src/ext.c:490 +msgid "mc.ext will be used for this moment." +msgstr "mc.ext sẽ được sử dụng trong thời điểm này." + +#: src/file.c:122 src/tree.c:593 +msgid " Copy " +msgstr " Sao chép " + +#: src/file.c:123 src/tree.c:634 +msgid " Move " +msgstr " Di chuyển " + +#: src/file.c:124 src/tree.c:708 +msgid " Delete " +msgstr " Xóa " + +#: src/file.c:217 +msgid " Invalid target mask " +msgstr " Dấu hiệu đích đến không đúng " + +#: src/file.c:316 +msgid " Cannot make the hardlink " +msgstr " Không thể tạo liên kết cứng " + +#: src/file.c:359 +#, c-format +msgid "" +" Cannot read source link \"%s\" \n" +" %s " +msgstr "" +" Không thể đọc liên kết nguồn \"%s\" \n" +" %s " + +#: src/file.c:370 +msgid "" +" Cannot make stable symlinks across non-local filesystems: \n" +"\n" +" Option Stable Symlinks will be disabled " +msgstr "" +" Không tạo được liên kết mềm bền vững giữa các hệ thống tập tin không phải nội bộ:\n" +"\n" +" Tùy chọn \"Liên kết mềm Bền vững\" sẽ bị tắt " + +#: src/file.c:419 +#, c-format +msgid "" +" Cannot create target symlink \"%s\" \n" +" %s " +msgstr "" +" Khônt tạo được liên kết mềm đích \"%s\" \n" +" %s " + +#: src/file.c:493 +#, c-format +msgid "" +" Cannot overwrite directory \"%s\" \n" +" %s " +msgstr "" +" Không thể ghi chèn lên thư mục \"%s\" \n" +" %s " + +#: src/file.c:504 +#, c-format +msgid "" +" Cannot stat source file \"%s\" \n" +" %s " +msgstr "" +" Không lấy được tính chất (stat) của tập tin nguồn \"%s\" \n" +" %s " + +#: src/file.c:514 src/file.c:1115 +#, c-format +msgid " `%s' and `%s' are the same file " +msgstr " `%s' và `%s' là một tập tin " + +#: src/file.c:552 +#, c-format +msgid "" +" Cannot create special file \"%s\" \n" +" %s " +msgstr "" +" Không tạo được tập tin đặc biệt \"%s\" \n" +" %s " + +#: src/file.c:564 src/file.c:813 +#, c-format +msgid "" +" Cannot chown target file \"%s\" \n" +" %s " +msgstr "" +" Không thay đổi được chủ sở hữu của tập tin đích đến \"%s\" \n" +" %s " + +#: src/file.c:575 src/file.c:830 +#, c-format +msgid "" +" Cannot chmod target file \"%s\" \n" +" %s " +msgstr "" +" Không thay đổi được quyền hạn (chmod) của tập tin đích đến \"%s\" \n" +" %s " + +#: src/file.c:589 +#, c-format +msgid "" +" Cannot open source file \"%s\" \n" +" %s " +msgstr "" +" Không mở được tập tin nguồn \"%s\" \n" +" %s " + +#: src/file.c:600 +msgid " Reget failed, about to overwrite file " +msgstr " Lấy phần còn lại của tập tin không thành công, tập tin sẽ bị ghi đè " + +#: src/file.c:607 +#, c-format +msgid "" +" Cannot fstat source file \"%s\" \n" +" %s " +msgstr "" +" Không lấy được tính chất (fstat) tập tin nguồn \"%s\" \n" +" %s " + +#: src/file.c:631 +#, c-format +msgid "" +" Cannot create target file \"%s\" \n" +" %s " +msgstr "" +" Không tạo được tập tin đích \"%s\" \n" +" %s " + +#: src/file.c:646 +#, c-format +msgid "" +" Cannot fstat target file \"%s\" \n" +" %s " +msgstr "" +" Không lấy được tính chất (fstat) tập tin đích \"%s\" \n" +" %s " + +#: src/file.c:680 +#, c-format +msgid "" +" Cannot read source file \"%s\" \n" +" %s " +msgstr "" +" Không đọc được tập tin nguồn \"%s\" \n" +" %s " + +#: src/file.c:715 +#, c-format +msgid "" +" Cannot write target file \"%s\" \n" +" %s " +msgstr "" +" Không ghi nhớ được tập tin nguồn \"%s\" \n" +" %s " + +#: src/file.c:733 +msgid "(stalled)" +msgstr "(bị nhốt)" + +#: src/file.c:780 +#, c-format +msgid "" +" Cannot close source file \"%s\" \n" +" %s " +msgstr "" +" Không đóng được tập tin nguồn \"%s\" \n" +" %s " + +#: src/file.c:791 +#, c-format +msgid "" +" Cannot close target file \"%s\" \n" +" %s " +msgstr "" +" Không đóng được tập tin đính \"%s\" \n" +" %s " + +#: src/file.c:804 +msgid "Incomplete file was retrieved. Keep it?" +msgstr "Nhận được tập tin không đầy đủ. Giữ tập tin?" + +#: src/file.c:805 +msgid "&Delete" +msgstr "&Xóa" + +#: src/file.c:805 +msgid "&Keep" +msgstr "&Giữ" + +#: src/file.c:873 +#, c-format +msgid "" +" Cannot stat source directory \"%s\" \n" +" %s " +msgstr "" +" Không lấy được thông tin (stat) thư mục nguồn \"%s\" \n" +" %s " + +#: src/file.c:900 +#, c-format +msgid "" +" Source directory \"%s\" is not a directory \n" +" %s " +msgstr "" +" Thư mục nguồn \"%s\" không phải là một thư mục \n" +" %s " + +#: src/file.c:910 +#, c-format +msgid "" +" Cannot copy cyclic symbolic link \n" +" `%s' " +msgstr "" +" Không sao chép được liên kết mềm vòng lặp \n" +" `%s' " + +#: src/file.c:945 src/file.c:1985 src/tree.c:648 +#, c-format +msgid "" +" Destination \"%s\" must be a directory \n" +" %s " +msgstr "" +" Nơi đến \"%s\" phải là một thư mục \n" +" %s " + +#: src/file.c:975 +#, c-format +msgid "" +" Cannot create target directory \"%s\" \n" +" %s " +msgstr "" +" Không tạo được thư mục đích đến \"%s\" \n" +" %s " + +#: src/file.c:994 +#, c-format +msgid "" +" Cannot chown target directory \"%s\" \n" +" %s " +msgstr "" +" Không thay đổi được chủ sở hữu (chown) của thư mục đích đến \"%s\" \n" +" %s " + +#: src/file.c:1096 +#, c-format +msgid "" +" Cannot stat file \"%s\" \n" +" %s " +msgstr "" +" Không nhận được tính chất (stat) của tập tin \"%s\" \n" +" %s " + +#: src/file.c:1122 +#, c-format +msgid " Cannot overwrite directory `%s' " +msgstr " Không thể ghi đè lên thư mục `%s' " + +#: src/file.c:1157 +#, c-format +msgid "" +" Cannot move file \"%s\" to \"%s\" \n" +" %s " +msgstr "" +" Không thể di chuyển tập tin \"%s\" vào \"%s\" \n" +" %s " + +#: src/file.c:1181 +#, c-format +msgid "" +" Cannot remove file \"%s\" \n" +" %s " +msgstr "" +" Không thể xóa tập tin \"%s\" \n" +" %s " + +#: src/file.c:1233 +#, c-format +msgid " `%s' and `%s' are the same directory " +msgstr " %s và %s - là một thư mục " + +#: src/file.c:1252 +#, c-format +msgid " Cannot overwrite directory \"%s\" %s " +msgstr " Không thể ghi đè lên thư mục \"%s\" %s " + +#: src/file.c:1256 +#, c-format +msgid " Cannot overwrite file \"%s\" %s " +msgstr " Không thể ghi đè tập tin \"%s\" %s " + +#: src/file.c:1282 +#, c-format +msgid "" +" Cannot move directory \"%s\" to \"%s\" \n" +" %s " +msgstr "" +" Không thể di chuyển thư mục \"%s\" vào \"%s\" \n" +" %s " + +#: src/file.c:1352 +#, c-format +msgid "" +" Cannot delete file \"%s\" \n" +" %s " +msgstr "" +" Không thể xóa tập tin \"%s\" \n" +" %s " + +#: src/file.c:1412 src/file.c:1481 src/file.c:1509 +#, c-format +msgid "" +" Cannot remove directory \"%s\" \n" +" %s " +msgstr "" +" Không thể xóa thư mục \"%s\" \n" +" %s " + +#: src/file.c:1657 +msgid "1Copy" +msgstr "1Sao chép" + +#: src/file.c:1657 +msgid "1Move" +msgstr "1Di chuyển" + +#: src/file.c:1657 +msgid "1Delete" +msgstr "1Xóa" + +#: src/file.c:1672 +#, no-c-format +msgid "%o %f \"%s\"%m" +msgstr "%o %f \"%s\"%m" + +# msgfmt warnings/errors must be ignored. mc parse this pattern itself. +#: src/file.c:1674 +#, no-c-format +msgid "%o %d %f%m" +msgstr "%o (%d cái) %f%m" + +#: src/file.c:1676 vfs/fish.c:561 +msgid "file" +msgstr "tập tin" + +#: src/file.c:1676 +msgid "files" +msgstr "các tập tin" + +#: src/file.c:1676 +msgid "directory" +msgstr "thư mục" + +#: src/file.c:1676 +msgid "directories" +msgstr "Các thư mục" + +#: src/file.c:1677 +msgid "files/directories" +msgstr "tập tin/thư mục" + +#: src/file.c:1677 +msgid " with source mask:" +msgstr " với nhãn ban đầu:" + +#: src/file.c:1677 +msgid " to:" +msgstr " vào:" + +#: src/file.c:1821 +msgid " Cannot operate on \"..\"! " +msgstr " Không thể thao tác trên \"..\"! " + +#: src/file.c:1877 +msgid " Sorry, I could not put the job in background " +msgstr " Xin lỗi, không thể đặt công việc nào vào chế độ nền sau " + +#: src/file.c:2147 src/view.c:441 +msgid "&Retry" +msgstr "&Thử lại" + +#: src/file.c:2148 src/file.c:2211 src/filegui.c:207 src/filegui.c:517 +msgid "&Abort" +msgstr "&Dừng" + +#: src/file.c:2200 +msgid "" +"\n" +" Directory not empty. \n" +" Delete it recursively? " +msgstr "" +"\n" +" Thư mục không rỗng. \n" +" Xóa toàn bộ (đệ quy)? " + +#: src/file.c:2202 +msgid "" +"\n" +" Background process: Directory not empty \n" +" Delete it recursively? " +msgstr "" +"\n" +" Tiến trình nền sau: Thư mục không rỗng \n" +" Xóa toàn bộ (đệ quy)? " + +#: src/file.c:2204 +msgid " Delete: " +msgstr " Xóa: " + +#: src/file.c:2210 src/filegui.c:519 +msgid "Non&e" +msgstr "&Không" + +#: src/filegui.c:324 +#, c-format +msgid "ETA %d:%02d.%02d" +msgstr "Còn lại %d:%02d.%02d" + +#: src/filegui.c:347 +#, c-format +msgid "%.2f MB/s" +msgstr "%.2f МB/giây" + +#: src/filegui.c:350 +#, c-format +msgid "%.2f KB/s" +msgstr "%.2f KB/giây" + +#: src/filegui.c:353 +#, c-format +msgid "%ld B/s" +msgstr "%ld B/giây" + +#: src/filegui.c:376 +msgid "File" +msgstr "Tập tin" + +#: src/filegui.c:399 +msgid "Count" +msgstr "Đếm" + +#: src/filegui.c:420 +msgid "Bytes" +msgstr "Byte" + +#: src/filegui.c:453 +msgid "Source" +msgstr "Nguồn" + +#: src/filegui.c:476 +msgid "Target" +msgstr "Đích" + +#: src/filegui.c:498 +msgid "Deleting" +msgstr "Đang xóa" + +#: src/filegui.c:516 +#, c-format +msgid "Target file \"%s\" already exists!" +msgstr "Tập tin đích \"%s\" đã tồn tại!" + +#: src/filegui.c:518 +msgid "If &size differs" +msgstr "&Nếu kích thước khác nhau" + +#: src/filegui.c:520 +msgid "&Update" +msgstr "&Cập nhật" + +#: src/filegui.c:522 +msgid "Overwrite all targets?" +msgstr "Khi đè lên mọi tập tin đích?" + +#: src/filegui.c:523 +msgid "&Reget" +msgstr "&Lấy lại" + +#: src/filegui.c:524 +msgid "A&ppend" +msgstr "&Thêm vào cuối" + +#: src/filegui.c:527 +msgid "Overwrite this target?" +msgstr "Khi đè lên tập tin này?" + +#: src/filegui.c:528 +#, c-format +msgid "Target date: %s, size %d" +msgstr "Thời gian sửa đổi của tập tin đích: %s, kích thước %d" + +#: src/filegui.c:529 +#, c-format +msgid "Source date: %s, size %d" +msgstr "Thời gian sửa đổi của tập tin nguồn: %s, kích thước %d" + +#: src/filegui.c:604 +msgid " File exists " +msgstr " Tập tin tồn tại " + +#: src/filegui.c:606 +msgid " Background process: File exists " +msgstr " Tiến trình nền sau: tập tin tồn tại " + +#: src/filegui.c:728 +msgid "preserve &Attributes" +msgstr "&Ghi nhớ thuộc tính" + +#: src/filegui.c:730 +msgid "follow &Links" +msgstr "đi theo &Liên kết" + +#: src/filegui.c:732 +msgid "to:" +msgstr "vào:" + +#: src/filegui.c:733 +msgid "&Using shell patterns" +msgstr "&Sử dụng mẫu (pattern) của shell" + +#: src/filegui.c:754 +msgid "&Background" +msgstr "&Trong nền sau" + +#: src/filegui.c:764 +msgid "&Stable Symlinks" +msgstr "liên kết &Bền vững" + +#: src/filegui.c:766 +msgid "&Dive into subdir if exists" +msgstr "&Vào thư mục con, nếu có" + +#: src/filegui.c:938 +#, c-format +msgid "" +"Invalid source pattern `%s' \n" +" %s " +msgstr "" +"Mẫu không đúng `%s' \n" +" %s " + +#: src/find.c:99 +msgid "&Suspend" +msgstr "&Hoãn" + +#: src/find.c:100 +msgid "Con&tinue" +msgstr "&Tiếp tục" + +#: src/find.c:101 +msgid "&Chdir" +msgstr "&Chuyển thư mục" + +#: src/find.c:102 +msgid "&Again" +msgstr "&Lặp lại" + +#: src/find.c:103 src/subshell.c:323 +msgid "&Quit" +msgstr "&Thoát" + +#: src/find.c:104 src/panelize.c:69 +msgid "Pane&lize" +msgstr "&Bảng" + +#: src/find.c:105 +msgid "&View - F3" +msgstr "X&em - F3" + +#: src/find.c:106 +msgid "&Edit - F4" +msgstr "&Soạn thảo - F4" + +#: src/find.c:183 +msgid "Start at:" +msgstr "Bắt đầu từ:" + +#: src/find.c:183 +msgid "Filename:" +msgstr "Tên tập tin:" + +#: src/find.c:183 +msgid "Content: " +msgstr "Nội dung: " + +#: src/find.c:184 src/main.c:795 src/main.c:819 +msgid "&Tree" +msgstr "&Cây thư mục" + +#: src/find.c:232 src/find.c:792 +msgid "Find File" +msgstr "Tìm tập tin" + +#: src/find.c:464 +#, c-format +msgid "Grepping in %s" +msgstr "Tìm trong %s" + +#: src/find.c:538 +msgid "Finished" +msgstr "Kết thúc" + +#: src/find.c:565 src/view.c:1594 +#, c-format +msgid "Searching %s" +msgstr "Tìm %s" + +#: src/find.c:721 src/find.c:818 +msgid "Searching" +msgstr "Tìm" + +#: src/help.c:279 +msgid " Help file format error\n" +msgstr " Lỗi định dạng tập tin trợ giúp\n" + +#: src/help.c:318 +msgid " Internal bug: Double start of link area " +msgstr " Lỗi (bug) nội bộ: vùng liên kết có hai đầu " + +#: src/help.c:554 src/help.c:778 +#, c-format +msgid " Cannot find node %s in help file " +msgstr " Không tìm thấy nút %s trong tập tin trợ giúp " + +#: src/help.c:816 +msgid "Index" +msgstr "Chỉ mục" + +#: src/help.c:818 +msgid "Prev" +msgstr "Quay lại" + +#: src/hotlist.c:115 +msgid "&Move" +msgstr "&Di chuyển" + +#: src/hotlist.c:116 src/panelize.c:68 +msgid "&Remove" +msgstr "&Xóa" + +#: src/hotlist.c:117 src/hotlist.c:834 src/hotlist.c:930 +msgid "&Append" +msgstr "&Thêm vào" + +#: src/hotlist.c:118 src/hotlist.c:832 src/hotlist.c:928 +msgid "&Insert" +msgstr "c&Hèn" + +#: src/hotlist.c:119 +msgid "New &Entry" +msgstr "tạo &Mục mới" + +#: src/hotlist.c:120 +msgid "New &Group" +msgstr "&Nhóm mới" + +#: src/hotlist.c:122 +msgid "&Up" +msgstr "&Lên" + +#: src/hotlist.c:123 +msgid "&Add current" +msgstr "&Thêm hiện thời" + +#: src/hotlist.c:125 +msgid "&Refresh" +msgstr "&Làm mới" + +#: src/hotlist.c:126 +msgid "Fr&ee VFSs now" +msgstr "&Giải phóng" + +#: src/hotlist.c:128 +msgid "Change &To" +msgstr "&Chuyển tới" + +#: src/hotlist.c:177 +msgid "Subgroup - press ENTER to see list" +msgstr "Nhóm con - nhấn ENTER để xem danh sách" + +#: src/hotlist.c:609 +msgid "Active VFS directories" +msgstr "Thư mục VFS hoạt động" + +#: src/hotlist.c:612 +msgid "Directory hotlist" +msgstr "Danh sách thư mục thường dùng" + +#: src/hotlist.c:640 +msgid " Directory path " +msgstr " Đường dẫn tới thư mục " + +#: src/hotlist.c:643 src/hotlist.c:692 +msgid " Directory label " +msgstr " Nhãn thư mục" + +#: src/hotlist.c:668 +#, c-format +msgid "Moving %s" +msgstr "Di chuyển %s" + +#: src/hotlist.c:907 +msgid "New hotlist entry" +msgstr " Thêm bản ghi vào tra cứu" + +#: src/hotlist.c:907 +msgid "Directory label" +msgstr " Tên nhãn thư mục" + +#: src/hotlist.c:907 +msgid "Directory path" +msgstr " Đường dẫn tới thư mục" + +#: src/hotlist.c:987 +msgid " New hotlist group " +msgstr " Thêm nhóm vào tra cứu " + +#: src/hotlist.c:987 +msgid "Name of new group" +msgstr " Tên nhóm mới" + +#: src/hotlist.c:1002 +#, c-format +msgid "Label for \"%s\":" +msgstr " Tên nhãn cho \"%s\":" + +#: src/hotlist.c:1006 +msgid " Add to hotlist " +msgstr " Thêm vào tra cứu " + +#: src/hotlist.c:1043 +msgid " Remove: " +msgstr " Xóa: " + +#: src/hotlist.c:1047 +msgid "" +"\n" +" Group not empty.\n" +" Remove it?" +msgstr "" +"\n" +" Nhóm không rỗng.\n" +" Xóa nó?" + +#: src/hotlist.c:1391 +msgid " Top level group " +msgstr "Nhóm cấp độ cao nhất " + +#: src/hotlist.c:1414 +msgid "MC was unable to write ~/" +msgstr "MC không thể ghi nhớ ~/" + +#: src/hotlist.c:1415 +msgid " file, your old hotlist entries were not deleted" +msgstr " tập tin, tra cứu thư mục cũ chưa bị xóa" + +#: src/hotlist.c:1417 +msgid " Hotlist Load " +msgstr " Nạp tra cứu " + +#: src/info.c:74 +#, c-format +msgid "Midnight Commander %s" +msgstr "Midnight Commander %s" + +#: src/info.c:91 +#, c-format +msgid "File: %s" +msgstr "Tập tin: %s" + +#: src/info.c:103 +#, c-format +msgid "Free nodes: %d (%d%%) of %d" +msgstr "Nút tự do: %d (%d%%) trong tổng số %d" + +#: src/info.c:109 +msgid "No node information" +msgstr "Không có thông tin về nút (node)" + +#: src/info.c:117 +#, c-format +msgid "Free space: %s (%d%%) of %s" +msgstr "Chỗ trống: %s (%d%%) của %s" + +#: src/info.c:121 +msgid "No space information" +msgstr "Không có thông tin về khoảng trống" + +#: src/info.c:125 +#, c-format +msgid "Type: %s " +msgstr "Loại: %s " + +#: src/info.c:125 +msgid "non-local vfs" +msgstr "không phải vfs cục bộ" + +#: src/info.c:131 +#, c-format +msgid "Device: %s" +msgstr "Thiết bị: %s" + +#: src/info.c:135 +#, c-format +msgid "Filesystem: %s" +msgstr "Hệ thống tập tin: %s" + +#: src/info.c:140 +#, c-format +msgid "Accessed: %s" +msgstr "Truy cập: %s" + +#: src/info.c:144 +#, c-format +msgid "Modified: %s" +msgstr "Sửa đổi: %s" + +#: src/info.c:148 +#, c-format +msgid "Created: %s" +msgstr "Tạo ra: %s" + +#: src/info.c:163 +#, c-format +msgid "Size: %s" +msgstr "Kích thước: %s" + +#: src/info.c:166 +#, c-format +msgid " (%d block)" +msgstr " (%d khối)" + +#: src/info.c:166 +#, c-format +msgid " (%d blocks)" +msgstr " (%d khối)" + +#: src/info.c:172 +#, c-format +msgid "Owner: %s/%s" +msgstr "Chủ sở hữu: %s/%s" + +#: src/info.c:177 +#, c-format +msgid "Links: %d" +msgstr "Liên kết: %d" + +#: src/info.c:181 +#, c-format +msgid "Mode: %s (%04o)" +msgstr "Quyền hạn: %s (%04o)" + +#: src/info.c:186 +#, c-format +msgid "Location: %Xh:%Xh" +msgstr "Vị trí: %Xh:%Xh" + +#: src/info.c:196 +msgid "File: None" +msgstr "Tập tin: Không có" + +#: src/layout.c:151 +msgid "&Vertical" +msgstr "&Thẳng đứng" + +#: src/layout.c:152 +msgid "&Horizontal" +msgstr "&Nằm ngang" + +#: src/layout.c:162 +msgid "&Xterm window title" +msgstr "tiê&U đề cửa sổ xterm" + +#: src/layout.c:163 +msgid "h&Intbar visible" +msgstr "dòng &Gợi ý" + +#: src/layout.c:164 +msgid "&Keybar visible" +msgstr "&Hiển thị thanh phím tắt" + +#: src/layout.c:165 +msgid "command &Prompt" +msgstr "&Dòng lệnh" + +#: src/layout.c:166 +msgid "show &Mini status" +msgstr "hiện trạng thái m&Ini" + +#: src/layout.c:167 +msgid "menu&Bar visible" +msgstr "thAnh trình đơn" + +#: src/layout.c:168 +msgid "&Equal split" +msgstr "&Kích thước bằng nhau" + +#: src/layout.c:169 +msgid "pe&Rmissions" +msgstr "&Quyền truy cập" + +#: src/layout.c:170 +msgid "&File types" +msgstr "&Loại tập tin" + +#: src/layout.c:350 src/learn.c:59 src/learn.c:174 src/option.c:115 +msgid "&Save" +msgstr "Ghi nhớ &+" + +#: src/layout.c:358 +msgid " Panel split " +msgstr " Chia bảng " + +#: src/layout.c:359 +msgid " Highlight... " +msgstr " Chiếu sáng... " + +#: src/layout.c:360 src/option.c:125 +msgid " Other options " +msgstr " Cấu hình khác " + +#: src/layout.c:361 +msgid "output lines" +msgstr "dòng kết quả" + +#: src/layout.c:423 +msgid "Layout" +msgstr "Vẻ ngoài" + +#: src/learn.c:73 +msgid "Learn keys" +msgstr "Tạo phím tắt" + +#: src/learn.c:79 +msgid " Teach me a key " +msgstr " Dạy tôi một phím " + +#: src/learn.c:80 +#, c-format +msgid "" +"Please press the %s\n" +"and then wait until this message disappears.\n" +"\n" +"Then, press it again to see if OK appears\n" +"next to its button.\n" +"\n" +"If you want to escape, press a single Escape key\n" +"and wait as well." +msgstr "" +"Xin hãy nhấn lên %s\n" +"và đợi cho thông báo này biến mất.\n" +"\n" +"Sau đó hãy nhấn một lần nữa để chắc chắn là ở bên phải\n" +"của tên xuất hiện \"OK\".\n" +"\n" +"Nếu bạn muốn dừng việc dạy phím, thì hãy nhấn\n" +"phím Esc và cũng cần đợi một chút." + +#: src/learn.c:114 +msgid " Cannot accept this key " +msgstr " Không thể chấp nhận phím này " + +#: src/learn.c:115 +#, c-format +msgid " You have entered \"%s\"" +msgstr " Đã nhập vào \"%s\"" + +#. TRANSLATORS: This label appears near learned keys. Keep it short. +#: src/learn.c:164 +msgid "OK" +msgstr "OK" + +#: src/learn.c:172 +msgid "" +"It seems that all your keys already\n" +"work fine. That's great." +msgstr "" +"Có vẻ như tất cả các phím của bạn\n" +"làm việc tốt. Thật là tuyệt." + +#: src/learn.c:174 +msgid "&Discard" +msgstr "&Vứt bỏ" + +#: src/learn.c:179 +msgid "" +"Great! You have a complete terminal database!\n" +"All your keys work well." +msgstr "" +"Tuyệt! Chúng ta có một cơ sở dữ liệu mô tả terminal đầy đủ!\n" +"Tất cả các phím đều làm việc tốt." + +#: src/learn.c:287 +msgid "Press all the keys mentioned here. After you have done it, check" +msgstr "Hãy nhấn tất cả những phím liệt kê ở trên. Sau khi nhấn xong, hãy kiểm tra" + +#: src/learn.c:291 +msgid "which keys are not marked with OK. Press space on the missing" +msgstr "xem những phím nào không có dấu hiệu \"OK\". Nhấn phím space trên những" + +#: src/learn.c:295 +msgid "key, or click with the mouse to define it. Move around with Tab." +msgstr "phím bị thiếu, hoặc nhấn chuột để xác định. Di chuyển bằng Tab." + +#: src/main.c:425 +msgid "" +" The Commander can't change to the directory that \n" +" the subshell claims you are in. Perhaps you have \n" +" deleted your working directory, or given yourself \n" +" extra access permissions with the \"su\" command? " +msgstr "" +" MC không thể chuyển vào thư mục, mà tiến trình shell \n" +" con thông báo. Rất có thể, bạn đã xóa thư mục làm việc \n" +" hoặc thêm cho mình quyền truy cập mở rộng bằng câu \n" +" lệnh \"su\"? " + +#: src/main.c:469 src/screen.c:1951 +msgid " The Midnight Commander " +msgstr " Midnight Commander " + +#: src/main.c:470 +msgid " Do you really want to quit the Midnight Commander? " +msgstr " Thực sự muốn thoát Midnight Commander? " + +#: src/main.c:792 src/main.c:816 +msgid "&Listing mode..." +msgstr "&Dạng danh sách..." + +#: src/main.c:793 src/main.c:817 +msgid "&Quick view C-x q" +msgstr "&Xem nhanh C-x q" + +#: src/main.c:794 src/main.c:818 +msgid "&Info C-x i" +msgstr "&Thông tin C-x i" + +#: src/main.c:797 src/main.c:821 +msgid "&Sort order..." +msgstr "t&Hứ tự sắp xếp..." + +#: src/main.c:799 src/main.c:823 +msgid "&Filter..." +msgstr "&Lọc tập tin..." + +#: src/main.c:803 src/main.c:827 +msgid "&Network link..." +msgstr "&Kết nối mạng..." + +#: src/main.c:805 src/main.c:829 +msgid "FT&P link..." +msgstr "kết nối &FTP..." + +#: src/main.c:806 src/main.c:830 +msgid "S&hell link..." +msgstr "kết nối &Shell..." + +#: src/main.c:808 src/main.c:832 +msgid "SM&B link..." +msgstr "kết nối SM&B..." + +#: src/main.c:812 src/main.c:836 +msgid "&Rescan C-r" +msgstr "&Quét lại C-r" + +#: src/main.c:840 +msgid "&User menu F2" +msgstr "&Trình đơn người dùng F2" + +#: src/main.c:841 +msgid "&View F3" +msgstr "&Xem F3" + +#: src/main.c:842 +msgid "Vie&w file... " +msgstr "x&Em tập tin... " + +#: src/main.c:843 +msgid "&Filtered view M-!" +msgstr "xe&M đã lọc M-!" + +#: src/main.c:844 +msgid "&Edit F4" +msgstr "&Soạn thảo F4" + +#: src/main.c:845 +msgid "&Copy F5" +msgstr "sao &Chép F5" + +#: src/main.c:846 +msgid "c&Hmod C-x c" +msgstr "c&Hmod C-x c" + +#: src/main.c:847 +msgid "&Link C-x l" +msgstr "&Liên kết cứng C-x l" + +#: src/main.c:848 +msgid "&SymLink C-x s" +msgstr "liên &Kết mềm C-x s" + +#: src/main.c:849 +msgid "edit s&Ymlink C-x C-s" +msgstr "sử&A liên kết mềm C-x C-s" + +#: src/main.c:850 +msgid "ch&Own C-x o" +msgstr "cho&Wn C-x o" + +#: src/main.c:851 +msgid "&Advanced chown " +msgstr "chown &Nâng cao " + +#: src/main.c:852 +msgid "&Rename/Move F6" +msgstr "Đổi tên/&Di chuyển F6" + +#: src/main.c:853 +msgid "&Mkdir F7" +msgstr "mkdi&R F7" + +#: src/main.c:854 +msgid "&Delete F8" +msgstr "xó&A F8" + +#: src/main.c:855 +msgid "&Quick cd M-c" +msgstr "cd nhanh &> M-c" + +#: src/main.c:857 +msgid "select &Group M-+" +msgstr "Chọn Nhóm &+ M-+" + +#: src/main.c:858 +msgid "u&Nselect group M-\\" +msgstr "&Bỏ chọn nhóm M-\\" + +#: src/main.c:859 +msgid "reverse selec&Tion M-*" +msgstr "Chọn ngược lạ&I M-*" + +#: src/main.c:861 +msgid "e&Xit F10" +msgstr "Th&Oát F10" + +#: src/main.c:869 +msgid "&Directory tree" +msgstr "cây thư &Mục" + +#: src/main.c:870 +msgid "&Find file M-?" +msgstr "&Tìm tập tin M-?" + +#: src/main.c:871 +msgid "s&Wap panels C-u" +msgstr "đổi chỗ h&Ai bảng C-u" + +#: src/main.c:872 +msgid "switch &Panels on/off C-o" +msgstr "&Bật/tắt bảng C-o" + +#: src/main.c:873 +msgid "&Compare directories C-x d" +msgstr "&So sánh thư mục C-x d" + +#: src/main.c:874 +msgid "e&Xternal panelize C-x !" +msgstr "bản&G ngoài C-x !" + +#: src/main.c:875 +msgid "show directory s&Izes" +msgstr "&Hiển thị kích thước thư mục" + +#: src/main.c:877 +msgid "command &History" +msgstr "&Lịch sử câu lệnh" + +#: src/main.c:878 +msgid "di&Rectory hotlist C-\\" +msgstr "Thư mục thường dùng &* C-\\" + +#: src/main.c:880 +msgid "&Active VFS list C-x a" +msgstr "&Danh sách VFS hoạt động C-x a" + +#: src/main.c:883 +msgid "&Background jobs C-x j" +msgstr "&Công việc nền sau C-x j" + +#: src/main.c:887 +msgid "&Undelete files (ext2fs only)" +msgstr "&Phục hồi tập tin đã xóa (chỉ ext2fs)" + +#: src/main.c:890 +msgid "&Listing format edit" +msgstr "&Soạn thảo định dạng danh sách" + +#: src/main.c:895 +msgid "Edit &extension file" +msgstr "soạn thảo tập tin phần mở &Rộng" + +#: src/main.c:896 +msgid "Edit &menu file" +msgstr "soạ&N thảo tập tin trình đơn" + +#: src/main.c:898 +msgid "Edit edi&tor menu file" +msgstr "sửa trình đơn của trình s&Oạn thảo" + +#: src/main.c:899 +msgid "Edit &syntax file" +msgstr "sửa tập tin cú &Pháp" + +#: src/main.c:905 +msgid "&Configuration..." +msgstr "&Cấu hình..." + +#: src/main.c:906 +msgid "&Layout..." +msgstr "&Vẻ ngoài..." + +#: src/main.c:907 +msgid "c&Onfirmation..." +msgstr "&Xác nhận..." + +#: src/main.c:908 +msgid "&Display bits..." +msgstr "bit &Hiển thị..." + +#: src/main.c:911 +msgid "&Virtual FS..." +msgstr "&FS ảo..." + +#: src/main.c:914 +msgid "&Save setup" +msgstr "&Ghi nhớ cấu hình" + +#: src/main.c:925 +msgid " &Above " +msgstr " Ở &trên " + +#: src/main.c:925 +msgid " &Left " +msgstr " &Bảng trái " + +#: src/main.c:929 +msgid " &File " +msgstr " &Tập tin " + +#: src/main.c:932 +msgid " &Command " +msgstr " &Câu lệnh " + +#: src/main.c:935 +msgid " &Options " +msgstr " &Cấu hình " + +#: src/main.c:938 +msgid " &Below " +msgstr " Ở &dưới " + +#: src/main.c:938 +msgid " &Right " +msgstr " Bảng &phải " + +#: src/main.c:981 +msgid " Information " +msgstr " Thông tin " + +#: src/main.c:983 +msgid "" +" Using the fast reload option may not reflect the exact \n" +" directory contents. In this case you'll need to do a \n" +" manual reload of the directory. See the man page for \n" +" the details. " +msgstr "" +" Sử dụng tùy chọn nạp lại nhanh có thể không phản ánh \n" +" đúng nội dung hiện thời của thư mục. Trong trường hợp \n" +" này cần nạp lại thư mục một cách thủ công. Hãy xem \n" +" trang hướng dẫn sử dụng man để biết them chi tiết. " + +#: src/main.c:1206 src/screen.c:2185 +msgid "Menu" +msgstr "Trđơn " + +#: src/main.c:1340 +msgid "The TERM environment variable is unset!\n" +msgstr "Biến môi trườn TERM chưa được xác định!\n" + +#: src/main.c:1642 src/textconf.c:116 +#, c-format +msgid "GNU Midnight Commander %s\n" +msgstr "GNU Midnight Commander %s\n" + +#: src/main.c:1848 +msgid "[flags] [this_dir] [other_panel_dir]\n" +msgstr "[cờ] [thư_mục_này] [thư_mục_bảng_còn_lại]\n" + +#: src/main.c:1852 +msgid "+number" +msgstr "+số" + +#: src/main.c:1853 +msgid "Set initial line number for the internal editor" +msgstr "Đặt số dòng ban đầu cho trình soạn thảo nội bộ" + +#: src/main.c:1855 +msgid "" +"\n" +"Please send any bug reports (including the output of `mc -V')\n" +"to mc-devel@gnome.org\n" +msgstr "" +"\n" +"Xin hãy gửi bất kỳ báo cáo lỗi (bug) nào (gồm cả kết quả của lệnh `mc -V')\n" +"tới mc-devel@gnome.org\n" + +#: src/main.c:1870 +msgid "" +"--colors KEYWORD={FORE},{BACK}\n" +"\n" +"{FORE} and {BACK} can be omitted, and the default will be used\n" +"\n" +"Keywords:\n" +" Global: errors, reverse, gauge, input\n" +" File display: normal, selected, marked, markselect\n" +" Dialog boxes: dnormal, dfocus, dhotnormal, dhotfocus\n" +" Menus: menu, menuhot, menusel, menuhotsel\n" +" Help: helpnormal, helpitalic, helplink, helpslink\n" +" File types: directory, executable, link, stalelink, device, special, " +"core\n" +"\n" +"Colors:\n" +" black, gray, red, brightred, green, brightgreen, brown,\n" +" yellow, blue, brightblue, magenta, brightmagenta, cyan,\n" +" brightcyan, lightgray and white\n" +"\n" +msgstr "" +"--colors TỪ_KHÓA={VĂN BẢN},{NỀN}\n" +"\n" +"có thể bỏ qua {VĂN BẢN} và {NỀN}, và sử dụng giá trị theo mặc định\n" +"\n" +"Từ khóa:\n" +" Toàn cầu: errors, reverse, gauge, input\n" +" Hiển thị tập tin: normal, selected, marked, markselect\n" +" Hộp thoại: dnormal, dfocus, dhotnormal, dhotfocus\n" +" Trình đơn: menu, menuhot, menusel, menuhotsel\n" +" Trợ giúp: helpnormal, helpitalic, helplink, helpslink\n" +" Dạng tập tin: directory, executable, link, stalelink, device, special, core\n" +"\n" +"Màu sắc:\n" +" black, gray, red, brightred, green, brightgreen, brown,\n" +" yellow, blue, brightblue, magenta, brightmagenta, cyan,\n" +" brightcyan, lightgray, white\n" +"\n" + +#: src/main.c:1945 +msgid "Displays this help message" +msgstr "Hiển thị thông báo trợ giúp này" + +#: src/main.c:1947 +msgid "Displays the current version" +msgstr "Hiển thị số phiên bản hiện thời" + +#: src/main.c:1951 +msgid "Forces xterm features" +msgstr "Bắt buộc dùng tính năng của xterm" + +#: src/main.c:1953 +msgid "Disable mouse support in text version" +msgstr "Bỏ hỗ trợ chuột trong phiên bản văn bản (text)" + +#: src/main.c:1956 +msgid "Tries to use termcap instead of terminfo" +msgstr "Thử sử dụng termcap thay cho terminfo" + +#: src/main.c:1959 +msgid "Resets soft keys on HP terminals" +msgstr "Đặt lại phím phần mềm trên các terminal HP" + +#: src/main.c:1961 +msgid "To run on slow terminals" +msgstr "Để chạy trên các terminal chậm" + +#: src/main.c:1963 +msgid "Use stickchars to draw" +msgstr "Sử dụng ký tự thẳng đứng để vẽ" + +#: src/main.c:1967 +msgid "Requests to run in black and white" +msgstr "Yêu cầu chạy trong chế độ đen trắng" + +#: src/main.c:1969 +msgid "Request to run in color mode" +msgstr "Yêu cầu chạy trong chế độ màu" + +#: src/main.c:1971 +msgid "Specifies a color configuration" +msgstr "Xác định cấu hình màu sắc" + +#: src/main.c:1973 +msgid "Displays a help screen on how to change the color scheme" +msgstr "Hiển thị cửa sổ trợ giúp cách thay đổi bộ phối hợp màu" + +#: src/main.c:1978 +msgid "Log ftp dialog to specified file" +msgstr "Ghi hội thoại FTP vào một tập tin" + +#: src/main.c:1981 +msgid "Set debug level" +msgstr "Đặt mức độ tìm sửa lỗi (debug)" + +#: src/main.c:1987 +msgid "Print data directory" +msgstr "In ra tên thư mục dữ liệu" + +#: src/main.c:1989 +msgid "Print last working directory to specified file" +msgstr "Ghi thư mục làm việc cuối cùng vào tập tin chỉ ra" + +#: src/main.c:1994 +msgid "Enables subshell support (default)" +msgstr "Bật hỗ trợ shell con (mặc định)" + +#: src/main.c:1996 +msgid "Disables subshell support" +msgstr "Tắt hỗ trợ shell con" + +#: src/main.c:2001 +msgid "Launches the file viewer on a file" +msgstr "Xem tập tin" + +#: src/main.c:2004 +msgid "Edits one file" +msgstr "Soạn thảo tập tin" + +#: src/main.c:2218 +msgid " Notice " +msgstr " Cảnh báo " + +#: src/main.c:2219 +msgid "" +" The Midnight Commander configuration files \n" +" are now stored in the ~/.mc directory, the \n" +" files have been moved now\n" +msgstr "" +" Các tập tin cấu hình Midnight Commander \n" +" bây giờ đặt trong thư mục ~/.mc, các \n" +" tập tin cũ bây giờ được chuyển tới đó\n" + +#: src/option.c:56 +msgid "safe de&Lete" +msgstr "Xóa một cách &An toàn" + +#: src/option.c:57 +msgid "cd follows lin&Ks" +msgstr "cd th&Eo liên kết" + +#: src/option.c:58 +msgid "L&ynx-like motion" +msgstr "di chuyển giống trong l&Ynx" + +#: src/option.c:59 +msgid "rotatin&G dash" +msgstr "cái chỉ &Quay" + +#: src/option.c:60 +msgid "co&Mplete: show all" +msgstr "tự động hoàn thành: hiện tất cả" + +#: src/option.c:61 +msgid "&Use internal view" +msgstr "trình xem nội &Bộ" + +#: src/option.c:62 +msgid "use internal ed&It" +msgstr "sử dụng s&Oạn thảo nội bộ" + +#: src/option.c:63 +msgid "auto m&Enus" +msgstr "t&Rình đơn tự động" + +#: src/option.c:64 +msgid "&Auto save setup" +msgstr "tự động gh&I nhớ cấu hình" + +#: src/option.c:65 +msgid "shell &Patterns" +msgstr "&Mẫu dạng shell" + +#: src/option.c:66 +msgid "Compute &Totals" +msgstr "tính tổn&G kích thước" + +#: src/option.c:67 +msgid "&Verbose operation" +msgstr "thao tác với thông báo &Dài dòng" + +#: src/option.c:69 +msgid "&Fast dir reload" +msgstr "nạ&P nhanh thư mục" + +#: src/option.c:70 +msgid "mi&X all files" +msgstr "trộn lẫn tất &Cả tập tin" + +#: src/option.c:71 +msgid "&Drop down menus" +msgstr "đẩy &Xuống trình đơn" + +#: src/option.c:72 +msgid "ma&Rk moves down" +msgstr "&Nhãn di chuyển xuống" + +#: src/option.c:73 +msgid "show &Hidden files" +msgstr "&Hiển thị tập tin ẩn" + +#: src/option.c:74 +msgid "show &Backup files" +msgstr "hiển thị tập tin sao &Lưu" + +#: src/option.c:85 +msgid "&Never" +msgstr "&Không bao giờ" + +#: src/option.c:86 +msgid "on dumb &Terminals" +msgstr "&Trên terminal ngu" + +#: src/option.c:87 +msgid "Alwa&ys" +msgstr "&Luôn luôn" + +#: src/option.c:123 +msgid " Panel options " +msgstr " Cấu hình bảng " + +#: src/option.c:124 +msgid " Pause after run... " +msgstr " Tạm ngừng sau khi chạy... " + +#: src/option.c:170 +msgid "Configure options" +msgstr "Tùy chọn cấu hình" + +#: src/panelize.c:67 +msgid "&Add new" +msgstr "&Thêm mới" + +#: src/panelize.c:154 src/panelize.c:420 +msgid "External panelize" +msgstr "Bảng ngoài" + +#: src/panelize.c:169 +msgid "Command" +msgstr "Câu lệnh" + +#: src/panelize.c:185 src/panelize.c:242 src/panelize.c:313 src/panelize.c:334 +msgid "Other command" +msgstr "Lệnh khác" + +#: src/panelize.c:226 +msgid " Add to external panelize " +msgstr " Thêm vào bảng ngoài " + +#: src/panelize.c:227 +msgid " Enter command label: " +msgstr " Nhập tên câu lệnh: " + +#: src/panelize.c:267 +msgid " Cannot run external panelize in a non-local directory " +msgstr " Không thể chạy câu lệnh này trên một thư mục không phải nội bộ " + +#: src/panelize.c:316 +msgid "Find rejects after patching" +msgstr "Tìm những loại bỏ sau khi vá lỗi (patch)" + +#: src/panelize.c:317 +msgid "Find *.orig after patching" +msgstr "Tìm *.orig) sau khi vá lỗi (patch)" + +#: src/panelize.c:318 +msgid "Find SUID and SGID programs" +msgstr "Tìm chương trình có các bit SUID/SGID" + +#: src/panelize.c:369 +msgid "Cannot invoke command." +msgstr "Không thực hiện được câu lệnh." + +#: src/panelize.c:420 +msgid "Pipe close failed" +msgstr "Đóng đường ống không thành công" + +#: src/popt.c:547 +msgid "missing argument" +msgstr "thiếu tham số" + +#: src/popt.c:549 +msgid "unknown option" +msgstr "tùy chọn không rõ" + +#: src/popt.c:555 +msgid "invalid numeric value" +msgstr "giá trị số không thích hợp" + +#: src/popthelp.c:31 +msgid "Show this help message" +msgstr "Hiển thị thông báo trợ giúp này" + +#: src/popthelp.c:32 +msgid "Display brief usage message" +msgstr "Hiển thị chỉ dẫn ngắn gọn" + +#: src/popthelp.c:60 +msgid "ARG" +msgstr "ARG" + +#: src/popthelp.c:179 +msgid "Usage:" +msgstr "Sử dụng:" + +#: src/screen.c:201 +msgid "UP--DIR" +msgstr "LÊNTRÊN" + +#: src/screen.c:222 +msgid "SYMLINK" +msgstr "LIÊNKẾTMỀM" + +#: src/screen.c:226 +msgid "SUB-DIR" +msgstr "THƯMỤCCON" + +#: src/screen.c:406 src/screen.c:407 +msgid "Size" +msgstr "Kích cỡ" + +#: src/screen.c:409 +msgid "MTime" +msgstr "Thời gian sửa" + +#: src/screen.c:410 +msgid "ATime" +msgstr "Truy cập cuối cùng" + +#: src/screen.c:411 +msgid "CTime" +msgstr "Thời gian thay đổi" + +#: src/screen.c:412 +msgid "Permission" +msgstr "Quyền hạn" + +#: src/screen.c:413 +msgid "Perm" +msgstr "Quyền" + +#: src/screen.c:414 +msgid "Nl" +msgstr "Nl" + +#: src/screen.c:415 +msgid "Inode" +msgstr "Nút" + +#: src/screen.c:416 +msgid "UID" +msgstr "UID" + +#: src/screen.c:417 +msgid "GID" +msgstr "GID" + +#: src/screen.c:418 +msgid "Owner" +msgstr "Chủ sở hữu" + +#: src/screen.c:419 +msgid "Group" +msgstr "Nhóm" + +#: src/screen.c:655 +#, c-format +msgid "%s bytes in %d file" +msgstr "%s byte trong %d tập tin" + +#: src/screen.c:655 +#, c-format +msgid "%s bytes in %d files" +msgstr "%s byte trong %d tập tin" + +#: src/screen.c:681 +msgid "" +msgstr "<đọc liên kết không thành công>" + +#: src/screen.c:1289 +msgid "Unknown tag on display format: " +msgstr "Thẻ ghi không rõ trong định dạng hiển thị: " + +#: src/screen.c:1415 +msgid "User supplied format looks invalid, reverting to default." +msgstr "Định dạng người dùng đưa ra có vẻ không thích hợp, chuyển lại thành mặc định." + +#: src/screen.c:1952 +msgid " Do you really want to execute? " +msgstr " Thực sự muốn thực hiện? " + +#: src/screen.c:2186 +msgid "View" +msgstr "Xem " + +#: src/screen.c:2187 src/view.c:2231 +msgid "Edit" +msgstr "Soạn " + +#: src/screen.c:2189 src/tree.c:977 +msgid "RenMov" +msgstr "Chuyển" + +#: src/screen.c:2190 src/tree.c:981 +msgid "Mkdir" +msgstr "Tạotm " + +#: src/selcodepage.c:54 +msgid " Choose input codepage " +msgstr " Chọn bảng mã dữ liệu vào " + +#: src/selcodepage.c:58 +msgid "- < No translation >" +msgstr "- < Không có dịch >" + +#: src/selcodepage.c:106 +msgid "" +"To use this feature select your codepage in\n" +"Setup / Display Bits dialog!\n" +"Do not forget to save options." +msgstr "" +"Để sử dụng tính năng này, hãy chọn bảng mã trong\n" +"trình đơn Cấu hình / hộp thoại Bit hiển thị!\n" +"Đừng quên ghi nhớ lại cấu hình." + +#: src/slint.c:188 +#, c-format +msgid "" +"Screen size %dx%d is not supported.\n" +"Check the TERM environment variable.\n" +msgstr "" +"Kích thước màn hình %dx%d không được hỗ trợ.\n" +"Hãy kiểm tra biến môi trường TERM.\n" + +#: src/subshell.c:320 +msgid "" +"GNU Midnight Commander is already\n" +"running on this terminal.\n" +"Subshell support will be disabled." +msgstr "" +"Một GNU Midnight Commander đã làm việc\n" +"trên terminal này. Sẽ không có hỗ trợ\n" +"shell con." + +#: src/subshell.c:425 +#, c-format +msgid "Cannot open named pipe %s\n" +msgstr "Không mở được đường ống tên (named pipe) %s\n" + +#: src/subshell.c:653 +msgid " The shell is still active. Quit anyway? " +msgstr " Shell vẫn còn hoạt động. Vẫn thoát? " + +#: src/subshell.c:790 +#, c-format +msgid "Warning: Cannot change to %s.\n" +msgstr "Cảnh báo: Không chuyển được vào %s.\n" + +#: src/textconf.c:50 +msgid "With builtin Editor\n" +msgstr "Với Trình soạn thảo nội trú\n" + +#: src/textconf.c:56 +msgid "Using system-installed S-Lang library" +msgstr "Sử dụng thư việc của S-Lang hệ thống" + +#: src/textconf.c:58 +msgid "Using included S-Lang library" +msgstr "Sử dụng thư việc S-Lang bao gồm" + +#: src/textconf.c:64 +msgid "with termcap database" +msgstr "với cơ sở dữ liệu termcap" + +#: src/textconf.c:66 +msgid "with terminfo database" +msgstr "với cơ sở dữ liệu terminfo" + +#: src/textconf.c:70 +msgid "Using the ncurses library" +msgstr "Dùng thư viện ncurses" + +#: src/textconf.c:79 +msgid "With optional subshell support" +msgstr "Với hỗ trợ shell con không bắt buộc" + +#: src/textconf.c:81 +msgid "With subshell support as default" +msgstr "Với hỗ trợ shell con mặc định" + +#: src/textconf.c:87 +msgid "With support for background operations\n" +msgstr "Với hỗ trợ thao tác nền sau\n" + +#: src/textconf.c:91 +msgid "With mouse support on xterm and Linux console\n" +msgstr "Với hỗ trợ chuột trong xterm và kênh giao tác Linux\n" + +#: src/textconf.c:93 +msgid "With mouse support on xterm\n" +msgstr "Với hỗ trợ chuột trong xterm\n" + +#: src/textconf.c:97 +msgid "With support for X11 events\n" +msgstr "Với hỗ trợ sự kiện X11\n" + +#: src/textconf.c:101 +msgid "With internationalization support\n" +msgstr "Với hỗ trợ các ngôn ngữ khác\n" + +#: src/textconf.c:105 +msgid "With multiple codepages support\n" +msgstr "Với hỗ trợ nhiều bảng mã\n" + +#: src/textconf.c:121 +msgid "Virtual File System:" +msgstr "Hệ thống tập tin ảo:" + +#: src/tree.c:147 +#, c-format +msgid "" +"Cannot open the %s file for writing:\n" +"%s\n" +msgstr "" +"Không mở được tập tin %s để ghi nhớ:\n" +"%s\n" + +#: src/tree.c:591 +#, c-format +msgid "Copy \"%s\" directory to:" +msgstr " Sao chép thư mục \"%s\" vào:" + +#: src/tree.c:632 +#, c-format +msgid "Move \"%s\" directory to:" +msgstr " Di chuyển thư mục \"%s\" vào:" + +#: src/tree.c:642 +#, c-format +msgid "" +" Cannot stat the destination \n" +" %s " +msgstr "" +" Không lấy (stat) được thuộc tính của đích đến \n" +" %s " + +#: src/tree.c:705 +#, c-format +msgid " Delete %s? " +msgstr " Xóa %s? " + +#: src/tree.c:735 +msgid "Static" +msgstr "Tĩnh" + +#: src/tree.c:735 +msgid "Dynamc" +msgstr "Động" + +#: src/tree.c:971 +msgid "Rescan" +msgstr "Quét lại" + +#: src/tree.c:973 +msgid "Forget" +msgstr "Quên" + +#: src/tree.c:986 +msgid "Rmdir" +msgstr "Xóa thư mục" + +#: src/treestore.c:343 +#, c-format +msgid "" +"Cannot write to the %s file:\n" +"%s\n" +msgstr "" +"Không ghi nhớ được vào tập tin %s:\n" +"%s\n" + +#: src/user.c:133 +msgid " Format error on file Extensions File " +msgstr " Lỗi định dạng tập tin \"Phần mở rộng của tập tin\" " + +#: src/user.c:134 +#, c-format +msgid " The %%var macro has no default " +msgstr " Macro %%var không có giá trị mặc định " + +#: src/user.c:135 +#, c-format +msgid " The %%var macro has no variable " +msgstr " Macro %%var không có giá trị biến " + +#: src/user.c:447 +msgid " Debug " +msgstr " Sửa lỗi " + +#: src/user.c:456 +msgid " ERROR: " +msgstr " LỖI: " + +#: src/user.c:460 +msgid " True: " +msgstr " Đúng: " + +#: src/user.c:462 +msgid " False: " +msgstr " Sai: " + +#: src/user.c:669 +msgid " Warning -- ignoring file " +msgstr " Cảnh báo - tập tin bị lờ đi " + +#: src/user.c:670 +#, c-format +msgid "" +"File %s is not owned by root or you or is world writable.\n" +"Using it may compromise your security" +msgstr "" +"Tập tin %s không thuộc quyền sở hữu của root, hay của bạn,\n" +"hoặc ai cũng có thể ghi. Sử dụng tập tin này có thể không an toàn" + +#: src/user.c:792 +#, c-format +msgid " No suitable entries found in %s " +msgstr " Không tìm thấy mục thích hợp trong %s" + +#: src/user.c:798 +msgid " User menu " +msgstr " Trình đơn người dùng " + +#: src/util.c:671 src/util.c:697 +msgid "%b %e %H:%M" +msgstr "%b %e %H:%M" + +#: src/util.c:672 src/util.c:695 +msgid "%b %e %Y" +msgstr "%b %e %Y" + +#: src/utilunix.c:333 +#, c-format +msgid "%s is not a directory\n" +msgstr "%s không phải là một thư mục\n" + +#: src/utilunix.c:335 +#, c-format +msgid "Directory %s is not owned by you\n" +msgstr "Bạn không sở hữu thư mục %s\n" + +#: src/utilunix.c:338 +#, c-format +msgid "Cannot set correct permissions for directory %s\n" +msgstr "Không đặt được quyền hạn đúng cho thư mục %s\n" + +#: src/utilunix.c:343 +#, c-format +msgid "Cannot create temporary directory %s: %s\n" +msgstr "Không tạo được thư mục tạm thời %s: %s\n" + +#: src/utilunix.c:373 +#, c-format +msgid "Temporary files will be created in %s\n" +msgstr "Tập tin tạm thời sẽ được tạo trong thư mục %s\n" + +#: src/utilunix.c:376 +msgid "Temporary files will not be created\n" +msgstr "Tập tin tạm thời sẽ không được tạo ra\n" + +#: src/utilunix.c:401 +msgid " Pipe failed " +msgstr " Lỗi đường ống " + +#: src/utilunix.c:405 +msgid " Dup failed " +msgstr " Lỗi lặp lại " + +#: src/view.c:502 +msgid " Cannot spawn child program " +msgstr " Không sinh ra được tiến trình con " + +#: src/view.c:513 +msgid "Empty output from child filter" +msgstr "Bộ lọc con trả lại kết quả rỗng" + +#: src/view.c:519 +msgid " Cannot open file " +msgstr " Không mở được tập tin " + +#: src/view.c:618 +#, c-format +msgid "" +" Cannot open \"%s\"\n" +" %s " +msgstr "" +" Không mở được \"%s\"\n" +" %s " + +#: src/view.c:627 +#, c-format +msgid "" +" Cannot stat \"%s\"\n" +" %s " +msgstr "" +" Không lấy (stat) được thuộc tính \"%s\"\n" +" %s " + +#: src/view.c:636 +msgid " Cannot view: not a regular file " +msgstr " Không xem được vì lý do: không\n" +" phải tập tin thông thường " + +#: src/view.c:775 +#, c-format +msgid "File: %s" +msgstr "Tập tin: %s" + +#: src/view.c:790 +#, c-format +msgid "Offset 0x%08lx" +msgstr "Bộ offset 0x%08lx" + +#: src/view.c:792 +#, c-format +msgid "Col %d" +msgstr "Cột %d" + +#: src/view.c:796 +#, c-format +msgid "%s bytes" +msgstr "%s byte" + +#: src/view.c:801 +msgid " [grow]" +msgstr " [lớn lên]" + +#: src/view.c:1826 +msgid "Invalid hex search expression" +msgstr "Biểu thức tìm kiếm hex không đúng" + +#: src/view.c:1880 +msgid " Invalid regular expression " +msgstr " Biểu thức chính quy không đúng" + +#: src/view.c:2003 +#, c-format +msgid "" +" The current line number is %d.\n" +" Enter the new line number:" +msgstr "" +" Số thứ tự dòng hiện thời %d.\n" +" Hãy nhập số thứ tự dòng muốn chuyển đến:" + +#: src/view.c:2026 +#, c-format +msgid "" +" The current address is 0x%lx.\n" +" Enter the new address:" +msgstr "" +" Địa chỉ hiện thời - 0x%lx.\n" +" Hãy nhập địa chỉ mới:" + +#: src/view.c:2028 +msgid " Goto Address " +msgstr " Đi tới địa chỉ " + +#: src/view.c:2060 +msgid " Enter regexp:" +msgstr " Nhập biểu thức chính quy:" + +#: src/view.c:2216 +msgid "Ascii" +msgstr "Ascii" + +#: src/view.c:2216 +msgid "Hex" +msgstr "Hex" + +#: src/view.c:2218 +msgid "Goto" +msgstr "ĐiTới" + +#: src/view.c:2218 +msgid "Line" +msgstr "Dòng" + +#: src/view.c:2220 +msgid "RxSrch" +msgstr "TìmRx" + +#: src/view.c:2225 +msgid "EdHex" +msgstr "SoạnHex" + +#: src/view.c:2225 +msgid "EdText" +msgstr "SoạnVb" + +#: src/view.c:2233 +msgid "UnWrap" +msgstr "BỏWrap" + +#: src/view.c:2233 +msgid "Wrap" +msgstr "CóWrap" + +#: src/view.c:2236 +msgid "HxSrch" +msgstr "TìmHx" + +#: src/view.c:2239 +msgid "Raw" +msgstr "Thô" + +#: src/view.c:2239 +msgid "Parse" +msgstr "Phtích" + +#: src/view.c:2244 +msgid "Unform" +msgstr "K0dạng" + +#: src/view.c:2244 +msgid "Format" +msgstr "CóDạng" + +#: src/widget.c:911 +msgid " History " +msgstr " Lịch sử" + +#: src/win.c:159 +msgid "Function key 1" +msgstr "Phím chức năng 1" + +#: src/win.c:160 +msgid "Function key 2" +msgstr "Phím chức năng 2" + +#: src/win.c:161 +msgid "Function key 3" +msgstr "Phím chức năng 3" + +#: src/win.c:162 +msgid "Function key 4" +msgstr "Phím chức năng 4" + +#: src/win.c:163 +msgid "Function key 5" +msgstr "Phím chức năng 5" + +#: src/win.c:164 +msgid "Function key 6" +msgstr "Phím chức năng 6" + +#: src/win.c:165 +msgid "Function key 7" +msgstr "Phím chức năng 7" + +#: src/win.c:166 +msgid "Function key 8" +msgstr "Phím chức năng 8" + +#: src/win.c:167 +msgid "Function key 9" +msgstr "Phím chức năng 9" + +#: src/win.c:168 +msgid "Function key 10" +msgstr "Phím chức năng 10" + +#: src/win.c:169 +msgid "Function key 11" +msgstr "Phím chức năng 11" + +#: src/win.c:170 +msgid "Function key 12" +msgstr "Phím chức năng 12" + +#: src/win.c:171 +msgid "Function key 13" +msgstr "Phím chức năng 13" + +#: src/win.c:172 +msgid "Function key 14" +msgstr "Phím chức năng 14" + +#: src/win.c:173 +msgid "Function key 15" +msgstr "Phím chức năng 15" + +#: src/win.c:174 +msgid "Function key 16" +msgstr "Phím chức năng 16" + +#: src/win.c:175 +msgid "Function key 17" +msgstr "Phím chức năng 17" + +#: src/win.c:176 +msgid "Function key 18" +msgstr "Phím chức năng 18" + +#: src/win.c:177 +msgid "Function key 19" +msgstr "Phím chức năng 19" + +#: src/win.c:178 +msgid "Function key 20" +msgstr "Phím chức năng 20" + +#: src/win.c:179 +msgid "Backspace key" +msgstr "Phím Backspace" + +#: src/win.c:180 +msgid "End key" +msgstr "Phím End" + +#: src/win.c:181 +msgid "Up arrow key" +msgstr "Phím mũi tên lên" + +#: src/win.c:182 +msgid "Down arrow key" +msgstr "Phím mũi tên xuống" + +#: src/win.c:183 +msgid "Left arrow key" +msgstr "Phím mũi tên sang trái" + +#: src/win.c:184 +msgid "Right arrow key" +msgstr "Phím mũi tên sang phải" + +#: src/win.c:185 +msgid "Home key" +msgstr "Phím Home" + +#: src/win.c:186 +msgid "Page Down key" +msgstr "Phím Page Down" + +#: src/win.c:187 +msgid "Page Up key" +msgstr "Phím Page Up" + +#: src/win.c:188 +msgid "Insert key" +msgstr "Phím Insert" + +#: src/win.c:189 +msgid "Delete key" +msgstr "Phím Delete" + +#: src/win.c:190 +msgid "Completion/M-tab" +msgstr "Hoàn thành/M-Tab" + +#: src/win.c:191 +msgid "+ on keypad" +msgstr "+ trên phần keypad" + +#: src/win.c:192 +msgid "- on keypad" +msgstr "- trên phần keypad" + +#: src/win.c:193 +msgid "* on keypad" +msgstr "* trên phần keypad" + +#: src/win.c:195 +msgid "Left arrow keypad" +msgstr "Mũi tên sang trái trên phần keypad" + +#: src/win.c:196 +msgid "Right arrow keypad" +msgstr "Mũi tên sang phải trên phần keypad" + +#: src/win.c:197 +msgid "Up arrow keypad" +msgstr "Mũi tên lên trên của phần keypad" + +#: src/win.c:198 +msgid "Down arrow keypad" +msgstr "Mũi tên xuống dưới của phần keypad" + +#: src/win.c:199 +msgid "Home on keypad" +msgstr "Home trên keypad" + +#: src/win.c:200 +msgid "End on keypad" +msgstr "End trên keypad" + +#: src/win.c:201 +msgid "Page Down keypad" +msgstr "Page Down trên keypad" + +#: src/win.c:202 +msgid "Page Up keypad" +msgstr "Page Up trên keypad" + +#: src/win.c:203 +msgid "Insert on keypad" +msgstr "Insert trên keypad" + +#: src/win.c:204 +msgid "Delete on keypad" +msgstr "Delete trên keypad" + +#: src/win.c:205 +msgid "Enter on keypad" +msgstr "Enter trên keypad" + +#: src/win.c:206 +msgid "Slash on keypad" +msgstr "Slash trên keypad" + +#: src/win.c:207 +msgid "NumLock on keypad" +msgstr "NumLock trên keypad" + +#: src/wtools.c:256 +msgid "Background process:" +msgstr "Tiến trình nền sau:" + +#: vfs/cpio.c:142 vfs/cpio.c:158 +#, c-format +msgid "" +"Cannot open cpio archive\n" +"%s" +msgstr "" +"Không mở được tập tin nén cpio\n" +"%s" + +#: vfs/cpio.c:223 +#, c-format +msgid "" +"Premature end of cpio archive\n" +"%s" +msgstr "" +"Phần cuối của tập tin nén cpio bị hỏng\n" +"%s" + +#: vfs/cpio.c:309 vfs/cpio.c:359 +#, c-format +msgid "" +"Corrupted cpio header encountered in\n" +"%s" +msgstr "" +"Lỗi phần đầu cpio phát hiện trong\n" +"%s" + +#: vfs/cpio.c:432 +#, c-format +msgid "" +"Inconsistent hardlinks of\n" +"%s\n" +"in cpio archive\n" +"%s" +msgstr "" +"Liên kết cứng không thích hợp \n" +"%s\n" +"trong tập tin nén cpio\n" +"%s" + +#: vfs/cpio.c:457 +#, c-format +msgid "%s contains duplicate entries! Skipping!" +msgstr "%s chứa mục lặp lại! Nhảy qua!" + +#: vfs/cpio.c:526 +#, c-format +msgid "" +"Unexpected end of file\n" +"%s" +msgstr "" +"Kết thúc tập tin không mong đợi\n" +"%s" + +#: vfs/direntry.c:326 +#, c-format +msgid "Directory cache expired for %s" +msgstr "Cache thư mục hết hạn cho %s" + +#: vfs/direntry.c:749 +msgid "Starting linear transfer..." +msgstr "Chạy truyền tải theo đường thẳng..." + +#: vfs/direntry.c:886 +#, c-format +msgid "%s: %s: %s %3d%% (%lu bytes transferred)" +msgstr "%s: %s: %s %3d%% (đã truyền tải %lu byte)" + +#: vfs/direntry.c:887 +#, c-format +msgid "%s: %s: %s %lu bytes transferred" +msgstr "%s: %s: %s đã truyền tải %lu byte" + +#: vfs/direntry.c:933 +msgid "Getting file" +msgstr "Nhận tập tin" + +#: vfs/extfs.c:303 +#, c-format +msgid "" +"Cannot open %s archive\n" +"%s" +msgstr "" +"Không mở được tập tin nén %s\n" +"%s" + +#: vfs/extfs.c:343 vfs/extfs.c:365 vfs/extfs.c:415 +msgid "Inconsistent extfs archive" +msgstr "Tập tin nén extfs không thích hợp" + +#: vfs/fish.c:157 +#, c-format +msgid "fish: Disconnecting from %s" +msgstr "fish: Ngừng kết nối từ %s" + +#: vfs/fish.c:232 +msgid "fish: Waiting for initial line..." +msgstr "fish: Đang chời dòng đầu tiên..." + +#: vfs/fish.c:244 +msgid "Sorry, we cannot do password authenticated connections for now." +msgstr "Xin lỗi, bây giờ không thể tạo kết nối xác thực theo mật khẩu." + +#: vfs/fish.c:249 +msgid " fish: Password required for " +msgstr "fish: yêu cầu mật khẩu cho " + +#: vfs/fish.c:258 +msgid "fish: Sending password..." +msgstr "fish: Đang gửi mật khẩu..." + +#: vfs/fish.c:264 +msgid "fish: Sending initial line..." +msgstr "fish: Đang gửi dòng đầu tiên..." + +#: vfs/fish.c:275 +msgid "fish: Handshaking version..." +msgstr "fish: Đang xác nhận phiên bản..." + +#: vfs/fish.c:289 +msgid "fish: Setting up current directory..." +msgstr "fish: Đang đặt thư mục hiện thời..." + +#: vfs/fish.c:291 +#, c-format +msgid "fish: Connected, home %s." +msgstr "fish: Kết nối thành công, thư mục cá nhân %s." + +#: vfs/fish.c:375 +#, c-format +msgid "fish: Reading directory %s..." +msgstr "fish: Đọc thư mục %s..." + +#: vfs/fish.c:477 vfs/ftpfs.c:1277 vfs/undelfs.c:343 +#, c-format +msgid "%s: done." +msgstr "%s: xong." + +#: vfs/fish.c:482 vfs/ftpfs.c:1247 vfs/undelfs.c:346 +#, c-format +msgid "%s: failure" +msgstr "%s: lỗi" + +#: vfs/fish.c:507 +#, c-format +msgid "fish: store %s: sending command..." +msgstr "fish: bản ghi %s: đang gửi câu lệnh..." + +#: vfs/fish.c:548 +msgid "fish: Local read failed, sending zeros" +msgstr "fish: Lỗi đọc nội bộ, đang gửi các số không" + +#: vfs/fish.c:560 +#, c-format +msgid "fish: storing %s %d (%lu)" +msgstr "fish: ghi %s %d (%lu)" + +#: vfs/fish.c:561 +msgid "zeros" +msgstr "các số không" + +#: vfs/fish.c:613 +msgid "Aborting transfer..." +msgstr "Dừng truyền tải..." + +#: vfs/fish.c:622 +msgid "Error reported after abort." +msgstr "Có lỗi báo cáo sau khi dừng." + +#: vfs/fish.c:624 +msgid "Aborted transfer would be successful." +msgstr "Dừng truyền tải thành công." + +#: vfs/ftpfs.c:378 +#, c-format +msgid "ftpfs: Disconnecting from %s" +msgstr "ftpfs: Ngắt kết nối từ %s" + +#: vfs/ftpfs.c:433 +msgid " FTP: Password required for " +msgstr " FTP: Cần mật khẩu cho " + +#: vfs/ftpfs.c:469 +msgid "ftpfs: sending login name" +msgstr "ftpfs: đang gửi tên đăng nhập" + +#: vfs/ftpfs.c:473 +msgid "ftpfs: sending user password" +msgstr "ftpfs: đang gửi mật khẩu người dùng" + +#: vfs/ftpfs.c:479 +#, c-format +msgid "FTP: Account required for user %s" +msgstr "FTP: Yêu cầu tài khoản cho người dùng %s" + +#: vfs/ftpfs.c:481 +msgid "Account:" +msgstr "Tài khoản:" + +#: vfs/ftpfs.c:485 +msgid "ftpfs: sending user account" +msgstr "ftpfs: đang gửi tài khoản người dùng" + +#: vfs/ftpfs.c:495 +msgid "ftpfs: logged in" +msgstr "ftpfs: đã đăng nhập" + +#: vfs/ftpfs.c:509 +#, c-format +msgid "ftpfs: Login incorrect for user %s " +msgstr "ftpfs: lỗi đăng nhập cho người dùng %s " + +#: vfs/ftpfs.c:633 +msgid "ftpfs: Invalid host name." +msgstr "ftpfs: Tên máy không đúng." + +#: vfs/ftpfs.c:651 +msgid "ftpfs: Invalid host address." +msgstr "ftpfs: Địa chỉ không đúng." + +#: vfs/ftpfs.c:673 +#, c-format +msgid "ftpfs: making connection to %s" +msgstr "ftpfs: Thực hiện kết nối với %s" + +#: vfs/ftpfs.c:683 +msgid "ftpfs: connection interrupted by user" +msgstr "ftpfs: người dùng dừng kết nối giữa chừng" + +#: vfs/ftpfs.c:685 +#, c-format +msgid "ftpfs: connection to server failed: %s" +msgstr "ftpfs: kết nối tới máy chủ không thành công: %s" + +#: vfs/ftpfs.c:726 +#, c-format +msgid "Waiting to retry... %d (Control-C to cancel)" +msgstr "Chờ thử lại... %d (Control-C để hủy bỏ)" + +#: vfs/ftpfs.c:906 +msgid "ftpfs: could not setup passive mode" +msgstr "ftpfs: không đặt được chế độ bị động (passive)" + +#: vfs/ftpfs.c:985 +msgid "ftpfs: aborting transfer." +msgstr "ftpfs: dừng truyền tải." + +#: vfs/ftpfs.c:987 +#, c-format +msgid "ftpfs: abort error: %s" +msgstr "ftpfs: lỗi thoát: %s" + +#: vfs/ftpfs.c:995 +msgid "ftpfs: abort failed" +msgstr "ftpfs: sự cố thoát" + +#: vfs/ftpfs.c:1099 vfs/ftpfs.c:1203 +msgid "ftpfs: CWD failed." +msgstr "ftpfs: CWD (thay đổi thư mục) không thành công." + +#: vfs/ftpfs.c:1109 vfs/ftpfs.c:1116 +msgid "ftpfs: couldn't resolve symlink" +msgstr "ftpfs: không tìm được liên kết mềm" + +#: vfs/ftpfs.c:1167 +msgid "Resolving symlink..." +msgstr "Đang tìm liên kết mềm..." + +#: vfs/ftpfs.c:1189 +#, c-format +msgid "ftpfs: Reading FTP directory %s... %s%s" +msgstr "ftpfs: Đọc thư mục FTP %s... %s%s" + +#: vfs/ftpfs.c:1192 +msgid "(strict rfc959)" +msgstr "(hạn chế rfc959)" + +#: vfs/ftpfs.c:1193 +msgid "(chdir first)" +msgstr "(đầu tiên chdir)" + +#: vfs/ftpfs.c:1290 +msgid "ftpfs: failed; nowhere to fallback to" +msgstr "ftpfs: lỗi; không có nơi nào để quay lại về" + +#: vfs/ftpfs.c:1355 +#, c-format +msgid "ftpfs: storing file %lu (%lu)" +msgstr "ftpfs: ghi tập tin %lu (%lu)" + +#: vfs/ftpfs.c:1740 +msgid "" +"~/.netrc file has incorrect mode.\n" +"Remove password or correct mode." +msgstr "" +"Tập tin ~/.netrc có chế độ truy cập/sở hữu không đúng.\n" +"Hãy xóa mật khẩu hoặc sửa lại chế độ cho đúng." + +#: vfs/mcfs.c:122 vfs/mcfs.c:167 +msgid " MCFS " +msgstr " MCFS " + +#: vfs/mcfs.c:123 +msgid " The server does not support this version " +msgstr " Máy chủ không hỗ trợ phiên bản này " + +#: vfs/mcfs.c:140 +msgid "" +" The remote server is not running on a system port \n" +" you need a password to log in, but the information may \n" +" not be safe on the remote side. Continue? \n" +msgstr "" +" Máy chủ ở xa không chạy trên một cổng hệ thống. Cần \n" +" mật khẩu để đăng nhập vào, nhưng điều này có thể \n" +" không an toàn cho thông tin phía ở xa. Tiếp tục?\n" + +#: vfs/mcfs.c:153 +msgid " MCFS Password required " +msgstr " Yêu cầu mật khẩu MCFS " + +#: vfs/mcfs.c:167 +msgid " Invalid password " +msgstr " Mật khẩu không đúng " + +#: vfs/mcfs.c:227 +#, c-format +msgid " Cannot locate hostname: %s " +msgstr " Không xác định được tên máy ở xa: %s" + +#: vfs/mcfs.c:246 +#, c-format +msgid " Cannot create socket: %s " +msgstr " Không tạo được socket: %s " + +#: vfs/mcfs.c:252 +#, c-format +msgid " Cannot connect to server: %s " +msgstr " Không kết nối được tới máy chủ: %s " + +#: vfs/mcfs.c:322 +msgid " Too many open connections " +msgstr " Quá nhiều kết nối mở " + +#: vfs/sfs.c:346 +#, c-format +msgid "" +"Warning: Invalid line in %s:\n" +"%s\n" +msgstr "" +"Cảnh báo: dòng không đúng trong %s:\n" +"%s\n" + +#: vfs/sfs.c:358 +#, c-format +msgid "" +"Warning: Invalid flag %c in %s:\n" +"%s\n" +msgstr "" +"Cảnh báo: Cờ không đúng %c trong %s:\n" +"%s\n" + +#: vfs/smbfs.c:576 +#, c-format +msgid "" +" smbfs_reconnect to %s failed\n" +" " +msgstr "" +" smbfs_reconnect (kết nối lại) tới %s không thành công\n" +" " + +#: vfs/smbfs.c:1120 +msgid " Authentication failed " +msgstr " Xác thực không thành công " + +#: vfs/smbfs.c:1632 +#, c-format +msgid " Error %s creating directory %s " +msgstr " Lỗi %s khi tạo thư mục %s " + +#: vfs/smbfs.c:1655 +#, c-format +msgid " Error %s removing directory %s " +msgstr " Lỗi %s khi xóa thư mục %s " + +#: vfs/smbfs.c:1744 +#, c-format +msgid " %s opening remote file %s " +msgstr " %s khi mở tập tin ở xa %s " + +#: vfs/smbfs.c:1817 +#, c-format +msgid " %s removing remote file %s " +msgstr " %s khi xoá tập tin ở xa %s " + +#: vfs/smbfs.c:1855 +#, c-format +msgid " %s renaming files\n" +msgstr " %s khi đổi tên các tập tin\n" + +#: vfs/tar.c:212 vfs/tar.c:229 +#, c-format +msgid "" +"Cannot open tar archive\n" +"%s" +msgstr "" +"Không mở được tập tin nén tar\n" +"%s" + +#: vfs/tar.c:424 +msgid "Unexpected EOF on archive file" +msgstr "Kết thúc tập tin EOF nén không mong đợi" + +#: vfs/tar.c:476 vfs/tar.c:483 +msgid "Inconsistent tar archive" +msgstr "Tập tin tar không thích hợp" + +#: vfs/tar.c:561 +#, c-format +msgid "" +"Hmm,...\n" +"%s\n" +"doesn't look like a tar archive." +msgstr "" +"Hừm,...\n" +"%s\n" +"không giống tập tin tar." + +#: vfs/undelfs.c:82 +msgid " undelfs: error " +msgstr " undelfs: lỗi " + +#: vfs/undelfs.c:189 +msgid " not enough memory " +msgstr " không đủ bộ nhớ " + +#: vfs/undelfs.c:194 +msgid " while allocating block buffer " +msgstr " khi phân phối bộ đệm khối " + +#: vfs/undelfs.c:198 +#, c-format +msgid " open_inode_scan: %d " +msgstr " open_inode_scan: %d " + +#: vfs/undelfs.c:202 +#, c-format +msgid " while starting inode scan %d " +msgstr " khi bắt đầu quét chỉ mục nút inode %d " + +#: vfs/undelfs.c:211 +#, c-format +msgid "undelfs: loading deleted files information %d inodes" +msgstr "undelfs: nạp thông tin về những tập tin bị xóa %d inode" + +#: vfs/undelfs.c:229 +#, c-format +msgid " while calling ext2_block_iterate %d " +msgstr " khi gọi ext2_block_iterate %d " + +#: vfs/undelfs.c:241 +msgid " no more memory while reallocating array " +msgstr " không đủ bộ nhớ khi phân phối lại chuỗi " + +#: vfs/undelfs.c:262 +#, c-format +msgid " while doing inode scan %d " +msgstr " khi quét chỉ mục nút inode %d " + +#: vfs/undelfs.c:297 +msgid " Ext2lib error " +msgstr " Lỗi Ext2lib " + +#: vfs/undelfs.c:325 vfs/undelfs.c:644 +#, c-format +msgid " Cannot open file %s " +msgstr " Không mở được tập tin %s " + +#: vfs/undelfs.c:328 +msgid "undelfs: reading inode bitmap..." +msgstr "undelfs: đọc sơ đồ bit của nút inode..." + +#: vfs/undelfs.c:331 +#, c-format +msgid "" +" Cannot load inode bitmap from: \n" +" %s \n" +msgstr "" +" Không nạp được sơ đồ bit của nút inode từ:\n" +" %s \n" + +#: vfs/undelfs.c:334 +msgid "undelfs: reading block bitmap..." +msgstr "undelfs: đọc sơ đồ bit của khối..." + +#: vfs/undelfs.c:337 +#, c-format +msgid "" +" Cannot load block bitmap from: \n" +" %s \n" +msgstr "" +" Không nạp được sơ đồ bit của khối từ:\n" +" %s \n" + +#: vfs/undelfs.c:360 +msgid " vfs_info is not fs! " +msgstr " vfs_info không phải là hệ thống tập tin! " + +#: vfs/undelfs.c:416 vfs/undelfs.c:600 +msgid " You have to chdir to extract files first " +msgstr " Đầu tiên bạn phải chdir để chuyển tới thư mục chứa tập tin cần giản nén " + +#: vfs/undelfs.c:539 +msgid " while iterating over blocks " +msgstr " khi lặp lại khối " + +#: vfs/vfs.c:880 +msgid "Changes to file lost" +msgstr "Thay đổi tới tập tin bị mất" + diff -urN mc-4.6.1.orig/src/achown.c mc-4.6.1/src/achown.c --- mc-4.6.1.orig/src/achown.c 2005-07-23 22:52:02.000000000 +0600 +++ mc-4.6.1/src/achown.c 2007-01-19 18:33:58.000000000 +0500 @@ -583,6 +583,12 @@ 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 -urN mc-4.6.1.orig/src/boxes.c mc-4.6.1/src/boxes.c --- mc-4.6.1.orig/src/boxes.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/boxes.c 2007-01-19 18:33:59.000000000 +0500 @@ -49,6 +49,7 @@ #ifdef HAVE_CHARSET #include "charsets.h" #include "selcodepage.h" +#include "recode.h" #endif #ifdef USE_NETCODE @@ -150,23 +151,23 @@ 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; @@ -285,20 +286,20 @@ 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; @@ -307,7 +308,7 @@ if (i > SORT_X) SORT_X = i; - i = strlen (sort_title) + 6; + i = mbstrlen (sort_title) + 6; if (i > SORT_X) SORT_X = i; @@ -402,7 +403,7 @@ 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; } @@ -417,8 +418,8 @@ * 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; @@ -446,8 +447,8 @@ } } -#define DISPY 11 -#define DISPX 46 +#define DISPY 13 +#define DISPX 35 #ifndef HAVE_CHARSET @@ -489,11 +490,11 @@ { 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; @@ -501,8 +502,8 @@ 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; @@ -543,26 +544,61 @@ static int new_display_codepage; +static int new_ftp_codepage; -static WLabel *cplabel; static WCheck *inpcheck; +static WButton *cpbutton; +static WButton *cpbutton_ftp; + static int sel_charset_button (int action) { const char *cpname; char buf[64]; - new_display_codepage = select_charset (new_display_codepage, 1); + new_display_codepage = select_charset (new_display_codepage, 1, _(" Choose input codepage ")); cpname = (new_display_codepage < 0) ? _("Other 8 bit") : codepages[new_display_codepage].name; /* avoid strange bug with label repainting */ - g_snprintf (buf, sizeof (buf), "%-27s", cpname); - label_set_text (cplabel, buf); + sprintf( buf, "%s", cpname ); + button_set_text (cpbutton, buf); + + if(new_display_codepage<0) new_ftp_codepage=-1; + cpname = (new_ftp_codepage < 0) + ? _("Other 8 bit") + : codepages[ new_ftp_codepage ].name; + sprintf( buf, "%s", cpname ); + button_set_text (cpbutton_ftp, buf); + return 0; } +static int sel_charset_button_ftp(int action) { + char *cpname, buf[64]; + if(new_display_codepage>0) { + new_ftp_codepage = select_charset(new_ftp_codepage, 0, _(" Choose default FTP codepage ")); + cpname = (new_display_codepage < 0) + ? _("Other 8 bit") + : codepages[ new_display_codepage ].name; + sprintf( buf, "%s", cpname ); + button_set_text( cpbutton, buf ); + cpname = (new_ftp_codepage < 0) + ? _("Other 8 bit") + : codepages[ new_ftp_codepage ].name; + sprintf( buf, "%s", cpname ); + button_set_text( cpbutton_ftp, buf ); + } + else { + message( 1, _(" Warning "), + _("To use this feature select your codepage in\n" + "Setup / Display Bits dialog!\n" + "Do not forget to save options." )); + } + return 0; +} + static Dlg_head * init_disp_bits_box (void) { @@ -581,9 +617,6 @@ cpname = (new_display_codepage < 0) ? _("Other 8 bit") : codepages[new_display_codepage].name; - cplabel = label_new (4, 4, cpname); - add_widget (dbits_dlg, cplabel); - add_widget (dbits_dlg, button_new (DISPY - 3, DISPX / 2 + 3, B_CANCEL, NORMAL_BUTTON, _("&Cancel"), 0)); @@ -592,13 +625,30 @@ 0)); inpcheck = - check_new (6, 4, !use_8th_bit_as_meta, _("F&ull 8 bits input")); + check_new (8, 4, !use_8th_bit_as_meta, _("F&ull 8 bits input")); add_widget (dbits_dlg, inpcheck); - cpname = _("&Select"); - add_widget (dbits_dlg, - button_new (4, DISPX - 8 - strlen (cpname), B_USER, - NORMAL_BUTTON, cpname, sel_charset_button)); + + add_widget( dbits_dlg, label_new( 5, 4, _("FTP default codepage:"))); + if(n_codepages>0) { + cpname = (new_display_codepage < 0) + ? _("Other 8 bit") + : codepages[ new_display_codepage ].name; + } + else cpname= _("Other 8 bit"); + cpbutton=button_new(4, 5, B_USER, + NORMAL_BUTTON, cpname, sel_charset_button); + + if(n_codepages>0) { + cpname = (new_ftp_codepage < 0) + ? _("Other 8 bit") + : codepages[ new_ftp_codepage ].name; + } + else cpname= _("Other 8 bit"); + cpbutton_ftp=button_new(6, 5, B_USER, + NORMAL_BUTTON, cpname, sel_charset_button_ftp); + add_widget( dbits_dlg, cpbutton_ftp); + add_widget (dbits_dlg, cpbutton); return dbits_dlg; } @@ -608,6 +658,7 @@ { Dlg_head *dbits_dlg; new_display_codepage = display_codepage; + new_ftp_codepage = ftp_codepage; application_keypad_mode (); dbits_dlg = init_disp_bits_box (); @@ -628,6 +679,17 @@ && display_codepage != 1) ? 128 : 160; #endif use_8th_bit_as_meta = !(inpcheck->state & C_BOOL); + + ftp_codepage=new_ftp_codepage; + if(display_codepage<=0) { + panel_reset_codepage(left_panel); + paint_dir(left_panel); + display_mini_info(left_panel); + panel_reset_codepage(right_panel); + paint_dir(right_panel); + display_mini_info(right_panel); + } + } destroy_dlg (dbits_dlg); repaint_screen (); @@ -803,7 +865,7 @@ 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; @@ -962,7 +1024,7 @@ { 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; @@ -971,7 +1033,7 @@ /* 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; } @@ -1029,7 +1091,7 @@ while (i--) { - l1 = strlen (labs [i] = _(labs [i])); + l1 = mbstrlen (labs [i] = _(labs [i])); if (l1 > maxlen) maxlen = l1; } @@ -1039,7 +1101,7 @@ 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) @@ -1048,7 +1110,7 @@ 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 -urN mc-4.6.1.orig/src/charsets.c mc-4.6.1/src/charsets.c --- mc-4.6.1.orig/src/charsets.c 2005-07-23 22:52:02.000000000 +0600 +++ mc-4.6.1/src/charsets.c 2007-01-19 18:33:59.000000000 +0500 @@ -119,8 +119,6 @@ } } -#define OTHER_8BIT "Other_8_bit" - const char * get_codepage_id (int n) { @@ -139,7 +137,7 @@ return -1; } -static char +char translate_character (iconv_t cd, char c) { char outbuf[4], *obuf; diff -urN mc-4.6.1.orig/src/charsets.h mc-4.6.1/src/charsets.h --- mc-4.6.1.orig/src/charsets.h 2004-08-30 16:38:00.000000000 +0600 +++ mc-4.6.1/src/charsets.h 2007-01-19 18:33:59.000000000 +0500 @@ -6,6 +6,7 @@ #define UNKNCHAR '\001' #define CHARSETS_INDEX "mc.charsets" +#define OTHER_8BIT "Other_8_bit" extern int n_codepages; @@ -19,6 +20,10 @@ extern struct codepage_desc *codepages; +#include +extern char translate_character(iconv_t cd, char c); +extern char errbuf[255]; + const char *get_codepage_id (int n); int get_codepage_index (const char *id); int load_codepages_list (void); diff -urN mc-4.6.1.orig/src/cmd.c mc-4.6.1/src/cmd.c --- mc-4.6.1.orig/src/cmd.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/cmd.c 2007-01-19 18:33:59.000000000 +0500 @@ -74,6 +74,10 @@ # include "../edit/edit.h" #endif +#ifdef HAVE_CHARSET +#include "recode.h" +#endif + /* If set and you don't have subshell support,then C-o will give you a shell */ int output_starts_shell = 0; @@ -350,6 +354,9 @@ { char *tempdir; char *dir; +#ifdef HAVE_CHARSET + char *recoded_dir; +#endif dir = input_expand_dialog (_("Create a new Directory"), @@ -360,8 +367,17 @@ if (dir[0] == '/' || dir[0] == '~') tempdir = g_strdup (dir); - else - tempdir = concat_dir_and_file (current_panel->cwd, dir); + else { +#ifdef HAVE_CHARSET + recoded_dir=g_strdup(dir); + my_translate_string(dir,strlen(dir), recoded_dir,current_panel->tr_table_input); + tempdir = concat_dir_and_file (current_panel->cwd, recoded_dir); + g_free(recoded_dir); +#else + tempdir = concat_dir_and_file (current_panel->cwd, dir); +#endif + } + g_free (dir); save_cwds_stat (); diff -urN mc-4.6.1.orig/src/dialog.c mc-4.6.1/src/dialog.c --- mc-4.6.1.orig/src/dialog.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/dialog.c 2007-01-19 18:33:58.000000000 +0500 @@ -162,7 +162,7 @@ if (h->title) { attrset (HOT_NORMALC); - dlg_move (h, space, (h->cols - strlen (h->title)) / 2); + dlg_move (h, space, (h->cols - mbstrlen (h->title)) / 2); addstr (h->title); } } diff -urN mc-4.6.1.orig/src/file.c mc-4.6.1/src/file.c --- mc-4.6.1.orig/src/file.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/file.c 2007-01-19 18:33:59.000000000 +0500 @@ -77,6 +77,9 @@ #include "../vfs/vfs-impl.h" /* }}} */ +#ifdef HAVE_CHARSET +#include "recode.h" +#endif int verbose = 1; @@ -165,15 +168,20 @@ do_transform_source (FileOpContext *ctx, const unsigned char *source) { size_t j, k, l, len; - unsigned const char *fnsource = x_basename (source); + unsigned const 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 +225,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 +240,7 @@ } } fntarget[k] = 0; + g_free(fnsource); return fntarget; } @@ -380,9 +390,9 @@ char *p, *q, *s; const char *r = strrchr (src_path, PATH_SEP); - + if (r) { - p = g_strndup (src_path, r - src_path); + p = g_strndup (src_path, r - src_path + 1); if (*dst_path == PATH_SEP) q = g_strdup (dst_path); else @@ -914,7 +924,11 @@ } /* Dive into subdir if exists */ if (toplevel && ctx->dive_into_subdirs) { - dest_dir = concat_dir_and_file (d, x_basename (s)); +#ifdef HAVE_CHARSET + dest_dir = concat_dir_and_recoded_fname(d, x_basename (s), ctx); +#else + dest_dir = concat_dir_and_file (d, x_basename (s)); +#endif } else { dest_dir = g_strdup (d); goto dont_mkdir; @@ -964,7 +978,11 @@ (*ctx->stat_func) (path, &buf); if (S_ISDIR (buf.st_mode)) { - mdpath = concat_dir_and_file (dest_dir, next->d_name); +#ifdef HAVE_CHARSET + mdpath = concat_dir_and_recoded_fname(dest_dir, next->d_name, ctx); +#else + mdpath = concat_dir_and_file (dest_dir, next->d_name); +#endif /* * From here, we just intend to recursively copy subdirs, not * the double functionality of copying different when the target @@ -975,7 +993,11 @@ parent_dirs, progress_count, progress_bytes); g_free (mdpath); } else { - dest_file = concat_dir_and_file (dest_dir, x_basename (path)); +#ifdef HAVE_CHARSET + dest_file=concat_dir_and_recoded_fname(dest_dir, x_basename(path),ctx); +#else + dest_file = concat_dir_and_file (dest_dir, x_basename (path)); +#endif return_status = copy_file_file (ctx, path, dest_file, 1, progress_count, progress_bytes, 0); g_free (dest_file); @@ -1159,7 +1181,12 @@ destdir = g_strdup (d); move_over = 1; } else - destdir = concat_dir_and_file (d, x_basename (s)); +#ifdef HAVE_CHARSET + destdir = concat_dir_and_recoded_fname(d, x_basename (s), ctx); +#else + destdir = concat_dir_and_file (d, x_basename (s)); +#endif + if (sbuf.st_dev == dbuf.st_dev && sbuf.st_ino == dbuf.st_ino) { int msize = COLS - 36; @@ -1875,7 +1902,12 @@ if (temp == NULL) { value = transform_error; } else { - char *temp2 = concat_dir_and_file (dest, temp); +#ifdef HAVE_CHARSET + char *temp2 = concat_dir_and_recoded_fname (dest, temp, ctx); +#else + char *temp2 = concat_dir_and_file (dest, temp); +#endif + g_free (dest); dest = temp2; temp = NULL; @@ -1969,7 +2001,12 @@ if (temp == NULL) value = transform_error; else { - char *temp2 = concat_dir_and_file (dest, temp); +#ifdef HAVE_CHARSET + char *temp2 = concat_dir_and_recoded_fname(dest, temp, ctx); +#else + char *temp2 = concat_dir_and_file (dest, temp); +#endif + switch (operation) { case OP_COPY: diff -urN mc-4.6.1.orig/src/filegui.c mc-4.6.1/src/filegui.c --- mc-4.6.1.orig/src/filegui.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/filegui.c 2007-01-19 18:33:59.000000000 +0500 @@ -69,6 +69,11 @@ #include "filegui.h" #include "key.h" /* get_event */ #include "util.h" /* strip_password() */ +#include "tty.h" + +#ifdef HAVE_CHARSET +#include "recode.h" +#endif /* }}} */ @@ -564,8 +569,8 @@ * longest of "Overwrite..." labels * (assume "Target date..." are short enough) */ - l1 = max (strlen (rd_widgets[6].text), - strlen (rd_widgets[11].text)); + l1 = max (mbstrlen (rd_widgets[6].text), + mbstrlen (rd_widgets[11].text)); /* longest of button rows */ i = sizeof (rd_widgets) / sizeof (rd_widgets[0]); @@ -576,7 +581,7 @@ l2 = max (l2, l); l = 0; } - l += strlen (rd_widgets[i].text) + 4; + l += mbstrlen (rd_widgets[i].text) + 4; } } l2 = max (l2, l); /* last row */ @@ -594,12 +599,12 @@ l = l1; } rd_widgets[i].xpos = l; - l += strlen (rd_widgets[i].text) + 4; + l += mbstrlen (rd_widgets[i].text) + 4; } } /* Abort button is centered */ rd_widgets[1].xpos = - (rd_xlen - strlen (rd_widgets[1].text) - 3) / 2; + (rd_xlen - mbstrlen (rd_widgets[1].text) - 3) / 2; } #endif /* ENABLE_NLS */ @@ -618,7 +623,7 @@ ADD_RD_LABEL (ui, 0, name_trunc (ui->replace_filename, - rd_trunc - strlen (rd_widgets[0].text)), 0); + rd_trunc - mbstrlen (rd_widgets[0].text)), 0); ADD_RD_BUTTON (1); ADD_RD_BUTTON (2); @@ -721,57 +726,79 @@ } } +#ifdef HAVE_CHARSET +#define FMDY 15 +#else #define FMDY 13 +#endif + #define FMD_XLEN 64 extern int fmd_xlen; static QuickWidget fmd_widgets[] = { -#define FMCB0 FMDC -#define FMCB12 0 -#define FMCB11 1 - /* follow symlinks and preserve Attributes must be the first */ - {quick_checkbox, 3, 64, 8, FMDY, N_("preserve &Attributes"), 9, 0, - 0 /* &op_preserve */ , 0, "preserve"}, - {quick_checkbox, 3, 64, 7, FMDY, N_("follow &Links"), 7, 0, - 0 /* &file_mask_op_follow_links */ , 0, "follow"}, - {quick_label, 3, 64, 5, FMDY, N_("to:"), 0, 0, 0, 0, "to"}, - {quick_checkbox, 37, 64, 4, FMDY, N_("&Using shell patterns"), 0, 0, - 0 /* &source_easy_patterns */ , 0, "using-shell"}, - {quick_input, 3, 64, 3, FMDY, "", 58, - 0, 0, 0, "input-def"}, -#define FMDI1 4 -#define FMDI2 5 -#define FMDC 3 - {quick_input, 3, 64, 6, FMDY, "", 58, 0, - 0, 0, "input2"}, -#define FMDI0 6 - {quick_label, 3, 64, 2, FMDY, "", 0, 0, 0, 0, "ql"}, -#define FMBRGT 7 - {quick_button, 42, 64, 9, FMDY, N_("&Cancel"), 0, B_CANCEL, 0, 0, - "cancel"}, -#undef SKIP +#ifdef HAVE_CHARSET + #define Y_OK 12 +#else + #define Y_OK 9 +#endif + +#ifdef WITH_BACKGROUND + #define ADD 0 +#else + #define ADD -1 +#endif + + #define FM_STAB_SYM 0 + #define FM_DIVE_INTO_SUBDIR 1 + #define FM_PRES_ATTR 2 + #define FM_FOLLOW_LINKS 3 + #define FM_DST_INPUT 4 + #define FM_DST_TITLE 5 + #define FM_USING_SHELL_PATT 6 + #define FM_SRC_INPUT 7 + #define FM_SRC_TITLE 8 + #define FM_CANCEL 9 +#ifdef WITH_BACKGROUND + #define FM_BKGND 10 +#endif + #define FM_OK 11+ADD +#ifdef HAVE_CHARSET + #define FM_TO_CODEPAGE 12+ADD + #define FM_FROM_CODEPAGE 13+ADD + #define FM_RECODE_TITLE 14+ADD + #define FM_RECODE_ARROW 15+ADD +#endif // HAVE_CHARSET + + +#ifdef HAVE_CHARSET + #define SKIP 10 + #define B_FROM B_USER+1 + #define B_TO B_USER+2 +#else + #define SKIP 10 +#endif + + {quick_checkbox, 42,64, 8, FMDY, N_("&Stable Symlinks"),0,0,0,0,"stab-sym"}, + {quick_checkbox, 31,64, 7, FMDY, N_("&Dive into subdir if exists"),0,0,0,0,"dive"}, + {quick_checkbox, 3, 64, 8, FMDY, N_("preserve &Attributes"),9,0,0,0,"preserve"}, + {quick_checkbox, 3, 64, 7, FMDY, N_("follow &Links"),7,0,0,0,"follow"}, + {quick_input, 3, 64, 6, FMDY, "", 58, 0, 0, 0, "input2"}, + {quick_label, 3, 64, 5, FMDY, N_("to:"), 0, 0, 0, 0, "to"}, + {quick_checkbox, 37,64, 4, FMDY, N_("&Using shell patterns"),0,0, 0,0,"us-sh"}, + {quick_input, 3, 64, 3, FMDY, "", 58, 0, 0, 0, "input-def"}, + {quick_label, 3, 64, 2, FMDY, "", 0, 0, 0, 0, "ql"}, + {quick_button, 42,64, Y_OK, FMDY, N_("&Cancel"), 0, B_CANCEL, 0,0, "cancel"}, #ifdef WITH_BACKGROUND -# define SKIP 5 -# define FMCB21 11 -# define FMCB22 10 -# define FMBLFT 9 -# define FMBMID 8 - {quick_button, 25, 64, 9, FMDY, N_("&Background"), 0, B_USER, 0, 0, - "back"}, -#else /* WITH_BACKGROUND */ -# define SKIP 4 -# define FMCB21 10 -# define FMCB22 9 -# define FMBLFT 8 -# undef FMBMID -#endif - {quick_button, 14, 64, 9, FMDY, N_("&OK"), 0, B_ENTER, 0, 0, "ok"}, - {quick_checkbox, 42, 64, 8, FMDY, N_("&Stable Symlinks"), 0, 0, - 0 /* &file_mask_stable_symlinks */ , 0, "stab-sym"}, - {quick_checkbox, 31, 64, 7, FMDY, N_("&Dive into subdir if exists"), 0, - 0, - 0 /* &dive_into_subdirs */ , 0, "dive"}, - NULL_QuickWidget + {quick_button, 25,64, Y_OK, FMDY, N_("&Background"), 0, B_USER, 0,0, "back"}, +#endif + {quick_button, 14,64, Y_OK, FMDY, N_("&OK"), 0, B_ENTER, 0, 0, "ok"}, +#ifdef HAVE_CHARSET + {quick_button, 46,64, 10, FMDY,"to codepage", 0, B_TO, 0, 0, "ql"}, + {quick_button, 25,64, 10, FMDY, "from codepage", 0, B_FROM, 0, 0, "ql"}, + {quick_label, 3, 64, 10, FMDY, N_("Recode file names:"), 0, 0, 0, 0, "ql"}, + {quick_label, 42,64, 10, FMDY, "->", 0, 0, 0, 0, "ql"}, +#endif + {0} }; static int @@ -805,48 +832,48 @@ if (fmd_widgets[i].text[0] != '\0') fmd_widgets[i].text = _(fmd_widgets[i].text); - len = strlen (fmd_widgets[FMCB11].text) - + strlen (fmd_widgets[FMCB21].text) + 15; + len = mbstrlen (fmd_widgets[FM_FOLLOW_LINKS].text) + + mbstrlen (fmd_widgets[FM_DIVE_INTO_SUBDIR].text) + 15; fmd_xlen = max (fmd_xlen, len); - len = strlen (fmd_widgets[FMCB12].text) - + strlen (fmd_widgets[FMCB22].text) + 15; + len = mbstrlen (fmd_widgets[FM_PRES_ATTR].text) + + mbstrlen (fmd_widgets[FM_STAB_SYM].text) + 15; fmd_xlen = max (fmd_xlen, len); - len = strlen (fmd_widgets[FMBRGT].text) - + strlen (fmd_widgets[FMBLFT].text) + 11; + len = mbstrlen (fmd_widgets[FM_CANCEL].text) + + mbstrlen (fmd_widgets[FM_OK].text) + 11; -#ifdef FMBMID - len += strlen (fmd_widgets[FMBMID].text) + 6; +#ifdef FM_BKGND + len += mbstrlen (fmd_widgets[FM_BKGND].text) + 6; #endif fmd_xlen = max (fmd_xlen, len + 4); len = (fmd_xlen - (len + 6)) / 2; - i = fmd_widgets[FMBLFT].relative_x = len + 3; - i += strlen (fmd_widgets[FMBLFT].text) + 8; + i = fmd_widgets[FM_OK].relative_x = len + 3; + i += mbstrlen (fmd_widgets[FM_OK].text) + 8; -#ifdef FMBMID - fmd_widgets[FMBMID].relative_x = i; - i += strlen (fmd_widgets[FMBMID].text) + 6; +#ifdef FM_BKGND + fmd_widgets[FM_BKGND].relative_x = i; + i += mbstrlen (fmd_widgets[FM_BKGND].text) + 6; #endif - fmd_widgets[FMBRGT].relative_x = i; + fmd_widgets[FM_CANCEL].relative_x = i; #define chkbox_xpos(i) \ - fmd_widgets [i].relative_x = fmd_xlen - strlen (fmd_widgets [i].text) - 6 + fmd_widgets [i].relative_x = fmd_xlen - mbstrlen (fmd_widgets [i].text) - 6 - chkbox_xpos (FMCB0); - chkbox_xpos (FMCB21); - chkbox_xpos (FMCB22); + chkbox_xpos (FM_USING_SHELL_PATT); + chkbox_xpos (FM_DIVE_INTO_SUBDIR); + chkbox_xpos (FM_STAB_SYM); if (fmd_xlen != FMD_XLEN) { i = sizeof (fmd_widgets) / sizeof (fmd_widgets[0]) - 1; while (i--) fmd_widgets[i].x_divisions = fmd_xlen; - fmd_widgets[FMDI1].hotkey_pos = - fmd_widgets[FMDI2].hotkey_pos = fmd_xlen - 6; + fmd_widgets[FM_SRC_INPUT].hotkey_pos = + fmd_widgets[FM_DST_INPUT].hotkey_pos = fmd_xlen - 6; } #undef chkbox_xpos @@ -856,7 +883,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,20 +892,32 @@ struct stat buf; int val; QuickDialog Quick_input; - + char *def_text; +#ifdef HAVE_CHARSET + char *errmsg; +#endif 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 */ - fmd_widgets[FMCB12].result = &ctx->op_preserve; - fmd_widgets[FMCB11].result = &ctx->follow_links; - fmd_widgets[FMCB22].result = &ctx->stable_symlinks; - fmd_widgets[FMCB21].result = &ctx->dive_into_subdirs; + fmd_widgets[FM_PRES_ATTR].result = &ctx->op_preserve; + fmd_widgets[FM_FOLLOW_LINKS].result = &ctx->follow_links; + fmd_widgets[FM_STAB_SYM].result = &ctx->stable_symlinks; + fmd_widgets[FM_DIVE_INTO_SUBDIR].result = &ctx->dive_into_subdirs; + /* filter out a possible password from def_text */ def_text_secure = strip_password (g_strdup (def_text), 1); @@ -886,8 +925,9 @@ /* Create the dialog */ ctx->stable_symlinks = 0; - fmd_widgets[FMDC].result = &source_easy_patterns; - fmd_widgets[FMDI1].text = easy_patterns ? "*" : "^\\(.*\\)$"; + fmd_widgets[FM_USING_SHELL_PATT].result = &source_easy_patterns; + fmd_widgets[FM_SRC_INPUT].text = easy_patterns ? "*" : "^\\(.*\\)$"; + Quick_input.xlen = fmd_xlen; Quick_input.xpos = -1; Quick_input.title = op_names[operation]; @@ -895,19 +935,34 @@ Quick_input.ylen = FMDY; Quick_input.i18n = 1; Quick_input.widgets = fmd_widgets; - fmd_widgets[FMDI0].text = text; - fmd_widgets[FMDI2].text = def_text_secure; - fmd_widgets[FMDI2].str_result = &dest_dir; - fmd_widgets[FMDI1].str_result = &source_mask; + fmd_widgets[FM_SRC_TITLE].text = text; + fmd_widgets[FM_DST_INPUT].text = def_text_secure; + fmd_widgets[FM_DST_INPUT].str_result = &dest_dir; + fmd_widgets[FM_SRC_INPUT].str_result = &source_mask; *do_background = 0; + +#ifdef HAVE_CHARSET + ctx->from_codepage=current_panel->src_codepage; + ctx->to_codepage=left_panel->src_codepage; + if(current_panel==left_panel) ctx->to_codepage=right_panel->src_codepage; +#endif + ask_file_mask: +#ifdef HAVE_CHARSET + if(operation!=OP_COPY && operation!=OP_MOVE) { + ctx->from_codepage=-1; + ctx->to_codepage=-1; + } + fmd_widgets[FM_FROM_CODEPAGE].text=get_codepage_id(ctx->from_codepage); + fmd_widgets[FM_TO_CODEPAGE].text=get_codepage_id(ctx->to_codepage); +#endif + if ((val = quick_dialog_skip (&Quick_input, SKIP)) == B_CANCEL) { g_free (def_text_secure); return 0; } - g_free (def_text_secure); if (ctx->follow_links) ctx->stat_func = (mc_stat_fn) mc_stat; @@ -929,6 +984,8 @@ orig_mask = source_mask; if (!dest_dir || !*dest_dir) { g_free (source_mask); + g_free (def_text_secure); + g_free(def_text); return dest_dir; } if (source_easy_patterns) { @@ -982,5 +1039,48 @@ } if (val == B_USER) *do_background = 1; +#ifdef HAVE_CHARSET + if(val == B_FROM) { + if(operation==OP_COPY || operation==OP_MOVE) { + if(display_codepage<=0) { + message( 1, _(" Warning "), + _("To use this feature select your codepage in\n" + "Setup / Display Bits dialog!\n" + "Do not forget to save options." )); + goto ask_file_mask; + } + ctx->from_codepage=select_charset(ctx->from_codepage,0, + _(" Choose \"FROM\" codepage for COPY/MOVE operaion ")); + } + else + message(1,"Warning",_("Recoding works only with COPY or MOVE operation")); + goto ask_file_mask; + } + if(val == B_TO) { + if(operation==OP_COPY || operation==OP_MOVE) { + if(display_codepage<=0) { + message( 1, _(" Warning "), + _("To use this feature select your codepage in\n" + "Setup / Display Bits dialog!\n" + "Do not forget to save options." )); + goto ask_file_mask; + } + ctx->to_codepage=select_charset(ctx->to_codepage,0, + _(" Choose \"TO\" codepage for COPY/MOVE operaion ")); + } + else + message(1,"Warning",_("Recoding works only with COPY or MOVE operation")); + goto ask_file_mask; + } + + errmsg=my_init_tt(ctx->to_codepage,ctx->from_codepage,ctx->tr_table); + if(errmsg) { + my_reset_tt(ctx->tr_table,256); + message( 1, MSG_ERROR, "%s", errmsg); + } +#endif + + g_free(def_text_secure); + g_free(def_text); return dest_dir; } diff -urN mc-4.6.1.orig/src/fileopctx.c mc-4.6.1/src/fileopctx.c --- mc-4.6.1.orig/src/fileopctx.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/fileopctx.c 2007-01-19 18:33:59.000000000 +0500 @@ -24,8 +24,12 @@ #include #include "global.h" -#include "fileopctx.h" +#ifdef HAVE_CHARSET +#include "recode.h" +#endif + +#include "fileopctx.h" /** * file_op_context_new: @@ -52,6 +56,12 @@ ctx->umask_kill = 0777777; ctx->erase_at_end = TRUE; +#ifdef HAVE_CHARSET + ctx->from_codepage=-1; + ctx->to_codepage=-1; + my_reset_tt(ctx->tr_table,256); +#endif + return ctx; } diff -urN mc-4.6.1.orig/src/fileopctx.h mc-4.6.1/src/fileopctx.h --- mc-4.6.1.orig/src/fileopctx.h 2004-10-07 00:06:26.000000000 +0600 +++ mc-4.6.1/src/fileopctx.h 2007-01-19 18:33:59.000000000 +0500 @@ -108,6 +108,14 @@ /* User interface data goes here */ void *ui; + +#ifdef HAVE_CHARSET + /* Recode data */ + int from_codepage, to_codepage; + unsigned char tr_table[256]; + unsigned char recode_buf[MC_MAXPATHLEN]; +#endif + } FileOpContext; diff -urN mc-4.6.1.orig/src/find.c mc-4.6.1/src/find.c --- mc-4.6.1.orig/src/find.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/find.c 2007-01-19 18:33:58.000000000 +0500 @@ -205,7 +205,7 @@ int l1, maxlen = 0; while (i--) { - l1 = strlen (labs[i] = _(labs[i])); + l1 = mbstrlen (labs[i] = _(labs[i])); if (l1 > maxlen) maxlen = l1; } @@ -214,7 +214,7 @@ 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) @@ -223,8 +223,8 @@ 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); @@ -813,7 +813,7 @@ 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; } diff -urN mc-4.6.1.orig/src/global.h mc-4.6.1/src/global.h --- mc-4.6.1.orig/src/global.h 2004-09-25 19:46:23.000000000 +0600 +++ mc-4.6.1/src/global.h 2007-01-19 18:33:58.000000000 +0500 @@ -146,6 +146,13 @@ # define N_(String) (String) #endif /* !ENABLE_NLS */ +#include +#if SLANG_VERSION >= 20000 +#define UTF8 1 +#define SLsmg_Is_Unicode SLsmg_is_utf8_mode() +void SLsmg_write_nwchars(wchar_t *s, size_t n); +#endif + #include "fs.h" #include "util.h" diff -urN mc-4.6.1.orig/src/help.c mc-4.6.1/src/help.c --- mc-4.6.1.orig/src/help.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/help.c 2007-01-19 18:33:59.000000000 +0500 @@ -445,10 +445,28 @@ #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; } @@ -771,6 +789,12 @@ 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 -urN mc-4.6.1.orig/src/hotlist.c mc-4.6.1/src/hotlist.c --- mc-4.6.1.orig/src/hotlist.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/hotlist.c 2007-01-19 18:33:58.000000000 +0500 @@ -555,7 +555,7 @@ 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; } @@ -580,12 +580,12 @@ /* 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); } } @@ -814,7 +814,7 @@ 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; @@ -860,7 +860,7 @@ static int i18n_flag = 0; #endif /* ENABLE_NLS */ - len = max (strlen (header), (size_t) msglen (text1, &lines1)); + len = max ((int) mbstrlen (header), (size_t) msglen (text1, &lines1)); len = max (len, (size_t) msglen (text2, &lines2)) + 4; len = max (len, 64); @@ -955,7 +955,7 @@ static int i18n_flag = 0; #endif /* ENABLE_NLS */ - len = max (strlen (header), (size_t) msglen (label, &lines)) + 4; + len = max ((int) mbstrlen (header), (size_t) msglen (label, &lines)) + 4; len = max (len, 64); #ifdef ENABLE_NLS @@ -1011,7 +1011,7 @@ { 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 -urN mc-4.6.1.orig/src/layout.c mc-4.6.1/src/layout.c --- mc-4.6.1.orig/src/layout.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/layout.c 2007-01-19 18:33:58.000000000 +0500 @@ -362,36 +362,36 @@ 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; } @@ -405,14 +405,14 @@ * * 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 @@ panel_do_cols (0); panel_do_cols (1); - promptl = strlen (prompt); + promptl = mbstrlen (prompt); widget_set_size (&the_menubar->widget, 0, 0, 1, COLS); diff -urN mc-4.6.1.orig/src/learn.c mc-4.6.1/src/learn.c --- mc-4.6.1.orig/src/learn.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/learn.c 2007-01-19 18:33:59.000000000 +0500 @@ -236,7 +236,7 @@ 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 -urN mc-4.6.1.orig/src/main.c mc-4.6.1/src/main.c --- mc-4.6.1.orig/src/main.c 2005-07-23 22:52:02.000000000 +0600 +++ mc-4.6.1/src/main.c 2007-01-19 18:33:59.000000000 +0500 @@ -86,6 +86,7 @@ #ifdef HAVE_CHARSET #include "charsets.h" +#include "recode.h" #endif /* HAVE_CHARSET */ #ifdef USE_VFS @@ -102,6 +103,7 @@ /* The structures for the panels */ WPanel *left_panel = NULL; WPanel *right_panel = NULL; +WPanel* ret_panel=NULL; /* The pointer to the tree */ WTree *the_tree = NULL; @@ -274,6 +276,9 @@ /* The user's shell */ const char *shell = NULL; +/* Is the LANG UTF-8 ? */ +gboolean is_utf8 = FALSE; + /* mc_home: The home of MC */ char *mc_home = NULL; @@ -585,6 +590,7 @@ } directory = *new_dir ? new_dir : home_dir; + ret_panel=panel; if (mc_chdir (directory) == -1) { strcpy (panel->cwd, olddir); g_free (olddir); @@ -798,6 +804,10 @@ {' ', N_("&Quick view C-x q"), 'Q', quick_view_cmd}, {' ', N_("&Info C-x i"), 'I', info_cmd}, {' ', N_("&Tree"), 'T', tree_cmd}, +#ifdef HAVE_CHARSET + {' ', "", ' ', 0}, + {' ', N_("Panel &codepage"), 'C', fnc_l_cmd}, +#endif {' ', "", ' ', 0}, {' ', N_("&Sort order..."), 'S', sort_cmd}, {' ', "", ' ', 0}, @@ -822,6 +832,10 @@ {' ', N_("&Quick view C-x q"), 'Q', quick_view_cmd}, {' ', N_("&Info C-x i"), 'I', info_cmd}, {' ', N_("&Tree"), 'T', tree_cmd}, +#ifdef HAVE_CHARSET + {' ', "", ' ', 0}, + {' ', N_("Panel &codepage"), 'C', fnc_r_cmd}, +#endif {' ', "", ' ', 0}, {' ', N_("&Sort order..."), 'S', sort_cmd}, {' ', "", ' ', 0}, @@ -1600,21 +1614,49 @@ #define xtoolkit_panel_setup() -/* Show current directory in the xterm title */ +/* Show hostname and current directory in the xterm title */ void update_xterm_title_path (void) { unsigned char *p, *s; + char *pvp; + size_t pvlen; + int pvresult; if (xterm_flag && xterm_title) { + // currrent path p = s = g_strdup (strip_home_and_password (current_panel->cwd)); + // hostname + pvlen = strlen(p); + pvp = g_malloc (pvlen + 64); //approach - max hostname length + pvresult = gethostname(pvp, 63); + if (pvresult) { // print just current path + g_free (pvp); + pvp = p; + } else { + s = pvp; + do { // merge hostname with path + if (!is_printable (*s)) + *s = '?'; + } while (*++s!=0x00); + *s++=':'; + strcpy (s, p); + g_free (p); + } + do { +#ifndef UTF8 if (!is_printable (*s)) +#else /* UTF8 */ + if (*s < ' ') +#endif /* UTF8 */ *s = '?'; } while (*++s); - fprintf (stdout, "\33]0;mc - %s\7", p); +// fprintf (stdout, "\33]0;mc - %s\7", p); + fprintf (stdout, "\33]0;mc - %s\7", pvp); fflush (stdout); - g_free (p); +// g_free (p); + g_free (pvp); } } @@ -2136,6 +2178,16 @@ /* if on, it displays the information that files have been moved to ~/.mc */ int show_change_notice = 0; + /* Check whether we have UTF-8 locale */ + char *lang = getenv("LANG"); + size_t len = 0; + + if ( lang ) + len = strlen(lang); + + if ( len >= 5 && !strcasecmp(&lang[len-5],"UTF-8") ) + is_utf8 = TRUE; + /* We had LC_CTYPE before, LC_ALL includs LC_TYPE as well */ setlocale (LC_ALL, ""); bindtextdomain ("mc", LOCALEDIR); diff -urN mc-4.6.1.orig/src/main.h mc-4.6.1/src/main.h --- mc-4.6.1.orig/src/main.h 2005-07-01 21:47:06.000000000 +0600 +++ mc-4.6.1/src/main.h 2007-01-19 18:33:59.000000000 +0500 @@ -64,6 +64,7 @@ extern int only_leading_plus_minus; extern int output_starts_shell; extern int midnight_shutdown; +extern gboolean is_utf8; extern char cmd_buf [512]; extern const char *shell; diff -urN mc-4.6.1.orig/src/Makefile.am mc-4.6.1/src/Makefile.am --- mc-4.6.1.orig/src/Makefile.am 2005-06-08 18:27:19.000000000 +0600 +++ mc-4.6.1/src/Makefile.am 2007-01-19 18:33:59.000000000 +0500 @@ -40,7 +40,8 @@ mc_LDADD = $(EDITLIB) $(SLANGLIB) $(VFSLIB) \ $(INTLLIBS) $(GLIB_LIBS) $(MCLIBS) $(LIBICONV) -CHARSET_SRC = charsets.c charsets.h selcodepage.c selcodepage.h +CHARSET_SRC = charsets.c charsets.h selcodepage.c selcodepage.h \ + recode.c recode.h SRCS = achown.c achown.h background.c background.h boxes.c boxes.h \ chmod.c chmod.h chown.c chown.h cmd.c cmd.h color.c color.h \ @@ -55,8 +56,8 @@ menu.c menu.h mountlist.c mountlist.h mouse.c mouse.h myslang.h \ option.c option.h panel.h panelize.c panelize.h poptalloca.h \ popt.c poptconfig.c popt.h popthelp.c poptint.h poptparse.c \ - profile.c profile.h regex.c rxvt.c screen.c setup.c setup.h \ - slint.c subshell.c subshell.h textconf.c textconf.h \ + profile.c profile.h regex.c rxvt.c screen.c screen.h setup.c \ + setup.h slint.c subshell.c subshell.h textconf.c textconf.h \ tree.c tree.h treestore.c treestore.h tty.h user.c user.h \ util.c util.h utilunix.c view.c view.h vfsdummy.h widget.c \ widget.h win.c win.h wtools.c wtools.h \ diff -urN mc-4.6.1.orig/src/Makefile.in mc-4.6.1/src/Makefile.in --- mc-4.6.1.orig/src/Makefile.in 2005-07-23 22:53:15.000000000 +0600 +++ mc-4.6.1/src/Makefile.in 2007-01-19 18:33:59.000000000 +0500 @@ -84,12 +84,12 @@ mouse.c mouse.h myslang.h option.c option.h panel.h panelize.c \ panelize.h poptalloca.h popt.c poptconfig.c popt.h popthelp.c \ poptint.h poptparse.c profile.c profile.h regex.c rxvt.c \ - screen.c setup.c setup.h slint.c subshell.c subshell.h \ + screen.c screen.h setup.c setup.h slint.c subshell.c subshell.h \ textconf.c textconf.h tree.c tree.h treestore.c treestore.h \ tty.h user.c user.h util.c util.h utilunix.c view.c view.h \ vfsdummy.h widget.c widget.h win.c win.h wtools.c wtools.h \ x11conn.h x11conn.c charsets.c charsets.h selcodepage.c \ - selcodepage.h + selcodepage.h recode.c recode.h am__objects_1 = achown.$(OBJEXT) background.$(OBJEXT) boxes.$(OBJEXT) \ chmod.$(OBJEXT) chown.$(OBJEXT) cmd.$(OBJEXT) color.$(OBJEXT) \ command.$(OBJEXT) complete.$(OBJEXT) cons.handler.$(OBJEXT) \ @@ -109,7 +109,8 @@ util.$(OBJEXT) utilunix.$(OBJEXT) view.$(OBJEXT) \ widget.$(OBJEXT) win.$(OBJEXT) wtools.$(OBJEXT) \ x11conn.$(OBJEXT) -am__objects_2 = charsets.$(OBJEXT) selcodepage.$(OBJEXT) +am__objects_2 = charsets.$(OBJEXT) selcodepage.$(OBJEXT) recode.$(OBJEXT) + @CHARSET_FALSE@am_mc_OBJECTS = $(am__objects_1) @CHARSET_TRUE@am_mc_OBJECTS = $(am__objects_1) $(am__objects_2) mc_OBJECTS = $(am_mc_OBJECTS) @@ -342,7 +343,8 @@ mc_LDADD = $(EDITLIB) $(SLANGLIB) $(VFSLIB) \ $(INTLLIBS) $(GLIB_LIBS) $(MCLIBS) $(LIBICONV) -CHARSET_SRC = charsets.c charsets.h selcodepage.c selcodepage.h +CHARSET_SRC = charsets.c charsets.h selcodepage.c selcodepage.h \ + recode.c recode.h SRCS = achown.c achown.h background.c background.h boxes.c boxes.h \ chmod.c chmod.h chown.c chown.h cmd.c cmd.h color.c color.h \ command.c command.h complete.c complete.h cons.handler.c \ @@ -356,8 +358,8 @@ menu.c menu.h mountlist.c mountlist.h mouse.c mouse.h myslang.h \ option.c option.h panel.h panelize.c panelize.h poptalloca.h \ popt.c poptconfig.c popt.h popthelp.c poptint.h poptparse.c \ - profile.c profile.h regex.c rxvt.c screen.c setup.c setup.h \ - slint.c subshell.c subshell.h textconf.c textconf.h \ + profile.c profile.h regex.c rxvt.c screen.c screen.h setup.c \ + setup.h slint.c subshell.c subshell.h textconf.c textconf.h \ tree.c tree.h treestore.c treestore.h tty.h user.c user.h \ util.c util.h utilunix.c view.c view.h vfsdummy.h widget.c \ widget.h win.c win.h wtools.c wtools.h \ diff -urN mc-4.6.1.orig/src/menu.c mc-4.6.1/src/menu.c --- mc-4.6.1.orig/src/menu.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/menu.c 2007-01-19 18:33:59.000000000 +0500 @@ -20,6 +20,8 @@ #include #include #include +#include + #include "global.h" #include "tty.h" #include "menu.h" @@ -50,33 +52,96 @@ { 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 (*(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); } } } } +#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->name = g_strdup (name); menu_scan_hotkey(menu); menu->start_x = 0; @@ -109,8 +174,26 @@ const unsigned 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 { @@ -119,7 +202,7 @@ addch(*(++text)); attrset(color); } - } + } } widget_move (&menubar->widget, y, x + 1); } @@ -167,7 +250,13 @@ if (menubar->active) attrset(i == menubar->selected?MENU_SELECTED_COLOR:SELECTED_COLOR); widget_move (&menubar->widget, 0, menubar->menu [i]->start_x); - printw ("%s", menubar->menu [i]->name); +#ifdef UTF8 + if (menubar->menu [i]->wname) + SLsmg_write_nwchars (menubar->menu [i]->wname, + wcslen (menubar->menu [i]->wname)); + else +#endif + printw ("%s", menubar->menu [i]->name); } if (menubar->dropped) @@ -489,7 +578,13 @@ 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; } @@ -502,7 +597,13 @@ 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); @@ -526,6 +627,9 @@ 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 -urN mc-4.6.1.orig/src/menu.h mc-4.6.1/src/menu.h --- mc-4.6.1.orig/src/menu.h 2004-09-18 20:30:59.000000000 +0600 +++ mc-4.6.1/src/menu.h 2007-01-19 18:33:59.000000000 +0500 @@ -21,6 +21,8 @@ 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 -urN mc-4.6.1.orig/src/mountlist.c mc-4.6.1/src/mountlist.c --- mc-4.6.1.orig/src/mountlist.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/mountlist.c 2007-01-19 18:33:59.000000000 +0500 @@ -132,11 +132,19 @@ struct fs_usage { +#ifndef HAVE_SYS_STATVFS_H long fsu_blocks; /* Total blocks. */ long fsu_bfree; /* Free blocks available to superuser. */ long fsu_bavail; /* Free blocks available to non-superuser. */ long fsu_files; /* Total file nodes. */ long fsu_ffree; /* Free file nodes. */ +#else /* We have sys/statvfs.h, use proper data types when _FILE_OFFSET_BITS=64 */ + fsblkcnt_t fsu_blocks; + fsblkcnt_t fsu_bfree; + fsblkcnt_t fsu_bavail; + fsblkcnt_t fsu_files; + fsblkcnt_t fsu_ffree; +#endif /* HAVE_SYS_STATVFS_H */ }; static int get_fs_usage (char *path, struct fs_usage *fsp); @@ -663,6 +671,7 @@ BLOCKS FROMSIZE-byte blocks, rounding away from zero. TOSIZE must be positive. Return -1 if FROMSIZE is not positive. */ +#if !defined(HAVE_SYS_STATFS_H) || !defined(STAT_STATVFS) static long fs_adjust_blocks (long blocks, int fromsize, int tosize) { @@ -670,13 +679,21 @@ abort (); if (fromsize <= 0) return -1; - +#else +static fsblkcnt_t +fs_adjust_blocks (fsblkcnt_t blocks, unsigned long fromsize, unsigned long tosize) +{ + if (!tosize) + abort (); + if (!fromsize) + return -1; +#endif if (fromsize == tosize) /* E.g., from 512 to 512. */ return blocks; else if (fromsize > tosize) /* E.g., from 2048 to 512. */ return blocks * (fromsize / tosize); else /* E.g., from 256 to 512. */ - return (blocks + (blocks < 0 ? -1 : 1)) / (tosize / fromsize); + return (blocks + 1) / (tosize / fromsize); } #if defined(_AIX) && defined(_I386) diff -urN mc-4.6.1.orig/src/myslang.h mc-4.6.1/src/myslang.h --- mc-4.6.1.orig/src/myslang.h 2004-10-12 10:32:04.000000000 +0600 +++ mc-4.6.1/src/myslang.h 2007-01-19 18:33:59.000000000 +0500 @@ -11,6 +11,10 @@ #endif /* HAVE_SLANG_SLANG_H */ #endif +#ifdef UTF8 +# include +#endif + enum { KEY_BACKSPACE = 400, KEY_END, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, diff -urN mc-4.6.1.orig/src/option.c mc-4.6.1/src/option.c --- mc-4.6.1.orig/src/option.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/option.c 2007-01-19 18:33:59.000000000 +0500 @@ -124,12 +124,12 @@ 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; @@ -142,23 +142,23 @@ 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 -urN mc-4.6.1.orig/src/panel.h mc-4.6.1/src/panel.h --- mc-4.6.1.orig/src/panel.h 2004-08-29 22:55:51.000000000 +0600 +++ mc-4.6.1/src/panel.h 2007-01-19 18:33:59.000000000 +0500 @@ -71,6 +71,19 @@ int searching; char search_buffer [256]; + +#ifdef HAVE_CHARSET + int src_codepage; + unsigned char tr_table[256], tr_table_input[256]; +#endif + +#ifdef USE_VFS + #ifdef HAVE_CHARSET + int ret_codepage; + #endif + int is_return; + char retdir[MC_MAXPATHLEN]; +#endif } WPanel; WPanel *panel_new (const char *panel_name); @@ -96,6 +109,7 @@ extern WPanel *left_panel; extern WPanel *right_panel; extern WPanel *current_panel; +extern WPanel* ret_panel; void try_to_select (WPanel *panel, const char *name); diff -urN mc-4.6.1.orig/src/panelize.c mc-4.6.1/src/panelize.c --- mc-4.6.1.orig/src/panelize.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/panelize.c 2007-01-19 18:33:59.000000000 +0500 @@ -127,7 +127,7 @@ 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 @@ 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 -urN mc-4.6.1.orig/src/recode.c mc-4.6.1/src/recode.c --- mc-4.6.1.orig/src/recode.c 1970-01-01 05:00:00.000000000 +0500 +++ mc-4.6.1/src/recode.c 2007-01-19 18:33:59.000000000 +0500 @@ -0,0 +1,153 @@ +#include "recode.h" +#ifdef HAVE_CHARSET + +char *lang; +char lang_codepage_name[256]; +int lang_codepage; + +int ftp_codepage=-1; + +// recode buffer for displaying file names +unsigned char recode_buf[MC_MAXPATHLEN]; + +WPanel* recode_panel; + +//--- get codepage from $LANG +void get_locale_codepage() { + char* a; + char* b; + int len; + + lang=getenv("LANG"); + if(!lang) { + strncpy(lang_codepage_name,OTHER_8BIT, sizeof(OTHER_8BIT)); + lang_codepage=-1; + return; + } + + a=strchr(lang,'.'); + if(!a) { + strncpy(lang_codepage_name,OTHER_8BIT, sizeof(OTHER_8BIT)); + lang_codepage=-1; + return; + } + ++a; + + b=strchr(lang,'@'); + if(!b) b=lang+strlen(lang); + + len=b-a; + if(len>=sizeof(lang_codepage_name)) len=sizeof(lang_codepage_name)-1; + + memcpy(lang_codepage_name,a, len); + lang_codepage_name[len]='\0'; + lang_codepage=get_codepage_index(lang_codepage_name); + if(lang_codepage<0) strncpy(lang_codepage_name,OTHER_8BIT, sizeof(OTHER_8BIT)); +} + +//--- reset translation table +void my_reset_tt(unsigned char *table,int n) { + int i; + for(i=0;isrc_codepage=-1; + my_reset_tt(p->tr_table,256); + my_reset_tt(p->tr_table_input,256); +} + +//--- Initialize translation table +// i need this function because init_translation_table from +// charsets.c fills only fixed translation tables conv_displ and conv_input +//--- +char* my_init_tt( int from, int to, unsigned char *table) { + int i; + iconv_t cd; + char *cpfrom, *cpto; + + if(from < 0 || to < 0 || from == to) { + my_reset_tt(table,256); + return NULL; + } + my_reset_tt(table,128); + cpfrom=codepages[from ].id; + cpto=codepages[to].id; + cd=iconv_open(cpfrom, cpto); + if(cd==(iconv_t)-1) { + snprintf(errbuf, 255, _("Cannot translate from %s to %s"), cpfrom, cpto); + return errbuf; + } + for(i=128; i<=255; ++i) table[i] = translate_character(cd, i); + iconv_close(cd); + return NULL; +} + +//--- Translate string from one codepage to another +void my_translate_string(unsigned char *s1,int l1, unsigned char *s2, unsigned char *table) { + int i=0; + if(!s1) return; + while(irecode_buf,ctx->tr_table); + if (dir [i-1] == PATH_SEP) + return g_strconcat (dir, ctx->recode_buf, NULL); + else + return g_strconcat (dir, PATH_SEP_STR, ctx->recode_buf, NULL); + return 0; +} + + +//--- Internal handler for "Panel codepage" +static void fnc_cmd(WPanel *p) { + char *errmsg; + if(display_codepage > 0) { + p->src_codepage=select_charset(p->src_codepage, 0, _(" Choose panel codepage ")); + errmsg=my_init_tt(display_codepage,p->src_codepage,p->tr_table); + if(errmsg) { + panel_reset_codepage(p); + message( 1, MSG_ERROR, "%s", errmsg); + } + errmsg=my_init_tt(p->src_codepage,display_codepage,p->tr_table_input); + if (errmsg) { + panel_reset_codepage(p); + message( 1, MSG_ERROR, "%s", errmsg ); + } + paint_dir(p); + show_dir(p); + display_mini_info(p); + } + else { + message( 1, _(" Warning "), + _("To use this feature select your codepage in\n" + "Setup / Display Bits dialog!\n" + "Do not forget to save options." )); + } +} + +//--- Menu handlers for "Panel codepage" for left and right panel menu + +void fnc_l_cmd() { + fnc_cmd(left_panel); +} + +void fnc_r_cmd() { + fnc_cmd(right_panel); +} + +//--- screen handler for "Panel codepage" +void fnc_c_cmd(WPanel *panel) { + fnc_cmd(current_panel); +} + +#endif //HAVE_CHARSET diff -urN mc-4.6.1.orig/src/recode.h mc-4.6.1/src/recode.h --- mc-4.6.1.orig/src/recode.h 1970-01-01 05:00:00.000000000 +0500 +++ mc-4.6.1/src/recode.h 2007-01-19 18:33:59.000000000 +0500 @@ -0,0 +1,48 @@ +#ifndef __RECODE_H__ +#define __RECODE_H__ +#include +#ifdef HAVE_CHARSET + +#include +#include +#include + +#include "global.h" +#include "wtools.h" +#include "panel.h" +#include "charsets.h" +#include "selcodepage.h" +#include "screen.h" +#include "main.h" +#include "fileopctx.h" + +extern char *lang; +extern char lang_codepage_name[256]; +extern int lang_codepage; + +extern int ftp_codepage; + +// recode buffer for displaying file names +extern unsigned char recode_buf[MC_MAXPATHLEN]; +extern WPanel* recode_panel; + +//--- get codepage from $LANG +extern void get_locale_codepage(); + +//--- reset translation table +extern void my_reset_tt(unsigned char *table,int n); +//--- reset panel codepage +extern void panel_reset_codepage(WPanel *p); +//--- Initialize translation table +extern char* my_init_tt( int from, int to, unsigned char *table); +//--- Translate string from one codepage to another +extern void my_translate_string(unsigned char *s1,int l1, unsigned char *s2, unsigned char *table); +//--- Recode filename and concat in to dir +extern char* concat_dir_and_recoded_fname(const char *dir, const char *fname, FileOpContext *ctx); +//--- handlers for "Panel codepage" +extern void fnc_l_cmd(); +extern void fnc_r_cmd(); +extern void fnc_c_cmd(WPanel *panel); + +#endif // HAVE_CHARSET +#endif //__RECODE_H__ diff -urN mc-4.6.1.orig/src/screen.c mc-4.6.1/src/screen.c --- mc-4.6.1.orig/src/screen.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/screen.c 2007-01-19 18:33:59.000000000 +0500 @@ -48,6 +48,10 @@ #define WANT_WIDGETS #include "main.h" /* the_menubar */ +#ifdef HAVE_CHARSET +#include "recode.h" +#endif + #define ELEMENTS(arr) ( sizeof(arr) / sizeof((arr)[0]) ) #define J_LEFT 1 @@ -169,22 +173,67 @@ static const char * string_file_name (file_entry *fe, int len) { - static char buffer [BUF_SMALL]; size_t i; + char* filename; +#ifdef UTF8 + static char buffer [BUF_SMALL * 4]; + mbstate_t s; + int mbmax = MB_CUR_MAX; + const char *str = fe->fname; - for (i = 0; i < sizeof(buffer) - 1; i++) { - char c; + memset (&s, 0, sizeof (s)); +#else + static char buffer [BUF_SMALL]; +#endif - c = fe->fname[i]; +#ifdef HAVE_CHARSET + my_translate_string(fe->fname,fe->fnamelen, recode_buf, recode_panel->tr_table); + filename= recode_buf; +#else + filename=fe->fname; +#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; - buffer[i] = c; - } + c= filename[i]; + + if (!c) + break; + + if (!is_printable(c)) + c = '?'; + + buffer[i] = c; + } buffer[i] = 0; return buffer; @@ -425,42 +474,6 @@ { "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) { @@ -514,14 +527,18 @@ /* 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; length = 0; empty_line = (file_index >= panel->count); @@ -539,34 +556,137 @@ 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 = strlen (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); @@ -589,7 +709,10 @@ { int second_column = 0; int width, offset; - char buffer [BUF_MEDIUM]; + +#ifdef HAVE_CHARSET + recode_panel=panel; +#endif offset = 0; if (!isstatus && panel->split){ @@ -618,7 +741,7 @@ 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) @@ -630,7 +753,7 @@ } } -static void +void display_mini_info (WPanel *panel) { if (!show_mini_info) @@ -658,7 +781,7 @@ g_snprintf (buffer, sizeof (buffer), (panel->marked == 1) ? _("%s bytes in %d file") : _("%s bytes in %d files"), size_trunc_sep (panel->total), panel->marked); - if ((int) strlen (buffer) > cols-2){ + if ((int) mbstrlen (buffer) > cols-2){ buffer [cols] = 0; p += 2; } else @@ -691,7 +814,7 @@ return; } -static void +void paint_dir (WPanel *panel) { int i; @@ -729,7 +852,7 @@ #endif /* !HAVE_SLANG */ } -static void +void show_dir (WPanel *panel) { char *tmp; @@ -749,6 +872,9 @@ } #endif /* HAVE_SLANG */ + vscrollbar (panel->widget, panel->widget.lines, panel->widget.cols-1, 2, 2, + panel->selected, panel->count, TRUE); + if (panel->active) attrset (REVERSE_COLOR); @@ -757,8 +883,15 @@ tmp = g_malloc (panel->widget.cols + 1); tmp[panel->widget.cols] = '\0'; +#ifdef HAVE_CHARSET + my_translate_string(panel->cwd,strlen(panel->cwd),recode_buf, panel->tr_table); + trim (strip_home_and_password (recode_buf), tmp, + min (max (panel->widget.cols - 7, 0), panel->widget.cols) ); +#else trim (strip_home_and_password (panel->cwd), tmp, min (max (panel->widget.cols - 7, 0), panel->widget.cols) ); +#endif + addstr (tmp); g_free (tmp); widget_move (&panel->widget, 0, 1); @@ -970,6 +1103,17 @@ mc_get_current_wd (panel->cwd, sizeof (panel->cwd) - 2); strcpy (panel->lwd, "."); +#ifdef HAVE_CHARSET + panel_reset_codepage(panel); +#endif + +#ifdef USE_VFS + panel->is_return=0; + #ifdef HAVE_CHARSET + panel->ret_codepage=-1; + #endif +#endif + panel->hist_name = g_strconcat ("Dir Hist ", panel_name, (char *) NULL); panel->dir_history = history_get (panel->hist_name); directory_history_add (panel, panel->cwd); @@ -1068,6 +1212,12 @@ 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); @@ -1092,16 +1242,37 @@ if (format->string_fn){ txt = format->title; + 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 = strlen (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; printw ("%*s%.*s%*s", spaces, "", header_len, txt, spaces+extra, ""); - width -= 2 * spaces + extra + header_len; } else { attrset (NORMAL_COLOR); one_vline (); @@ -1320,7 +1491,7 @@ panel->dirty = 1; /* Status needn't to be split */ - usable_columns = ((panel->widget.cols-2)/((isstatus) + usable_columns = ((panel->widget.cols-3)/((isstatus) ? 1 : (panel->split+1))) - (!isstatus && panel->split); @@ -2100,7 +2271,12 @@ { XCTRL('n'), move_down }, /* C-n like emacs */ { XCTRL('s'), start_search }, /* C-s like emacs */ { ALT('s'), start_search }, /* M-s not like emacs */ +#ifndef HAVE_CHARSET { XCTRL('t'), mark_file }, +#endif +#ifdef HAVE_CHARSET + { XCTRL('t'), mark_file }, /* was 'fnc_c_cmd' */ +#endif { ALT('o'), chdir_other_panel }, { ALT('l'), chdir_to_readlink }, { ALT('H'), directory_history_list }, diff -urN mc-4.6.1.orig/src/screen.h mc-4.6.1/src/screen.h --- mc-4.6.1.orig/src/screen.h 1970-01-01 05:00:00.000000000 +0500 +++ mc-4.6.1/src/screen.h 2007-01-19 18:33:59.000000000 +0500 @@ -0,0 +1,11 @@ +#ifndef __SCREEN_H__ +#define __SCREEN_H__ +#include + +#include "global.h" + +extern void paint_dir (WPanel *panel); +extern void display_mini_info (WPanel *panel); +extern void show_dir(WPanel *panel); +#endif //__SCREEN_H__ + diff -urN mc-4.6.1.orig/src/selcodepage.c mc-4.6.1/src/selcodepage.c --- mc-4.6.1.orig/src/selcodepage.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/selcodepage.c 2007-01-19 18:33:59.000000000 +0500 @@ -44,14 +44,16 @@ } int -select_charset (int current_charset, int seldisplay) +select_charset (int current_charset, int seldisplay, const char *title) { + int new_charset; + int i, menu_lines = n_codepages + 1; char buffer[255]; /* Create listbox */ Listbox *listbox = create_listbox_window (ENTRY_LEN + 2, menu_lines, - _(" Choose input codepage "), + title, "[Codepages Translation]"); if (!seldisplay) @@ -81,20 +83,26 @@ i = run_listbox (listbox); - return (seldisplay) ? ((i >= n_codepages) ? -1 : i) - : (i - 1); + if(i==-1) + i = (seldisplay) + ? ((current_charset < 0) ? n_codepages : current_charset) + : (current_charset + 1); + + new_charset =(seldisplay) ? ( (i >= n_codepages) ? -1 : i ) : ( i-1 ); + new_charset = (new_charset==-2) ? current_charset:new_charset; + return new_charset; } /* Helper functions for codepages support */ int -do_select_codepage (void) +do_select_codepage (const char *title) { const char *errmsg; if (display_codepage > 0) { - source_codepage = select_charset (source_codepage, 0); + source_codepage = select_charset (source_codepage, 0, title); errmsg = init_translation_table (source_codepage, display_codepage); if (errmsg) { diff -urN mc-4.6.1.orig/src/selcodepage.h mc-4.6.1/src/selcodepage.h --- mc-4.6.1.orig/src/selcodepage.h 2002-10-31 04:16:16.000000000 +0500 +++ mc-4.6.1/src/selcodepage.h 2007-01-19 18:33:59.000000000 +0500 @@ -2,8 +2,8 @@ #ifndef __SELCODEPAGE_H__ #define __SELCODEPAGE_H__ -int select_charset (int current_charset, int seldisplay); -int do_select_codepage (void); +int select_charset (int current_charset, int seldisplay, const char *title); +int do_select_codepage (const char *title); #endif /* __SELCODEPAGE_H__ */ #endif /* HAVE_CHARSET */ diff -urN mc-4.6.1.orig/src/setup.c mc-4.6.1/src/setup.c --- mc-4.6.1.orig/src/setup.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/setup.c 2007-01-19 18:33:59.000000000 +0500 @@ -47,6 +47,8 @@ #ifdef HAVE_CHARSET #include "charsets.h" +#include"recode.h" +#include "wtools.h" #endif #ifdef USE_NETCODE @@ -255,6 +257,11 @@ g_snprintf (buffer, sizeof (buffer), "%d", panel->user_mini_status); save_string (section, "user_mini_status", buffer, profile_name); + +#ifdef HAVE_CHARSET + // save panel codepage + save_string(section, "panel_display_codepage", get_codepage_id(panel->src_codepage), profile_name); +#endif } void @@ -352,6 +359,7 @@ #ifdef HAVE_CHARSET save_string( "Misc", "display_codepage", get_codepage_id( display_codepage ), profile_name ); + save_string( "Misc", "ftp_codepage", get_codepage_id(ftp_codepage), profile_name); #endif /* HAVE_CHARSET */ g_free (profile); @@ -401,6 +409,31 @@ panel->user_mini_status = load_int (section, "user_mini_status", 0); +#ifdef HAVE_CHARSET +//--- Loading panel codepage + panel_reset_codepage(panel); + if(load_codepages_list()>0) { + char cpname[128]; + char *errmsg; + + + if(display_codepage>=0) { + load_string(section, "panel_display_codepage", "", cpname, sizeof(cpname)); + if(cpname[0]!='\0') panel->src_codepage = get_codepage_index(cpname); + } + + errmsg=my_init_tt(display_codepage,panel->src_codepage,panel->tr_table); + if(errmsg) { + panel_reset_codepage(panel); + message( 1, MSG_ERROR, "%s", errmsg ); + } + errmsg=my_init_tt(panel->src_codepage,display_codepage,panel->tr_table_input); + if(errmsg) { + panel_reset_codepage(panel); + message( 1, MSG_ERROR, "%s", errmsg ); + } + } +#endif } static void @@ -543,12 +576,18 @@ #endif /* USE_VFS && USE_NETCODE */ #ifdef HAVE_CHARSET - if ( load_codepages_list() > 0 ) { - char cpname[128]; - load_string( "Misc", "display_codepage", "", - cpname, sizeof(cpname) ); - if ( cpname[0] != '\0' ) - display_codepage = get_codepage_index( cpname ); + if(load_codepages_list() > 0) { + char cpname[128]; + get_locale_codepage(); + load_string("Misc", "display_codepage", "", cpname, sizeof(cpname)); + if(cpname[0] != '\0') display_codepage=get_codepage_index(cpname); + else display_codepage=lang_codepage; + + ftp_codepage=-1; + if(display_codepage >= 0) { + load_string( "Misc", "ftp_codepage", "", cpname, sizeof(cpname)); + if(cpname[0] != '\0') ftp_codepage=get_codepage_index(cpname); + } } init_translation_table( source_codepage, display_codepage ); diff -urN mc-4.6.1.orig/src/slint.c mc-4.6.1/src/slint.c --- mc-4.6.1.orig/src/slint.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/slint.c 2007-01-19 18:33:59.000000000 +0500 @@ -180,6 +180,9 @@ struct sigaction act, oact; SLtt_get_terminfo (); +#if SLANG_VERSION >= 20000 + SLutf8_enable (-1); +#endif /* * If the terminal in not in terminfo but begins with a well-known diff -urN mc-4.6.1.orig/src/util.c mc-4.6.1/src/util.c --- mc-4.6.1.orig/src/util.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/util.c 2007-01-19 18:33:59.000000000 +0500 @@ -32,7 +32,11 @@ #include #include #include +#include +#include +#include +#include "tty.h" #include "global.h" #include "profile.h" #include "main.h" /* mc_home */ @@ -44,9 +48,40 @@ #include "charsets.h" #endif +#ifdef UTF8 +#include +#include +#endif + static const char app_text [] = "Midnight-Commander"; int easy_patterns = 1; +#if SLANG_VERSION >= 20000 +void SLsmg_write_nwchars(wchar_t *s, size_t n) +{ + if (SLsmg_is_utf8_mode()) { /* slang can handle it directly */ + while(n-- && *s) + SLsmg_write_char(*s++); + } + else { /* convert wchars back to 8bit encoding */ + mbstate_t mbs; + memset (&mbs, 0, sizeof (mbs)); + while (n-- && *s) { + char buf[MB_LEN_MAX + 1]; /* should use 1 char, but to be sure */ + if (*s < 0x80) { + SLsmg_write_char(*s++); /* ASCII */ + } + else { + if (wcrtomb(buf, *s++, &mbs) == 1) + SLsmg_write_char((wchar_t)(buf[0])); + else + SLsmg_write_char('?'); /* should not happen */ + } + } + } +} +#endif + extern void str_replace(char *s, char from, char to) { for (; *s != '\0'; s++) { @@ -77,9 +112,106 @@ return (c > 31 && c != 127 && c != 155); } +size_t +mbstrlen (const char *str) +{ +#ifdef UTF8 + if (SLsmg_Is_Unicode) { + size_t width = 0; + + for (; *str; str++) { + wchar_t c; + size_t len; + + len = mbrtowc (&c, str, MB_CUR_MAX, NULL); + + if (len == (size_t)(-1) || len == (size_t)(-2)) break; + + if (len > 0) { + int wcsize = wcwidth(c); + width += wcsize > 0 ? wcsize : 0; + str += len-1; + } + } + + return width; + } else +#endif + 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 + + + +#ifdef UTF8 +wchar_t * +mbstr_to_wchar (const char *str) +{ + int len = mbstrlen(str); + wchar_t *buf = g_malloc((len+1) * sizeof(wchar_t)); + mbstate_t mbs; + memset (&mbs, 0, sizeof (mbs)); + mbsrtowcs (buf, &str, len, &mbs); + buf[len] = 0; + return buf; +} + +char * +wchar_to_mbstr (const wchar_t *wstr) +{ + mbstate_t mbs; + const wchar_t *wstr2; + char * string; + int len; + + memset (&mbs, 0, sizeof (mbs)); + wstr2 = wstr; + len = wcsrtombs(NULL, &wstr2, 0, &mbs); + if (len <= 0) + return NULL; + + string = g_malloc(len + 1); + + wstr2 = wstr; + wcsrtombs(string, &wstr2, len, &mbs); + string[len] = 0; + return string; +} +#endif + + + int is_printable (int c) { +#ifdef UTF8 + if (SLsmg_Is_Unicode) + return iswprint (c); +#endif c &= 0xff; #ifdef HAVE_CHARSET @@ -97,7 +229,7 @@ #endif /* !HAVE_CHARSET */ } -/* Returns the message dimensions (lines and columns) */ +/* Returns the message dimensions columns */ int msglen (const char *text, int *lines) { int max = 0; @@ -108,8 +240,18 @@ line_len = 0; (*lines)++; } else { - line_len++; - if (line_len > max) +#ifdef UTF8 + size_t len; + wchar_t c; + + len = mbrtowc (&c, text, MB_CUR_MAX, NULL); + if (len > 0 && len != (size_t)(-1) && len != (size_t)(-2)) { + int wcsize = wcwidth(c); + line_len += wcsize > 0 ? wcsize-1 : -1; + text += len-1; + } +#endif + if (++line_len > max) max = line_len; } } @@ -201,7 +343,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; @@ -222,25 +381,90 @@ name_trunc (const char *txt, int trunc_len) { static char x[MC_MAXPATHLEN + MC_MAXPATHLEN]; - int txt_len; + int txt_len, first, skip; char *p; + const char *str; if ((size_t) trunc_len > sizeof (x) - 1) { trunc_len = sizeof (x) - 1; } - txt_len = strlen (txt); - if (txt_len <= trunc_len) { - strcpy (x, txt); - } else { - int y = (trunc_len / 2) + (trunc_len % 2); - strncpy (x, txt, y); - strncpy (x + y, txt + txt_len - (trunc_len / 2), trunc_len / 2); - x[y] = '~'; - } - x[trunc_len] = 0; - for (p = x; *p; p++) - if (!is_printable (*p)) - *p = '?'; + txt_len = mbstrlen (txt); + first = 0; + skip = 0; + if (txt_len > trunc_len) { + first = trunc_len / 2; + skip = txt_len - trunc_len + 1; + } + +#ifdef UTF8 + if (SLsmg_Is_Unicode) { + mbstate_t s; + int mbmax; + + str = txt; + memset (&s, 0, sizeof (s)); + mbmax = MB_CUR_MAX; + p = x; + while (p < x + sizeof (x) - 1 && trunc_len) { + wchar_t wc; + int len; + + len = mbrtowc (&wc, str, mbmax, &s); + if (!len) + break; + if (len < 0) { + memset (&s, 0, sizeof (s)); + *p = '?'; + len = 1; + str++; + } else if (!is_printable (wc)) { + *p = '?'; + str += len; + len = 1; + } else if (p >= x + sizeof (x) - len) + break; + else { + memcpy (p, str, len); + str += len; + } + if (first) { + --trunc_len; + --first; + p += len; + if (!first && p < x + sizeof (x) - 1 && trunc_len) { + *p++ = '~'; + --trunc_len; + } + } else if (skip) + --skip; + else { + --trunc_len; + p += len; + } + } + } else +#endif + { + str = txt; + p = x; + while (p < x + sizeof (x) - 1) { + if (*str == '\0') + break; + else if (!is_printable (*str)) + *p++ = '?'; + else + *p++ = *str; + ++str; + if (first) { + --first; + if (!first) { + *p++ = '~'; + str += skip; + } + } + } + } + *p = '\0'; return x; } @@ -650,11 +874,66 @@ } char * +utf8_to_local(char *str) +{ + iconv_t cd; + size_t buflen; + char *output; + int retry = 1; + + if (str == NULL) + return NULL; + else + buflen = strlen(str); + + cd = iconv_open (nl_langinfo(CODESET), "UTF-8"); + if (cd == (iconv_t) -1) { + return g_strdup(str); + } + + output = g_malloc(buflen + 1); + + while (retry) + { + char *wrptr = output; + char *inptr = str; + size_t insize = buflen; + size_t avail = buflen; + size_t nconv; + + nconv = iconv (cd, &inptr, &insize, &wrptr, &avail); + if (nconv == (size_t) -1) + { + if (errno == E2BIG) + { + buflen *= 2; + g_free(output); + output = g_malloc(buflen + 1); + } + else + { + g_free(output); + return g_strdup(str); + } + } + else { + retry = 0; + *wrptr = 0; + } + } + + iconv_close (cd); + + return output; +} + +char * load_mc_home_file (const char *filename, char **allocated_filename) { char *hintfile_base, *hintfile; char *lang; char *data; + char *conv_data; hintfile_base = concat_dir_and_file (mc_home, filename); lang = guess_message_value (); @@ -687,7 +966,10 @@ else g_free (hintfile); - return data; + conv_data = utf8_to_local(data); + g_free(data); + + return conv_data; } /* Check strftime() results. Some systems (i.e. Solaris) have different @@ -695,12 +977,14 @@ size_t i18n_checktimelength (void) { size_t length, a, b; - char buf [MAX_I18NTIMELENGTH + 1]; + char buf [4 * MAX_I18NTIMELENGTH + 1]; time_t testtime = time (NULL); - a = strftime (buf, sizeof(buf)-1, _("%b %e %H:%M"), localtime(&testtime)); - b = strftime (buf, sizeof(buf)-1, _("%b %e %Y"), localtime(&testtime)); - + strftime (buf, sizeof(buf)-1, _("%b %e %H:%M"), localtime(&testtime)); + a = mbstrlen (buf); + strftime (buf, sizeof(buf)-1, _("%b %e %Y"), localtime(&testtime)); + b = mbstrlen (buf); + length = max (a, b); /* Don't handle big differences. Use standard value (email bug, please) */ @@ -712,15 +996,12 @@ const char *file_date (time_t when) { - static char timebuf [MAX_I18NTIMELENGTH + 1]; + static char timebuf [4 * MAX_I18NTIMELENGTH + 1]; time_t current_time = time ((time_t) 0); - static size_t i18n_timelength = 0; static const char *fmtyear, *fmttime; const char *fmt; - if (i18n_timelength == 0){ - i18n_timelength = i18n_checktimelength() + 1; - + if (fmtyear == NULL) { /* strftime() format string for old dates */ fmtyear = _("%b %e %Y"); /* strftime() format string for recent dates */ @@ -740,7 +1021,7 @@ else fmt = fmttime; - strftime (timebuf, i18n_timelength, fmt, localtime(&when)); + strftime (timebuf, sizeof (timebuf) - 1, fmt, localtime(&when)); return timebuf; } @@ -863,10 +1144,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; @@ -1140,21 +1438,23 @@ * as needed up in first and then goes down using second */ char *diff_two_paths (const char *first, const char *second) { - char *p, *q, *r, *s, *buf = 0; + char *p, *q, *r, *s, *buf = NULL; int i, j, prevlen = -1, currlen; char *my_first = NULL, *my_second = NULL; my_first = resolve_symlinks (first); if (my_first == NULL) return NULL; + my_second= resolve_symlinks (second); + if (my_second == NULL) { + g_free (my_first); + return NULL; + } for (j = 0; j < 2; j++) { p = my_first; if (j) { - my_second = resolve_symlinks (second); - if (my_second == NULL) { - g_free (my_first); + if (my_second == NULL) return buf; - } } q = my_second; for (;;) { diff -urN mc-4.6.1.orig/src/util.h mc-4.6.1/src/util.h --- mc-4.6.1.orig/src/util.h 2005-01-14 00:20:47.000000000 +0500 +++ mc-4.6.1/src/util.h 2007-01-19 18:33:59.000000000 +0500 @@ -93,6 +93,13 @@ 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 @@ -210,7 +217,7 @@ #define PATH_ENV_SEP ':' #define TMPDIR_DEFAULT "/tmp" #define SCRIPT_SUFFIX "" -#define get_default_editor() "vi" +#define get_default_editor() "editor" #define OS_SORT_CASE_SENSITIVE_DEFAULT 1 #define STRCOMP strcmp #define STRNCOMP strncmp diff -urN mc-4.6.1.orig/src/view.c mc-4.6.1/src/view.c --- mc-4.6.1.orig/src/view.c 2005-05-27 20:19:18.000000000 +0600 +++ mc-4.6.1/src/view.c 2007-01-19 18:33:59.000000000 +0500 @@ -36,6 +36,10 @@ #include #include +#ifdef UTF8 +#include +#endif /* UTF8 */ + #include "global.h" #include "tty.h" #include "cmd.h" /* For view_other_cmd */ @@ -793,7 +797,7 @@ if (!i18n_adjust) { file_label = _("File: %s"); - i18n_adjust = strlen (file_label) - 2; + i18n_adjust = mbstrlen (file_label) - 2; } if (w < i18n_adjust + 6) @@ -849,7 +853,11 @@ widget_erase ((Widget *) view); } +#ifndef UTF8 #define view_add_character(view,c) addch (c) +#else /* UTF8 */ +#define view_add_character(view,c) {wchar_t tmp=c; SLsmg_write_nwchars(&tmp, 1);} +#endif /* UTF8 */ #define view_add_one_vline() one_vline() #define view_add_string(view,s) addstr (s) #define view_gotoyx(v,r,c) widget_move (v,r,c) @@ -1071,6 +1079,12 @@ if (view->growing_buffer && from == view->last_byte) get_byte (view, from); for (; row < height && from < view->last_byte; from++) { +#ifdef UTF8 + mbstate_t mbs; + char mbbuf[MB_LEN_MAX]; + int mblen; + wchar_t wc; +#endif /* UTF8 */ c = get_byte (view, from); if ((c == '\n') || (col >= width && view->wrap_mode)) { col = frame_shift; @@ -1084,7 +1098,37 @@ col = ((col - frame_shift) / 8) * 8 + 8 + frame_shift; continue; } +#ifndef UTF8 if (view->viewer_nroff_flag && 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->viewer_nroff_flag && wc == '\b') { +#endif /* UTF8 */ int c_prev; int c_next; @@ -1122,12 +1166,23 @@ && col < width - view->start_col) { view_gotoyx (view, row, col + view->start_col); +#ifndef UTF8 c = convert_to_display_c (c); - if (!is_printable (c)) c = '.'; - view_add_character (view, c); +#else /* UTF8 */ + if (!iswprint (wc)) + wc = '.'; + view_add_character (view, wc); + + { + int cw = wcwidth(wc); + if (cw > 1) + col+= cw - 1; + } +#endif /* UTF8 */ + } col++; if (boldflag != MARK_NORMAL) { @@ -1239,7 +1294,12 @@ if (lines != -1 && line >= lines) return p; - c = get_byte (view, p); + if ((c = get_byte (view, p)) == -1) { + if (upto) + return line; + else + return p; + } if (view->wrap_mode) { if (c == '\r') @@ -2534,7 +2594,7 @@ #ifdef HAVE_CHARSET case XCTRL ('t'): - do_select_codepage (); + do_select_codepage (_(" Choose codepage ")); view->dirty++; view_update (view, TRUE); return MSG_HANDLED; diff -urN mc-4.6.1.orig/src/widget.c mc-4.6.1/src/widget.c --- mc-4.6.1.orig/src/widget.c 2005-05-27 20:19:19.000000000 +0600 +++ mc-4.6.1/src/widget.c 2007-01-19 18:33:59.000000000 +0500 @@ -33,6 +33,9 @@ #include #include "global.h" #include "tty.h" +#ifdef UTF8 +#include +#endif /* UTF8 */ #include "color.h" #include "mouse.h" #include "dialog.h" @@ -148,6 +151,11 @@ if (b->hotpos >= 0) { attrset ((b->selected) ? HOT_FOCUSC : HOT_NORMALC); widget_move (&b->widget, 0, b->hotpos + off); +#ifdef UTF8 + if (SLsmg_Is_Unicode) + SLsmg_write_nwchars (&b->hotwc, 1); + else +#endif addch ((unsigned char) b->text[b->hotpos]); } return MSG_HANDLED; @@ -179,7 +187,7 @@ static int button_len (const char *text, unsigned int flags) { - int ret = strlen (text); + int ret = mbstrlen (text); switch (flags){ case DEFPUSH_BUTTON: ret += 6; @@ -202,14 +210,36 @@ * the button text is g_malloc()ed, we can safely change and shorten it. */ static void -button_scan_hotkey (WButton *b) +scan_hotkey (char *text, int *hotposp, int *hotkeyp, wchar_t *hotwcp) { - char *cp = strchr (b->text, '&'); + char *cp = strchr (text, '&'); if (cp != NULL && cp[1] != '\0') { - g_strlcpy (cp, cp + 1, strlen (cp)); - b->hotkey = tolower (*cp); - b->hotpos = cp - b->text; +#ifdef UTF8 + if (SLsmg_Is_Unicode) { + mbstate_t s; + int len; + + *cp = '\0'; + memset (&s, 0, sizeof (s)); + len = mbrtowc (hotwcp, cp + 1, MB_CUR_MAX, &s); + if (len > 0) { + *hotposp = mbstrlen (text); + if (*hotposp < 0) { + *hotposp = -1; + } else { + /* FIXME */ + *hotkeyp = tolower (*hotwcp); + } + } + } else +#endif + { + *hotkeyp = tolower (cp[1]); + *hotposp = cp - text; + } + + memmove (cp, cp + 1, strlen (cp + 1) + 1); } } @@ -231,22 +261,23 @@ widget_want_hotkey (b->widget, 1); b->hotkey = 0; b->hotpos = -1; + b->hotwc = L'\0'; - button_scan_hotkey(b); + scan_hotkey(b->text, &b->hotpos, &b->hotkey, &b->hotwc); return b; } void button_set_text (WButton *b, const char *text) { - g_free (b->text); + g_free (b->text); b->text = g_strdup (text); b->widget.cols = button_len (text, b->flags); - button_scan_hotkey(b); + scan_hotkey(b->text, &b->hotpos, &b->hotkey, &b->hotwc); dlg_redraw (b->widget.parent); } - + /* Radio button widget */ static int radio_event (Gpm_Event *event, WRadio *r); @@ -320,16 +351,37 @@ widget_move (&r->widget, i, 0); printw ("(%c) ", (r->sel == i) ? '*' : ' '); - for (cp = r->texts[i]; *cp; cp++) { - if (*cp == '&') { - attrset ((i == r->pos && msg == WIDGET_FOCUS) - ? HOT_FOCUSC : HOT_NORMALC); - addch (*++cp); - attrset ((i == r->pos - && msg == WIDGET_FOCUS) ? FOCUSC : NORMALC); + cp = strchr (r->texts[i], '&'); + if (cp != NULL) { +#ifdef UTF8 + mbstate_t s; + wchar_t wc; + int len; +#endif + printw ("%.*s", (int) ((char *) cp - r->texts[i]), + r->texts[i]); + attrset ((i == r->pos && msg == WIDGET_FOCUS) + ? HOT_FOCUSC : HOT_NORMALC); +#ifdef UTF8 + if (SLsmg_Is_Unicode) { + memset (&s, 0, sizeof (s)); + len = mbrtowc (&wc, cp + 1, MB_CUR_MAX, &s); + ++cp; + if (len > 0) { + printw ("%.*s", len, cp); + cp += len; + } } else - addch (*cp); - } +#endif + { + addch (*++cp); + ++cp; + } + attrset ((i == r->pos && msg == WIDGET_FOCUS) + ? FOCUSC : NORMALC); + } else + cp = r->texts[i]; + addstr ((char *) cp); } return MSG_HANDLED; @@ -365,7 +417,7 @@ /* Compute the longest string */ max = 0; for (i = 0; i < count; i++){ - m = strlen (texts [i]); + m = mbstrlen (texts [i]); if (m > max) max = m; } @@ -426,6 +478,11 @@ if (c->hotpos >= 0) { attrset ((msg == WIDGET_FOCUS) ? HOT_FOCUSC : HOT_NORMALC); widget_move (&c->widget, 0, +c->hotpos + 4); +#ifdef UTF8 + if (SLsmg_Is_Unicode) + SLsmg_write_nwchars (&c->hotwc, 1); + else +#endif addch ((unsigned char) c->text[c->hotpos]); } return MSG_HANDLED; @@ -460,32 +517,18 @@ check_new (int y, int x, int state, const char *text) { WCheck *c = g_new (WCheck, 1); - const char *s; - char *t; - init_widget (&c->widget, y, x, 1, strlen (text), + init_widget (&c->widget, y, x, 1, mbstrlen (text), (callback_fn)check_callback, (mouse_h) check_event); c->state = state ? C_BOOL : 0; c->text = g_strdup (text); c->hotkey = 0; c->hotpos = -1; + c->hotwc = L'\0'; widget_want_hotkey (c->widget, 1); - /* Scan for the hotkey */ - for (s = text, t = c->text; *s; s++, t++){ - if (*s != '&'){ - *t = *s; - continue; - } - s++; - if (*s){ - c->hotkey = tolower (*s); - c->hotpos = t - c->text; - } - *t = *s; - } - *t = 0; + scan_hotkey (c->text, &c->hotpos, &c->hotkey, &c->hotwc); return c; } @@ -527,7 +570,7 @@ } widget_move (&l->widget, y, 0); printw ("%s", p); - xlen = l->widget.cols - strlen (p); + xlen = l->widget.cols - mbstrlen (p); if (xlen > 0) printw ("%*s", xlen, " "); if (!q) @@ -561,7 +604,7 @@ if (text){ label->text = g_strdup (text); if (label->auto_adjust_cols) { - newcols = strlen (text); + newcols = mbstrlen (text); if (newcols > label->widget.cols) label->widget.cols = newcols; } @@ -585,7 +628,7 @@ if (!text || strchr(text, '\n')) width = 1; else - width = strlen (text); + width = mbstrlen (text); l = g_new (WLabel, 1); init_widget (&l->widget, y, x, 1, width, @@ -734,13 +777,69 @@ /* Pointer to killed data */ static char *kill_buffer = 0; +#ifdef UTF8 +static int +charpos(WInput *in, int idx) +{ + int i, pos, l, len; + mbstate_t mbs; + memset (&mbs, 0, sizeof (mbs)); + i = 0; + pos = 0; + len = strlen(in->buffer); + + while (in->buffer[pos]) { + if (i == idx) + return pos; + l = mbrlen(in->buffer + pos, len - pos, &mbs); + if (l <= 0) + return pos; + pos+=l; + i++; + }; + return pos; +} + +static int +charcolumn(WInput *in, int idx) +{ + int i, pos, l, width, len; + mbstate_t mbs; + memset (&mbs, 0, sizeof (mbs)); + i = 0; + pos = 0; width = 0; + len = strlen(in->buffer); + + while (in->buffer[pos]) { + wchar_t wc; + if (i == idx) + return width; + l = mbrtowc(&wc, in->buffer + pos, len - pos, &mbs); + if (l <= 0) + return width; + pos += l; width += wcwidth(wc); + i++; + }; + return width; +} +#else +#define charpos(in, idx) (idx) +#define charcolumn(in, idx) (idx) +#endif /* UTF8 */ + void update_input (WInput *in, int clear_first) { int has_history = 0; int i, j; - unsigned char c; - int buf_len = strlen (in->buffer); + int buf_len = mbstrlen (in->buffer); +#ifndef UTF8 + unsigned char c; +#else /* UTF8 */ + wchar_t c; + mbstate_t mbs; + memset (&mbs, 0, sizeof (mbs)); +#endif /* UTF8 */ if (should_show_history_button (in)) has_history = HISTORY_BUTTON_WIDTH; @@ -750,7 +849,7 @@ /* Make the point visible */ if ((in->point < in->first_shown) || - (in->point >= in->first_shown+in->field_len - has_history)){ + (charcolumn(in, in->point) >= charcolumn(in, in->first_shown) + in->field_len - has_history)){ in->first_shown = in->point - (in->field_len / 3); if (in->first_shown < 0) in->first_shown = 0; @@ -770,14 +869,29 @@ addch (' '); widget_move (&in->widget, 0, 0); +#ifndef UTF8 for (i = 0, j = in->first_shown; i < in->field_len - has_history && in->buffer [j]; i++){ c = in->buffer [j++]; c = is_printable (c) ? c : '.'; - if (in->is_password) +#else /* UTF8 */ + for (i = 0, j = in->first_shown; (i < in->field_len - has_history) && (j < buf_len); i++,j++){ + char * chp = in->buffer + charpos(in,j); + size_t res = mbrtowc(&c, chp, strlen(chp), &mbs); + c = (res && iswprint (c)) ? 0 : '.'; +#endif /* UTF8 */ + if (in->is_password) c = '*'; +#ifndef UTF8 addch (c); +#else /* UTF8 */ + if (c) { + addch (c); + } + else + SLsmg_write_nchars (chp, res); +#endif /* UTF8 */ } - widget_move (&in->widget, 0, in->point - in->first_shown); + widget_move (&in->widget, 0, charcolumn(in, in->point) - charcolumn(in, in->first_shown)); if (clear_first) in->first = 0; @@ -919,7 +1033,7 @@ show_hist (GList *history, int widget_x, int widget_y) { GList *hi, *z; - size_t maxlen = strlen (i18n_htitle ()), i, count = 0; + size_t maxlen = mbstrlen (i18n_htitle ()), i, count = 0; int x, y, w, h; char *q, *r = 0; Dlg_head *query_dlg; @@ -932,7 +1046,7 @@ z = g_list_first (history); hi = z; while (hi) { - if ((i = strlen ((char *) hi->data)) > maxlen) + if ((i = mbstrlen ((char *) hi->data)) > maxlen) maxlen = i; count++; hi = g_list_next (hi); @@ -1104,35 +1218,83 @@ in->need_push = 1; in->buffer [0] = 0; in->point = 0; + in->charpoint = 0; in->mark = 0; free_completions (in); update_input (in, 0); } +static void +move_buffer_backward (WInput *in, int point) +{ + int i, pos, len; + int str_len = mbstrlen (in->buffer); + if (point >= str_len) return; + + pos = charpos(in,point); + len = charpos(in,point + 1) - pos; + + for (i = pos; in->buffer [i + len - 1]; i++) + in->buffer [i] = in->buffer [i + len]; +} + static cb_ret_t insert_char (WInput *in, int c_code) { size_t i; +#ifdef UTF8 + mbstate_t mbs; + int res; + + memset (&mbs, 0, sizeof (mbs)); +#else + in->charpoint = 0; +#endif /* UTF8 */ if (c_code == -1) return MSG_NOT_HANDLED; +#ifdef UTF8 + if (in->charpoint >= MB_CUR_MAX) return 1; + + in->charbuf[in->charpoint++] = c_code; + + res = mbrlen((char *)in->charbuf, in->charpoint, &mbs); + if (res < 0) { + if (res != -2) in->charpoint = 0; /* broken multibyte char, skip */ + return 1; + } + +#endif /* UTF8 */ in->need_push = 1; - if (strlen (in->buffer)+1 == (size_t) in->current_max_len){ + if (strlen (in->buffer) + 1 + in->charpoint >= (size_t) in->current_max_len){ /* Expand the buffer */ - char *narea = g_realloc (in->buffer, in->current_max_len + in->field_len); + char *narea = g_realloc (in->buffer, in->current_max_len + in->field_len + in->charpoint); if (narea){ in->buffer = narea; - in->current_max_len += in->field_len; + in->current_max_len += in->field_len + in->charpoint; } } +#ifndef UTF8 if (strlen (in->buffer)+1 < (size_t) in->current_max_len){ size_t l = strlen (&in->buffer [in->point]); for (i = l+1; i > 0; i--) in->buffer [in->point+i] = in->buffer [in->point+i-1]; in->buffer [in->point] = c_code; +#else /* UTF8 */ + if (strlen (in->buffer) + in->charpoint < in->current_max_len){ + size_t ins_point = charpos(in,in->point); /* bytes from begin */ + /* move chars */ + size_t rest_bytes = strlen (in->buffer + ins_point); + + for (i = rest_bytes + 1; i > 0; i--) + in->buffer [ins_point + i + in->charpoint - 1] = in->buffer [ins_point + i - 1]; + + memcpy(in->buffer + ins_point, in->charbuf, in->charpoint); +#endif /* UTF8 */ in->point++; } + in->charpoint = 0; return MSG_HANDLED; } @@ -1140,12 +1302,14 @@ beginning_of_line (WInput *in) { in->point = 0; + in->charpoint = 0; } static void end_of_line (WInput *in) { - in->point = strlen (in->buffer); + in->point = mbstrlen (in->buffer); + in->charpoint = 0; } static void @@ -1153,18 +1317,21 @@ { if (in->point) in->point--; + in->charpoint = 0; } static void forward_char (WInput *in) { - if (in->buffer [in->point]) + if (in->buffer [charpos(in,in->point)]) in->point++; + in->charpoint = 0; } static void forward_word (WInput *in) { +#ifndef UTF8 unsigned char *p = in->buffer+in->point; while (*p && (isspace (*p) || ispunct (*p))) @@ -1172,11 +1339,39 @@ while (*p && isalnum (*p)) p++; in->point = p - in->buffer; +#else /* UTF8 */ + mbstate_t mbs; + int len = mbstrlen (in->buffer); + memset (&mbs, 0, sizeof (mbs)); + + while (in->point < len) { + wchar_t c; + char *p = in->buffer + charpos(in,in->point); + size_t res = mbrtowc(&c, p, strlen(p), &mbs); + if (res <= 0 || !(iswspace (c) || iswpunct (c))) + break; + in->point++; + } + + memset (&mbs, 0, sizeof (mbs)); + + while (in->point < len) { + wchar_t c; + char *p = in->buffer + charpos(in,in->point); + size_t res = mbrtowc(&c, p, strlen(p), &mbs); + if (res <= 0 || !iswalnum (c)) + break; + in->point++; + } + + in->charpoint = 0; +#endif /* UTF8 */ } static void backward_word (WInput *in) { +#ifndef UTF8 unsigned char *p = in->buffer+in->point; while (p-1 > in->buffer-1 && (isspace (*(p-1)) || ispunct (*(p-1)))) @@ -1184,6 +1379,32 @@ while (p-1 > in->buffer-1 && isalnum (*(p-1))) p--; in->point = p - in->buffer; +#else /* UTF8 */ + mbstate_t mbs; + + memset (&mbs, 0, sizeof (mbs)); + while (in->point > 0) { + wchar_t c; + char *p = in->buffer + charpos(in,in->point); + size_t res = mbrtowc(&c, p, strlen(p), &mbs); + if (*p && (res <= 0 || !(iswspace (c) || iswpunct (c)))) + break; + in->point--; + } + + memset (&mbs, 0, sizeof (mbs)); + + while (in->point > 0) { + wchar_t c; + char *p = in->buffer + charpos(in,in->point); + size_t res = mbrtowc(&c, p, strlen(p), &mbs); + if (*p && (res <= 0 || !iswalnum (c))) + break; + in->point--; + } + + in->charpoint = 0; +#endif /* UTF8 */ } static void @@ -1216,8 +1437,9 @@ if (!in->point) return; - for (i = in->point; in->buffer [i-1]; i++) - in->buffer [i-1] = in->buffer [i]; + + move_buffer_backward(in, in->point - 1); + in->charpoint = 0; in->need_push = 1; in->point--; } @@ -1225,10 +1447,8 @@ static void delete_char (WInput *in) { - int i; - - for (i = in->point; in->buffer [i]; i++) - in->buffer [i] = in->buffer [i+1]; + move_buffer_backward(in, in->point); + in->charpoint = 0; in->need_push = 1; } @@ -1243,6 +1463,9 @@ g_free (kill_buffer); + first=charpos(in,first); + last=charpos(in,last); + kill_buffer = g_strndup(in->buffer+first,last-first); } @@ -1251,11 +1474,13 @@ { int first = min (x_first, x_last); int last = max (x_first, x_last); - size_t len = strlen (&in->buffer [last]) + 1; + size_t len; in->point = first; in->mark = first; - memmove (&in->buffer [first], &in->buffer [last], len); + len = strlen (&in->buffer [charpos(in,last)]) + 1; + memmove (&in->buffer [charpos(in,first)], &in->buffer [charpos(in,last)], len); + in->charpoint = 0; in->need_push = 1; } @@ -1272,6 +1497,8 @@ copy_region (in, old_point, new_point); delete_region (in, old_point, new_point); in->need_push = 1; + in->charpoint = 0; + in->charpoint = 0; } static void @@ -1315,16 +1542,20 @@ if (!kill_buffer) return; + in->charpoint = 0; for (p = kill_buffer; *p; p++) insert_char (in, *p); + in->charpoint = 0; } static void kill_line (WInput *in) { + int chp = charpos(in,in->point); g_free (kill_buffer); - kill_buffer = g_strdup (&in->buffer [in->point]); - in->buffer [in->point] = 0; + kill_buffer = g_strdup (&in->buffer [chp]); + in->buffer [chp] = 0; + in->charpoint = 0; } void @@ -1334,9 +1565,10 @@ g_free (in->buffer); in->buffer = g_strdup (text); /* was in->buffer->text */ in->current_max_len = strlen (in->buffer) + 1; - in->point = strlen (in->buffer); + in->point = mbstrlen (in->buffer); in->mark = 0; in->need_push = 1; + in->charpoint = 0; } static void @@ -1461,6 +1693,7 @@ *in->buffer = 0; in->point = 0; in->first = 0; + in->charpoint = 0; } cb_ret_t @@ -1489,7 +1722,11 @@ } } if (!input_map [i].fn){ +#ifndef UTF8 if (c_code > 255 || !is_printable (c_code)) +#else /* UTF8 */ + if (c_code > 255) +#endif /* UTF8 */ return MSG_NOT_HANDLED; if (in->first){ port_region_marked_for_delete (in); @@ -1523,6 +1760,9 @@ if (pos != in->point) free_completions (in); in->point = pos; +#ifdef UTF8 + in->charpoint = 0; +#endif /* UTF8 */ update_input (in, 1); } @@ -1562,7 +1802,7 @@ return MSG_HANDLED; case WIDGET_CURSOR: - widget_move (&in->widget, 0, in->point - in->first_shown); + widget_move (&in->widget, 0, charcolumn(in, in->point) - charcolumn(in, in->first_shown)); return MSG_HANDLED; case WIDGET_DESTROY: @@ -1584,7 +1824,7 @@ && should_show_history_button (in)) { do_show_hist (in); } else { - in->point = strlen (in->buffer); + in->point = mbstrlen (in->buffer); if (event->x - in->first_shown - 1 < in->point) in->point = event->x - in->first_shown - 1; if (in->point < 0) @@ -1642,56 +1882,91 @@ in->is_password = 0; strcpy (in->buffer, def_text); - in->point = strlen (in->buffer); + in->point = mbstrlen (in->buffer); + in->charpoint = 0; return in; } - -/* Listbox widget */ +/* Vertical scrollbar widget */ -/* Should draw the scrollbar, but currently draws only - * indications that there is more information - */ -static int listbox_cdiff (WLEntry *s, WLEntry *e); - -static void -listbox_drawscroll (WListbox *l) +void +vscrollbar (Widget widget, int height, int width, int tpad, int bpad, + int selected, int count, gboolean color) { int line; - int i, top; - int max_line = l->height-1; - + int i; + /* Are we at the top? */ - widget_move (&l->widget, 0, l->width); - if (l->list == l->top) - one_vline (); + widget_move (&widget, tpad, width); +#ifndef UTF8 + if (!selected) + one_vline (); + else + addch ('^'); +#else + if (color) attrset (MARKED_COLOR); + if (is_utf8) + SLsmg_write_string("▲"); else - addch ('^'); + addch ('^'); + if (color) attrset (NORMAL_COLOR); +#endif /* Are we at the bottom? */ - widget_move (&l->widget, max_line, l->width); - top = listbox_cdiff (l->list, l->top); - if ((top + l->height == l->count) || l->height >= l->count) - one_vline (); + widget_move (&widget, height-1-bpad, width); +#ifndef UTF8 + if (selected == count-1) + one_vline (); + else + addch ('v'); +#else + if (color) attrset (MARKED_COLOR); + if (is_utf8) + SLsmg_write_string("▼"); else - addch ('v'); + addch('v'); + if (color) attrset (NORMAL_COLOR); +#endif /* Now draw the nice relative pointer */ - if (l->count) - line = 1+ ((l->pos * (l->height-2)) / l->count); + if (count > 1) + line = tpad + 1 + ((selected * (height-3-tpad-bpad)) / (count-1)); else - line = 0; - - for (i = 1; i < max_line; i++){ - widget_move (&l->widget, i, l->width); - if (i != line) - one_vline (); - else - addch ('*'); + line = 0; + + for (i = tpad + 1; i < height-1-bpad; i++){ + widget_move (&widget, i, width); + if (i != line) +#ifndef UTF8 + one_vline (); + else + addch ('*'); +#else + if (is_utf8) + SLsmg_write_string("▒"); + else + one_vline(); + else { + if (color) attrset (MARKED_COLOR); + if (is_utf8) + SLsmg_write_string("●"); + else + addch('*'); + if (color) attrset (NORMAL_COLOR); + } +#endif } } - -static void + + +/* Listbox widget */ + +/* Should draw the scrollbar, but currently draws only + * indications that there is more information + */ +static int listbox_cdiff (WLEntry *s, WLEntry *e); + +void listbox_draw (WListbox *l, int focused) { WLEntry *e; @@ -1732,7 +2007,7 @@ if (!l->scrollbar) return; attrset (normalc); - listbox_drawscroll (l); + vscrollbar (l->widget, l->height, l->width, 0, 0, l->pos, l->count, FALSE); } /* Returns the number of items between s and e, diff -urN mc-4.6.1.orig/src/widget.h mc-4.6.1/src/widget.h --- mc-4.6.1.orig/src/widget.h 2004-08-30 00:46:16.000000000 +0600 +++ mc-4.6.1/src/widget.h 2007-01-19 18:33:59.000000000 +0500 @@ -25,6 +25,7 @@ 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; @@ -43,6 +44,7 @@ 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 { @@ -58,16 +60,20 @@ 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? */ unsigned char *buffer; /* pointer to editing buffer */ +#ifdef UTF8 + unsigned 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 */ @@ -176,6 +182,10 @@ /* Listbox manager */ WLEntry *listbox_get_data (WListbox *l, int pos); +/* Vertical scrollbar */ +void vscrollbar (Widget widget, int height, int width, int tpad, int bpad, + int selected, int count, gboolean color); + /* search text int listbox entries */ WLEntry *listbox_search_text (WListbox *l, const char *text); void listbox_select_entry (WListbox *l, WLEntry *dest); diff -urN mc-4.6.1.orig/src/wtools.c mc-4.6.1/src/wtools.c --- mc-4.6.1.orig/src/wtools.c 2005-05-27 20:19:19.000000000 +0600 +++ mc-4.6.1/src/wtools.c 2007-01-19 18:33:59.000000000 +0500 @@ -48,11 +48,11 @@ /* 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; @@ -123,7 +123,7 @@ 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--; } @@ -131,7 +131,7 @@ } /* count coordinates */ - cols = 6 + max (win_len, max ((int) strlen (header), msglen (text, &lines))); + cols = 6 + max (win_len, max ((int) mbstrlen (header), msglen (text, &lines))); lines += 4 + (count > 0 ? 2 : 0); xpos = COLS / 2 - cols / 2; ypos = LINES / 3 - (lines - 3) / 2; @@ -146,7 +146,7 @@ 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--; @@ -457,7 +457,7 @@ g_strlcpy (histname + 3, header, 61); quick_widgets[2].histname = histname; - len = max ((int) strlen (header), msglen (text, &lines)) + 4; + len = max ((int) mbstrlen (header), msglen (text, &lines)) + 4; len = max (len, 64); /* The special value of def_text is used to identify password boxes @@ -477,7 +477,7 @@ */ 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 -urN mc-4.6.1.orig/syntax/c.syntax mc-4.6.1/syntax/c.syntax --- mc-4.6.1.orig/syntax/c.syntax 2005-05-31 12:03:45.000000000 +0600 +++ mc-4.6.1/syntax/c.syntax 2007-01-19 18:33:58.000000000 +0500 @@ -32,34 +32,7 @@ keyword whole volatile yellow keyword whole while yellow keyword whole asm yellow - keyword whole catch yellow - keyword whole class yellow - keyword whole friend yellow - keyword whole delete yellow keyword whole inline yellow - keyword whole new yellow - keyword whole operator yellow - keyword whole private yellow - keyword whole protected yellow - keyword whole public yellow - keyword whole this yellow - keyword whole throw yellow - keyword whole template yellow - keyword whole try yellow - keyword whole virtual yellow - keyword whole bool yellow - keyword whole const_cast yellow - keyword whole dynamic_cast yellow - keyword whole explicit yellow - keyword whole false yellow - keyword whole mutable yellow - keyword whole namespace yellow - keyword whole reinterpret_cast yellow - keyword whole static_cast yellow - keyword whole true yellow - keyword whole typeid yellow - keyword whole typename yellow - keyword whole using yellow keyword whole wchar_t yellow keyword whole ... yellow keyword whole linestart \{\s\t\}\[\s\t\]#*\n brightmagenta diff -urN mc-4.6.1.orig/syntax/cxx.syntax mc-4.6.1/syntax/cxx.syntax --- mc-4.6.1.orig/syntax/cxx.syntax 1970-01-01 05:00:00.000000000 +0500 +++ mc-4.6.1/syntax/cxx.syntax 2007-01-19 18:33:58.000000000 +0500 @@ -0,0 +1,128 @@ +context default + keyword whole auto yellow + keyword whole break yellow + keyword whole case yellow + keyword whole char yellow + keyword whole const yellow + keyword whole continue yellow + keyword whole default yellow + keyword whole do yellow + keyword whole double yellow + keyword whole else yellow + keyword whole enum yellow + keyword whole extern yellow + keyword whole float yellow + keyword whole for yellow + keyword whole goto yellow + keyword whole if yellow + keyword whole int yellow + keyword whole long yellow + keyword whole register yellow + keyword whole return yellow + keyword whole short yellow + keyword whole signed yellow + keyword whole sizeof yellow + keyword whole static yellow + keyword whole struct yellow + keyword whole switch yellow + keyword whole typedef yellow + keyword whole union yellow + keyword whole unsigned yellow + keyword whole void yellow + keyword whole volatile yellow + keyword whole while yellow + keyword whole asm yellow + keyword whole catch yellow + keyword whole class yellow + keyword whole friend yellow + keyword whole delete yellow + keyword whole inline yellow + keyword whole new yellow + keyword whole operator yellow + keyword whole private yellow + keyword whole protected yellow + keyword whole public yellow + keyword whole this yellow + keyword whole throw yellow + keyword whole template yellow + keyword whole try yellow + keyword whole virtual yellow + keyword whole bool yellow + keyword whole const_cast yellow + keyword whole dynamic_cast yellow + keyword whole explicit yellow + keyword whole false yellow + keyword whole mutable yellow + keyword whole namespace yellow + keyword whole reinterpret_cast yellow + keyword whole static_cast yellow + keyword whole true yellow + keyword whole typeid yellow + keyword whole typename yellow + keyword whole using yellow + keyword whole wchar_t yellow + keyword whole ... yellow + keyword whole linestart \{\s\t\}\[\s\t\]#*\n brightmagenta + + keyword /\* brown + keyword \*/ brown + keyword // brown + + keyword '\\\{"abtnvfr\}' brightgreen + keyword '\\\{0123\}\{01234567\}\{01234567\}' brightgreen + keyword '\\'' brightgreen + keyword '\\\\' brightgreen + keyword '\\0' brightgreen + keyword '\{\s!"#$%&()\*\+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~\}' brightgreen + + keyword > yellow + keyword < yellow + keyword \+ yellow + keyword - yellow + keyword \* yellow + keyword / yellow + keyword % yellow + keyword = yellow + keyword != yellow + keyword == yellow + keyword { brightcyan + keyword } brightcyan + keyword ( brightcyan + keyword ) brightcyan + keyword [ brightcyan + keyword ] brightcyan + keyword , brightcyan + keyword : brightcyan + keyword ? brightcyan + keyword ; brightmagenta + +context exclusive /\* \*/ brown + spellcheck + +context exclusive // \n brown + spellcheck + +context linestart # \n brightred + keyword \\\n yellow + keyword /\**\*/ brown + keyword //*\n brown + keyword "+" red + keyword <+> red + +context " " green + spellcheck + keyword \\" brightgreen + keyword %% brightgreen + keyword %\[#0\s-\+,\]\[0123456789\*\]\[.\]\[0123456789\*\]\[L\]\{eEfgGoxX\} brightgreen + keyword %\[0\s-\+,\]\[0123456789\*\]\[.\]\[0123456789\*\]\[hl\]\{diuxX\} brightgreen + keyword %\[hl\]n brightgreen + keyword %\[-\]\[0123456789\*\]\[.\]\[0123456789\*\]s brightgreen + keyword %[*] brightgreen + keyword %c brightgreen + keyword %p brightgreen + keyword \\\{0123\}\{01234567\}\{01234567\} brightgreen + keyword \\\\ brightgreen + keyword \\' brightgreen + keyword \\\{abtnvfr\} brightgreen + + diff -urN mc-4.6.1.orig/syntax/Makefile.am mc-4.6.1/syntax/Makefile.am --- mc-4.6.1.orig/syntax/Makefile.am 2005-03-19 22:39:06.000000000 +0500 +++ mc-4.6.1/syntax/Makefile.am 2007-01-19 18:33:58.000000000 +0500 @@ -4,6 +4,7 @@ aspx.syntax \ assembler.syntax \ c.syntax \ + cxx.syntax \ cs.syntax \ changelog.syntax \ diff.syntax \ diff -urN mc-4.6.1.orig/syntax/Makefile.in mc-4.6.1/syntax/Makefile.in --- mc-4.6.1.orig/syntax/Makefile.in 2005-07-23 22:53:15.000000000 +0600 +++ mc-4.6.1/syntax/Makefile.in 2007-01-19 18:33:58.000000000 +0500 @@ -218,6 +218,7 @@ aspx.syntax \ assembler.syntax \ c.syntax \ + cxx.syntax \ cs.syntax \ changelog.syntax \ diff.syntax \ diff -urN mc-4.6.1.orig/syntax/sh.syntax mc-4.6.1/syntax/sh.syntax --- mc-4.6.1.orig/syntax/sh.syntax 2004-12-02 15:47:14.000000000 +0500 +++ mc-4.6.1/syntax/sh.syntax 2007-01-19 18:33:58.000000000 +0500 @@ -41,7 +41,9 @@ keyword whole bg yellow keyword whole break yellow keyword whole case yellow + keyword whole clear yellow keyword whole continue yellow + keyword whole declare yellow keyword whole done yellow keyword whole do yellow keyword whole elif yellow @@ -56,11 +58,13 @@ keyword whole for yellow keyword whole if yellow keyword whole in yellow + keyword whole let yellow keyword whole read yellow keyword whole return yellow keyword whole select yellow keyword whole set yellow keyword whole shift yellow + keyword whole source yellow keyword whole then yellow keyword whole trap yellow keyword whole umask yellow @@ -69,6 +73,8 @@ keyword whole wait yellow keyword whole while yellow + keyword whole apt-get cyan + keyword whole ar cyan keyword whole arch cyan keyword whole ash cyan keyword whole awk cyan @@ -77,90 +83,204 @@ keyword whole bg_backup cyan keyword whole bg_restore cyan keyword whole bsh cyan + keyword whole bzip cyan + keyword whole bzip2 cyan + keyword whole cam cyan keyword whole cat cyan keyword whole cd cyan + keyword whole cdda2wav cyan keyword whole chgrp cyan keyword whole chmod cyan keyword whole chown cyan + keyword whole cmp cyan + keyword whole col cyan + keyword whole compress cyan keyword whole cp cyan keyword whole cpio cyan + keyword whole cpp cyan keyword whole csh cyan + keyword whole curl cyan + keyword whole cut cyan keyword whole date cyan keyword whole dd cyan keyword whole df cyan + keyword whole dialog cyan + keyword whole diff cyan + keyword whole dirname cyan keyword whole dmesg cyan keyword whole dnsdomainname cyan keyword whole doexec cyan keyword whole domainname cyan + keyword whole dpkg cyan + keyword whole dpkg-buildpackage cyan + keyword whole dpkg-scanpackages cyan + keyword whole dpkg-scansources cyan keyword whole echo cyan keyword whole ed cyan + keyword whole editor cyan keyword whole egrep cyan keyword whole ex cyan + keyword whole fakeroot cyan keyword whole false cyan + keyword whole fdformat cyan + keyword whole fetchmail cyan keyword whole fgrep cyan keyword whole find cyan + keyword whole formail cyan + keyword whole free cyan + keyword whole freeze cyan keyword whole fsconf cyan keyword whole gawk cyan + keyword whole gdb cyan + keyword whole gcc cyan keyword whole grep cyan keyword whole gunzip cyan keyword whole gzip cyan + keyword whole ha cyan keyword whole hostname cyan keyword whole igawk cyan + keyword whole insmod cyan keyword whole ipcalc cyan + keyword whole iptables cyan keyword whole kill cyan keyword whole ksh cyan + keyword whole lame cyan + keyword whole less cyan + keyword whole lharc cyan + keyword whole lilo cyan + keyword whole linux_logo cyan keyword whole linuxconf cyan keyword whole ln cyan + keyword whole locale cyan + keyword whole logger cyan keyword whole login cyan keyword whole lpdconf cyan keyword whole ls cyan + keyword whole lynx cyan keyword whole mail cyan + keyword whole man cyan + keyword whole mc cyan + keyword whole mcedit cyan + keyword whole mcview cyan + keyword whole mimedecode cyan keyword whole mkdir cyan + keyword whole mkdirhier cyan + keyword whole mkfs.ext2 cyan + keyword whole mkfs.ext3 cyan + keyword whole mkfs.minix cyan + keyword whole mkfs.msdos cyan + keyword whole mke2fs cyan + keyword whole mkdosfs cyan + keyword whole mkinitrd cyan keyword whole mknod cyan keyword whole mktemp cyan + keyword whole modprobe cyan keyword whole more cyan keyword whole mount cyan + keyword whole mozilla cyan + keyword whole mp3info cyan + keyword whole munpack cyan + keyword whole msgfmt cyan keyword whole mt cyan + keyword whole mutt cyan keyword whole mv cyan keyword whole netconf cyan keyword whole netstat cyan keyword whole nice cyan keyword whole nisdomainname cyan + keyword whole nm cyan + keyword whole patch cyan + keyword whole pinfo cyan keyword whole ping cyan + keyword whole procmail cyan keyword whole ps cyan keyword whole pwd cyan + keyword whole rar cyan keyword whole red cyan keyword whole remadmin cyan + keyword whole rename cyan keyword whole rm cyan keyword whole rmdir cyan + keyword whole rmmod cyan + keyword whole rplay cyan keyword whole rpm cyan + keyword whole rpm2cpio cyan keyword whole sed cyan keyword whole set cyan keyword whole setserial cyan keyword whole sh cyan keyword whole sleep cyan keyword whole sort cyan + keyword whole sa-learn cyan + keyword whole spamassassin cyan + keyword whole spamc cyan + keyword whole spamd cyan + keyword whole ssmtp cyan + keyword whole strace cyan keyword whole stty cyan keyword whole su cyan keyword whole sync cyan keyword whole taper cyan keyword whole tar cyan + keyword whole tcpdump cyan keyword whole tcsh cyan keyword whole test cyan + keyword whole tempfile cyan keyword whole time cyan + keyword whole tnef cyan keyword whole touch cyan + keyword whole tr cyan keyword whole true cyan + keyword whole tune2fs cyan keyword whole umount cyan keyword whole uname cyan + keyword whole unarj cyan + keyword whole uniq cyan + keyword whole unzip cyan + keyword whole uptime cyan keyword whole userconf cyan keyword whole usleep cyan keyword whole vi cyan keyword whole view cyan keyword whole vim cyan + keyword whole wc cyan + keyword whole wget cyan + keyword whole whiptail cyan + keyword whole wvWare cyan keyword whole xconf cyan + keyword whole xgettext cyan + keyword whole xmessage cyan + keyword whole xmodmap cyan + keyword whole xterm cyan keyword whole ypdomainname cyan keyword whole zcat cyan + keyword whole zgv cyan + keyword whole zip cyan + keyword whole zoo cyan keyword whole zsh cyan + keyword whole Xdialog cyan + + keyword whole gpg red + keyword whole md5sum red + keyword whole openssl red + keyword whole ssh red + + keyword whole TEXTDOMAINDIR magenta + keyword whole TEXTDOMAIN magenta + keyword whole VERSION magenta + + keyword whole jpegtopnm cyan + keyword whole pnmscale cyan + keyword whole ppmtoxpm cyan + + keyword whole /dev/audio brightblue + keyword whole /dev/dsp brightblue + keyword whole /dev/null brightblue + keyword whole /dev/mixed brightblue + keyword whole /dev/stdin brightblue + keyword whole /dev/stdout brightblue + keyword whole /dev/stderr brightblue + keyword whole /dev/zero brightblue wholechars abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_ @@ -224,7 +344,9 @@ keyword whole break yellow keyword whole case yellow + keyword whole clear yellow keyword whole continue yellow + keyword whole declare yellow keyword whole done yellow keyword whole do yellow keyword whole elif yellow @@ -238,11 +360,15 @@ keyword whole return yellow keyword whole select yellow keyword whole shift yellow + keyword whole source yellow keyword whole then yellow keyword whole trap yellow keyword whole until yellow + keyword whole wait yellow keyword whole while yellow + keyword whole apt-get cyan + keyword whole ar cyan keyword whole arch cyan keyword whole ash cyan keyword whole awk cyan @@ -251,89 +377,194 @@ keyword whole bg_backup cyan keyword whole bg_restore cyan keyword whole bsh cyan + keyword whole bzip cyan + keyword whole bzip2 cyan + keyword whole cam cyan keyword whole cat cyan keyword whole cd cyan + keyword whole cdda2wav cyan keyword whole chgrp cyan keyword whole chmod cyan keyword whole chown cyan + keyword whole cmp cyan + keyword whole col cyan + keyword whole compress cyan keyword whole cp cyan keyword whole cpio cyan + keyword whole cpp cyan keyword whole csh cyan + keyword whole curl cyan + keyword whole cut cyan keyword whole date cyan keyword whole dd cyan keyword whole df cyan + keyword whole dialog cyan + keyword whole diff cyan + keyword whole dirname cyan keyword whole dmesg cyan keyword whole dnsdomainname cyan keyword whole doexec cyan keyword whole domainname cyan + keyword whole dpkg cyan + keyword whole dpkg-buildpackage cyan + keyword whole dpkg-scanpackages cyan + keyword whole dpkg-scansources cyan keyword whole echo cyan keyword whole ed cyan + keyword whole editor cyan keyword whole egrep cyan keyword whole ex cyan + keyword whole fakeroot cyan keyword whole false cyan + keyword whole fdformat cyan + keyword whole fetchmail cyan keyword whole fgrep cyan keyword whole find cyan + keyword whole free cyan + keyword whole freeze cyan keyword whole fsconf cyan keyword whole gawk cyan + keyword whole gdb cyan + keyword whole gcc cyan keyword whole grep cyan keyword whole gunzip cyan keyword whole gzip cyan + keyword whole ha cyan keyword whole hostname cyan keyword whole igawk cyan + keyword whole insmod cyan + keyword whole iptables cyan keyword whole ipcalc cyan keyword whole kill cyan keyword whole ksh cyan + keyword whole lame cyan + keyword whole less cyan + keyword whole lharc cyan + keyword whole lilo cyan + keyword whole linux_logo cyan keyword whole linuxconf cyan keyword whole ln cyan + keyword whole locale cyan + keyword whole logger cyan keyword whole login cyan keyword whole lpdconf cyan keyword whole ls cyan + keyword whole lynx cyan keyword whole mail cyan + keyword whole man cyan + keyword whole mc cyan + keyword whole mcedit cyan + keyword whole mcview cyan + keyword whole mimedecode cyan keyword whole mkdir cyan + keyword whole mkdirhier cyan + keyword whole mkfs.ext2 cyan + keyword whole mkfs.ext3 cyan + keyword whole mkfs.minix cyan + keyword whole mkfs.msdos cyan + keyword whole mke2fs cyan + keyword whole mkdosfs cyan + keyword whole mkinitrd cyan keyword whole mknod cyan keyword whole mktemp cyan + keyword whole modprobe cyan keyword whole more cyan keyword whole mount cyan + keyword whole mozilla cyan + keyword whole mp3info cyan + keyword whole msgfmt cyan keyword whole mt cyan + keyword whole mutt cyan keyword whole mv cyan keyword whole netconf cyan keyword whole netstat cyan keyword whole nice cyan keyword whole nisdomainname cyan + keyword whole nm cyan + keyword whole patch cyan + keyword whole pinfo cyan keyword whole ping cyan keyword whole ps cyan keyword whole pwd cyan + keyword whole rar cyan keyword whole red cyan keyword whole remadmin cyan + keyword whole rename cyan keyword whole rm cyan keyword whole rmdir cyan + keyword whole rmmod cyan + keyword whole rplay cyan keyword whole rpm cyan + keyword whole rpm2cpio cyan keyword whole sed cyan keyword whole set cyan keyword whole setserial cyan keyword whole sh cyan keyword whole sleep cyan keyword whole sort cyan + keyword whole sa-learn cyan + keyword whole spamassassin cyan + keyword whole spamc cyan + keyword whole spamd cyan + keyword whole ssmtp cyan + keyword whole strace cyan keyword whole stty cyan keyword whole su cyan keyword whole sync cyan keyword whole taper cyan keyword whole tar cyan + keyword whole tcpdump cyan keyword whole tcsh cyan + keyword whole tempfile cyan keyword whole test cyan keyword whole time cyan + keyword whole tnef cyan keyword whole touch cyan + keyword whole tr cyan keyword whole true cyan + keyword whole tune2fs cyan keyword whole umount cyan keyword whole uname cyan + keyword whole unarj cyan + keyword whole uniq cyan + keyword whole unzip cyan + keyword whole uptime cyan keyword whole userconf cyan keyword whole usleep cyan keyword whole vi cyan keyword whole view cyan keyword whole vim cyan + keyword whole wc cyan + keyword whole wget cyan + keyword whole whiptail cyan + keyword whole wvWare cyan keyword whole xconf cyan + keyword whole xgettext cyan + keyword whole xmessage cyan + keyword whole xmodmap cyan + keyword whole xterm cyan keyword whole ypdomainname cyan keyword whole zcat cyan + keyword whole zgv cyan + keyword whole zoo cyan + keyword whole zip cyan keyword whole zsh cyan + keyword whole Xdialog cyan - + keyword whole gpg red + keyword whole md5sum red + keyword whole openssl red + keyword whole ssh red + + keyword whole TEXTDOMAINDIR magenta + keyword whole TEXTDOMAIN magenta + keyword whole VERSION magenta + + keyword whole /dev/audio brightblue + keyword whole /dev/dsp brightblue + keyword whole /dev/null brightblue + keyword whole /dev/mixed brightblue + keyword whole /dev/stdin brightblue + keyword whole /dev/stdout brightblue + keyword whole /dev/stderr brightblue + keyword whole /dev/zero brightblue diff -urN mc-4.6.1.orig/syntax/Syntax mc-4.6.1/syntax/Syntax --- mc-4.6.1.orig/syntax/Syntax 2005-05-26 13:21:34.000000000 +0600 +++ mc-4.6.1/syntax/Syntax 2007-01-19 18:33:58.000000000 +0500 @@ -45,9 +45,10 @@ file ..\*\\.(rb|RB)$ Ruby\sProgram ^#!.\*([\s/]ruby|@RUBY@) include ruby.syntax -file ..\*\\.(man|[0-9n]|[0-9]x)$ NROFF\sSource +file ..\*\\.(man|[0-9n]|[0-9](x|ncurses|ssl|p|pm|menu|form|vga|t|td))$ NROFF\sSource include nroff.syntax + file ..\*\\.(htm|html|HTM|HTML)$ HTML\sFile include html.syntax @@ -72,9 +73,12 @@ file ..\*\.(texi|texinfo|TEXI|TEXINFO)$ Texinfo\sDocument include texinfo.syntax -file ..\*\\.([chC]|CC|cxx|cc|cpp|CPP|CXX|hxx|h\.in)$ C/C\+\+\sProgram +file ..\*\\.c$ C\sProgram include c.syntax +file ..\*\\.([hC]|CC|cxx|cc|cpp|CPP|CXX|hxx|h\.in)$ C/C\+\+\sProgram +include cxx.syntax + file ..\*\\.[fF]$ Fortran\sProgram include fortran.syntax diff -urN mc-4.6.1.orig/vfs/cpio.c mc-4.6.1/vfs/cpio.c --- mc-4.6.1.orig/vfs/cpio.c 2005-05-27 20:19:19.000000000 +0600 +++ mc-4.6.1/vfs/cpio.c 2007-01-19 18:33:58.000000000 +0500 @@ -83,7 +83,7 @@ struct vfs_s_inode *inode; }; -static int cpio_position; +static off_t cpio_position; static int cpio_find_head(struct vfs_class *me, struct vfs_s_super *super); static int cpio_read_bin_head(struct vfs_class *me, struct vfs_s_super *super); @@ -107,7 +107,7 @@ return l; } -static int cpio_skip_padding(struct vfs_s_super *super) +static off_t cpio_skip_padding(struct vfs_s_super *super) { switch(super->u.arch.type) { case CPIO_BIN: diff -urN mc-4.6.1.orig/vfs/direntry.c mc-4.6.1/vfs/direntry.c --- mc-4.6.1.orig/vfs/direntry.c 2004-11-29 23:44:49.000000000 +0500 +++ mc-4.6.1/vfs/direntry.c 2007-01-19 18:33:58.000000000 +0500 @@ -243,7 +243,13 @@ char * const pathref = g_strdup (a_path); char *path = pathref; - canonicalize_pathname (path); + if (strncmp(me->name, "ftpfs", 5) != 0) + canonicalize_pathname (path); + else { + char *p = path + strlen (path) - 1; + while (p > path && *p == PATH_SEP) + *p-- = 0; + } while (root) { while (*path == PATH_SEP) /* Strip leading '/' */ @@ -313,7 +319,13 @@ if (root->super->root != root) vfs_die ("We have to use _real_ root. Always. Sorry."); - canonicalize_pathname (path); + if (strncmp (me->name, "ftpfs", 5) != 0) + canonicalize_pathname (path); + else { + char *p = path + strlen (path) - 1; + while (p > path && *p == PATH_SEP) + *p-- = 0; + } if (!(flags & FL_DIR)) { char *dirname, *name, *save; @@ -836,13 +848,13 @@ return 0; } -static int +static off_t vfs_s_lseek (void *fh, off_t offset, int whence) { off_t size = FH->ino->st.st_size; if (FH->handle != -1){ /* If we have local file opened, we want to work with it */ - int retval = lseek (FH->handle, offset, whence); + off_t retval = lseek (FH->handle, offset, whence); if (retval == -1) FH->ino->super->me->verrno = errno; return retval; diff -urN mc-4.6.1.orig/vfs/extfs/uzip.in mc-4.6.1/vfs/extfs/uzip.in --- mc-4.6.1.orig/vfs/extfs/uzip.in 2004-09-02 06:16:33.000000000 +0600 +++ mc-4.6.1/vfs/extfs/uzip.in 2007-01-19 18:33:58.000000000 +0500 @@ -34,6 +34,14 @@ # Command used to extract a file to standard out my $cmd_extract = "$app_unzip -p"; +# -rw-r--r-- 2.2 unx 2891 tx 1435 defN 20000330.211927 ./edit.html +# (perm) (?) (?) (size) (?) (zippedsize) (method) (yyyy)(mm)(dd)(HH)(MM) (fname) +my $regex_zipinfo_line = qr"^(\S{7,10})\s+(\d+\.\d+)\s+(\S+)\s+(\d+)\s+(\S\S)\s+(\d+)\s+(\S{4})\s+(\d{4})(\d\d)(\d\d)\.(\d\d)(\d\d)(\d\d)\s(.*)$"; + +# 2891 Defl:N 1435 50% 03-30-00 21:19 50cbaaf8 ./edit.html +# (size) (method) (zippedsize) (zipratio) (mm)(dd)(yy)(HH)(MM) (cksum) (fname) +my $regex_nonzipinfo_line = qr"^\s*(\d+)\s+(\S+)\s+(\d+)\s+(-?\d+\%)\s+(\d?\d)-(\d?\d)-(\d\d)\s+(\d?\d):(\d\d)\s+([0-9a-f]+)\s\s(.*)$"; + # # Main code # @@ -50,6 +58,50 @@ my $cmd_list = ($op_has_zipinfo ? $cmd_list_zi : $cmd_list_nzi); my ($qarchive, $aqarchive) = map (quotemeta, $archive, $aarchive); +# Strip all "." and ".." path components from a pathname. +sub zipfs_canonicalize_pathname($) { + my ($fname) = @_; + $fname =~ s,/+,/,g; + $fname =~ s,(^|/)(?:\.?\./)+,$1,; + return $fname; +} + +# The Midnight Commander never calls this script with archive pathnames +# starting with either "./" or "../". Some ZIP files contain such names, +# so we need to build a translation table for them. +my $zipfs_realpathname_table = undef; +sub zipfs_realpathname($) { + my ($fname) = @_; + + if (!defined($zipfs_realpathname_table)) { + $zipfs_realpathname_table = {}; + if (!open(ZIP, "$cmd_list $qarchive |")) { + return $fname; + } + foreach my $line () { + $line =~ s/\r*\n*$//; + if ($op_has_zipinfo) { + if ($line =~ $regex_zipinfo_line) { + my ($fname) = ($14); + $zipfs_realpathname_table->{zipfs_canonicalize_pathname($fname)} = $fname; + } + } else { + if ($line =~ $regex_nonzipinfo_line) { + my ($fname) = ($11); + $zipfs_realpathname_table->{zipfs_canonicalize_pathname($fname)} = $fname; + } + } + } + if (!close(ZIP)) { + return $fname; + } + } + if (exists($zipfs_realpathname_table->{$fname})) { + return $zipfs_realpathname_table->{$fname}; + } + return $fname; +} + if ($cmd eq 'list') { &mczipfs_list(@ARGV); } if ($cmd eq 'rm') { &mczipfs_rm(@ARGV); } if ($cmd eq 'rmdir') { &mczipfs_rmdir(@ARGV); } @@ -63,7 +115,12 @@ # Remove a file from the archive. sub mczipfs_rm { - my ($qfile) = map { &zipquotemeta($_) } @_; + my ($qfile) = map { &zipquotemeta(zipfs_realpathname($_)) } @_; + + # "./" at the beginning of pathnames is stripped by Info-ZIP, + # so convert it to "[.]/" to prevent stripping. + $qfile =~ s/^\\\./[.]/; + &checkargs(1, 'archive file', @_); &safesystem("$cmd_delete $qarchive $qfile >/dev/null"); exit; @@ -74,7 +131,7 @@ # additional slash to the directory name to remove. I am not # sure this is absolutely necessary, but it doesn't hurt. sub mczipfs_rmdir { - my ($qfile) = map { &zipquotemeta($_) } @_; + my ($qfile) = map { &zipquotemeta(zipfs_realpathname($_)) } @_; &checkargs(1, 'archive directory', @_); &safesystem("$cmd_delete $qarchive $qfile/ >/dev/null", 12); exit; @@ -84,7 +141,7 @@ # Note that we don't need to check if the file is a link, # because mc apparently doesn't call copyout for symbolic links. sub mczipfs_copyout { - my ($qafile, $qfsfile) = map { &zipquotemeta($_) } @_; + my ($qafile, $qfsfile) = map { &zipquotemeta(zipfs_realpathname($_)) } @_; &checkargs(1, 'archive file', @_); &checkargs(2, 'local file', @_); &safesystem("$cmd_extract $qarchive $qafile > $qfsfile", 11); @@ -195,14 +252,14 @@ next if /^Archive:/; next if /^\d+ file/; next if /^Empty zipfile\.$/; - my @match = /^(.{10}) +([\d.]+) +([a-z\d]+) +(\d+) +([^ ]{2}) +(\d+) +([^ ]{4}) +(\d{4})(\d\d)(\d\d)\.(\d\d)(\d\d)(\d\d) +(.*)$/; + my @match = /$regex_zipinfo_line/; next if ($#match != 13); &checked_print_file(@match); } } else { while () { chomp; - my @match = /^ *(\d+) +([^ ]+) +(\d+) +(-?\d+\%) +(\d?\d)-(\d?\d)-(\d\d) (\d?\d):(\d\d) +([0-9a-f]+) +(.*)$/; + my @match = /$regex_nonzipinfo_line/; next if ($#match != 10); my @rmatch = ('', '', 'unknown', $match[0], '', $match[2], $match[1], $match[6] + ($match[6] < 70 ? 2000 : 1900), $match[4], $match[5], @@ -230,7 +287,7 @@ sub mczipfs_run { my ($afile) = @_; &checkargs(1, 'archive file', @_); - my $qafile = &zipquotemeta($afile); + my $qafile = &zipquotemeta(zipfs_realpathname($afile)); my $tmpdir = &mktmpdir(); my $tmpfile = File::Basename::basename($afile); diff -urN mc-4.6.1.orig/vfs/extfs.c mc-4.6.1/vfs/extfs.c --- mc-4.6.1.orig/vfs/extfs.c 2005-05-27 20:19:19.000000000 +0600 +++ mc-4.6.1/vfs/extfs.c 2007-01-19 18:33:58.000000000 +0500 @@ -1125,7 +1125,7 @@ return 0; } -static int extfs_lseek (void *data, off_t offset, int whence) +static off_t extfs_lseek (void *data, off_t offset, int whence) { struct pseudofile *file = (struct pseudofile *) data; diff -urN mc-4.6.1.orig/vfs/ftpfs.c mc-4.6.1/vfs/ftpfs.c --- mc-4.6.1.orig/vfs/ftpfs.c 2005-05-27 20:19:19.000000000 +0600 +++ mc-4.6.1/vfs/ftpfs.c 2007-01-19 18:33:58.000000000 +0500 @@ -114,7 +114,7 @@ int ftpfs_use_unix_list_options = 1; /* First "CWD ", then "LIST -la ." */ -int ftpfs_first_cd_then_ls; +int ftpfs_first_cd_then_ls = 1; /* Use the ~/.netrc */ int use_netrc = 1; diff -urN mc-4.6.1.orig/vfs/local.c mc-4.6.1/vfs/local.c --- mc-4.6.1.orig/vfs/local.c 2004-09-25 05:00:18.000000000 +0600 +++ mc-4.6.1/vfs/local.c 2007-01-19 18:33:58.000000000 +0500 @@ -197,7 +197,7 @@ return chdir (path); } -int +off_t local_lseek (void *data, off_t offset, int whence) { int fd = * (int *) data; diff -urN mc-4.6.1.orig/vfs/local.h mc-4.6.1/vfs/local.h --- mc-4.6.1.orig/vfs/local.h 2004-08-17 15:17:43.000000000 +0600 +++ mc-4.6.1/vfs/local.h 2007-01-19 18:33:58.000000000 +0500 @@ -11,7 +11,7 @@ extern int local_read (void *data, char *buffer, int count); extern int local_fstat (void *data, struct stat *buf); extern int local_errno (struct vfs_class *me); -extern int local_lseek (void *data, off_t offset, int whence); +extern off_t local_lseek (void *data, off_t offset, int whence); #ifdef HAVE_MMAP extern caddr_t local_mmap (struct vfs_class *me, caddr_t addr, size_t len, int prot, int flags, void *data, off_t offset); diff -urN mc-4.6.1.orig/vfs/mcfs.c mc-4.6.1/vfs/mcfs.c --- mc-4.6.1.orig/vfs/mcfs.c 2005-05-27 20:19:19.000000000 +0600 +++ mc-4.6.1/vfs/mcfs.c 2007-01-19 18:33:58.000000000 +0500 @@ -1037,7 +1037,7 @@ return 0; } -static int +static off_t mcfs_lseek (void *data, off_t offset, int whence) { mcfs_handle *info = (mcfs_handle *) data; diff -urN mc-4.6.1.orig/vfs/smbfs.c mc-4.6.1/vfs/smbfs.c --- mc-4.6.1.orig/vfs/smbfs.c 2005-05-27 20:19:19.000000000 +0600 +++ mc-4.6.1/vfs/smbfs.c 2007-01-19 18:33:58.000000000 +0500 @@ -283,7 +283,7 @@ static int smbfs_init (struct vfs_class * me) { - const char *servicesf = CONFIGDIR PATH_SEP_STR "smb.conf"; + const char *servicesf = CONFIGDIR PATH_SEP_STR "samba/smb.conf"; /* DEBUGLEVEL = 4; */ @@ -1585,7 +1585,7 @@ #define smbfs_lstat smbfs_stat /* no symlinks on smb filesystem? */ -static int +static off_t smbfs_lseek (void *data, off_t offset, int whence) { smbfs_handle *info = (smbfs_handle *) data; diff -urN mc-4.6.1.orig/vfs/tar.c mc-4.6.1/vfs/tar.c --- mc-4.6.1.orig/vfs/tar.c 2005-07-23 22:52:04.000000000 +0600 +++ mc-4.6.1/vfs/tar.c 2007-01-19 18:33:58.000000000 +0500 @@ -194,7 +194,7 @@ } /* As we open one archive at a time, it is safe to have this static */ -static int current_tar_position = 0; +static off_t current_tar_position = 0; /* Returns fd of the open tar file */ static int @@ -461,7 +461,7 @@ struct stat st; struct vfs_s_entry *entry; struct vfs_s_inode *inode, *parent; - long data_position; + off_t data_position; char *q; int len; char *current_file_name, *current_link_name; @@ -646,8 +646,9 @@ int fd = FH_SUPER->u.arch.fd; struct vfs_class *me = FH_SUPER->me; - if (mc_lseek (fd, begin + FH->pos, SEEK_SET) != - begin + FH->pos) ERRNOR (EIO, -1); + + off_t o = mc_lseek(fd, begin + FH->pos, SEEK_SET); + if ( o != begin + FH->pos) ERRNOR (EIO, -1); count = MIN(count, FH->ino->st.st_size - FH->pos); diff -urN mc-4.6.1.orig/vfs/undelfs.c mc-4.6.1/vfs/undelfs.c --- mc-4.6.1.orig/vfs/undelfs.c 2005-05-27 20:19:19.000000000 +0600 +++ mc-4.6.1/vfs/undelfs.c 2007-01-19 18:33:58.000000000 +0500 @@ -645,7 +645,7 @@ } /* this has to stay here for now: vfs layer does not know how to emulate it */ -static int +static off_t undelfs_lseek(void *vfs_info, off_t offset, int whence) { return -1; diff -urN mc-4.6.1.orig/vfs/vfs.c mc-4.6.1/vfs/vfs.c --- mc-4.6.1.orig/vfs/vfs.c 2005-05-27 20:19:19.000000000 +0600 +++ mc-4.6.1/vfs/vfs.c 2007-01-19 18:33:59.000000000 +0500 @@ -49,6 +49,11 @@ #include "smbfs.h" #include "local.h" +#include "../src/panel.h" +#ifdef HAVE_CHARSET +#include "../src/recode.h" +#endif + /* They keep track of the current directory */ static struct vfs_class *current_vfs; static char *current_dir; @@ -623,14 +628,14 @@ off_t mc_lseek (int fd, off_t offset, int whence) { struct vfs_class *vfs; - int result; + off_t result; if (fd == -1) return -1; vfs = vfs_op (fd); result = vfs->lseek ? (*vfs->lseek)(vfs_info (fd), offset, whence) : -1; - if (result == -1) + if (result == (off_t)-1) errno = vfs->lseek ? ferrno (vfs) : E_NOTSUPP; return result; } @@ -681,8 +686,66 @@ vfsid old_vfsid; int result; +#ifdef HAVE_CHARSET + char* errmsg; +#endif + WPanel* p=ret_panel; + new_dir = vfs_canon (path); new_vfs = vfs_get_class (new_dir); + old_vfsid = vfs_getid (current_vfs, current_dir); + old_vfs = current_vfs; + + if(p) { + + // Change from localfs to ftpfs + ret_panel=NULL; + if( (strcmp(old_vfs->name,"localfs")==0) && + (strcmp(new_vfs->name,"ftpfs")==0)){ + p->is_return=1; + strncpy(p->retdir,current_dir, MC_MAXPATHLEN); +#ifdef HAVE_CHARSET + p->ret_codepage=p->src_codepage; + p->src_codepage=ftp_codepage; + errmsg=my_init_tt(display_codepage,p->src_codepage,p->tr_table); + if(errmsg) { + panel_reset_codepage(p); + message( 1, MSG_ERROR, "%s", errmsg ); + } + errmsg=my_init_tt(p->src_codepage,display_codepage,p->tr_table_input); + if(errmsg) { + panel_reset_codepage(p); + message( 1, MSG_ERROR, "%s", errmsg ); + } +#endif + } + + // Change from ftpfs to localfs + if( (strcmp(old_vfs->name,"ftpfs")==0) && + (strcmp(new_vfs->name,"localfs")==0) && + p->is_return){ + p->is_return=0; + g_free(new_dir); + new_dir = vfs_canon (p->retdir); + new_vfs = vfs_get_class (new_dir); +#ifdef HAVE_CHARSET + p->src_codepage=p->ret_codepage; + errmsg=my_init_tt(display_codepage,p->src_codepage,p->tr_table); + if(errmsg) { + panel_reset_codepage(p); + message( 1, MSG_ERROR, "%s", errmsg ); + } + errmsg=my_init_tt(p->src_codepage,display_codepage,p->tr_table_input); + if(errmsg) { + panel_reset_codepage(p); + message( 1, MSG_ERROR, "%s", errmsg ); + } +#endif + } + } + + + if (!new_vfs->chdir) { g_free (new_dir); return -1; @@ -696,9 +759,6 @@ return -1; } - old_vfsid = vfs_getid (current_vfs, current_dir); - old_vfs = current_vfs; - /* Actually change directory */ g_free (current_dir); current_dir = new_dir; diff -urN mc-4.6.1.orig/vfs/vfs-impl.h mc-4.6.1/vfs/vfs-impl.h --- mc-4.6.1.orig/vfs/vfs-impl.h 2004-09-02 19:57:59.000000000 +0600 +++ mc-4.6.1/vfs/vfs-impl.h 2007-01-19 18:33:58.000000000 +0500 @@ -53,7 +53,7 @@ int (*rename) (struct vfs_class *me, const char *p1, const char *p2); int (*chdir) (struct vfs_class *me, const char *path); int (*ferrno) (struct vfs_class *me); - int (*lseek) (void *vfs_info, off_t offset, int whence); + off_t (*lseek) (void *vfs_info, off_t offset, int whence); int (*mknod) (struct vfs_class *me, const char *path, int mode, int dev); vfsid (*getid) (struct vfs_class *me, const char *path); diff -urN mc-4.6.1.orig/vfs/xdirentry.h mc-4.6.1/vfs/xdirentry.h --- mc-4.6.1.orig/vfs/xdirentry.h 2004-10-07 00:04:15.000000000 +0600 +++ mc-4.6.1/vfs/xdirentry.h 2007-01-19 18:33:58.000000000 +0500 @@ -90,7 +90,7 @@ char *linkname; /* Symlink's contents */ char *localname; /* Filename of local file, if we have one */ struct timeval timestamp; /* Subclass specific */ - long data_offset; /* Subclass specific */ + off_t data_offset; /* Subclass specific */ }; /* Data associated with an open file */