nixpkgs/pkgs/tools/misc/mc/mc-4.6.1-debian_fixes-1.patch
Sander van der Burg 3e69dab469 Applied some fixes to midnight commander so that it no longer displays weird characters
svn path=/nixpkgs/trunk/; revision=17207
2009-09-16 17:08:33 +00:00

12671 lines
329 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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; j<charpos; j++)
+ edit_insert (edit, BINARY_CHAR_OFFSET + (mc_wchar_t)buf[j]);
+#endif
+ charpos = 0;
+ }
+#endif /* UTF8 */
}
return i;
}
@@ -252,9 +287,32 @@
long edit_write_stream (WEdit * edit, FILE * f)
{
long i;
+#ifndef UTF8
for (i = 0; i < edit->last_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 <config.h>
-#include <ctype.h>
#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 <filename> file,
b) save to <filename>;
if 1 (safe save) then a) save to <tempnam>,
@@ -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, ", &macro[n].command, &macro[n].ch))
+#else /* UTF8 */
+ while (fscanf (f, "%hd %lu, ", &macro[n].command, &macro[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, ", &macro[*n].command, &macro[*n].ch))
+#else /* UTF8 */
+ while (*n < MAX_MACRO_LENGTH && 2 == fscanf (f, "%hd %lu, ", &macro[*n].command, &macro[*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 <daia@stoilow.imar.ro> 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 <EOF>,
@@ -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, "<EOF>");
}
@@ -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 <wchar.h>
+#include <wctype.h>
+
+#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 tempor<6F>re Befehlsdaei nicht anlegen \n"
+" Kann tempor<6F>re 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 "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
+
+#: messages for recode patch
+msgid "Panel &codepage"
+msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
+
+msgid " Choose codepage "
+msgstr " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
+
+msgid " Choose panel codepage "
+msgstr " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "
+
+msgid " Choose default FTP codepage "
+msgstr " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> FTP <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "
+
+msgid "FTP default codepage:"
+msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> FTP <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:"
+
+msgid "Recode file names:"
+msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>:"
+
+msgid "Recoding works only with COPY/MOVE operation"
+msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
+
+msgid " Choose \"FROM\" codepage for COPY/MOVE operaion "
+msgstr" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "
+
+msgid " Choose \"TO\" codepage for COPY/MOVE operaion "
+msgstr" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "
+
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 <teppi@vnlinux.org>, 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 <teppi@vnlinux.org>\n"
+"Language-Team: Vietnamese <gnomevi-list@lists.sourceforge.net>\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 <subject> -c <cc> <to>"
+msgstr " mail -s <Tên thư> -c <cc> <Người nhận>"
+
+#: 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 &macro... 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 &macro... 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 "<Unknown user>"
+msgstr "<không rõ người dùng>"
+
+#: src/chown.c:179
+msgid "<Unknown group>"
+msgstr "<không rõ nhóm>"
+
+#: 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 "<readlink failed>"
+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 <iconv.h>
+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 <unistd.h>
#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 <slang.h>
+#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 <stdarg.h>
#include <sys/types.h>
#include <ctype.h>
+#include <wchar.h>
+
#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 <wchar.h>
+#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;i<n;i++) table[i]=i;
+}
+
+//--- reset panel codepage
+void panel_reset_codepage(WPanel *p) {
+ p->src_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(i<l1) {
+ s2[i]=table[s1[i]];
+ i++;
+ }
+ s2[i]=0;
+}
+
+//--- Recode filename and concat in to dir
+char* concat_dir_and_recoded_fname(const char *dir, const char *fname, FileOpContext *ctx) {
+ int i = strlen (dir);
+
+ my_translate_string((unsigned char*)fname,strlen(fname),ctx->recode_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 <config.h>
+#ifdef HAVE_CHARSET
+
+#include <stdio.h>
+#include <locale.h>
+#include <iconv.h>
+
+#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 <config.h>
+
+#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 <stdarg.h>
#include <string.h>
#include <ctype.h>
+#include <iconv.h>
+#include <langinfo.h>
+#include <errno.h>
+#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 <wctype.h>
+#include <wchar.h>
+#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 <errno.h>
#include <limits.h>
+#ifdef UTF8
+#include <wctype.h>
+#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 <ctype.h>
#include "global.h"
#include "tty.h"
+#ifdef UTF8
+#include <wctype.h>
+#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{|}~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\}' 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 (<ZIP>) {
+ $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 (<PIPE>) {
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 <path>", 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 */