mc/mc-utf8.patch

5399 lines
149 KiB
Diff
Raw Normal View History

diff -up mc-4.6.2-pre1/acinclude.m4.utf8 mc-4.6.2-pre1/acinclude.m4
--- mc-4.6.2-pre1/acinclude.m4.utf8 2006-09-07 17:59:51.000000000 +0200
+++ mc-4.6.2-pre1/acinclude.m4 2008-10-23 14:00:12.000000000 +0200
@@ -399,14 +399,14 @@ AC_DEFUN([MC_WITH_SLANG], [
fi
dnl Unless external S-Lang was requested, reject S-Lang with UTF-8 hacks
- if test x$with_screen = xslang; then
- :
- m4_if([$1], strict, ,
- [AC_CHECK_LIB([slang], [SLsmg_write_nwchars],
- [AC_MSG_WARN([Rejecting S-Lang with UTF-8 support, \
-it's not fully supported yet])
- with_screen=mcslang])])
- fi
+dnl if test x$with_screen = xslang; then
+dnl :
+dnl m4_if([$1], strict, ,
+dnl [AC_CHECK_LIB([slang], [SLsmg_write_nwchars],
+dnl [AC_MSG_WARN([Rejecting S-Lang with UTF-8 support, \
+dnl it's not fully supported yet])
+dnl with_screen=mcslang])])
+dnl fi
if test x$with_screen = xslang; then
AC_DEFINE(HAVE_SYSTEM_SLANG, 1,
diff -up mc-4.6.2-pre1/edit/editcmd.c.utf8 mc-4.6.2-pre1/edit/editcmd.c
--- mc-4.6.2-pre1/edit/editcmd.c.utf8 2007-05-02 13:22:01.000000000 +0200
+++ mc-4.6.2-pre1/edit/editcmd.c 2008-10-23 14:00:12.000000000 +0200
@@ -61,7 +61,7 @@
#define edit_get_save_file(f,h) input_expand_dialog (h, _(" Enter file name: "), f)
struct selection {
- unsigned char * text;
+ mc_wchar_t *text;
int len;
};
@@ -84,12 +84,16 @@ int edit_confirm_save = 1;
#define MAX_REPL_LEN 1024
static int edit_save_cmd (WEdit *edit);
-static unsigned char *edit_get_block (WEdit *edit, long start,
+static mc_wchar_t *edit_get_block (WEdit *edit, long start,
long finish, int *l);
-static inline int my_lower_case (int c)
+static inline mc_wchar_t my_lower_case (mc_wchar_t c)
{
+#ifndef UTF8
return tolower(c & 0xFF);
+#else
+ return towlower(c);
+#endif
}
static const char *
@@ -124,11 +128,11 @@ static void *memmove (void *dest, const
#endif /* !HAVE_MEMMOVE */
/* #define itoa MY_itoa <---- this line is now in edit.h */
-static char *
+static mc_wchar_t *
MY_itoa (int i)
{
- static char t[14];
- char *s = t + 13;
+ static mc_wchar_t t[14];
+ mc_wchar_t *s = t + 13;
int j = i;
*s-- = 0;
do {
@@ -213,6 +217,48 @@ void edit_refresh_cmd (WEdit * edit)
doupdate();
}
+#ifdef UTF8
+
+static size_t
+wchar_write(int fd, mc_wchar_t *buf, size_t len)
+{
+ char *tmpbuf = g_malloc(len + MB_LEN_MAX);
+ mbstate_t mbs;
+ size_t i;
+ size_t outlen = 0;
+ size_t res;
+
+ for (i = 0; i < len; i++) {
+ if (outlen >= len) {
+ if ((res = mc_write(fd, tmpbuf, outlen)) != outlen) {
+ g_free(tmpbuf);
+ return -1;
+ }
+ outlen = 0;
+ }
+ memset (&mbs, 0, sizeof (mbs));
+#ifdef __STDC_ISO_10646__
+ if (buf[i] >= BINARY_CHAR_OFFSET && buf[i] < (BINARY_CHAR_OFFSET + 256)) {
+ res = 1;
+ tmpbuf[outlen] = (char) (buf[i] - BINARY_CHAR_OFFSET);
+
+ } else
+#endif
+ res = wcrtomb(tmpbuf + outlen, buf[i], &mbs);
+ if (res > 0) {
+ outlen += res;
+ }
+ }
+ if ((res = mc_write(fd, tmpbuf, outlen)) != outlen) {
+ g_free(tmpbuf);
+ return -1;
+ }
+ g_free(tmpbuf);
+ return len;
+}
+
+#endif /* UTF8 */
+
/* If 0 (quick save) then a) create/truncate <filename> file,
b) save to <filename>;
if 1 (safe save) then a) save to <tempnam>,
@@ -360,32 +406,48 @@ edit_save_file (WEdit *edit, const char
buf = 0;
filelen = edit->last_byte;
while (buf <= (edit->curs1 >> S_EDIT_BUF_SIZE) - 1) {
+#ifndef UTF8
if (mc_write (fd, (char *) edit->buffers1[buf], EDIT_BUF_SIZE)
+#else /* UTF8 */
+ if (wchar_write (fd, edit->buffers1[buf], EDIT_BUF_SIZE)
+#endif /* UTF8 */
!= EDIT_BUF_SIZE) {
mc_close (fd);
goto error_save;
}
buf++;
}
+#ifndef UTF8
if (mc_write
(fd, (char *) edit->buffers1[buf],
+#else /* UTF8 */
+ if (wchar_write
+ (fd, edit->buffers1[buf],
+#endif /* UTF8 */
edit->curs1 & M_EDIT_BUF_SIZE) !=
(edit->curs1 & M_EDIT_BUF_SIZE)) {
filelen = -1;
} else if (edit->curs2) {
edit->curs2--;
buf = (edit->curs2 >> S_EDIT_BUF_SIZE);
- if (mc_write
- (fd,
- (char *) edit->buffers2[buf] + EDIT_BUF_SIZE -
+#ifndef UTF8
+ if (mc_write(fd, (char *) edit->buffers2[buf] + EDIT_BUF_SIZE -
+#else /* UTF8 */
+ if (wchar_write(fd, edit->buffers2[buf] + EDIT_BUF_SIZE -
+#endif /* UTF8 */
(edit->curs2 & M_EDIT_BUF_SIZE) - 1,
1 + (edit->curs2 & M_EDIT_BUF_SIZE)) !=
1 + (edit->curs2 & M_EDIT_BUF_SIZE)) {
filelen = -1;
} else {
while (--buf >= 0) {
+#ifndef UTF8
if (mc_write
(fd, (char *) edit->buffers2[buf],
+#else /* UTF8 */
+ if (wchar_write
+ (fd, edit->buffers2[buf],
+#endif /* UTF8 */
EDIT_BUF_SIZE) != EDIT_BUF_SIZE) {
filelen = -1;
break;
@@ -705,13 +767,21 @@ edit_delete_macro (WEdit * edit, int k)
if (!n || n == EOF)
break;
n = 0;
+#ifndef UTF8
while (fscanf (f, "%hd %hd, ", &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");
}
}
@@ -744,7 +814,11 @@ int edit_save_macro_cmd (WEdit * edit, s
if (f) {
fprintf (f, ("key '%d 0': "), s);
for (i = 0; i < n; i++)
+#ifndef UTF8
fprintf (f, "%hd %hd, ", macro[i].command, macro[i].ch);
+#else /* UTF8 */
+ fprintf (f, "%hd %lu, ", macro[i].command, macro[i].ch);
+#endif /* UTF8 */
fprintf (f, ";\n");
fclose (f);
if (saved_macros_loaded) {
@@ -794,10 +868,18 @@ int edit_load_macro_cmd (WEdit * edit, s
saved_macro[i++] = s;
if (!found) {
*n = 0;
+#ifndef UTF8
while (*n < MAX_MACRO_LENGTH && 2 == fscanf (f, "%hd %hd, ", &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)
@@ -944,7 +1026,7 @@ int eval_marks (WEdit * edit, long *star
#define space_width 1
static void
-edit_insert_column_of_text (WEdit * edit, unsigned char *data, int size, int width)
+edit_insert_column_of_text (WEdit * edit, mc_wchar_t *data, int size, int width)
{
long cursor;
int i, col;
@@ -992,7 +1074,7 @@ edit_block_copy_cmd (WEdit *edit)
{
long start_mark, end_mark, current = edit->curs1;
int size;
- unsigned char *copy_buf;
+ mc_wchar_t *copy_buf;
edit_update_curs_col (edit);
if (eval_marks (edit, &start_mark, &end_mark))
@@ -1032,7 +1114,7 @@ edit_block_move_cmd (WEdit *edit)
{
long count;
long current;
- unsigned char *copy_buf;
+ mc_wchar_t *copy_buf;
long start_mark, end_mark;
int deleted = 0;
int x = 0;
@@ -1093,7 +1175,7 @@ edit_block_move_cmd (WEdit *edit)
edit_push_action (edit, COLUMN_ON);
column_highlighting = 0;
} else {
- copy_buf = g_malloc (end_mark - start_mark);
+ copy_buf = g_malloc ((end_mark - start_mark) * sizeof(mc_wchar_t));
edit_cursor_move (edit, start_mark - edit->curs1);
edit_scroll_screen_over_cursor (edit);
count = start_mark;
@@ -1432,7 +1514,11 @@ static long sargs[NUM_REPL_ARGS][256 / s
/* This function is a modification of mc-3.2.10/src/view.c:regexp_view_search() */
/* returns -3 on error in pattern, -1 on not found, found_len = 0 if either */
static int
+#ifndef UTF8
string_regexp_search (char *pattern, char *string, int match_type,
+#else /* UTF8 */
+string_regexp_search (char *pattern, mc_wchar_t *wstring, int match_type,
+#endif /* UTF8 */
int match_bol, int icase, int *found_len, void *d)
{
static regex_t r;
@@ -1441,6 +1527,11 @@ string_regexp_search (char *pattern, cha
regmatch_t *pmatch;
static regmatch_t s[1];
+#ifdef UTF8
+ char *string;
+ int i;
+#endif /* UTF8 */
+
pmatch = (regmatch_t *) d;
if (!pmatch)
pmatch = s;
@@ -1460,13 +1551,51 @@ string_regexp_search (char *pattern, cha
old_type = match_type;
old_icase = icase;
}
+
+#ifdef UTF8
+ string = wchar_to_mbstr(wstring);
+ if (string == NULL)
+ return -1;
+#endif /* UTF8 */
+
if (regexec
(&r, string, d ? NUM_REPL_ARGS : 1, pmatch,
((match_bol
|| match_type != match_normal) ? 0 : REG_NOTBOL)) != 0) {
*found_len = 0;
+
+#ifdef UTF8
+ g_free(string);
+#endif /* UTF8 */
+
return -1;
}
+
+#ifdef UTF8
+ for (i = 0; i < (d ? NUM_REPL_ARGS : 1); i++) {
+ char tmp;
+ int new_o;
+
+ if (pmatch[i].rm_so < 0)
+ continue;
+ tmp = string[pmatch[i].rm_so];
+ string[pmatch[i].rm_so] = 0;
+ new_o = mbstrlen(string);
+ string[pmatch[i].rm_so] = tmp;
+ pmatch[i].rm_so = new_o;
+
+ if (pmatch[i].rm_eo < 0)
+ continue;
+ tmp = string[pmatch[i].rm_eo];
+ string[pmatch[i].rm_eo] = 0;
+ new_o = mbstrlen(string);
+ string[pmatch[i].rm_eo] = tmp;
+ pmatch[i].rm_eo = new_o;
+ }
+
+ g_free(string);
+#endif /* UTF8 */
+
*found_len = pmatch[0].rm_eo - pmatch[0].rm_so;
return (pmatch[0].rm_so);
}
@@ -1474,13 +1603,29 @@ string_regexp_search (char *pattern, cha
/* thanks to Liviu Daia <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... */
@@ -1489,19 +1634,22 @@ edit_find_string (long start, unsigned c
n++;
if (replace_scanf || replace_regexp) {
- int c;
- unsigned char *buf;
- unsigned char mbuf[MAX_REPL_LEN * 2 + 3];
+ mc_wint_t c;
+ mc_wchar_t *buf;
+ mc_wchar_t mbuf[MAX_REPL_LEN * 2 + 3];
replace_scanf = (!replace_regexp); /* can't have both */
buf = mbuf;
if (replace_scanf) {
- unsigned char e[MAX_REPL_LEN];
- if (n >= NUM_REPL_ARGS)
- return -3;
-
+ mc_wchar_t e[MAX_REPL_LEN];
+ if (n >= NUM_REPL_ARGS) {
+#ifdef UTF8
+ g_free(exp_backup);
+#endif /* UTF8 */
+ return -3;
+ }
if (replace_case) {
for (p = start; p < last_byte && p < start + MAX_REPL_LEN; p++)
buf[p - start] = (*get_byte) (data, p);
@@ -1515,20 +1663,36 @@ edit_find_string (long start, unsigned c
}
buf[(q = p - start)] = 0;
+#ifndef UTF8
strcpy ((char *) e, (char *) exp);
strcat ((char *) e, "%n");
+#else /* UTF8 */
+ wcscpy (e, exp);
+ wcscat (e, L"%n");
+#endif /* UTF8 */
exp = e;
while (q) {
*((int *) sargs[n]) = 0; /* --> here was the problem - now fixed: good */
+#ifndef UTF8
if (n == sscanf ((char *) buf, (char *) exp, SCANF_ARGS)) {
+#else /* UTF8 */
+ if (n == swscanf (buf, exp, SCANF_ARGS)) {
+#endif /* UTF8 */
if (*((int *) sargs[n])) {
*len = *((int *) sargs[n]);
+#ifdef UTF8
+ g_free(exp_backup);
+#endif /* UTF8 */
return start;
}
}
- if (once_only)
+ if (once_only) {
+#ifdef UTF8
+ g_free(exp_backup);
+#endif /* UTF8 */
return -2;
+ }
if (q + start < last_byte) {
if (replace_case) {
buf[q] = (*get_byte) (data, q + start);
@@ -1542,7 +1706,11 @@ edit_find_string (long start, unsigned c
start++;
buf++; /* move the window along */
if (buf == mbuf + MAX_REPL_LEN) { /* the window is about to go past the end of array, so... */
+#ifndef UTF8
memmove (mbuf, buf, strlen ((char *) buf) + 1); /* reset it */
+#else /* UTF8 */
+ wmemmove (mbuf, buf, (wcslen (buf) + 1)); /* reset it */
+#endif /* UTF8 */
buf = mbuf;
}
q--;
@@ -1569,10 +1737,16 @@ edit_find_string (long start, unsigned c
buf = mbuf;
while (q) {
+#ifndef UTF8
found_start = string_regexp_search ((char *) exp, (char *) buf, match_normal, match_bol, !replace_case, len, d);
-
+#else /* UTF8 */
+ found_start = string_regexp_search ((char *) exp_mb, buf, match_normal, match_bol, !replace_case, len, d);
+#endif /* UTF8 */
if (found_start <= -2) { /* regcomp/regexec error */
*len = 0;
+#ifdef UTF8
+ g_free (exp_backup);
+#endif /* UTF8 */
return -3;
}
else if (found_start == -1) /* not found: try next line */
@@ -1583,15 +1757,27 @@ edit_find_string (long start, unsigned c
match_bol = 0;
continue;
}
- else /* found */
+ else { /* found */
+#ifdef UTF8
+ g_free(exp_backup);
+#endif /* UTF8 */
return (start + offset - q + found_start);
+ }
}
- if (once_only)
+ if (once_only) {
+#ifdef UTF8
+ g_free(exp_backup);
+#endif /* UTF8 */
return -2;
+ }
if (buf[q - 1] != '\n') { /* incomplete line: try to recover */
buf = mbuf + MAX_REPL_LEN / 2;
+#ifndef UTF8
q = strlen ((const char *) buf);
+#else /* UTF8 */
+ q = wcslen (buf);
+#endif /* UTF8 */
memmove (mbuf, buf, q);
p = start + q;
move_win = 1;
@@ -1601,36 +1787,59 @@ edit_find_string (long start, unsigned c
}
}
} else {
+#ifndef UTF8
*len = strlen ((const char *) exp);
+#else /* UTF8 */
+ *len = wcslen (exp);
+#endif /* UTF8 */
if (replace_case) {
for (p = start; p <= last_byte - l; p++) {
- if ((*get_byte) (data, p) == (unsigned char)exp[0]) { /* check if first char matches */
+ if ((*get_byte) (data, p) == exp[0]) { /* check if first char matches */
for (f = 0, q = 0; q < l && f < 1; q++)
- if ((*get_byte) (data, q + p) != (unsigned char)exp[q])
+ if ((*get_byte) (data, q + p) != exp[q])
f = 1;
- if (f == 0)
+ if (f == 0) {
+#ifdef UTF8
+ g_free (exp_backup);
+#endif /* UTF8 */
return p;
+ }
}
- if (once_only)
+ if (once_only) {
+#ifdef UTF8
+ g_free(exp_backup);
+#endif /* UTF8 */
return -2;
+ }
}
} else {
for (p = 0; exp[p] != 0; p++)
exp[p] = my_lower_case (exp[p]);
for (p = start; p <= last_byte - l; p++) {
- if (my_lower_case ((*get_byte) (data, p)) == (unsigned char)exp[0]) {
+ if (my_lower_case ((*get_byte) (data, p)) == exp[0]) {
for (f = 0, q = 0; q < l && f < 1; q++)
- if (my_lower_case ((*get_byte) (data, q + p)) != (unsigned char)exp[q])
+ if (my_lower_case ((*get_byte) (data, q + p)) != exp[q])
f = 1;
- if (f == 0)
+ if (f == 0) {
+#ifdef UTF8
+ g_free (exp_backup);
+#endif /* UTF8 */
return p;
+ }
}
- if (once_only)
+ if (once_only) {
+#ifdef UTF8
+ g_free (exp_backup);
+#endif /* UTF8 */
return -2;
+ }
}
}
}
+#ifdef UTF8
+ g_free (exp_backup);
+#endif /* UTF8 */
return -2;
}
@@ -1644,9 +1853,14 @@ edit_find_forwards (long search_start, u
while ((p = edit_find_string (p, exp, len, last_byte, get_byte, data, once_only, d)) >= 0) {
if (replace_whole) {
+#ifndef UTF8
/*If the bordering chars are not in option_whole_chars_search then word is whole */
if (!strcasechr (option_whole_chars_search, (*get_byte) (data, p - 1))
&& !strcasechr (option_whole_chars_search, (*get_byte) (data, p + *len)))
+#else /* UTF8 */
+ if (!iswalnum((*get_byte) (data, p - 1))
+ && !iswalnum((*get_byte) (data, p + *len)))
+#endif /* UTF8 */
return p;
if (once_only)
return -2;
@@ -1678,6 +1892,7 @@ edit_find (long search_start, unsigned c
#define is_digit(x) ((x) >= '0' && (x) <= '9')
+#ifndef UTF8
#define snprint(v) { \
*p1++ = *p++; \
*p1 = '\0'; \
@@ -1685,33 +1900,48 @@ edit_find (long search_start, unsigned c
if (n >= (size_t) (e - s)) goto nospc; \
s += n; \
}
+#else /* UTF8 */
+#define snprint(v) { \
+ *p1++ = *p++; \
+ *p1 = '\0'; \
+ n = swprintf(s, e-s, q1,v); \
+ if (n >= (size_t) (e - s)) goto nospc; \
+ s += n; \
+ }
+#endif /* UTF8 */
/* this function uses the sprintf command to do a vprintf */
/* it takes pointers to arguments instead of the arguments themselves */
/* The return value is the number of bytes written excluding '\0'
if successfull, -1 if the resulting string would be too long and
-2 if the format string is errorneous. */
-static int snprintf_p (char *str, size_t size, const char *fmt,...)
- __attribute__ ((format (printf, 3, 4)));
-
-static int snprintf_p (char *str, size_t size, const char *fmt,...)
+static int snprintf_p (mc_wchar_t *str, size_t size, const mc_wchar_t *fmt,...)
{
va_list ap;
size_t n;
- const char *q, *p;
- char *s = str, *e = str + size;
- char q1[40];
- char *p1;
+ const mc_wchar_t *q, *p;
+ mc_wchar_t *s = str, *e = str + size;
+ mc_wchar_t q1[40];
+
+ mc_wchar_t *p1;
int nargs = 0;
va_start (ap, fmt);
p = q = fmt;
+#ifndef UTF8
while ((p = strchr (p, '%'))) {
+#else /* UTF8 */
+ while ((p = wcschr (p, L'%'))) {
+#endif /* UTF8 */
n = p - q;
if (n >= (size_t) (e - s))
goto nospc;
+#ifndef UTF8
memcpy (s, q, n); /* copy stuff between format specifiers */
+#else /* UTF8 */
+ wmemcpy (s, q, n); /* copy stuff between format specifiers */
+#endif /* UTF8 */
s += n;
q = p;
p1 = q1;
@@ -1739,45 +1969,78 @@ static int snprintf_p (char *str, size_t
*p1++ = *p++;
if (*p == '*') {
p++;
+#ifndef UTF8
strcpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace field width with a number */
p1 += strlen (p1);
+#else /* UTF8 */
+ wcscpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace field width with a number */
+ p1 += wcslen (p1);
+#endif /* UTF8 */
} else {
- while (is_digit (*p) && p1 < q1 + 20)
+#ifndef UTF8
+ while (is_digit (*p)
+#else /* UTF8 */
+ while (iswdigit (*p)
+#endif /* UTF8 */
+ && p1 < q1 + 20)
*p1++ = *p++;
- if (is_digit (*p))
+#ifndef UTF8
+ if (is_digit (*p))
+#else /* UTF8 */
+ if (iswdigit (*p))
+#endif /* UTF8 */
goto err;
}
if (*p == '.')
*p1++ = *p++;
if (*p == '*') {
p++;
+#ifndef UTF8
strcpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace precision with a number */
p1 += strlen (p1);
+#else /* UTF8 */
+ wcscpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace precision with a number */
+ p1 += wcslen (p1);
+#endif /* UTF8 */
} else {
- while (is_digit (*p) && p1 < q1 + 32)
+#ifndef UTF8
+ while (is_digit (*p)
+#else /* UTF8 */
+ while (iswdigit (*p)
+#endif /* UTF8 */
+ && p1 < q1 + 32)
*p1++ = *p++;
- if (is_digit (*p))
+#ifndef UTF8
+ if (is_digit (*p))
+#else /* UTF8 */
+ if (iswdigit (*p))
+#endif /* UTF8 */
goto err;
}
/* flags done, now get argument */
if (*p == 's') {
+#ifndef UTF8
snprint (va_arg (ap, char *));
+#else /* UTF8 */
+ *p1++ = 'l';
+ snprint (va_arg (ap, mc_wchar_t *));
+#endif /* UTF8 */
} else if (*p == 'h') {
- if (strchr ("diouxX", *p))
+ if (*p < 128 && strchr ("diouxX", *p))
snprint (*va_arg (ap, short *));
} else if (*p == 'l') {
*p1++ = *p++;
- if (strchr ("diouxX", *p))
+ if (*p < 128 && strchr ("diouxX", *p))
snprint (*va_arg (ap, long *));
- } else if (strchr ("cdiouxX", *p)) {
+ } else if (*p < 128 && strchr ("cdiouxX", *p)) {
snprint (*va_arg (ap, int *));
} else if (*p == 'L') {
*p1++ = *p++;
- if (strchr ("EefgG", *p))
+ if (*p < 128 && strchr ("EefgG", *p))
snprint (*va_arg (ap, double *)); /* should be long double */
- } else if (strchr ("EefgG", *p)) {
+ } else if (*p < 128 && strchr ("EefgG", *p)) {
snprint (*va_arg (ap, double *));
- } else if (strchr ("DOU", *p)) {
+ } else if (*p < 128 && strchr ("DOU", *p)) {
snprint (*va_arg (ap, long *));
} else if (*p == 'p') {
snprint (*va_arg (ap, void **));
@@ -1786,10 +2049,17 @@ static int snprintf_p (char *str, size_t
q = p;
}
va_end (ap);
+#ifndef UTF8
n = strlen (q);
if (n >= (size_t) (e - s))
return -1;
memcpy (s, q, n + 1);
+#else /* UTF8 */
+ n = wcslen (q);
+ if (n >= (size_t) (e - s))
+ return -1;
+ wmemcpy (s, q, n + 1);
+#endif /* UTF8 */
return s + n - str;
nospc:
va_end (ap);
@@ -1968,8 +2238,11 @@ edit_replace_cmd (WEdit *edit, int again
}
}
if (replace_yes) { /* delete then insert new */
+#ifdef UTF8
+ mc_wchar_t *winput2 = mbstr_to_wchar(input2);
+#endif /* UTF8 */
if (replace_scanf) {
- char repl_str[MAX_REPL_LEN + 2];
+ mc_wchar_t repl_str[MAX_REPL_LEN + 2];
int ret = 0;
/* we need to fill in sargs just like with scanf */
@@ -1978,17 +2251,25 @@ edit_replace_cmd (WEdit *edit, int again
for (k = 1;
k < NUM_REPL_ARGS && pmatch[k].rm_eo >= 0;
k++) {
+#ifndef UTF8
unsigned char *t;
+#else /* UTF8 */
+ mc_wchar_t *t;
+#endif
if (pmatch[k].rm_eo - pmatch[k].rm_so > 255) {
ret = -1;
break;
}
+#ifndef UTF8
t = (unsigned char *) &sargs[k - 1][0];
+#else /* UTF8 */
+ t = (mc_wchar_t *) &sargs[k - 1][0];
+#endif /* UTF8 */
for (j = 0;
j < pmatch[k].rm_eo - pmatch[k].rm_so
&& j < 255; j++, t++)
- *t = (unsigned char) edit_get_byte (edit,
+ *t = edit_get_byte (edit,
edit->
search_start
-
@@ -2006,14 +2287,23 @@ edit_replace_cmd (WEdit *edit, int again
}
if (!ret)
ret =
+#ifndef UTF8
snprintf_p (repl_str, MAX_REPL_LEN + 2, input2,
+#else /* UTF8 */
+ snprintf_p (repl_str, MAX_REPL_LEN + 2, winput2,
+#endif /* UTF8 */
PRINTF_ARGS);
if (ret >= 0) {
times_replaced++;
while (i--)
edit_delete (edit);
+#ifndef UTF8
while (repl_str[++i])
edit_insert (edit, repl_str[i]);
+#else /* UTF8 */
+ while (winput2[++i])
+ edit_insert (edit, winput2[i]);
+#endif /* UTF8 */
} else {
edit_error_dialog (_(" Replace "),
ret ==
@@ -2027,10 +2317,18 @@ edit_replace_cmd (WEdit *edit, int again
times_replaced++;
while (i--)
edit_delete (edit);
+#ifndef UTF8
while (input2[++i])
edit_insert (edit, input2[i]);
+#else /* UTF8 */
+ while (winput2[++i])
+ edit_insert (edit, winput2[i]);
+#endif /* UTF8 */
}
edit->found_len = i;
+#ifdef UTF8
+ g_free (winput2);
+#endif /* UTF8 */
}
/* so that we don't find the same string again */
if (replace_backwards) {
@@ -2203,16 +2501,17 @@ edit_ok_to_exit (WEdit *edit)
#define TEMP_BUF_LEN 1024
/* Return a null terminated length of text. Result must be g_free'd */
-static unsigned char *
+static mc_wchar_t *
edit_get_block (WEdit *edit, long start, long finish, int *l)
{
- unsigned char *s, *r;
- r = s = g_malloc (finish - start + 1);
+ mc_wchar_t *s, *r;
+ r = s = g_malloc ((finish - start + 1) * sizeof(mc_wchar_t));
if (column_highlighting) {
*l = 0;
/* copy from buffer, excluding chars that are out of the column 'margins' */
while (start < finish) {
- int c, x;
+ mc_wchar_t c;
+ int x;
x = edit_move_forward3 (edit, edit_bol (edit, start), 0,
start);
c = edit_get_byte (edit, start);
@@ -2245,11 +2544,15 @@ edit_save_block (WEdit * edit, const cha
return 0;
if (column_highlighting) {
- unsigned char *block, *p;
+ mc_wchar_t *block, *p;
int r;
p = block = edit_get_block (edit, start, finish, &len);
while (len) {
+#ifndef UTF8
r = mc_write (file, p, len);
+#else /* UTF8 */
+ r = wchar_write (file, p, len);
+#endif /* UTF8 */
if (r < 0)
break;
p += r;
@@ -2257,15 +2560,19 @@ edit_save_block (WEdit * edit, const cha
}
g_free (block);
} else {
- unsigned char *buf;
+ mc_wchar_t *buf;
int i = start, end;
len = finish - start;
- buf = g_malloc (TEMP_BUF_LEN);
+ buf = g_malloc (TEMP_BUF_LEN * sizeof(mc_wchar_t));
while (start != finish) {
end = min (finish, start + TEMP_BUF_LEN);
for (; i < end; i++)
buf[i - start] = edit_get_byte (edit, i);
+#ifndef UTF8
len -= mc_write (file, (char *) buf, end - start);
+#else /* UTF8 */
+ len -= wchar_write (file, buf, end - start);
+#endif /* UTF8 */
start = end;
}
g_free (buf);
@@ -2603,17 +2910,20 @@ edit_block_process_cmd (WEdit *edit, con
/* prints at the cursor */
/* returns the number of chars printed */
+#ifndef UTF8
int edit_print_string (WEdit * e, const char *s)
+#else /* UTF8 */
+int edit_print_wstring (WEdit * e, mc_wchar_t *s)
+#endif /* UTF8 */
{
int i = 0;
while (s[i])
- edit_execute_cmd (e, -1, (unsigned char) s[i++]);
+ edit_execute_cmd (e, -1, s[i++]);
e->force |= REDRAW_COMPLETELY;
edit_update_screen (e);
return i;
}
-
static void pipe_mail (WEdit *edit, char *to, char *subject, char *cc)
{
FILE *p = 0;
@@ -2707,15 +3017,20 @@ void edit_mail_dialog (WEdit * edit)
/* find first character of current word */
static int edit_find_word_start (WEdit *edit, long *word_start, int *word_len)
{
- int i, c, last;
+ int i;
+ mc_wint_t c, last;
/* return if at begin of file */
if (edit->curs1 <= 0)
return 0;
- c = (unsigned char) edit_get_byte (edit, edit->curs1 - 1);
+ c = edit_get_byte (edit, edit->curs1 - 1);
/* return if not at end or in word */
+#ifndef UTF8
if (isspace (c) || !(isalnum (c) || c == '_'))
+#else /* UTF8 */
+ if (iswspace (c) || !(iswalnum (c) || c == '_'))
+#endif /* UTF8 */
return 0;
/* search start of word to be completed */
@@ -2725,11 +3040,19 @@ static int edit_find_word_start (WEdit *
return 0;
last = c;
- c = (unsigned char) edit_get_byte (edit, edit->curs1 - i);
+ c = edit_get_byte (edit, edit->curs1 - i);
+#ifndef UTF8
if (!(isalnum (c) || c == '_')) {
+#else /* UTF8 */
+ if (!(iswalnum (c) || c == '_')) {
+#endif /* UTF8 */
/* return if word starts with digit */
+#ifndef UTF8
if (isdigit (last))
+#else /* UTF8 */
+ if (iswdigit (last))
+#endif /* UTF8 */
return 0;
*word_start = edit->curs1 - (i - 1); /* start found */
@@ -2762,7 +3085,7 @@ edit_collect_completions (WEdit *edit, l
int *num)
{
int len, max_len = 0, i, skip;
- unsigned char *bufpos;
+ mc_wchar_t *bufpos;
/* collect max MAX_WORD_COMPLETIONS completions */
while (*num < MAX_WORD_COMPLETIONS) {
@@ -2781,11 +3104,16 @@ edit_collect_completions (WEdit *edit, l
buffers1[start >> S_EDIT_BUF_SIZE][start & M_EDIT_BUF_SIZE];
skip = 0;
for (i = 0; i < *num; i++) {
+#ifndef UTF8
if (strncmp
((char *) &compl[i].text[word_len],
- (char *) &bufpos[word_len], max (len,
- compl[i].len) -
- word_len) == 0) {
+ (char *) &bufpos[word_len],
+#else /* UTF8 */
+ if (wcsncmp
+ ((wchar_t *) &compl[i].text[word_len],
+ (wchar_t *) &bufpos[word_len],
+#endif /* UTF8 */
+ max (len, compl[i].len) - word_len) == 0) {
skip = 1;
break; /* skip it, already added */
}
@@ -2793,7 +3121,7 @@ edit_collect_completions (WEdit *edit, l
if (skip)
continue;
- compl[*num].text = g_malloc (len + 1);
+ compl[*num].text = g_malloc ((len + 1) * sizeof(mc_wchar_t));
compl[*num].len = len;
for (i = 0; i < len; i++)
compl[*num].text[i] = *(bufpos + i);
@@ -2807,6 +3135,18 @@ edit_collect_completions (WEdit *edit, l
return max_len;
}
+#ifdef UTF8
+int edit_print_string (WEdit * e, const char *s)
+{
+ int i;
+ mc_wchar_t *ws = mbstr_to_wchar(s);
+ i = edit_print_wstring (e, ws);
+ g_free(ws);
+ return i;
+}
+
+#endif /* UTF8 */
+
/* let the user select its preferred completion */
static void
@@ -2819,6 +3159,9 @@ edit_completion_dialog (WEdit * edit, in
WListbox *compl_list;
int compl_dlg_h; /* completion dialog height */
int compl_dlg_w; /* completion dialog width */
+#ifdef UTF8
+ char *mbtext;
+#endif /* UTF8 */
/* calculate the dialog metrics */
compl_dlg_h = num_compl + 2;
@@ -2854,9 +3197,18 @@ edit_completion_dialog (WEdit * edit, in
add_widget (compl_dlg, compl_list);
/* fill the listbox with the completions */
+#ifndef UTF8
for (i = 0; i < num_compl; i++)
listbox_add_item (compl_list, LISTBOX_APPEND_AT_END, 0,
(char *) compl[i].text, NULL);
+#else /* UTF8 */
+ for (i = 0; i < num_compl; i++) {
+ mbtext = wchar_to_mbstr(compl[i].text);
+ listbox_add_item (compl_list, LISTBOX_APPEND_AT_END, 0,
+ mbtext, NULL);
+ g_free(mbtext);
+ }
+#endif /* UTF8 */
/* pop up the dialog */
run_dlg (compl_dlg);
@@ -2864,9 +3216,17 @@ edit_completion_dialog (WEdit * edit, in
/* apply the choosen completion */
if (compl_dlg->ret_value == B_ENTER) {
listbox_get_current (compl_list, &curr, NULL);
- if (curr)
+ if (curr){
+#ifndef UTF8
for (curr += word_len; *curr; curr++)
edit_insert (edit, *curr);
+#else /* UTF8 */
+ mc_wchar_t *wc, *wccurr = mbstr_to_wchar(curr);
+ for (wc = wccurr + word_len; *wc; wc++)
+ edit_insert (edit, *wc);
+ g_free(wccurr);
+#endif /* UTF8 */
+ }
}
/* destroy dialog before return */
@@ -2883,8 +3243,9 @@ edit_complete_word_cmd (WEdit *edit)
{
int word_len = 0, i, num_compl = 0, max_len;
long word_start = 0;
- unsigned char *bufpos;
- char *match_expr;
+ mc_wchar_t *bufpos;
+ mc_wchar_t *match_expr;
+ char *mbmatch_expr;
struct selection compl[MAX_WORD_COMPLETIONS]; /* completions */
/* don't want to disturb another search */
@@ -2901,16 +3262,32 @@ edit_complete_word_cmd (WEdit *edit)
/* prepare match expression */
bufpos = &edit->buffers1[word_start >> S_EDIT_BUF_SIZE]
[word_start & M_EDIT_BUF_SIZE];
+
+ match_expr = g_malloc((word_len + 14) * sizeof(mc_wchar_t));
+#ifndef UTF8
match_expr = g_strdup_printf ("%.*s[a-zA-Z_0-9]+", word_len, bufpos);
+#else /* UTF8 */
+ wcsncpy (match_expr, bufpos, word_len);
+ match_expr[word_len] = '\0';
+ wcscat (match_expr, L"[a-zA-Z_0-9]+");
+#endif /* UTF8 */
/* init search: backward, regexp, whole word, case sensitive */
edit_set_search_parameters (0, 1, 1, 1, 1);
/* collect the possible completions */
/* start search from curs1 down to begin of file */
+#ifndef UTF8
max_len =
edit_collect_completions (edit, word_start, word_len, match_expr,
(struct selection *) &compl, &num_compl);
+#else /* UTF8 */
+ mbmatch_expr = wchar_to_mbstr(match_expr);
+ max_len =
+ edit_collect_completions (edit, word_start, word_len, mbmatch_expr,
+ (struct selection *) &compl, &num_compl);
+ g_free(mbmatch_expr);
+#endif /* UTF8 */
if (num_compl > 0) {
/* insert completed word if there is only one match */
diff -up mc-4.6.2-pre1/edit/edit.c.utf8 mc-4.6.2-pre1/edit/edit.c
--- mc-4.6.2-pre1/edit/edit.c.utf8 2007-01-04 16:37:23.000000000 +0100
+++ mc-4.6.2-pre1/edit/edit.c 2008-10-23 14:00:12.000000000 +0200
@@ -102,7 +102,11 @@ char *option_backup_ext = NULL;
static void user_menu (WEdit *edit);
+#ifndef UTF8
int edit_get_byte (WEdit * edit, long byte_index)
+#else
+mc_wchar_t edit_get_byte (WEdit * edit, long byte_index)
+#endif
{
unsigned long p;
if (byte_index >= (edit->curs1 + edit->curs2) || byte_index < 0)
@@ -131,7 +135,7 @@ edit_init_buffers (WEdit *edit)
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));
}
/*
@@ -156,7 +160,7 @@ edit_load_file_fast (WEdit *edit, const
}
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 -
@@ -166,7 +170,7 @@ edit_load_file_fast (WEdit *edit, const
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);
}
@@ -239,9 +243,44 @@ edit_insert_stream (WEdit * edit, FILE *
2005-11-16 13:17:52 +00:00
{
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;
}
@@ -249,9 +288,32 @@ edit_insert_stream (WEdit * edit, FILE *
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;
}
@@ -290,12 +352,46 @@ edit_insert_file (WEdit *edit, const cha
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);
@@ -385,7 +481,11 @@ cleanup:
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)
@@ -451,6 +551,7 @@ edit_load_position (WEdit *edit)
edit->prev_col = column;
edit_move_to_prev_col (edit, edit_bol (edit, edit->curs1));
edit_move_display (edit, line - (edit->num_widget_lines / 2));
+ edit->charpoint = 0;
}
/* Save cursor position in the file */
@@ -534,7 +635,7 @@ edit_init (WEdit *edit, int lines, int c
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)
@@ -689,14 +790,23 @@ void edit_push_action (WEdit * edit, lon
{
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;
@@ -711,7 +821,7 @@ void edit_push_action (WEdit * edit, lon
#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));
@@ -722,12 +832,14 @@ void edit_push_action (WEdit * edit, lon
&& 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;
}
}
@@ -735,19 +847,20 @@ void edit_push_action (WEdit * edit, lon
#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
@@ -759,7 +872,9 @@ void edit_push_action (WEdit * edit, lon
#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;
@@ -772,10 +887,10 @@ void edit_push_action (WEdit * edit, lon
(((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;
}
@@ -784,30 +899,30 @@ void edit_push_action (WEdit * edit, lon
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 */
@@ -828,7 +943,7 @@ static inline void edit_modification (WE
*/
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)
@@ -866,12 +981,11 @@ edit_insert (WEdit *edit, int c)
/* 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++;
@@ -882,7 +996,7 @@ edit_insert (WEdit *edit, int c)
/* 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;
@@ -905,7 +1019,7 @@ void edit_insert_ahead (WEdit * edit, in
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++;
@@ -915,7 +1029,7 @@ void edit_insert_ahead (WEdit * edit, in
int edit_delete (WEdit * edit)
{
- int p;
+ mc_wint_t p;
if (!edit->curs2)
return 0;
@@ -939,7 +1053,7 @@ int edit_delete (WEdit * edit)
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')
@@ -953,7 +1067,7 @@ int edit_delete (WEdit * edit)
static int
edit_backspace (WEdit * edit)
{
- int p;
+ mc_wint_t p;
if (!edit->curs1)
return 0;
@@ -977,7 +1091,7 @@ edit_backspace (WEdit * edit)
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--;
@@ -990,10 +1104,18 @@ edit_backspace (WEdit * edit)
#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;
@@ -1006,7 +1128,7 @@ int
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;
@@ -1046,7 +1168,7 @@ edit_move_backward_lots (WEdit *edit, lo
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);
}
@@ -1084,7 +1206,7 @@ edit_move_backward_lots (WEdit *edit, lo
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);
}
@@ -1116,7 +1238,7 @@ int edit_cursor_move (WEdit * edit, long
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];
@@ -1141,7 +1263,7 @@ int edit_cursor_move (WEdit * edit, long
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];
@@ -1248,7 +1370,7 @@ long edit_move_forward3 (WEdit * edit, l
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;
@@ -1266,7 +1388,7 @@ long edit_move_forward3 (WEdit * edit, l
} else if (c < 32 || c == 127)
col += 2; /* Caret notation for control characters */
else
- col++;
+ col += wcwidth(c);
}
return col;
}
@@ -1399,12 +1521,16 @@ static int
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) {
c = edit_get_byte (edit, s++);
+#ifndef UTF8
if (!isspace (c))
+#else
+ if (!iswspace (c))
+#endif /* UTF8 */
return 0;
}
return 1;
@@ -1659,6 +1785,7 @@ my_type_of (int c)
return 2;
return 0x80000000UL;
}
+#ifndef UTF8
if (isupper (c))
c = 'A';
else if (islower (c))
@@ -1669,6 +1796,18 @@ my_type_of (int c)
c = '0';
else if (isspace (c))
c = ' ';
+#else
+ if (iswupper (c))
+ c = 'A';
+ else if (iswlower (c))
+ c = 'a';
+ else if (iswalpha (c))
+ c = 'a';
+ else if (iswdigit (c))
+ c = '0';
+ else if (iswspace (c))
+ c = ' ';
+#endif /* UTF8 */
q = strchr (option_chars_move_whole_word, c);
if (!q)
return 0xFFFFFFFFUL;
@@ -1693,10 +1832,18 @@ edit_left_word_move (WEdit *edit, int s)
c2 = edit_get_byte (edit, edit->curs1);
if (!(my_type_of (c1) & my_type_of (c2)))
break;
+#ifndef UTF8
if (isspace (c1) && !isspace (c2))
+#else
+ if (iswspace (c1) && !iswspace (c2))
+#endif /* UTF8 */
break;
if (s)
+#ifndef UTF8
if (!isspace (c1) && isspace (c2))
+#else
+ if (!iswspace (c1) && iswspace (c2))
+#endif /* UTF8 */
break;
}
}
@@ -1719,10 +1866,18 @@ edit_right_word_move (WEdit *edit, int s
c2 = edit_get_byte (edit, edit->curs1);
if (!(my_type_of (c1) & my_type_of (c2)))
break;
+#ifndef UTF8
if (isspace (c1) && !isspace (c2))
+#else
+ if (iswspace (c1) && !iswspace (c2))
+#endif /* UTF8 */
break;
if (s)
+#ifndef UTF8
if (!isspace (c1) && isspace (c2))
+#else
+ if (!iswspace (c1) && iswspace (c2))
+#endif /* UTF8 */
break;
}
}
@@ -1742,7 +1897,11 @@ static void edit_right_delete_word (WEdi
break;
c1 = edit_delete (edit);
c2 = edit_get_byte (edit, edit->curs1);
+#ifndef UTF8
if ((isspace (c1) == 0) != (isspace (c2) == 0))
+#else
+ if ((iswspace (c1) == 0) != (iswspace (c2) == 0))
+#endif /* UTF8 */
break;
if (!(my_type_of (c1) & my_type_of (c2)))
break;
@@ -1757,7 +1916,11 @@ static void edit_left_delete_word (WEdit
break;
c1 = edit_backspace (edit);
c2 = edit_get_byte (edit, edit->curs1 - 1);
+#ifndef UTF8
if ((isspace (c1) == 0) != (isspace (c2) == 0))
+#else
+ if ((iswspace (c1) == 0) != (iswspace (c2) == 0))
+#endif /* UTF8 */
break;
if (!(my_type_of (c1) & my_type_of (c2)))
break;
@@ -1771,13 +1934,13 @@ static void edit_left_delete_word (WEdit
static void
edit_do_undo (WEdit * edit)
{
- 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:
@@ -1798,31 +1961,33 @@ edit_do_undo (WEdit * edit)
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 +2267,7 @@ static void edit_goto_matching_bracket (
* 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 +2302,7 @@ static const char * const shell_cmd[] =
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 +2335,7 @@ edit_execute_cmd (WEdit *edit, int comma
}
/* 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 -up mc-4.6.2-pre1/edit/editdraw.c.utf8 mc-4.6.2-pre1/edit/editdraw.c
--- mc-4.6.2-pre1/edit/editdraw.c.utf8 2007-08-27 14:06:03.000000000 +0200
+++ mc-4.6.2-pre1/edit/editdraw.c 2008-10-23 14:00:45.000000000 +0200
@@ -70,11 +70,16 @@ static void status_string (WEdit * edit,
* as decimal and as hex.
*/
if (edit->curs1 < edit->last_byte) {
- unsigned char cur_byte = edit_get_byte (edit, edit->curs1);
+ mc_wchar_t cur_byte = edit_get_byte (edit, edit->curs1);
+#ifndef UTF8
g_snprintf (byte_str, sizeof (byte_str), "%c %3d 0x%02X",
is_printable (cur_byte) ? cur_byte : '.',
- (int) cur_byte,
- (unsigned) cur_byte);
+#else /* UTF8 */
+ g_snprintf (byte_str, sizeof(byte_str), "%lc %3d 0x%02X",
+ iswprint(cur_byte) ? cur_byte : '.',
+#endif /* UTF8 */
+ (int) cur_byte,
+ (unsigned) cur_byte);
} else {
strcpy (byte_str, "<EOF>");
}
@@ -206,11 +211,16 @@ void edit_scroll_screen_over_cursor (WEd
#define lowlevel_set_color(x) attrset(MY_COLOR_PAIR(color))
#endif
+struct line_s {
+ mc_wchar_t ch;
+ unsigned int style;
+};
+
static void
print_to_widget (WEdit *edit, long row, int start_col, int start_col_real,
- long end_col, unsigned int line[])
+ long end_col, struct line_s line[])
{
- unsigned int *p;
+ struct line_s *p;
int x = start_col_real + EDIT_TEXT_HORIZONTAL_OFFSET;
int x1 = start_col + EDIT_TEXT_HORIZONTAL_OFFSET;
@@ -224,9 +234,9 @@ print_to_widget (WEdit *edit, long row,
edit_move (x1 + FONT_OFFSET_X, y + FONT_OFFSET_Y);
p = line;
- while (*p) {
+ while (p->ch) {
int style;
- int textchar;
+ mc_wchar_t textchar;
int color;
if (cols_to_skip) {
@@ -235,9 +245,9 @@ print_to_widget (WEdit *edit, long row,
continue;
}
- style = *p & 0xFF00;
- textchar = *p & 0xFF;
- color = *p >> 16;
+ style = p->style & 0xFF00;
+ textchar = p->ch;
+ color = p->style >> 16;
if (style & MOD_ABNORMAL) {
/* Non-printable - use black background */
@@ -266,8 +276,11 @@ print_to_widget (WEdit *edit, long row,
lowlevel_set_color (color);
}
}
-
+#ifdef UTF8
+ SLsmg_write_nwchars(&textchar, 1);
+#else
addch (textchar);
+#endif
p++;
}
}
@@ -279,11 +292,11 @@ static void
edit_draw_this_line (WEdit *edit, long b, long row, long start_col,
long end_col)
{
- static unsigned int line[MAX_LINE_LEN];
- unsigned int *p = line;
+ struct line_s line[MAX_LINE_LEN];
+ struct line_s *p = line;
long m1 = 0, m2 = 0, q, c1, c2, tws;
int col, start_col_real;
- unsigned int c;
+ mc_wint_t c;
int color;
int i;
@@ -307,62 +320,89 @@ edit_draw_this_line (WEdit *edit, long b
}
while (col <= end_col - edit->start_col) {
- *p = 0;
+ p->ch = 0;
+ p->style = 0;
if (q == edit->curs1)
- *p |= MOD_CURSOR;
+ p->style |= MOD_CURSOR;
if (q >= m1 && q < m2) {
if (column_highlighting) {
int x;
x = edit_move_forward3 (edit, b, 0, q);
if (x >= c1 && x < c2)
- *p |= MOD_MARKED;
+ p->style |= MOD_MARKED;
} else
- *p |= MOD_MARKED;
+ p->style |= MOD_MARKED;
}
if (q == edit->bracket)
- *p |= MOD_BOLD;
+ p->style |= MOD_BOLD;
if (q >= edit->found_start
&& q < edit->found_start + edit->found_len)
- *p |= MOD_BOLD;
+ p->style |= MOD_BOLD;
c = edit_get_byte (edit, q);
/* we don't use bg for mc - fg contains both */
edit_get_syntax_color (edit, q, &color);
- *p |= color << 16;
+ p->style |= color << 16;
switch (c) {
case '\n':
col = end_col - edit->start_col + 1; /* quit */
- *(p++) |= ' ';
+ p->ch = ' ';
+ p++;
break;
case '\t':
i = TAB_SIZE - ((int) col % TAB_SIZE);
col += i;
if (use_colors && visible_tabs) {
- c = (*p & ~MOD_CURSOR) | MOD_WHITESPACE;
+// c = (p->style & ~MOD_CURSOR) | MOD_WHITESPACE;
+ c = 0;
if (i > 2) {
- *(p++) |= '<' | MOD_WHITESPACE;
- while (--i > 1)
- *(p++) = c | '-';
- *(p++) = c | '>';
+ p->ch |= '<';
+ p->style = MOD_WHITESPACE;
+ p++;
+ while (--i > 1) {
+ p->ch = c | '-';
+ p->style = MOD_WHITESPACE;
+ p++;
+ }
+ p->ch = c | '>';
+ p->style = MOD_WHITESPACE;
+ p++;
} else if (i > 1) {
- *(p++) |= '<' | MOD_WHITESPACE;
- *(p++) = c | '>';
- } else
- *(p++) |= '>' | MOD_WHITESPACE;
+ p->ch |= '<';
+ p->style = MOD_WHITESPACE;
+ p++;
+ p->ch = c | '>';
+ p->style = MOD_WHITESPACE;
+ p++;
+ } else {
+ p->ch |= '>';
+ p->style = MOD_WHITESPACE;
+ p++;
+ }
} else if (use_colors && visible_tws && q >= tws) {
- *p |= '.' | MOD_WHITESPACE;
- c = *(p++) & ~MOD_CURSOR;
- while (--i)
- *(p++) = c;
+ p->ch |= '.';
+ p->style = MOD_WHITESPACE;
+ c = p->style & ~MOD_CURSOR;
+ p++;
+ while (--i) {
+ p->ch = c;
+ p++;
+ }
} else {
- *p |= ' ';
- c = *(p++) & ~MOD_CURSOR;
- while (--i)
- *(p++) = c;
+ p->ch |= ' ';
+ p->style = ' ';
+ c = p->style & ~MOD_CURSOR;
+ p++;
+ while (--i) {
+ p->ch = c;
+ p++;
+ }
}
break;
case ' ':
if (use_colors && visible_tws && q >= tws) {
- *(p++) |= '.' | MOD_WHITESPACE;
+ p->ch |= '.';
+ p->style = MOD_WHITESPACE;
+ p++;
col++;
break;
}
@@ -372,22 +412,47 @@ edit_draw_this_line (WEdit *edit, long b
/* Caret notation for control characters */
if (c < 32) {
- *(p++) = '^' | MOD_ABNORMAL;
- *(p++) = (c + 0x40) | MOD_ABNORMAL;
+ p->ch = '^';
+ p->style = MOD_ABNORMAL;
+ p++;
+ p->ch = c + 0x40;
+ p->style = MOD_ABNORMAL;
+ p++;
col += 2;
break;
}
if (c == 127) {
- *(p++) = '^' | MOD_ABNORMAL;
- *(p++) = '?' | MOD_ABNORMAL;
+ p->ch = '^';
+ p->style = MOD_ABNORMAL;
+ p++;
+ p->ch = '?';
+ p->style = MOD_ABNORMAL;
+ p++;
col += 2;
break;
}
- if (is_printable (c)) {
- *(p++) |= c;
+#ifndef UTF8
+ if (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;
@@ -398,7 +463,7 @@ edit_draw_this_line (WEdit *edit, long b
} else {
start_col_real = start_col = 0;
}
- *p = 0;
+ p->ch = 0;
print_to_widget (edit, row, start_col, start_col_real, end_col, line);
}
diff -up mc-4.6.2-pre1/edit/edit.h.utf8 mc-4.6.2-pre1/edit/edit.h
--- mc-4.6.2-pre1/edit/edit.h.utf8 2006-12-10 23:07:28.000000000 +0100
+++ mc-4.6.2-pre1/edit/edit.h 2008-10-23 14:00:12.000000000 +0200
@@ -25,6 +25,27 @@
#include <stdio.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 << 0)
@@ -86,6 +107,8 @@
#define START_STACK_SIZE 32
/* Some codes that may be pushed onto or returned from the undo stack */
+#define CHAR_INSERT 65
+#define CHAR_INSERT_AHEAD 66
#define CURS_LEFT 601
#define CURS_RIGHT 602
#define DELCHAR 603
@@ -105,7 +128,7 @@
struct macro {
short command;
- short ch;
+ mc_wchar_t ch;
};
struct WEdit;
@@ -120,8 +143,12 @@ void edit_reload_menu (void);
void menu_save_mode_cmd (void);
int edit_raw_key_query (const char *heading, const char *query, int cancel);
int edit_file (const char *_file, int line);
-int edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch);
+int edit_translate_key (WEdit *edit, long x_key, int *cmd, mc_wint_t *ch);
+#ifndef UTF8
int edit_get_byte (WEdit * edit, long byte_index);
+#else /* UTF8 */
+mc_wchar_t edit_get_byte (WEdit * edit, long byte_index);
+#endif /* UTF8 */
int edit_count_lines (WEdit * edit, long current, int upto);
long edit_move_forward (WEdit * edit, long current, int lines, long upto);
long edit_move_forward3 (WEdit * edit, long current, int cols, long upto);
@@ -148,11 +175,11 @@ int edit_block_delete_cmd (WEdit * edit)
void edit_delete_line (WEdit * edit);
int edit_delete (WEdit * edit);
-void edit_insert (WEdit * edit, int c);
+void edit_insert (WEdit * edit, mc_wchar_t c);
int edit_cursor_move (WEdit * edit, long increment);
void edit_push_action (WEdit * edit, long c, ...);
void edit_push_key_press (WEdit * edit);
-void edit_insert_ahead (WEdit * edit, int c);
+void edit_insert_ahead (WEdit * edit, mc_wchar_t c);
long edit_write_stream (WEdit * edit, FILE * f);
char *edit_get_write_filter (const char *writename, const char *filename);
int edit_save_confirm_cmd (WEdit * edit);
@@ -183,7 +210,7 @@ void edit_goto_cmd (WEdit * edit);
int eval_marks (WEdit * edit, long *start_mark, long *end_mark);
void edit_status (WEdit * edit);
void edit_execute_key_command (WEdit *edit, int command,
- int char_for_insertion);
+ mc_wint_t char_for_insertion);
void edit_update_screen (WEdit * edit);
int edit_print_string (WEdit * e, const char *s);
void edit_move_to_line (WEdit * e, long line);
@@ -233,7 +260,7 @@ void edit_mail_dialog (WEdit *edit);
void format_paragraph (WEdit *edit, int force);
/* either command or char_for_insertion must be passed as -1 */
-void edit_execute_cmd (WEdit *edit, int command, int char_for_insertion);
+void edit_execute_cmd (WEdit *edit, int command, mc_wint_t char_for_insertion);
#define get_sys_error(s) (s)
diff -up mc-4.6.2-pre1/edit/editkeys.c.utf8 mc-4.6.2-pre1/edit/editkeys.c
--- mc-4.6.2-pre1/edit/editkeys.c.utf8 2006-02-01 18:07:11.000000000 +0100
+++ mc-4.6.2-pre1/edit/editkeys.c 2008-10-23 14:00:12.000000000 +0200
@@ -182,10 +182,10 @@ static const edit_key_map_type common_ke
* 'command' is one of the editor commands from editcmddef.h.
*/
int
-edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch)
+edit_translate_key (WEdit *edit, long x_key, int *cmd, mc_wint_t *ch)
{
int command = CK_Insert_Char;
- int char_for_insertion = -1;
+ mc_wint_t char_for_insertion = -1;
int i = 0;
int extmod = 0;
const edit_key_map_type *key_map = NULL;
@@ -242,9 +242,30 @@ edit_translate_key (WEdit *edit, long x_
/* an ordinary insertable character */
if (x_key < 256 && !extmod) {
int c = convert_from_input_c (x_key);
-
+#ifdef UTF8
+ mbstate_t mbs;
+ int res;
+ mc_wchar_t wc;
+
+ memset (&mbs, 0, sizeof (mbs));
+
+ if (edit->charpoint >= MB_CUR_MAX) edit->charpoint = 0;
+
+ edit->charbuf[edit->charpoint++] = c;
+
+ res = mbrtowc(&wc, (char *)edit->charbuf, edit->charpoint, &mbs);
+ if (res < 0) {
+ if (res != -2) edit->charpoint = 0; /* broken multibyte char, skip */
+ return 0;
+ }
+ edit->charpoint = 0;
+
+ if (iswprint (wc)) {
+ char_for_insertion = wc;
+#else
if (is_printable (c)) {
char_for_insertion = c;
+#endif /* UTF8 */
goto fin;
}
}
@@ -283,7 +304,7 @@ edit_translate_key (WEdit *edit, long x_
*cmd = command;
*ch = char_for_insertion;
- if (command == CK_Insert_Char && char_for_insertion == -1) {
+ if (command == CK_Insert_Char && char_for_insertion == (mc_wint_t)-1) {
/* unchanged, key has no function here */
return 0;
}
diff -up mc-4.6.2-pre1/edit/editwidget.c.utf8 mc-4.6.2-pre1/edit/editwidget.c
--- mc-4.6.2-pre1/edit/editwidget.c.utf8 2006-12-10 23:07:28.000000000 +0100
+++ mc-4.6.2-pre1/edit/editwidget.c 2008-10-23 14:00:12.000000000 +0200
@@ -331,7 +331,8 @@ edit_callback (Widget *w, widget_msg_t m
case WIDGET_KEY:
{
- int cmd, ch;
+ int cmd;
+ mc_wint_t ch;
/* The user may override the access-keys for the menu bar. */
if (edit_translate_key (e, parm, &cmd, &ch)) {
diff -up mc-4.6.2-pre1/edit/edit-widget.h.utf8 mc-4.6.2-pre1/edit/edit-widget.h
--- mc-4.6.2-pre1/edit/edit-widget.h.utf8 2007-02-03 02:03:53.000000000 +0100
+++ mc-4.6.2-pre1/edit/edit-widget.h 2008-10-23 14:00:12.000000000 +0200
@@ -30,6 +30,11 @@ typedef struct edit_key_map_type {
long command;
} edit_key_map_type;
+struct action {
+ mc_wchar_t ch;
+ long flags;
+};
+
struct WEdit {
Widget widget;
@@ -42,8 +47,17 @@ struct WEdit {
/* dynamic buffers and cursor position for editor: */
long curs1; /* position of the cursor from the beginning of the file. */
long curs2; /* position from the end of the file */
+#ifndef UTF8
unsigned char *buffers1[MAXBUFF + 1]; /* all data up to curs1 */
unsigned char *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */
+#else /* UTF8 */
+ mc_wchar_t *buffers1[MAXBUFF + 1]; /* all data up to curs1 */
+ mc_wchar_t *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */
+
+ unsigned char charbuf[MB_LEN_MAX];
+ int charpoint;
+#endif /* UTF8 */
+
/* search variables */
long search_start; /* First character to start searching from */
@@ -87,7 +101,7 @@ struct WEdit {
/* undo stack and pointers */
unsigned long stack_pointer;
- long *undo_stack;
+ struct action *undo_stack;
unsigned long stack_size;
unsigned long stack_size_mask;
unsigned long stack_bottom;
diff -up mc-4.6.2-pre1/edit/wordproc.c.utf8 mc-4.6.2-pre1/edit/wordproc.c
--- mc-4.6.2-pre1/edit/wordproc.c.utf8 2006-06-16 22:01:29.000000000 +0200
+++ mc-4.6.2-pre1/edit/wordproc.c 2008-10-23 14:00:12.000000000 +0200
@@ -40,7 +40,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
@@ -57,14 +62,21 @@ line_start (WEdit *edit, long line)
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) == '.')
@@ -78,7 +90,13 @@ static int bad_line_start (WEdit * edit,
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;
}
@@ -131,33 +149,37 @@ end_paragraph (WEdit *edit, int force)
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++;
@@ -174,7 +196,7 @@ static inline int next_tab_pos (int x)
{
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 (;;) {
@@ -198,7 +220,7 @@ static int line_pixel_length (unsigned c
}
static int
-next_word_start (unsigned char *t, int q, int size)
+next_word_start (mc_wchar_t *t, int q, int size)
{
int i;
int saw_ws = 0;
@@ -222,7 +244,7 @@ next_word_start (unsigned char *t, int q
/* find the start of a word */
static int
-word_start (unsigned char *t, int q, int size)
+word_start (mc_wchar_t *t, int q, int size)
{
int i = q;
if (t[q] == ' ' || t[q] == '\t')
@@ -241,7 +263,7 @@ word_start (unsigned char *t, int q, int
}
/* 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);
@@ -269,7 +291,7 @@ static void format_this (unsigned char *
}
}
-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);
@@ -278,18 +300,27 @@ static void replace_at (WEdit * edit, lo
/* replaces a block of text */
static void
-put_paragraph (WEdit * edit, unsigned char *t, long p, int indent, int size)
+put_paragraph (WEdit * edit, mc_wchar_t *t, long p, 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;
@@ -301,7 +332,11 @@ put_paragraph (WEdit * edit, unsigned ch
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--;
@@ -334,7 +369,7 @@ format_paragraph (WEdit *edit, int force
{
long p, q;
int size;
- unsigned char *t;
+ mc_wchar_t *t;
int indent = 0;
if (option_word_wrap_line_length < 2)
return;
@@ -344,17 +379,25 @@ format_paragraph (WEdit *edit, int force
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 -up mc-4.6.2-pre1/src/achown.c.utf8 mc-4.6.2-pre1/src/achown.c
--- mc-4.6.2-pre1/src/achown.c.utf8 2005-09-05 03:36:58.000000000 +0200
+++ mc-4.6.2-pre1/src/achown.c 2008-10-23 14:00:12.000000000 +0200
@@ -584,6 +584,12 @@ init_chown_advanced (void)
b_att[2] = button_new (XTRACT (6));
b_user = button_new (XTRACT (5));
b_group = button_new (XTRACT (4));
+#ifdef UTF8
+ if (SLsmg_Is_Unicode) {
+ b_user->text = g_realloc (b_user->text, MB_CUR_MAX * 15 + 1);
+ b_group->text = g_realloc (b_group->text, MB_CUR_MAX * 15 + 1);
+ }
+#endif
add_widget (ch_dlg, b_group);
add_widget (ch_dlg, b_user);
diff -up mc-4.6.2-pre1/src/boxes.c.utf8 mc-4.6.2-pre1/src/boxes.c
--- mc-4.6.2-pre1/src/boxes.c.utf8 2006-02-28 17:15:21.000000000 +0100
+++ mc-4.6.2-pre1/src/boxes.c 2008-10-23 14:00:12.000000000 +0200
@@ -153,23 +153,23 @@ display_init (int radio_sel, char *init_
display_title = _(display_title);
for (i = 0; i < LIST_TYPES; i++) {
displays[i] = _(displays[i]);
- if ((l = strlen (displays[i])) > maxlen)
+ if ((l = mbstrlen (displays[i])) > maxlen)
maxlen = l;
}
- i = strlen (ok_button) + 5;
- l = strlen (cancel_button) + 3;
+ i = mbstrlen (ok_button) + 5;
+ l = mbstrlen (cancel_button) + 3;
l = max (i, l);
i = maxlen + l + 16;
if (i > DISPLAY_X)
DISPLAY_X = i;
- i = strlen (user_mini_status) + 13;
+ i = mbstrlen (user_mini_status) + 13;
if (i > DISPLAY_X)
DISPLAY_X = i;
- i = strlen (display_title) + 10;
+ i = mbstrlen (display_title) + 10;
if (i > DISPLAY_X)
DISPLAY_X = i;
@@ -288,20 +288,20 @@ sort_box (sortfn *sort_fn, int *reverse,
int maxlen = 0;
for (i = SORT_TYPES - 1; i >= 0; i--) {
sort_orders_names[i] = _(sort_orders[i].sort_name);
- r = strlen (sort_orders_names[i]);
+ r = mbstrlen (sort_orders_names[i]);
if (r > maxlen)
maxlen = r;
}
check_pos = maxlen + 9;
- r = strlen (reverse_label) + 4;
- i = strlen (case_label) + 4;
+ r = mbstrlen (reverse_label) + 4;
+ i = mbstrlen (case_label) + 4;
if (i > r)
r = i;
- l = strlen (ok_button) + 6;
- i = strlen (cancel_button) + 4;
+ l = mbstrlen (ok_button) + 6;
+ i = mbstrlen (cancel_button) + 4;
if (i > l)
l = i;
@@ -310,7 +310,7 @@ sort_box (sortfn *sort_fn, int *reverse,
if (i > SORT_X)
SORT_X = i;
- i = strlen (sort_title) + 6;
+ i = mbstrlen (sort_title) + 6;
if (i > SORT_X)
SORT_X = i;
@@ -408,7 +408,7 @@ confirm_box (void)
while (i--)
{
conf_widgets [i].text = _(conf_widgets [i].text);
- l1 = strlen (conf_widgets [i].text) + 3;
+ l1 = mbstrlen (conf_widgets [i].text) + 3;
if (l1 > maxlen)
maxlen = l1;
}
@@ -423,8 +423,8 @@ confirm_box (void)
* And this for the case when buttons with some space to the right
* do not fit within 2/6
*/
- l1 = strlen (conf_widgets [0].text) + 3;
- i = strlen (conf_widgets [1].text) + 5;
+ l1 = mbstrlen (conf_widgets [0].text) + 3;
+ i = mbstrlen (conf_widgets [1].text) + 5;
if (i > l1)
l1 = i;
@@ -497,11 +497,11 @@ display_bits_box (void)
{
display_widgets [i].text = _(display_widgets[i].text);
display_bits_str [i] = _(display_bits_str [i]);
- l1 = strlen (display_bits_str [i]);
+ l1 = mbstrlen (display_bits_str [i]);
if (l1 > maxlen)
maxlen = l1;
}
- l1 = strlen (display_widgets [2].text);
+ l1 = mbstrlen (display_widgets [2].text);
if (l1 > maxlen)
maxlen = l1;
@@ -509,8 +509,8 @@ display_bits_box (void)
display_bits.xlen = (maxlen + 5) * 6 / 4;
/* See above confirm_box */
- l1 = strlen (display_widgets [0].text) + 3;
- i = strlen (display_widgets [1].text) + 5;
+ l1 = mbstrlen (display_widgets [0].text) + 3;
+ i = mbstrlen (display_widgets [1].text) + 5;
if (i > l1)
l1 = i;
@@ -605,7 +605,7 @@ init_disp_bits_box (void)
cpname = _("&Select");
add_widget (dbits_dlg,
- button_new (4, DISPX - 8 - strlen (cpname), B_USER,
+ button_new (4, DISPX - 8 - mbstrlen (cpname), B_USER,
NORMAL_BUTTON, cpname, sel_charset_button));
return dbits_dlg;
@@ -816,7 +816,7 @@ cd_dialog (void)
quick_widgets [1].y_divisions =
quick_widgets [0].y_divisions = Quick_input.ylen = 5;
- len = strlen (quick_widgets [1].text);
+ len = mbstrlen (quick_widgets [1].text);
quick_widgets [0].relative_x =
quick_widgets [1].relative_x + len + 1;
@@ -975,7 +975,7 @@ jobs_cmd (void)
{
job_buttons [i].name = _(job_buttons [i].name);
- len = strlen (job_buttons [i].name) + 4;
+ len = mbstrlen (job_buttons [i].name) + 4;
JOBS_X = max (JOBS_X, startx + len + 3);
job_buttons [i].xpos = startx;
@@ -984,7 +984,7 @@ jobs_cmd (void)
/* Last button - Ok a.k.a. Cancel :) */
job_buttons [n_buttons - 1].xpos =
- JOBS_X - strlen (job_buttons [n_buttons - 1].name) - 7;
+ JOBS_X - mbstrlen (job_buttons [n_buttons - 1].name) - 7;
i18n_flag = 1;
}
@@ -1042,7 +1042,7 @@ vfs_smb_get_authinfo (const char *host,
while (i--)
{
- l1 = strlen (labs [i] = _(labs [i]));
+ l1 = mbstrlen (labs [i] = _(labs [i]));
if (l1 > maxlen)
maxlen = l1;
}
@@ -1052,7 +1052,7 @@ vfs_smb_get_authinfo (const char *host,
for (i = sizeof(buts)/sizeof(buts[0]), l1 = 0; i--; )
{
- l1 += strlen (buts [i] = _(buts [i]));
+ l1 += mbstrlen (buts [i] = _(buts [i]));
}
l1 += 15;
if (l1 > dialog_x)
@@ -1061,7 +1061,7 @@ vfs_smb_get_authinfo (const char *host,
ilen = dialog_x - 7 - maxlen; /* for the case of very long buttons :) */
istart = dialog_x - 3 - ilen;
- b2 = dialog_x - (strlen(buts[1]) + 6);
+ b2 = dialog_x - (mbstrlen(buts[1]) + 6);
i18n_flag = 1;
}
diff -up mc-4.6.2-pre1/src/dialog.c.utf8 mc-4.6.2-pre1/src/dialog.c
--- mc-4.6.2-pre1/src/dialog.c.utf8 2005-09-05 05:20:27.000000000 +0200
+++ mc-4.6.2-pre1/src/dialog.c 2008-10-23 14:00:12.000000000 +0200
@@ -166,7 +166,7 @@ common_dialog_repaint (struct Dlg_head *
if (h->title) {
attrset (DLG_HOT_NORMALC (h));
- dlg_move (h, space, (h->cols - strlen (h->title)) / 2);
+ dlg_move (h, space, (h->cols - mbstrlen (h->title)) / 2);
addstr (h->title);
}
}
diff -up mc-4.6.2-pre1/src/file.c.utf8 mc-4.6.2-pre1/src/file.c
--- mc-4.6.2-pre1/src/file.c.utf8 2007-02-22 15:29:11.000000000 +0100
+++ mc-4.6.2-pre1/src/file.c 2008-10-23 14:00:12.000000000 +0200
@@ -161,15 +161,20 @@ static const char *
do_transform_source (FileOpContext *ctx, const char *source)
{
size_t j, k, l, len;
- const char *fnsource = x_basename (source);
+ char *fnsource = g_strdup (x_basename (source));
int next_reg;
enum CaseConvs case_conv = NO_CONV;
static char fntarget[MC_MAXPATHLEN];
+#ifdef UTF8
+ fix_utf8(fnsource);
+#endif
+
len = strlen (fnsource);
j = re_match (&ctx->rx, fnsource, len, 0, &ctx->regs);
if (j != len) {
transform_error = FILE_SKIP;
+ g_free (fnsource);
return NULL;
}
for (next_reg = 1, j = 0, k = 0; j < strlen (ctx->dest_mask); j++) {
@@ -213,6 +218,7 @@ do_transform_source (FileOpContext *ctx,
|| ctx->regs.start[next_reg] < 0) {
message (1, MSG_ERROR, _(" Invalid target mask "));
transform_error = FILE_ABORT;
+ g_free(fnsource);
return NULL;
}
for (l = (size_t) ctx->regs.start[next_reg];
@@ -227,6 +233,7 @@ do_transform_source (FileOpContext *ctx,
}
}
fntarget[k] = 0;
+ g_free(fnsource);
return fntarget;
}
@@ -1688,13 +1695,13 @@ panel_operate_generate_prompt (const WPa
*dp = '\0';
if (single_source) {
- i = fmd_xlen - strlen (format_string) - 4;
+ i = fmd_xlen - mbstrlen (format_string) - 4;
g_snprintf (cmd_buf, sizeof (cmd_buf), format_string,
name_trunc (single_source, i));
} else {
g_snprintf (cmd_buf, sizeof (cmd_buf), format_string,
panel->marked);
- i = strlen (cmd_buf) + 6 - fmd_xlen;
+ i = mbstrlen (cmd_buf) + 6 - fmd_xlen;
if (i > 0) {
fmd_xlen += i;
fmd_init_i18n (TRUE); /* to recalculate positions of child widgets */
diff -up mc-4.6.2-pre1/src/filegui.c.utf8 mc-4.6.2-pre1/src/filegui.c
--- mc-4.6.2-pre1/src/filegui.c.utf8 2007-08-23 15:16:39.000000000 +0200
+++ mc-4.6.2-pre1/src/filegui.c 2008-10-23 14:00:12.000000000 +0200
@@ -65,6 +65,7 @@
#include "filegui.h"
#include "key.h" /* get_event */
#include "util.h" /* strip_password() */
+#include "tty.h"
/* }}} */
@@ -563,8 +564,8 @@ init_replace (FileOpContext *ctx, enum O
* 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]);
@@ -575,7 +576,7 @@ init_replace (FileOpContext *ctx, enum O
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 */
@@ -593,12 +594,12 @@ init_replace (FileOpContext *ctx, enum O
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 */
@@ -617,7 +618,7 @@ init_replace (FileOpContext *ctx, enum O
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);
@@ -804,36 +805,36 @@ fmd_init_i18n (int force)
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[FMCB11].text)
+ + mbstrlen (fmd_widgets[FMCB21].text) + 15;
fmd_xlen = max (fmd_xlen, len);
- len = strlen (fmd_widgets[FMCB12].text)
- + strlen (fmd_widgets[FMCB22].text) + 15;
+ len = mbstrlen (fmd_widgets[FMCB12].text)
+ + mbstrlen (fmd_widgets[FMCB22].text) + 15;
fmd_xlen = max (fmd_xlen, len);
- len = strlen (fmd_widgets[FMBRGT].text)
- + strlen (fmd_widgets[FMBLFT].text) + 11;
+ len = mbstrlen (fmd_widgets[FMBRGT].text)
+ + mbstrlen (fmd_widgets[FMBLFT].text) + 11;
#ifdef FMBMID
- len += strlen (fmd_widgets[FMBMID].text) + 6;
+ len += mbstrlen (fmd_widgets[FMBMID].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 += mbstrlen (fmd_widgets[FMBLFT].text) + 8;
#ifdef FMBMID
fmd_widgets[FMBMID].relative_x = i;
- i += strlen (fmd_widgets[FMBMID].text) + 6;
+ i += mbstrlen (fmd_widgets[FMBMID].text) + 6;
#endif
fmd_widgets[FMBRGT].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);
@@ -855,7 +856,7 @@ fmd_init_i18n (int force)
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;
@@ -864,12 +865,20 @@ file_mask_dialog (FileOpContext *ctx, Fi
struct stat buf;
int val;
QuickDialog Quick_input;
-
+ char *def_text;
g_return_val_if_fail (ctx != NULL, NULL);
+
+ def_text = g_strdup(def_text_orig);
+
#if 0
message (1, __FUNCTION__, "text = `%s' \n def_text = `%s'", text,
def_text);
#endif
+
+#ifdef UTF8
+ fix_utf8(def_text);
+#endif
+
fmd_init_i18n (FALSE);
/* Set up the result pointers */
@@ -928,6 +937,7 @@ file_mask_dialog (FileOpContext *ctx, Fi
orig_mask = source_mask;
if (!dest_dir || !*dest_dir) {
g_free (source_mask);
+ g_free(def_text);
return dest_dir;
}
if (source_easy_patterns) {
@@ -981,5 +991,6 @@ file_mask_dialog (FileOpContext *ctx, Fi
}
if (val == B_USER)
*do_background = 1;
+ g_free(def_text);
return dest_dir;
}
diff -up mc-4.6.2-pre1/src/find.c.utf8 mc-4.6.2-pre1/src/find.c
--- mc-4.6.2-pre1/src/find.c.utf8 2006-02-04 12:03:35.000000000 +0100
+++ mc-4.6.2-pre1/src/find.c 2008-10-23 14:00:12.000000000 +0200
@@ -217,7 +217,7 @@ find_parameters (char **start_dir, char
int l1, maxlen = 0;
while (i--) {
- l1 = strlen (labs[i] = _(labs[i]));
+ l1 = mbstrlen (labs[i] = _(labs[i]));
if (l1 > maxlen)
maxlen = l1;
}
@@ -226,7 +226,7 @@ find_parameters (char **start_dir, char
FIND_X = i;
for (i = sizeof (buts) / sizeof (buts[0]), l1 = 0; i--;) {
- l1 += strlen (buts[i] = _(buts[i]));
+ l1 += mbstrlen (buts[i] = _(buts[i]));
}
l1 += 21;
if (l1 > FIND_X)
@@ -235,8 +235,8 @@ find_parameters (char **start_dir, char
ilen = FIND_X - 7 - maxlen; /* for the case of very long buttons :) */
istart = FIND_X - 3 - ilen;
- b1 = b0 + strlen (buts[0]) + 7;
- b2 = FIND_X - (strlen (buts[2]) + 6);
+ b1 = b0 + mbstrlen (buts[0]) + 7;
+ b2 = FIND_X - (mbstrlen (buts[2]) + 6);
i18n_flag = 1;
case_label = _(case_label);
@@ -863,7 +863,7 @@ setup_gui (void)
if (!i18n_flag) {
register int i = sizeof (fbuts) / sizeof (fbuts[0]);
while (i--)
- fbuts[i].len = strlen (fbuts[i].text = _(fbuts[i].text)) + 3;
+ fbuts[i].len = mbstrlen (fbuts[i].text = _(fbuts[i].text)) + 3;
fbuts[2].len += 2; /* DEFPUSH_BUTTON */
i18n_flag = 1;
}
@@ -1028,7 +1028,7 @@ find_file (char *start_dir, char *patter
if (!next_free) /* first turn i.e clean old list */
panel_clean_dir (current_panel);
- list->list[next_free].fnamelen = strlen (name);
+ list->list[next_free].fnamelen = mbstrlen (name);
list->list[next_free].fname = name;
list->list[next_free].f.marked = 0;
list->list[next_free].f.link_to_dir = link_to_dir;
diff -up mc-4.6.2-pre1/src/help.c.utf8 mc-4.6.2-pre1/src/help.c
--- mc-4.6.2-pre1/src/help.c.utf8 2007-01-20 12:40:45.000000000 +0100
+++ mc-4.6.2-pre1/src/help.c 2008-10-23 14:00:12.000000000 +0200
@@ -447,10 +447,28 @@ static void help_show (Dlg_head *h, cons
#ifndef HAVE_SLANG
addch (acs_map [c]);
#else
+#if defined(UTF8) && SLANG_VERSION < 20000
+ SLsmg_draw_object (h->y + line + 2, h->x + col + 2, acs_map [c]);
+#else
SLsmg_draw_object (h->y + line + 2, h->x + col + 2, c);
+#endif /* UTF8 */
#endif
+ } else {
+#ifdef UTF8
+ if (SLsmg_Is_Unicode) {
+ int len;
+ mbstate_t mbs;
+ wchar_t wc;
+ memset (&mbs, 0, sizeof (mbs));
+ len = mbrtowc(&wc, p, MB_CUR_MAX, &mbs);
+ if (len <= 0) len = 1; /* skip broken multibyte chars */
+
+ SLsmg_write_nwchars(&wc, 1);
+ p += len - 1;
} else
+#endif
addch (c);
+ }
col++;
break;
}
@@ -803,6 +821,12 @@ interactive_display (const char *filenam
message (1, MSG_ERROR, _(" Cannot open file %s \n %s "), filename ? filename : hlpfile,
unix_error_string (errno));
}
+ else
+ {
+ char *conv = utf8_to_local(data);
+ g_free(data);
+ data = conv;
+ }
if (!filename)
g_free (hlpfile);
diff -up mc-4.6.2-pre1/src/hotlist.c.utf8 mc-4.6.2-pre1/src/hotlist.c
--- mc-4.6.2-pre1/src/hotlist.c.utf8 2006-08-08 14:17:14.000000000 +0200
+++ mc-4.6.2-pre1/src/hotlist.c 2008-10-23 14:00:12.000000000 +0200
@@ -563,7 +563,7 @@ init_i18n_stuff(int list_type, int cols)
row = hotlist_but [i].y;
++count [row];
- len [row] += strlen (hotlist_but [i].text) + 5;
+ len [row] += mbstrlen (hotlist_but [i].text) + 5;
if (hotlist_but [i].flags == DEFPUSH_BUTTON)
len [row] += 2;
}
@@ -588,12 +588,12 @@ init_i18n_stuff(int list_type, int cols)
/* not first int the row */
if (!strcmp (hotlist_but [i].text, cancel_but))
hotlist_but [i].x =
- cols - strlen (hotlist_but [i].text) - 13;
+ cols - mbstrlen (hotlist_but [i].text) - 13;
else
hotlist_but [i].x = cur_x [row];
}
- cur_x [row] += strlen (hotlist_but [i].text) + 2
+ cur_x [row] += mbstrlen (hotlist_but [i].text) + 2
+ (hotlist_but [i].flags == DEFPUSH_BUTTON ? 5 : 3);
}
}
@@ -834,7 +834,7 @@ static void add_widgets_i18n(QuickWidget
for (i = 0; i < 3; i++)
{
qw [i].text = _(qw [i].text);
- l[i] = strlen (qw [i].text) + 3;
+ l[i] = mbstrlen (qw [i].text) + 3;
}
space = (len - 4 - l[0] - l[1] - l[2]) / 4;
@@ -883,7 +883,7 @@ add_new_entry_input (const char *header,
msglen(text1, &lines1, &cols1);
msglen(text2, &lines2, &cols2);
- len = max ((int) strlen (header), cols1);
+ len = max ((int) mbstrlen (header), cols1);
len = max (len, cols2) + 4;
len = max (len, 64);
@@ -979,7 +979,7 @@ add_new_group_input (const char *header,
#endif /* ENABLE_NLS */
msglen (label, &lines, &cols);
- len = max ((int) strlen (header), cols) + 4;
+ len = max ((int) mbstrlen (header), cols) + 4;
len = max (len, 64);
#ifdef ENABLE_NLS
@@ -1035,7 +1035,7 @@ void add2hotlist_cmd (void)
{
char *prompt, *label;
const char *cp = _("Label for \"%s\":");
- int l = strlen (cp);
+ int l = mbstrlen (cp);
char *label_string = g_strdup (current_panel->cwd);
strip_password (label_string, 1);
diff -up mc-4.6.2-pre1/src/layout.c.utf8 mc-4.6.2-pre1/src/layout.c
--- mc-4.6.2-pre1/src/layout.c.utf8 2006-11-08 14:37:25.000000000 +0100
+++ mc-4.6.2-pre1/src/layout.c 2008-10-23 14:00:12.000000000 +0200
@@ -366,36 +366,36 @@ init_layout (void)
while (i--) {
s_split_direction[i] = _(s_split_direction[i]);
- l1 = strlen (s_split_direction[i]) + 7;
+ l1 = mbstrlen (s_split_direction[i]) + 7;
if (l1 > first_width)
first_width = l1;
}
for (i = 0; i <= 8; i++) {
check_options[i].text = _(check_options[i].text);
- l1 = strlen (check_options[i].text) + 7;
+ l1 = mbstrlen (check_options[i].text) + 7;
if (l1 > first_width)
first_width = l1;
}
- l1 = strlen (title1) + 1;
+ l1 = mbstrlen (title1) + 1;
if (l1 > first_width)
first_width = l1;
- l1 = strlen (title2) + 1;
+ l1 = mbstrlen (title2) + 1;
if (l1 > first_width)
first_width = l1;
- second_width = strlen (title3) + 1;
+ second_width = mbstrlen (title3) + 1;
for (i = 0; i < 6; i++) {
check_options[i].text = _(check_options[i].text);
- l1 = strlen (check_options[i].text) + 7;
+ l1 = mbstrlen (check_options[i].text) + 7;
if (l1 > second_width)
second_width = l1;
}
if (console_flag) {
- l1 = strlen (output_lines_label) + 13;
+ l1 = mbstrlen (output_lines_label) + 13;
if (l1 > second_width)
second_width = l1;
}
@@ -409,14 +409,14 @@ init_layout (void)
*
* Now the last thing to do - properly space buttons...
*/
- l1 = 11 + strlen (ok_button) /* 14 - all brackets and inner space */
- +strlen (save_button) /* notice: it is 3 char less because */
- +strlen (cancel_button); /* of '&' char in button text */
+ l1 = 11 + mbstrlen (ok_button) /* 14 - all brackets and inner space */
+ +mbstrlen (save_button) /* notice: it is 3 char less because */
+ +mbstrlen (cancel_button); /* of '&' char in button text */
i = (first_width + second_width - l1) / 4;
b1 = 5 + i;
- b2 = b1 + strlen (ok_button) + i + 6;
- b3 = b2 + strlen (save_button) + i + 4;
+ b2 = b1 + mbstrlen (ok_button) + i + 6;
+ b3 = b2 + mbstrlen (save_button) + i + 4;
i18n_layt_flag = 1;
}
@@ -684,7 +684,7 @@ setup_panels (void)
panel_do_cols (0);
panel_do_cols (1);
- promptl = strlen (prompt);
+ promptl = mbstrlen (prompt);
widget_set_size (&the_menubar->widget, 0, 0, 1, COLS);
diff -up mc-4.6.2-pre1/src/learn.c.utf8 mc-4.6.2-pre1/src/learn.c
--- mc-4.6.2-pre1/src/learn.c.utf8 2005-05-27 05:35:15.000000000 +0200
+++ mc-4.6.2-pre1/src/learn.c 2008-10-23 14:00:12.000000000 +0200
@@ -237,7 +237,7 @@ init_learn (void)
learn_but[0].x = 78 / 2 + 4;
learn_but[1].text = _(learn_but[1].text);
- learn_but[1].x = 78 / 2 - (strlen (learn_but[1].text) + 9);
+ learn_but[1].x = 78 / 2 - (mbstrlen (learn_but[1].text) + 9);
learn_title = _(learn_title);
i18n_flag = 1;
diff -up mc-4.6.2-pre1/src/main.c.utf8 mc-4.6.2-pre1/src/main.c
--- mc-4.6.2-pre1/src/main.c.utf8 2006-09-22 17:14:58.000000000 +0200
+++ mc-4.6.2-pre1/src/main.c 2008-10-23 14:00:12.000000000 +0200
@@ -704,7 +704,7 @@ load_prompt (int fd, void *unused)
int prompt_len;
tmp_prompt = strip_ctrl_codes (subshell_prompt);
- prompt_len = strlen (tmp_prompt);
+ prompt_len = mbstrlen (tmp_prompt);
/* Check for prompts too big */
if (COLS > 8 && prompt_len > COLS - 8) {
@@ -1610,7 +1610,11 @@ update_xterm_title_path (void)
if (xterm_flag && xterm_title) {
p = s = g_strdup (strip_home_and_password (current_panel->cwd));
do {
+#ifndef UTF8
if (!is_printable ((unsigned char) *s))
+#else /* UTF8 */
+ if (*(unsigned char *)s < ' ')
+#endif /* UTF8 */
*s = '?';
} while (*++s);
fprintf (stdout, "\33]0;mc - %s\7", p);
diff -up mc-4.6.2-pre1/src/menu.c.utf8 mc-4.6.2-pre1/src/menu.c
--- mc-4.6.2-pre1/src/menu.c.utf8 2005-09-05 04:12:09.000000000 +0200
+++ mc-4.6.2-pre1/src/menu.c 2008-10-23 14:00:12.000000000 +0200
@@ -22,6 +22,7 @@
#include <string.h>
#include <sys/types.h>
+#include <wchar.h>
#include "global.h"
#include "tty.h"
@@ -53,35 +54,95 @@ create_menu (const char *name, menu_entr
{
Menu *menu;
const char *cp;
+ int wlen = 0;
+ mbstate_t s;
menu = (Menu *) g_malloc (sizeof (*menu));
menu->count = count;
menu->max_entry_len = 20;
menu->entries = entries;
+ menu->name = g_strdup (name);
+ menu_scan_hotkey (menu);
+#ifdef UTF8
+ menu->wentries = NULL;
+ menu->wname = NULL;
+ if (SLsmg_Is_Unicode) {
+ const char *str = menu->name;
+ memset (&s, 0, sizeof (s));
+ wlen = mbsrtowcs (NULL, &str, -1, &s);
+ if (wlen > 0)
+ ++wlen;
+ else {
+ wlen = 0;
+ memset (&s, 0, sizeof (s));
+ }
+ }
+#endif
if (entries != (menu_entry*) NULL) {
register menu_entry* mp;
for (mp = entries; count--; mp++) {
if (mp->text[0] != '\0') {
+ int len;
#ifdef ENABLE_NLS
mp->text = _(mp->text);
#endif /* ENABLE_NLS */
cp = strchr (mp->text,'&');
+#ifdef UTF8
+ if (SLsmg_Is_Unicode) {
+ len = mbstrlen(mp->text) + 1;
+ wlen += len;
+ menu->max_entry_len = max (len - 1, menu->max_entry_len);
+ } else
+#endif
+ len = strlen (mp->text);
if (cp != NULL && *(cp+1) != '\0') {
mp->hot_key = tolower ((unsigned char) *(cp+1));
- menu->max_entry_len = max ((int) (strlen (mp->text) - 1),
- menu->max_entry_len);
+ menu->max_entry_len = max (len - 1, menu->max_entry_len);
} else {
- menu->max_entry_len = max ((int) strlen (mp->text),
- menu->max_entry_len);
+ menu->max_entry_len = max (len, menu->max_entry_len);
}
}
}
}
- menu->name = g_strdup (name);
- menu_scan_hotkey(menu);
+#ifdef UTF8
+ if (wlen) {
+ wchar_t *wp;
+ const char *str;
+ int len;
+
+ menu->wentries = (wchar_t **)
+ g_malloc (sizeof (wchar_t *) * menu->count
+ + wlen * sizeof (wchar_t));
+ wp = (wchar_t *) (menu->wentries + menu->count);
+ str = menu->name;
+ len = mbsrtowcs (wp, &str, wlen, &s);
+ if (len > 0) {
+ menu->wname = wp;
+ wlen -= len + 1;
+ wp += len + 1;
+ } else
+ memset (&s, 0, sizeof (s));
+ if (menu->entries != NULL)
+ for (count = 0; count < menu->count; ++count)
+ if (menu->entries[count].text[0] != '\0') {
+ str = menu->entries[count].text;
+ menu->wentries[count] = wp;
+ len = mbsrtowcs (wp, &str, wlen, &s);
+ if (len > 0) {
+ wlen -= len + 1;
+ wp += len + 1;
+ } else {
+ memset (&s, 0, sizeof (s));
+ *wp++ = L'\0';
+ --wlen;
+ }
+ }
+ }
+#endif
+
menu->start_x = 0;
menu->help_node = g_strdup (help_node);
return menu;
@@ -112,8 +173,26 @@ static void menubar_paint_idx (WMenu *me
const char *text;
addch((unsigned char)menu->entries [idx].first_letter);
- for (text = menu->entries [idx].text; *text; text++)
- {
+#ifdef UTF8
+ if (menu->wentries) {
+ wchar_t *wtext, *wp;
+
+ for (wtext = wp = menu->wentries [idx]; *wtext; wtext++) {
+ if (*wtext == L'&') {
+ if (wtext > wp)
+ SLsmg_write_nwchars (wp, wtext - wp);
+ attrset (color == MENU_SELECTED_COLOR ?
+ MENU_HOTSEL_COLOR : MENU_HOT_COLOR);
+ SLsmg_write_nwchars (++wtext, 1);
+ attrset (color);
+ wp = wtext + 1;
+ }
+ }
+ if (wtext > wp)
+ SLsmg_write_nwchars (wp, wtext - wp);
+ } else
+#endif
+ for (text = menu->entries [idx].text; *text; text++) {
if (*text != '&')
addch(*text);
else {
@@ -122,7 +201,7 @@ static void menubar_paint_idx (WMenu *me
addch(*(++text));
attrset(color);
}
- }
+ }
}
widget_move (&menubar->widget, y, x + 1);
}
@@ -168,6 +247,12 @@ static void menubar_draw (WMenu *menubar
if (menubar->active)
attrset(i == menubar->selected?MENU_SELECTED_COLOR:SELECTED_COLOR);
widget_move (&menubar->widget, 0, menubar->menu [i]->start_x);
+#ifdef UTF8
+ if (menubar->menu [i]->wname)
+ SLsmg_write_nwchars (menubar->menu [i]->wname,
+ wcslen (menubar->menu [i]->wname));
+ else
+#endif
tty_printf ("%s", menubar->menu [i]->name);
}
@@ -493,7 +578,13 @@ menubar_arrange(WMenu* menubar)
for (i = 0; i < items; i++)
{
- int len = strlen(menubar->menu[i]->name);
+ int len;
+#ifdef UTF8
+ if (menubar->menu[i]->wname)
+ len = wcslen (menubar->menu[i]->wname);
+ else
+#endif
+ len = strlen(menubar->menu[i]->name);
menubar->menu[i]->start_x = start_x;
start_x += len + gap;
}
@@ -506,7 +597,13 @@ menubar_arrange(WMenu* menubar)
for (i = 0; i < items; i++)
{
/* preserve length here, to be used below */
- gap -= (menubar->menu[i]->start_x = strlen(menubar->menu[i]->name));
+#ifdef UTF8
+ if (menubar->menu[i]->wname)
+ menubar->menu[i]->start_x = wcslen (menubar->menu[i]->wname);
+ else
+#endif
+ menubar->menu[i]->start_x = strlen (menubar->menu[i]->name);
+ gap -= menubar->menu[i]->start_x;
}
gap /= (items - 1);
@@ -530,6 +627,9 @@ menubar_arrange(WMenu* menubar)
void
destroy_menu (Menu *menu)
{
+#ifdef UTF8
+ g_free (menu->wentries);
+#endif
g_free (menu->name);
g_free (menu->help_node);
g_free (menu);
diff -up mc-4.6.2-pre1/src/menu.h.utf8 mc-4.6.2-pre1/src/menu.h
--- mc-4.6.2-pre1/src/menu.h.utf8 2004-12-03 20:17:47.000000000 +0100
+++ mc-4.6.2-pre1/src/menu.h 2008-10-23 14:00:12.000000000 +0200
@@ -21,6 +21,8 @@ typedef struct Menu {
menu_entry *entries;
int start_x; /* position relative to menubar start */
char *help_node;
+ wchar_t **wentries;
+ wchar_t *wname;
} Menu;
extern int menubar_visible;
diff -up mc-4.6.2-pre1/src/myslang.h.utf8 mc-4.6.2-pre1/src/myslang.h
--- mc-4.6.2-pre1/src/myslang.h.utf8 2005-09-05 05:22:04.000000000 +0200
+++ mc-4.6.2-pre1/src/myslang.h 2008-10-23 14:00:12.000000000 +0200
@@ -11,6 +11,16 @@
#endif /* HAVE_SLANG_SLANG_H */
#endif
+#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
+
+#ifdef UTF8
+# include <wchar.h>
+#endif
+
enum {
KEY_BACKSPACE = 400,
KEY_END, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT,
diff -up mc-4.6.2-pre1/src/option.c.utf8 mc-4.6.2-pre1/src/option.c
--- mc-4.6.2-pre1/src/option.c.utf8 2006-02-28 17:15:21.000000000 +0100
+++ mc-4.6.2-pre1/src/option.c 2008-10-23 14:00:12.000000000 +0200
@@ -123,12 +123,12 @@ init_configure (void)
title2 = _(" Pause after run... ");
title3 = _(" Other options ");
- first_width = strlen (title1) + 1;
- second_width = strlen (title3) + 1;
+ first_width = mbstrlen (title1) + 1;
+ second_width = mbstrlen (title3) + 1;
for (i = 0; check_options[i].text; i++) {
check_options[i].text = _(check_options[i].text);
- l1 = strlen (check_options[i].text) + 7;
+ l1 = mbstrlen (check_options[i].text) + 7;
if (i >= OTHER_OPTIONS) {
if (l1 > first_width)
first_width = l1;
@@ -141,23 +141,23 @@ init_configure (void)
i = PAUSE_OPTIONS;
while (i--) {
pause_options[i] = _(pause_options[i]);
- l1 = strlen (pause_options[i]) + 7;
+ l1 = mbstrlen (pause_options[i]) + 7;
if (l1 > first_width)
first_width = l1;
}
- l1 = strlen (title2) + 1;
+ l1 = mbstrlen (title2) + 1;
if (l1 > first_width)
first_width = l1;
- l1 = 11 + strlen (ok_button)
- + strlen (save_button)
- + strlen (cancel_button);
+ l1 = 11 + mbstrlen (ok_button)
+ + mbstrlen (save_button)
+ + mbstrlen (cancel_button);
i = (first_width + second_width - l1) / 4;
b1 = 5 + i;
- b2 = b1 + strlen (ok_button) + i + 6;
- b3 = b2 + strlen (save_button) + i + 4;
+ b2 = b1 + mbstrlen (ok_button) + i + 6;
+ b3 = b2 + mbstrlen (save_button) + i + 4;
i18n_config_flag = 1;
}
diff -up mc-4.6.2-pre1/src/panelize.c.utf8 mc-4.6.2-pre1/src/panelize.c
--- mc-4.6.2-pre1/src/panelize.c.utf8 2005-05-27 05:35:15.000000000 +0200
+++ mc-4.6.2-pre1/src/panelize.c 2008-10-23 14:00:12.000000000 +0200
@@ -127,7 +127,7 @@ init_panelize (void)
i = sizeof (panelize_but) / sizeof (panelize_but[0]);
while (i--) {
panelize_but[i].text = _(panelize_but[i].text);
- maxlen += strlen (panelize_but[i].text) + 5;
+ maxlen += mbstrlen (panelize_but[i].text) + 5;
}
maxlen += 10;
@@ -136,11 +136,11 @@ init_panelize (void)
panelize_cols = max (panelize_cols, maxlen);
panelize_but[2].x =
- panelize_but[3].x + strlen (panelize_but[3].text) + 7;
+ panelize_but[3].x + mbstrlen (panelize_but[3].text) + 7;
panelize_but[1].x =
- panelize_but[2].x + strlen (panelize_but[2].text) + 5;
+ panelize_but[2].x + mbstrlen (panelize_but[2].text) + 5;
panelize_but[0].x =
- panelize_cols - strlen (panelize_but[0].text) - 8 - BX;
+ panelize_cols - mbstrlen (panelize_but[0].text) - 8 - BX;
#endif /* ENABLE_NLS */
diff -up mc-4.6.2-pre1/src/screen.c.utf8 mc-4.6.2-pre1/src/screen.c
--- mc-4.6.2-pre1/src/screen.c.utf8 2007-08-24 14:22:29.000000000 +0200
+++ mc-4.6.2-pre1/src/screen.c 2008-10-23 14:00:12.000000000 +0200
@@ -171,21 +171,56 @@ add_permission_string (char *dest, int w
static const char *
string_file_name (file_entry *fe, int len)
{
- static char buffer [MC_MAXPATHLEN + 1];
size_t i;
- for (i = 0; i < sizeof(buffer) - 1; i++) {
- char c;
+#ifdef UTF8
+ static char buffer [BUF_SMALL * 4];
+ mbstate_t s;
+ int mbmax = MB_CUR_MAX;
+ const char *str = fe->fname;
- c = fe->fname[i];
+ memset (&s, 0, sizeof (s));
+#else
+ static char buffer [BUF_SMALL];
+#endif
- if (!c)
- break;
+#ifdef UTF8
+ if (SLsmg_Is_Unicode)
+ for (i = 0; i < sizeof (buffer) - 1; i++) {
+ wchar_t wc;
+ int len;
- if (!is_printable(c))
- c = '?';
+ len = mbrtowc (&wc, str, mbmax, &s);
+ if (!len)
+ break;
+ if (len < 0) {
+ memset (&s, 0, sizeof (s));
+ buffer[i] = '?';
+ str++;
+ continue;
+ }
+ if (!is_printable (wc)) {
+ buffer[i] = '?';
+ str++;
+ continue;
+ }
+ if (i >= sizeof (buffer) - len)
+ break;
+ memcpy (buffer + i, str, len);
+ i += len - 1;
+ str += len;
+ } else
+#endif
+ for (i = 0; i < sizeof(buffer) - 1; i++) {
+ char c;
+
+ c = fe->fname[i];
- buffer[i] = c;
+ if (!c) break;
+
+ if (!is_printable(c)) c = '?';
+
+ buffer[i] = c;
}
buffer[i] = 0;
@@ -450,42 +485,6 @@ static struct {
{ "dot", 1, 0, J_RIGHT, " ", 0, string_dot, NULL },
};
-static char *
-to_buffer (char *dest, int just_mode, int len, const char *txt)
-{
- int txtlen = strlen (txt);
- int still, over;
-
- /* Fill buffer with spaces */
- memset (dest, ' ', len);
-
- still = (over=(txtlen > len)) ? (txtlen - len) : (len - txtlen);
-
- switch (HIDE_FIT(just_mode)){
- case J_LEFT:
- still = 0;
- break;
- case J_CENTER:
- still /= 2;
- break;
- case J_RIGHT:
- default:
- break;
- }
-
- if (over){
- if (IS_FIT(just_mode))
- strcpy (dest, name_trunc(txt, len));
- else
- strncpy (dest, txt+still, len);
- } else
- strncpy (dest+still, txt, txtlen);
-
- dest[len] = '\0';
-
- return (dest + len);
-}
-
static int
file_compute_color (int attr, file_entry *fe)
{
@@ -539,14 +538,18 @@ file_compute_color (int attr, file_entry
/* Formats the file number file_index of panel in the buffer dest */
static void
-format_file (char *dest, int limit, WPanel *panel, int file_index, int width, int attr, int isstatus)
+format_file (WPanel *panel, int file_index, int width, int attr, int isstatus)
{
int color, length, empty_line;
const char *txt;
- char *old_pos;
- char *cdest = dest;
format_e *format, *home;
file_entry *fe;
+#ifdef UTF8
+ char buffer[BUF_MEDIUM * sizeof (wchar_t)];
+#else
+ char buffer[BUF_MEDIUM];
+#endif
+ int txtwidth = 0;
length = 0;
empty_line = (file_index >= panel->count);
@@ -564,34 +567,137 @@ format_file (char *dest, int limit, WPan
break;
if (format->string_fn){
- int len;
+ int len, still, over, perm, txtlen, wide;
if (empty_line)
txt = " ";
else
txt = (*format->string_fn)(fe, format->field_len);
- old_pos = cdest;
-
len = format->field_len;
if (len + length > width)
len = width - length;
- if (len + (cdest - dest) > limit)
- len = limit - (cdest - dest);
+ if (len >= BUF_MEDIUM)
+ len = BUF_MEDIUM - 1;
if (len <= 0)
break;
- cdest = to_buffer (cdest, format->just_mode, len, txt);
- length += len;
- attrset (color);
+ perm = 0;
+ if (permission_mode) {
+ if (!strcmp(format->id, "perm"))
+ perm = 1;
+ else if (!strcmp(format->id, "mode"))
+ perm = 2;
+ }
- if (permission_mode && !strcmp(format->id, "perm"))
- add_permission_string (old_pos, format->field_len, fe, attr, color, 0);
- else if (permission_mode && !strcmp(format->id, "mode"))
- add_permission_string (old_pos, format->field_len, fe, attr, color, 1);
- else
- addstr (old_pos);
+ wide = 0;
+#ifdef UTF8
+ if (SLsmg_Is_Unicode && !empty_line && !perm) {
+ mbstate_t s;
+ const char *str = txt;
+
+ memset (&s, 0, sizeof (s));
+ txtlen = mbsrtowcs ((wchar_t *) buffer, &str,
+ sizeof (buffer) / sizeof (wchar_t), &s);
+ if (txtlen < 0) {
+ txt = " ";
+ txtlen = 1;
+ } else {
+ wide = 1;
+ txtwidth = wcswidth((wchar_t*)buffer, txtlen);
+ }
+ } else
+#endif
+ {
+ txtlen = mbstrlen (txt);
+ txtwidth = txtlen;
+ }
+
+ over = txtwidth > len;
+ still = over ? txtlen - len : len - txtlen;
+
+ switch (HIDE_FIT(format->just_mode)) {
+ case J_LEFT:
+ still = 0;
+ break;
+ case J_CENTER:
+ still /= 2;
+ break;
+ case J_RIGHT:
+ default:
+ break;
+ }
+
+ attrset (color);
+
+ if (wide) {
+#ifdef UTF8
+ if (over) {
+ if (IS_FIT (format->just_mode)) {
+ int n1 = 0;
+ int width1 = 0;
+ int n2 = 0;
+ int width2 = 0;
+ int len1 = len / 2;
+ int len2;
+
+ while (1) {
+ int w = wcwidth(((wchar_t *) buffer)[n1]);
+ if (width1 + w <= len1) {
+ width1 += w;
+ n1++;
+ }
+ else
+ break;
+ }
+ len2 = len - width1 - 1;
+
+ while (1) {
+ int w = wcwidth(((wchar_t *) buffer)[txtlen - n2 - 1]);
+ if (width2 + w <= len2) {
+ width2 += w;
+ n2++;
+ }
+ else
+ break;
+ }
+
+
+ SLsmg_write_nwchars ((wchar_t *) buffer, n1);
+ SLsmg_write_nwchars (L"~", 1);
+ printw ("%*s", len - width1 - width2 - 1, "");
+ SLsmg_write_nwchars (((wchar_t *) buffer)
+ + txtlen - n2, n2);
+ } else
+ SLsmg_write_nwchars ((wchar_t *) buffer, len);
+ } else {
+ printw ("%*s", still, "");
+ SLsmg_write_nwchars ((wchar_t *) buffer, txtlen);
+ printw ("%*s", len - txtwidth - still, "");
+ }
+#endif
+ } else {
+ if (over) {
+ if (IS_FIT (format->just_mode))
+ strcpy (buffer, name_trunc(txt, len));
+ else
+ memcpy (buffer, txt + still, len);
+ } else {
+ memset (buffer, ' ', still);
+ memcpy (buffer + still, txt, txtlen);
+ memset (buffer + still + txtlen, ' ',
+ len - txtlen - still);
+ }
+ buffer[len] = '\0';
+ if (perm)
+ add_permission_string (buffer, format->field_len, fe,
+ attr, color, perm - 1);
+ else
+ addstr (buffer);
+ }
+
+ length += len;
} else {
if (attr == SELECTED || attr == MARKED_SELECTED)
attrset (SELECTED_COLOR);
@@ -614,7 +720,6 @@ repaint_file (WPanel *panel, int file_in
{
int second_column = 0;
int width, offset;
- char buffer [BUF_MEDIUM];
offset = 0;
if (!isstatus && panel->split){
@@ -643,7 +748,7 @@ repaint_file (WPanel *panel, int file_in
widget_move (&panel->widget, file_index - panel->top_file + 2, 1);
}
- format_file (buffer, sizeof(buffer), panel, file_index, width, attr, isstatus);
+ format_file (panel, file_index, width, attr, isstatus);
if (!isstatus && panel->split){
if (second_column)
@@ -692,7 +797,7 @@ display_mini_info (WPanel *panel)
ngettext("%s in %d file", "%s in %d files", panel->marked),
b_bytes, panel->marked);
- if ((int) strlen (buffer) > cols-2){
+ if ((int) mbstrlen (buffer) > cols-2){
buffer [cols] = 0;
p += 2;
} else
@@ -1104,6 +1209,12 @@ paint_frame (WPanel *panel)
int side, width;
const char *txt;
+#ifdef UTF8
+ char buffer[30 * sizeof (wchar_t)];
+ mbstate_t s;
+
+ memset (&s, 0, sizeof (s));
+#endif
if (!panel->split)
adjust_top_file (panel);
@@ -1128,16 +1239,38 @@ paint_frame (WPanel *panel)
if (format->string_fn){
txt = format->title;
- header_len = strlen (txt);
+ attrset (MARKED_COLOR);
+ width -= format->field_len;
+#ifdef UTF8
+ if (SLsmg_Is_Unicode) {
+ const char *str = txt;
+ header_len = mbsrtowcs ((wchar_t *) buffer, &str,
+ sizeof (buffer) / sizeof (wchar_t),
+ &s);
+ if (header_len < 0) {
+ memset (&s, 0, sizeof (s));
+ printw ("%*s", format->field_len, "");
+ continue;
+ }
+ if (header_len > format->field_len)
+ header_len = format->field_len;
+ spaces = (format->field_len - header_len) / 2;
+ extra = (format->field_len - header_len) % 2;
+ printw ("%*s", spaces, "");
+ SLsmg_write_nwchars ((wchar_t *) buffer, header_len);
+ printw ("%*s", spaces + extra, "");
+ continue;
+ }
+#endif
+
+ header_len = mbstrlen (txt);
if (header_len > format->field_len)
header_len = format->field_len;
- attrset (MARKED_COLOR);
spaces = (format->field_len - header_len) / 2;
extra = (format->field_len - header_len) % 2;
tty_printf ("%*s%.*s%*s", spaces, "",
header_len, txt, spaces+extra, "");
- width -= 2 * spaces + extra + header_len;
} else {
attrset (NORMAL_COLOR);
one_vline ();
@@ -1894,11 +2027,24 @@ do_search (WPanel *panel, int c_code)
int i;
int wrapped = 0;
int found;
+ int prevpos, pos;
+ int j;
+ mbstate_t mbs;
l = strlen (panel->search_buffer);
if (c_code == KEY_BACKSPACE) {
- if (l)
- panel->search_buffer[--l] = '\0';
+ if (l) {
+ prevpos = pos = 0;
+ memset (&mbs, 0, sizeof (mbs));
+ while (pos < l) {
+ prevpos = pos;
+ j = mbrlen (panel->search_buffer + pos, l - pos, &mbs);
+ if (j <= 0) break;
+ pos += j;
+ }
+ --l;
+ panel->search_buffer[prevpos] = 0;
+ }
} else {
if (c_code && l < sizeof (panel->search_buffer)) {
panel->search_buffer[l] = c_code;
@@ -1907,6 +2053,14 @@ do_search (WPanel *panel, int c_code)
}
}
+ prevpos = pos = 0;
+ memset (&mbs, 0, sizeof (mbs));
+ while (pos < l) {
+ prevpos = pos;
+ j = mbrlen (panel->search_buffer + pos, l - pos, &mbs);
+ if (j <= 0) break;
+ pos += j;
+ }
found = 0;
for (i = panel->selected; !wrapped || i != panel->selected; i++) {
if (i >= panel->count) {
@@ -1917,9 +2071,9 @@ do_search (WPanel *panel, int c_code)
}
if (panel->
case_sensitive
- ? (strncmp (panel->dir.list[i].fname, panel->search_buffer, l)
+ ? (strncmp (panel->dir.list[i].fname, panel->search_buffer, pos)
== 0) : (g_strncasecmp (panel->dir.list[i].fname,
- panel->search_buffer, l) == 0)) {
+ panel->search_buffer, pos) == 0)) {
unselect_item (panel);
panel->selected = i;
select_item (panel);
@@ -1928,7 +2082,7 @@ do_search (WPanel *panel, int c_code)
}
}
if (!found)
- panel->search_buffer[--l] = 0;
+ panel->search_buffer[prevpos] = 0;
paint_panel (panel);
}
diff -up mc-4.6.2-pre1/src/slint.c.utf8 mc-4.6.2-pre1/src/slint.c
--- mc-4.6.2-pre1/src/slint.c.utf8 2005-09-05 04:14:29.000000000 +0200
+++ mc-4.6.2-pre1/src/slint.c 2008-10-23 14:00:12.000000000 +0200
@@ -141,7 +141,9 @@ void
slang_init (void)
{
SLtt_get_terminfo ();
-
+#if SLANG_VERSION >= 20000
+ SLutf8_enable (-1);
+#endif
/*
* If the terminal in not in terminfo but begins with a well-known
* string such as "linux" or "xterm" S-Lang will go on, but the
diff -up mc-4.6.2-pre1/src/tty.c.utf8 mc-4.6.2-pre1/src/tty.c
--- mc-4.6.2-pre1/src/tty.c.utf8 2006-05-23 09:38:59.000000000 +0200
+++ mc-4.6.2-pre1/src/tty.c 2008-10-23 14:00:12.000000000 +0200
@@ -134,10 +134,12 @@ tty_print_char(int c)
* defined or not. Congratulations! At least, they left the API call
* for SLsmg_write_nchars as it has always been.
*/
- char ch;
-
- ch = c;
- SLsmg_write_nchars(&ch, 1);
+
+ /* The above comment is a nonsense, SLsmg_write_char(c) works pretty
+ * good for me. So please don't mess with Red Hat people.
+ * Jindrich Novy (jnovy@redhat.com)
+ */
+ SLsmg_write_char(c);
#else
addch(c);
#endif
diff -up mc-4.6.2-pre1/src/tty.h.utf8 mc-4.6.2-pre1/src/tty.h
--- mc-4.6.2-pre1/src/tty.h.utf8 2006-05-15 15:26:18.000000000 +0200
+++ mc-4.6.2-pre1/src/tty.h 2008-10-23 14:00:12.000000000 +0200
@@ -8,6 +8,8 @@
of ifdefs in the other files small.
*/
+#include <glib.h> /* gboolean is used here */
+
#ifdef HAVE_SLANG
# include "myslang.h"
#endif
diff -up mc-4.6.2-pre1/src/util.c.utf8 mc-4.6.2-pre1/src/util.c
--- mc-4.6.2-pre1/src/util.c.utf8 2005-11-03 03:18:38.000000000 +0100
+++ mc-4.6.2-pre1/src/util.c 2008-10-23 14:00:12.000000000 +0200
@@ -33,7 +33,11 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <iconv.h>
+#include <langinfo.h>
+#include <errno.h>
+#include "tty.h"
#include "global.h"
#include "profile.h"
#include "main.h" /* mc_home */
@@ -45,9 +49,39 @@
#include "charsets.h"
#endif
+#ifdef UTF8
+#include <wctype.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++) {
@@ -78,9 +112,106 @@ is_8bit_printable (unsigned char c)
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
@@ -98,7 +229,7 @@ is_printable (int c)
#endif /* !HAVE_CHARSET */
}
-/* Calculates the message dimensions (lines and columns) */
+/* Calculates the message dimension in columns and lines. */
void
msglen (const char *text, int *lines, int *columns)
{
@@ -111,8 +242,21 @@ msglen (const char *text, int *lines, in
nlines++;
colindex = 0;
} else {
+#ifndef UTF8
colindex++;
if (colindex > ncolumns)
+#else /* 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);
+ colindex += wcsize > 0 ? wcsize-1 : -1;
+ text += len-1;
+ }
+ if (++colindex > ncolumns)
+#endif /* UTF8 */
ncolumns = colindex;
}
}
@@ -206,7 +350,24 @@ name_quote (const char *s, int quote_per
*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;
@@ -228,25 +389,90 @@ const char *
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;
}
@@ -678,11 +904,61 @@ load_file (const char *filename)
}
char *
+utf8_to_local(char *str)
+{
+ iconv_t cd;
+ size_t buflen = strlen(str);
+ char *output;
+ int retry = 1;
+
+ 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 ();
@@ -715,7 +991,10 @@ load_mc_home_file (const char *filename,
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
@@ -724,12 +1003,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) */
@@ -742,15 +1023,12 @@ i18n_checktimelength (void)
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 */
@@ -770,7 +1048,7 @@ file_date (time_t when)
else
fmt = fmttime;
- strftime (timebuf, i18n_timelength, fmt, localtime(&when));
+ strftime (timebuf, sizeof (timebuf) - 1, fmt, localtime(&when));
return timebuf;
}
@@ -900,10 +1178,27 @@ strip_ctrl_codes (char *s)
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;
diff -up mc-4.6.2-pre1/src/util.h.utf8 mc-4.6.2-pre1/src/util.h
--- mc-4.6.2-pre1/src/util.h.utf8 2006-02-03 18:04:17.000000000 +0100
+++ mc-4.6.2-pre1/src/util.h 2008-10-23 14:00:12.000000000 +0200
@@ -103,6 +103,13 @@ void init_uid_gid_cache (void);
char *get_group (int);
char *get_owner (int);
+void fix_utf8(char *str);
+size_t mbstrlen (const char *);
+wchar_t *mbstr_to_wchar (const char *);
+char *wchar_to_mbstr (const wchar_t *);
+char *utf8_to_local(char *str);
+
+
#define MAX_I18NTIMELENGTH 14
#define MIN_I18NTIMELENGTH 10
#define STD_I18NTIMELENGTH 12
diff -up mc-4.6.2-pre1/src/view.c.utf8 mc-4.6.2-pre1/src/view.c
--- mc-4.6.2-pre1/src/view.c.utf8 2006-12-30 14:16:54.000000000 +0100
+++ mc-4.6.2-pre1/src/view.c 2008-10-23 14:00:12.000000000 +0200
@@ -43,6 +43,10 @@
#include <sys/stat.h>
#include <unistd.h>
+#ifdef UTF8
+#include <wctype.h>
+#endif /* UTF8 */
+
#include "global.h"
#include "tty.h"
#include "cmd.h" /* For view_other_cmd */
@@ -1642,7 +1646,7 @@ view_display_status (WView *view)
hline (' ', width);
file_label = _("File: %s");
- file_label_width = strlen (file_label) - 2;
+ file_label_width = mbstrlen (file_label) - 2;
file_name = view->filename ? view->filename
: view->command ? view->command
: "";
@@ -1910,6 +1914,12 @@ view_display_text (WView * view)
offset_type from;
int c;
struct hexedit_change_node *curr = view->change_list;
+#ifdef UTF8
+ mbstate_t mbs;
+ char mbbuf[MB_LEN_MAX];
+ int mblen;
+ wchar_t wc;
+#endif /* UTF8 */
view_display_clean (view);
view_display_ruler (view);
@@ -1922,8 +1932,37 @@ view_display_text (WView * view)
tty_setcolor (NORMAL_COLOR);
for (row = 0, col = 0; row < height && (c = get_byte (view, from)) != -1; from++) {
-
+#ifndef UTF8
if (view->text_nroff_mode && c == '\b') {
+#else /* UTF8 */
+ mblen = 1;
+ mbbuf[0] = convert_to_display_c (c);
+
+ while (mblen < MB_LEN_MAX) {
+ int res;
+ memset (&mbs, 0, sizeof (mbs));
+ res = mbrtowc (&wc, mbbuf, mblen, &mbs);
+ if (res <= 0 && res != -2) {
+ wc = '.';
+ mblen = 1;
+ break;
+ }
+ if (res == mblen)
+ break;
+
+ mbbuf[mblen] = convert_to_display_c (get_byte (view, from + mblen));
+ mblen++;
+ }
+
+ if (mblen == MB_LEN_MAX) {
+ wc = '.';
+ mblen = 1;
+ }
+
+ from += mblen - 1;
+
+ if (view->text_nroff_mode && wc == '\b') {
+#endif /* UTF8 */
int c_prev;
int c_next;
@@ -1988,10 +2027,20 @@ view_display_text (WView * view)
if (col >= view->dpy_text_column
&& col - view->dpy_text_column < width) {
widget_move (view, top + row, left + (col - view->dpy_text_column));
+#ifdef UTF8
+ if (SLsmg_is_utf8_mode ()) {
+ if (!iswprint (wc))
+ wc = '.';
+ tty_print_char (wc);
+ } else {
+#endif
c = convert_to_display_c (c);
if (!is_printable (c))
c = '.';
tty_print_char (c);
+#ifdef UTF8
+ }
+#endif
}
col++;
tty_setcolor (NORMAL_COLOR);
diff -up mc-4.6.2-pre1/src/widget.c.utf8 mc-4.6.2-pre1/src/widget.c
--- mc-4.6.2-pre1/src/widget.c.utf8 2006-05-29 13:58:43.000000000 +0200
+++ mc-4.6.2-pre1/src/widget.c 2008-10-23 14:00:12.000000000 +0200
@@ -36,6 +36,9 @@
#include "global.h"
#include "tty.h"
+#ifdef UTF8
+#include <wctype.h>
+#endif /* UTF8 */
#include "color.h"
#include "mouse.h"
#include "dialog.h"
@@ -182,6 +185,11 @@ button_callback (Widget *w, widget_msg_t
if (b->hotpos >= 0) {
widget_selectcolor (w, b->selected, TRUE);
widget_move (w, 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;
@@ -215,7 +223,7 @@ button_event (Gpm_Event *event, void *da
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;
@@ -238,14 +246,36 @@ button_len (const char *text, unsigned i
* 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 ((unsigned char) *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);
}
}
@@ -266,8 +296,9 @@ button_new (int y, int x, int action, in
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;
}
@@ -280,14 +311,13 @@ button_get_text (WButton *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, void *);
@@ -362,14 +392,35 @@ radio_callback (Widget *w, widget_msg_t
widget_move (&r->widget, i, 0);
tty_printf ("(%c) ", (r->sel == i) ? '*' : ' ');
- for (cp = r->texts[i]; *cp; cp++) {
- if (*cp == '&') {
- widget_selectcolor (w, focused, TRUE);
+ cp = strchr (r->texts[i], '&');
+ if (cp != NULL) {
+#ifdef UTF8
+ mbstate_t s;
+ wchar_t wc;
+ int len;
+#endif
+ tty_printf ("%.*s", (int) ((char *) cp - r->texts[i]),
+ r->texts[i]);
+ widget_selectcolor (w, focused, TRUE);
+#ifdef UTF8
+ if (SLsmg_Is_Unicode) {
+ memset (&s, 0, sizeof (s));
+ len = mbrtowc (&wc, cp + 1, MB_CUR_MAX, &s);
+ ++cp;
+ if (len > 0) {
+ tty_printf ("%.*s", len, cp);
+ cp += len;
+ }
+ } else
+#endif
+ {
addch (*++cp);
- widget_selectcolor (w, focused, FALSE);
- } else
- addch (*cp);
- }
+ ++cp;
+ }
+ widget_selectcolor (w, focused, FALSE);
+ } else
+ cp = r->texts[i];
+ addstr ((char *) cp);
}
return MSG_HANDLED;
@@ -408,7 +459,7 @@ radio_new (int y, int x, int count, cons
/* 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;
}
@@ -468,6 +519,11 @@ check_callback (Widget *w, widget_msg_t
if (c->hotpos >= 0) {
widget_selectcolor (w, msg == WIDGET_FOCUS, TRUE);
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;
@@ -505,35 +561,20 @@ WCheck *
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),
check_callback, 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 ((unsigned char) *s);
- c->hotpos = t - c->text;
- }
- *t = *s;
- }
- *t = 0;
+ scan_hotkey (c->text, &c->hotpos, &c->hotkey, &c->hotwc);
return c;
}
-
/* Label widget */
static cb_ret_t
@@ -572,7 +613,7 @@ label_callback (Widget *w, widget_msg_t
}
widget_move (&l->widget, y, 0);
tty_printf ("%s", p);
- xlen = l->widget.cols - strlen (p);
+ xlen = l->widget.cols - mbstrlen (p);
if (xlen > 0)
tty_printf ("%*s", xlen, " ");
if (!q)
@@ -606,7 +647,7 @@ label_set_text (WLabel *label, const cha
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;
}
@@ -630,7 +671,7 @@ label_new (int y, int x, const char *tex
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, label_callback, NULL);
@@ -778,13 +819,69 @@ static void draw_history_button (WInput
/* 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;
@@ -794,7 +891,7 @@ update_input (WInput *in, int clear_firs
/* 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;
@@ -814,14 +911,29 @@ update_input (WInput *in, int clear_firs
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;
@@ -974,7 +1086,7 @@ char *
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;
@@ -987,7 +1099,7 @@ show_hist (GList *history, int widget_x,
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);
@@ -1157,35 +1269,83 @@ new_input (WInput *in)
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;
}
@@ -1193,12 +1353,14 @@ static void
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
@@ -1206,18 +1368,21 @@ backward_char (WInput *in)
{
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
char *p = in->buffer + in->point;
while (*p
@@ -1227,11 +1392,39 @@ forward_word (WInput * in)
while (*p && isalnum ((unsigned char) *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
char *p = in->buffer + in->point;
while (p - 1 > in->buffer - 1 && (isspace ((unsigned char) *(p - 1))
@@ -1241,6 +1434,32 @@ backward_word (WInput *in)
while (p - 1 > in->buffer - 1 && isalnum ((unsigned char) *(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
@@ -1273,8 +1492,9 @@ backward_delete (WInput *in)
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--;
}
@@ -1282,10 +1502,8 @@ backward_delete (WInput *in)
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;
}
@@ -1300,6 +1518,9 @@ copy_region (WInput *in, int x_first, in
g_free (kill_buffer);
+ first=charpos(in,first);
+ last=charpos(in,last);
+
kill_buffer = g_strndup(in->buffer+first,last-first);
}
@@ -1308,11 +1529,13 @@ delete_region (WInput *in, int x_first,
{
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;
}
@@ -1329,6 +1552,8 @@ kill_word (WInput *in)
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
@@ -1372,16 +1597,20 @@ yank (WInput *in)
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
@@ -1391,9 +1620,10 @@ assign_text (WInput *in, const char *tex
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
@@ -1520,6 +1750,7 @@ port_region_marked_for_delete (WInput *i
*in->buffer = 0;
in->point = 0;
in->first = 0;
+ in->charpoint = 0;
}
cb_ret_t
@@ -1548,7 +1779,11 @@ handle_char (WInput *in, int c_code)
}
}
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);
@@ -1581,6 +1816,9 @@ input_set_point (WInput *in, int pos)
if (pos != in->point)
free_completions (in);
in->point = pos;
+#ifdef UTF8
+ in->charpoint = 0;
+#endif /* UTF8 */
update_input (in, 1);
}
@@ -1621,7 +1859,7 @@ input_callback (Widget *w, widget_msg_t
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:
@@ -1645,7 +1883,7 @@ input_event (Gpm_Event * event, void *da
&& 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)
@@ -1702,7 +1940,8 @@ input_new (int y, int x, int color, int
in->is_password = 0;
strcpy (in->buffer, def_text);
- in->point = strlen (in->buffer);
+ in->point = mbstrlen (in->buffer);
+ in->charpoint = 0;
return in;
}
diff -up mc-4.6.2-pre1/src/widget.h.utf8 mc-4.6.2-pre1/src/widget.h
--- mc-4.6.2-pre1/src/widget.h.utf8 2006-02-28 17:15:21.000000000 +0100
+++ mc-4.6.2-pre1/src/widget.h 2008-10-23 14:00:12.000000000 +0200
@@ -22,6 +22,7 @@ typedef struct WButton {
char *text; /* text of button */
int hotkey; /* hot KEY */
int hotpos; /* offset hot KEY char in text */
+ wchar_t hotwc;
bcback callback; /* Callback function */
} WButton;
@@ -42,6 +43,7 @@ typedef struct WCheck {
char *text; /* text of check button */
int hotkey; /* hot KEY */
int hotpos; /* offset hot KEY char in text */
+ wchar_t hotwc;
} WCheck;
typedef struct WGauge {
@@ -57,16 +59,20 @@ char *show_hist (GList *history, int wid
typedef struct {
Widget widget;
- int point; /* cursor position in the input line */
- int mark; /* The mark position */
- int first_shown; /* Index of the first shown character */
- int current_max_len; /* Maximum length of input line */
- int field_len; /* Length of the editing field */
+ int point; /* cursor position in the input line (mb chars) */
+ int mark; /* The mark position (mb chars) */
+ int first_shown; /* Index of the first shown character (mb chars) */
+ int current_max_len; /* Maximum length of input line (bytes) */
+ int field_len; /* Length of the editing field (mb chars) */
int color; /* color used */
int first; /* Is first keystroke? */
int disable_update; /* Do we want to skip updates? */
int is_password; /* Is this a password input line? */
char *buffer; /* pointer to editing buffer */
+#ifdef UTF8
+ char charbuf[MB_LEN_MAX];
+#endif /* UTF8 */
+ int charpoint;
GList *history; /* The history */
int need_push; /* need to push the current Input on hist? */
char **completions; /* Possible completions array */
diff -up mc-4.6.2-pre1/src/wtools.c.utf8 mc-4.6.2-pre1/src/wtools.c
--- mc-4.6.2-pre1/src/wtools.c.utf8 2006-09-14 11:12:49.000000000 +0200
+++ mc-4.6.2-pre1/src/wtools.c 2008-10-23 14:00:12.000000000 +0200
@@ -49,11 +49,11 @@ create_listbox_window (int cols, int lin
/* Adjust sizes */
lines = (lines > LINES - 6) ? LINES - 6 : lines;
- if (title && (cols < (len = strlen (title) + 2)))
+ if (title && (cols < (len = mbstrlen (title) + 2)))
cols = len;
/* no &, but 4 spaces around button for brackets and such */
- if (cols < (len = strlen (cancel_string) + 3))
+ if (cols < (len = mbstrlen (cancel_string) + 3))
cols = len;
cols = cols > COLS - 6 ? COLS - 6 : cols;
@@ -124,7 +124,7 @@ query_dialog (const char *header, const
va_start (ap, count);
for (i = 0; i < count; i++) {
char *cp = va_arg (ap, char *);
- win_len += strlen (cp) + 6;
+ win_len += mbstrlen (cp) + 6;
if (strchr (cp, '&') != NULL)
win_len--;
2008-03-27 13:33:05 +00:00
}
@@ -133,7 +133,7 @@ query_dialog (const char *header, const
/* count coordinates */
msglen (text, &lines, &cols);
- cols = 6 + max (win_len, max ((int) strlen (header), cols));
+ cols = 6 + max (win_len, max ((int) mbstrlen (header), cols));
lines += 4 + (count > 0 ? 2 : 0);
xpos = COLS / 2 - cols / 2;
ypos = LINES / 3 - (lines - 3) / 2;
@@ -148,7 +148,7 @@ query_dialog (const char *header, const
va_start (ap, count);
for (i = 0; i < count; i++) {
cur_name = va_arg (ap, char *);
- xpos = strlen (cur_name) + 6;
+ xpos = mbstrlen (cur_name) + 6;
if (strchr (cur_name, '&') != NULL)
xpos--;
@@ -463,7 +463,7 @@ fg_input_dialog_help (const char *header
quick_widgets[2].histname = histname;
msglen (text, &lines, &cols);
- len = max ((int) strlen (header), cols) + 4;
+ len = max ((int) mbstrlen (header), cols) + 4;
len = max (len, 64);
/* The special value of def_text is used to identify password boxes
@@ -485,7 +485,7 @@ fg_input_dialog_help (const char *header
quick_widgets[1].text = _(quick_widgets[1].text);
quick_widgets[0].relative_x = len / 2 + 4;
quick_widgets[1].relative_x =
- len / 2 - (strlen (quick_widgets[1].text) + 9);
+ len / 2 - (mbstrlen (quick_widgets[1].text) + 9);
quick_widgets[0].x_divisions = quick_widgets[1].x_divisions = len;
#endif /* ENABLE_NLS */