mc/mc-utf8.patch
2005-11-16 13:17:52 +00:00

5112 lines
140 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

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

--- mc-4.6.1a/acinclude.m4.utf8 2005-11-16 00:27:27.000000000 +0100
+++ mc-4.6.1a/acinclude.m4 2005-11-16 14:03:46.000000000 +0100
@@ -768,14 +768,14 @@ AC_DEFUN([MC_WITH_SLANG], [
fi
dnl Unless external S-Lang was requested, reject S-Lang with UTF-8 hacks
- if test x$with_screen = xslang; then
- :
- m4_if([$1], strict, ,
- [AC_CHECK_LIB([slang], [SLsmg_write_nwchars],
- [AC_MSG_WARN([Rejecting S-Lang with UTF-8 support, \
-it's not fully supported yet])
- with_screen=mcslang])])
- fi
+dnl if test x$with_screen = xslang; then
+dnl :
+dnl m4_if([$1], strict, ,
+dnl [AC_CHECK_LIB([slang], [SLsmg_write_nwchars],
+dnl [AC_MSG_WARN([Rejecting S-Lang with UTF-8 support, \
+dnl it's not fully supported yet])
+dnl with_screen=mcslang])])
+dnl fi
if test x$with_screen = xslang; then
AC_DEFINE(HAVE_SYSTEM_SLANG, 1,
--- mc-4.6.1a/src/layout.c.utf8 2005-09-05 03:40:45.000000000 +0200
+++ mc-4.6.1a/src/layout.c 2005-11-16 14:03:46.000000000 +0100
@@ -369,36 +369,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;
}
@@ -412,14 +412,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;
}
@@ -687,7 +687,7 @@ setup_panels (void)
panel_do_cols (0);
panel_do_cols (1);
- promptl = strlen (prompt);
+ promptl = mbstrlen (prompt);
widget_set_size (&the_menubar->widget, 0, 0, 1, COLS);
--- mc-4.6.1a/src/tty.c.utf8 2005-09-05 05:05:39.000000000 +0200
+++ mc-4.6.1a/src/tty.c 2005-11-16 14:03:46.000000000 +0100
@@ -123,10 +123,12 @@ tty_print_char(int c)
* defined or not. Congratulations! At least, they left the API call
* for SLsmg_write_nchars as it has always been.
*/
- char ch;
-
- ch = c;
- SLsmg_write_nchars(&ch, 1);
+
+ /* The above comment is a nonsense, SLsmg_write_char(c) works pretty
+ * good for me. So please don't mess with Red Hat people.
+ * Jindrich Novy (jnovy@redhat.com)
+ */
+ SLsmg_write_char(c);
#else
addch(c);
#endif
--- mc-4.6.1a/src/option.c.utf8 2005-05-27 05:35:15.000000000 +0200
+++ mc-4.6.1a/src/option.c 2005-11-16 14:03:46.000000000 +0100
@@ -123,12 +123,12 @@ init_configure (void)
title2 = _(" Pause after run... ");
title3 = _(" Other options ");
- first_width = strlen (title1) + 1;
- second_width = strlen (title3) + 1;
+ first_width = mbstrlen (title1) + 1;
+ second_width = mbstrlen (title3) + 1;
for (i = 0; check_options[i].text; i++) {
check_options[i].text = _(check_options[i].text);
- l1 = strlen (check_options[i].text) + 7;
+ l1 = mbstrlen (check_options[i].text) + 7;
if (i >= OTHER_OPTIONS) {
if (l1 > first_width)
first_width = l1;
@@ -141,23 +141,23 @@ init_configure (void)
i = PAUSE_OPTIONS;
while (i--) {
pause_options[i] = _(pause_options[i]);
- l1 = strlen (pause_options[i]) + 7;
+ l1 = mbstrlen (pause_options[i]) + 7;
if (l1 > first_width)
first_width = l1;
}
- l1 = strlen (title2) + 1;
+ l1 = mbstrlen (title2) + 1;
if (l1 > first_width)
first_width = l1;
- l1 = 11 + strlen (ok_button)
- + strlen (save_button)
- + strlen (cancel_button);
+ l1 = 11 + mbstrlen (ok_button)
+ + mbstrlen (save_button)
+ + mbstrlen (cancel_button);
i = (first_width + second_width - l1) / 4;
b1 = 5 + i;
- b2 = b1 + strlen (ok_button) + i + 6;
- b3 = b2 + strlen (save_button) + i + 4;
+ b2 = b1 + mbstrlen (ok_button) + i + 6;
+ b3 = b2 + mbstrlen (save_button) + i + 4;
i18n_config_flag = 1;
}
--- mc-4.6.1a/src/menu.h.utf8 2004-12-03 20:17:47.000000000 +0100
+++ mc-4.6.1a/src/menu.h 2005-11-16 14:03:46.000000000 +0100
@@ -21,6 +21,8 @@ typedef struct Menu {
menu_entry *entries;
int start_x; /* position relative to menubar start */
char *help_node;
+ wchar_t **wentries;
+ wchar_t *wname;
} Menu;
extern int menubar_visible;
--- mc-4.6.1a/src/menu.c.utf8 2005-09-05 04:12:09.000000000 +0200
+++ mc-4.6.1a/src/menu.c 2005-11-16 14:03:46.000000000 +0100
@@ -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);
--- mc-4.6.1a/src/filegui.c.utf8 2005-05-27 05:35:15.000000000 +0200
+++ mc-4.6.1a/src/filegui.c 2005-11-16 14:03:46.000000000 +0100
@@ -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;
}
--- mc-4.6.1a/src/panelize.c.utf8 2005-05-27 05:35:15.000000000 +0200
+++ mc-4.6.1a/src/panelize.c 2005-11-16 14:03:46.000000000 +0100
@@ -127,7 +127,7 @@ init_panelize (void)
i = sizeof (panelize_but) / sizeof (panelize_but[0]);
while (i--) {
panelize_but[i].text = _(panelize_but[i].text);
- maxlen += strlen (panelize_but[i].text) + 5;
+ maxlen += mbstrlen (panelize_but[i].text) + 5;
}
maxlen += 10;
@@ -136,11 +136,11 @@ init_panelize (void)
panelize_cols = max (panelize_cols, maxlen);
panelize_but[2].x =
- panelize_but[3].x + strlen (panelize_but[3].text) + 7;
+ panelize_but[3].x + mbstrlen (panelize_but[3].text) + 7;
panelize_but[1].x =
- panelize_but[2].x + strlen (panelize_but[2].text) + 5;
+ panelize_but[2].x + mbstrlen (panelize_but[2].text) + 5;
panelize_but[0].x =
- panelize_cols - strlen (panelize_but[0].text) - 8 - BX;
+ panelize_cols - mbstrlen (panelize_but[0].text) - 8 - BX;
#endif /* ENABLE_NLS */
--- mc-4.6.1a/src/slint.c.utf8 2005-09-05 04:14:29.000000000 +0200
+++ mc-4.6.1a/src/slint.c 2005-11-16 14:03:46.000000000 +0100
@@ -141,7 +141,9 @@ void
slang_init (void)
{
SLtt_get_terminfo ();
-
+#if SLANG_VERSION >= 20000
+ SLutf8_enable (-1);
+#endif
/*
* If the terminal in not in terminfo but begins with a well-known
* string such as "linux" or "xterm" S-Lang will go on, but the
--- mc-4.6.1a/src/main.c.utf8 2005-11-02 12:50:52.000000000 +0100
+++ mc-4.6.1a/src/main.c 2005-11-16 14:03:46.000000000 +0100
@@ -698,7 +698,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) {
@@ -1611,7 +1611,11 @@ update_xterm_title_path (void)
if (xterm_flag && xterm_title) {
p = s = g_strdup (strip_home_and_password (current_panel->cwd));
do {
+#ifndef UTF8
if (!is_printable ((unsigned char) *s))
+#else /* UTF8 */
+ if (*(unsigned char *)s < ' ')
+#endif /* UTF8 */
*s = '?';
} while (*++s);
fprintf (stdout, "\33]0;mc - %s\7", p);
--- mc-4.6.1a/src/view.c.utf8 2005-10-04 23:07:20.000000000 +0200
+++ mc-4.6.1a/src/view.c 2005-11-16 14:04:27.000000000 +0100
@@ -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 */
@@ -1631,7 +1635,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
: "";
@@ -1884,6 +1888,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);
@@ -1896,8 +1906,37 @@ view_display_text (WView * view)
attrset (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;
@@ -1956,10 +1995,17 @@ view_display_text (WView * view)
if (col >= view->dpy_text_column
&& col - view->dpy_text_column < width) {
widget_move (view, top + row, left + (col - view->dpy_text_column));
+#ifndef UTF8
c = convert_to_display_c (c);
if (!is_printable (c))
c = '.';
tty_print_char (c);
+#else
+ wc = convert_to_display_c (wc);
+ if (!is_printable (wc))
+ wc = '.';
+ tty_print_char (wc);
+#endif
}
col++;
attrset (NORMAL_COLOR);
--- mc-4.6.1a/src/screen.c.utf8 2005-11-11 04:32:40.000000000 +0100
+++ mc-4.6.1a/src/screen.c 2005-11-16 14:03:46.000000000 +0100
@@ -171,21 +171,56 @@ add_permission_string (char *dest, int w
static const char *
string_file_name (file_entry *fe, int len)
{
- static char buffer [MC_MAXPATHLEN + 1];
size_t i;
- for (i = 0; i < sizeof(buffer) - 1; i++) {
- char c;
+#ifdef UTF8
+ static char buffer [BUF_SMALL * 4];
+ mbstate_t s;
+ int mbmax = MB_CUR_MAX;
+ const char *str = fe->fname;
- c = fe->fname[i];
+ memset (&s, 0, sizeof (s));
+#else
+ static char buffer [BUF_SMALL];
+#endif
- if (!c)
- break;
+#ifdef UTF8
+ if (SLsmg_Is_Unicode)
+ for (i = 0; i < sizeof (buffer) - 1; i++) {
+ wchar_t wc;
+ int len;
+
+ 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];
- if (!is_printable(c))
- c = '?';
+ if (!c) break;
- buffer[i] = c;
+ 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;
length = 0;
empty_line = (file_index >= panel->count);
@@ -564,34 +567,137 @@ format_file (char *dest, int limit, WPan
break;
if (format->string_fn){
- int len;
+ int len, still, over, perm, txtlen, wide;
if (empty_line)
txt = " ";
else
txt = (*format->string_fn)(fe, format->field_len);
- old_pos = cdest;
-
len = format->field_len;
if (len + length > width)
len = width - length;
- if (len + (cdest - dest) > limit)
- len = limit - (cdest - dest);
+ if (len >= BUF_MEDIUM)
+ len = BUF_MEDIUM - 1;
if (len <= 0)
break;
- cdest = to_buffer (cdest, format->just_mode, len, txt);
- length += len;
- attrset (color);
+ perm = 0;
+ if (permission_mode) {
+ if (!strcmp(format->id, "perm"))
+ perm = 1;
+ else if (!strcmp(format->id, "mode"))
+ perm = 2;
+ }
- if (permission_mode && !strcmp(format->id, "perm"))
- add_permission_string (old_pos, format->field_len, fe, attr, color, 0);
- else if (permission_mode && !strcmp(format->id, "mode"))
- add_permission_string (old_pos, format->field_len, fe, attr, color, 1);
- else
- addstr (old_pos);
+ wide = 0;
+#ifdef UTF8
+ if (SLsmg_Is_Unicode && !empty_line && !perm) {
+ mbstate_t s;
+ const char *str = txt;
+
+ memset (&s, 0, sizeof (s));
+ txtlen = mbsrtowcs ((wchar_t *) buffer, &str,
+ sizeof (buffer) / sizeof (wchar_t), &s);
+ if (txtlen < 0) {
+ txt = " ";
+ txtlen = 1;
+ } else {
+ wide = 1;
+ txtwidth = wcswidth((wchar_t*)buffer, txtlen);
+ }
+ } else
+#endif
+ {
+ txtlen = mbstrlen (txt);
+ txtwidth = txtlen;
+ }
+
+ over = txtwidth > len;
+ still = over ? txtlen - len : len - txtlen;
+
+ switch (HIDE_FIT(format->just_mode)) {
+ case J_LEFT:
+ still = 0;
+ break;
+ case J_CENTER:
+ still /= 2;
+ break;
+ case J_RIGHT:
+ default:
+ break;
+ }
+ attrset (color);
+
+ if (wide) {
+#ifdef UTF8
+ if (over) {
+ if (IS_FIT (format->just_mode)) {
+ int n1 = 0;
+ int width1 = 0;
+ int n2 = 0;
+ int width2 = 0;
+ int len1 = len / 2;
+ int len2;
+
+ while (1) {
+ int w = wcwidth(((wchar_t *) buffer)[n1]);
+ if (width1 + w <= len1) {
+ width1 += w;
+ n1++;
+ }
+ else
+ break;
+ }
+ len2 = len - width1 - 1;
+
+ while (1) {
+ int w = wcwidth(((wchar_t *) buffer)[txtlen - n2 - 1]);
+ if (width2 + w <= len2) {
+ width2 += w;
+ n2++;
+ }
+ else
+ break;
+ }
+
+
+ SLsmg_write_nwchars ((wchar_t *) buffer, n1);
+ SLsmg_write_nwchars (L"~", 1);
+ printw ("%*s", len - width1 - width2 - 1, "");
+ SLsmg_write_nwchars (((wchar_t *) buffer)
+ + txtlen - n2, n2);
+ } else
+ SLsmg_write_nwchars ((wchar_t *) buffer, len);
+ } else {
+ printw ("%*s", still, "");
+ SLsmg_write_nwchars ((wchar_t *) buffer, txtlen);
+ printw ("%*s", len - txtwidth - still, "");
+ }
+#endif
+ } else {
+ if (over) {
+ if (IS_FIT (format->just_mode))
+ strcpy (buffer, name_trunc(txt, len));
+ else
+ memcpy (buffer, txt + still, len);
+ } else {
+ memset (buffer, ' ', still);
+ memcpy (buffer + still, txt, txtlen);
+ memset (buffer + still + txtlen, ' ',
+ len - txtlen - still);
+ }
+ buffer[len] = '\0';
+
+ if (perm)
+ add_permission_string (buffer, format->field_len, fe,
+ attr, color, perm - 1);
+ else
+ addstr (buffer);
+ }
+
+ length += len;
} else {
if (attr == SELECTED || attr == MARKED_SELECTED)
attrset (SELECTED_COLOR);
@@ -614,7 +720,6 @@ repaint_file (WPanel *panel, int file_in
{
int second_column = 0;
int width, offset;
- char buffer [BUF_MEDIUM];
offset = 0;
if (!isstatus && panel->split){
@@ -643,7 +748,7 @@ repaint_file (WPanel *panel, int file_in
widget_move (&panel->widget, file_index - panel->top_file + 2, 1);
}
- format_file (buffer, sizeof(buffer), panel, file_index, width, attr, isstatus);
+ format_file (panel, file_index, width, attr, isstatus);
if (!isstatus && panel->split){
if (second_column)
@@ -692,7 +797,7 @@ display_mini_info (WPanel *panel)
ngettext("%s in %d file", "%s in %d files", panel->marked),
b_bytes, panel->marked);
- if ((int) strlen (buffer) > cols-2){
+ if ((int) mbstrlen (buffer) > cols-2){
buffer [cols] = 0;
p += 2;
} else
@@ -1101,6 +1206,12 @@ paint_frame (WPanel *panel)
int side, width;
const char *txt;
+#ifdef UTF8
+ char buffer[30 * sizeof (wchar_t)];
+ mbstate_t s;
+
+ memset (&s, 0, sizeof (s));
+#endif
if (!panel->split)
adjust_top_file (panel);
@@ -1125,16 +1236,38 @@ paint_frame (WPanel *panel)
if (format->string_fn){
txt = format->title;
- header_len = strlen (txt);
+ attrset (MARKED_COLOR);
+ width -= format->field_len;
+#ifdef UTF8
+ if (SLsmg_Is_Unicode) {
+ const char *str = txt;
+ header_len = mbsrtowcs ((wchar_t *) buffer, &str,
+ sizeof (buffer) / sizeof (wchar_t),
+ &s);
+ if (header_len < 0) {
+ memset (&s, 0, sizeof (s));
+ printw ("%*s", format->field_len, "");
+ continue;
+ }
+ if (header_len > format->field_len)
+ header_len = format->field_len;
+ spaces = (format->field_len - header_len) / 2;
+ extra = (format->field_len - header_len) % 2;
+ printw ("%*s", spaces, "");
+ SLsmg_write_nwchars ((wchar_t *) buffer, header_len);
+ printw ("%*s", spaces + extra, "");
+ continue;
+ }
+#endif
+
+ header_len = mbstrlen (txt);
if (header_len > format->field_len)
header_len = format->field_len;
- attrset (MARKED_COLOR);
spaces = (format->field_len - header_len) / 2;
extra = (format->field_len - header_len) % 2;
tty_printf ("%*s%.*s%*s", spaces, "",
header_len, txt, spaces+extra, "");
- width -= 2 * spaces + extra + header_len;
} else {
attrset (NORMAL_COLOR);
one_vline ();
--- mc-4.6.1a/src/widget.h.utf8 2005-06-14 15:02:31.000000000 +0200
+++ mc-4.6.1a/src/widget.h 2005-11-16 14:03:46.000000000 +0100
@@ -22,6 +22,7 @@ typedef struct WButton {
char *text; /* text of button */
int hotkey; /* hot KEY */
int hotpos; /* offset hot KEY char in text */
+ wchar_t hotwc;
bcback callback; /* Callback function */
} WButton;
@@ -43,6 +44,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 {
@@ -58,16 +60,20 @@ char *show_hist (GList *history, int wid
typedef struct {
Widget widget;
- int point; /* cursor position in the input line */
- int mark; /* The mark position */
- int first_shown; /* Index of the first shown character */
- int current_max_len; /* Maximum length of input line */
- int field_len; /* Length of the editing field */
+ int point; /* cursor position in the input line (mb chars) */
+ int mark; /* The mark position (mb chars) */
+ int first_shown; /* Index of the first shown character (mb chars) */
+ int current_max_len; /* Maximum length of input line (bytes) */
+ int field_len; /* Length of the editing field (mb chars) */
int color; /* color used */
int first; /* Is first keystroke? */
int disable_update; /* Do we want to skip updates? */
int is_password; /* Is this a password input line? */
char *buffer; /* pointer to editing buffer */
+#ifdef UTF8
+ char charbuf[MB_LEN_MAX];
+#endif /* UTF8 */
+ int charpoint;
GList *history; /* The history */
int need_push; /* need to push the current Input on hist? */
char **completions; /* Possible completions array */
--- mc-4.6.1a/src/tty.h.utf8 2005-09-05 04:14:29.000000000 +0200
+++ mc-4.6.1a/src/tty.h 2005-11-16 14:03:46.000000000 +0100
@@ -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
--- mc-4.6.1a/src/hotlist.c.utf8 2005-05-27 05:35:15.000000000 +0200
+++ mc-4.6.1a/src/hotlist.c 2005-11-16 14:03:46.000000000 +0100
@@ -555,7 +555,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;
}
@@ -580,12 +580,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);
}
}
@@ -814,7 +814,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;
@@ -863,7 +863,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);
@@ -959,7 +959,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
@@ -1015,7 +1015,7 @@ void add2hotlist_cmd (void)
{
char *prompt, *label;
const char *cp = _("Label for \"%s\":");
- int l = strlen (cp);
+ int l = mbstrlen (cp);
char *label_string = g_strdup (current_panel->cwd);
strip_password (label_string, 1);
--- mc-4.6.1a/src/help.c.utf8 2005-07-22 11:29:50.000000000 +0200
+++ mc-4.6.1a/src/help.c 2005-11-16 14:03:46.000000000 +0100
@@ -449,10 +449,28 @@ static void help_show (Dlg_head *h, cons
#ifndef HAVE_SLANG
addch (acs_map [c]);
#else
+#if defined(UTF8) && SLANG_VERSION < 20000
+ SLsmg_draw_object (h->y + line + 2, h->x + col + 2, acs_map [c]);
+#else
SLsmg_draw_object (h->y + line + 2, h->x + col + 2, c);
+#endif /* UTF8 */
#endif
+ } else {
+#ifdef UTF8
+ if (SLsmg_Is_Unicode) {
+ int len;
+ mbstate_t mbs;
+ wchar_t wc;
+ memset (&mbs, 0, sizeof (mbs));
+ len = mbrtowc(&wc, p, MB_CUR_MAX, &mbs);
+ if (len <= 0) len = 1; /* skip broken multibyte chars */
+
+ SLsmg_write_char(wc);
+ p += len - 1;
} else
+#endif
addch (c);
+ }
col++;
break;
}
@@ -805,6 +823,12 @@ interactive_display (const char *filenam
message (1, MSG_ERROR, _(" Cannot open file %s \n %s "), filename ? filename : hlpfile,
unix_error_string (errno));
}
+ else
+ {
+ char *conv = utf8_to_local(data);
+ g_free(data);
+ data = conv;
+ }
if (!filename)
g_free (hlpfile);
--- mc-4.6.1a/src/wtools.c.utf8 2005-09-05 05:21:32.000000000 +0200
+++ mc-4.6.1a/src/wtools.c 2005-11-16 14:03:46.000000000 +0100
@@ -49,11 +49,11 @@ create_listbox_window (int cols, int lin
/* Adjust sizes */
lines = (lines > LINES - 6) ? LINES - 6 : lines;
- if (title && (cols < (len = strlen (title) + 2)))
+ if (title && (cols < (len = mbstrlen (title) + 2)))
cols = len;
/* no &, but 4 spaces around button for brackets and such */
- if (cols < (len = strlen (cancel_string) + 3))
+ if (cols < (len = mbstrlen (cancel_string) + 3))
cols = len;
cols = cols > COLS - 6 ? COLS - 6 : cols;
@@ -124,7 +124,7 @@ query_dialog (const char *header, const
va_start (ap, count);
for (i = 0; i < count; i++) {
char *cp = va_arg (ap, char *);
- win_len += strlen (cp) + 6;
+ win_len += mbstrlen (cp) + 6;
if (strchr (cp, '&') != NULL)
win_len--;
}
@@ -133,7 +133,7 @@ query_dialog (const char *header, const
/* count coordinates */
msglen (text, &lines, &cols);
- cols = 6 + max (win_len, max ((int) strlen (header), cols));
+ cols = 6 + max (win_len, max ((int) mbstrlen (header), cols));
lines += 4 + (count > 0 ? 2 : 0);
xpos = COLS / 2 - cols / 2;
ypos = LINES / 3 - (lines - 3) / 2;
@@ -148,7 +148,7 @@ query_dialog (const char *header, const
va_start (ap, count);
for (i = 0; i < count; i++) {
cur_name = va_arg (ap, char *);
- xpos = strlen (cur_name) + 6;
+ xpos = mbstrlen (cur_name) + 6;
if (strchr (cur_name, '&') != NULL)
xpos--;
@@ -461,7 +461,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
@@ -481,7 +481,7 @@ fg_input_dialog_help (const char *header
*/
quick_widgets[0].relative_x = len / 2 + 4;
quick_widgets[1].relative_x =
- len / 2 - (strlen (_(quick_widgets[1].text)) + 9);
+ len / 2 - (mbstrlen (_(quick_widgets[1].text)) + 9);
quick_widgets[0].x_divisions = quick_widgets[1].x_divisions = len;
#endif /* ENABLE_NLS */
--- mc-4.6.1a/src/util.h.utf8 2005-11-03 03:18:38.000000000 +0100
+++ mc-4.6.1a/src/util.h 2005-11-16 14:03:46.000000000 +0100
@@ -111,6 +111,13 @@ void init_uid_gid_cache (void);
char *get_group (int);
char *get_owner (int);
+void fix_utf8(char *str);
+size_t mbstrlen (const char *);
+wchar_t *mbstr_to_wchar (const char *);
+char *wchar_to_mbstr (const wchar_t *);
+char *utf8_to_local(char *str);
+
+
#define MAX_I18NTIMELENGTH 14
#define MIN_I18NTIMELENGTH 10
#define STD_I18NTIMELENGTH 12
--- mc-4.6.1a/src/widget.c.utf8 2005-10-08 06:52:42.000000000 +0200
+++ mc-4.6.1a/src/widget.c 2005-11-16 14:03:46.000000000 +0100
@@ -35,6 +35,9 @@
#include "global.h"
#include "tty.h"
+#ifdef UTF8
+#include <wctype.h>
+#endif /* UTF8 */
#include "color.h"
#include "mouse.h"
#include "dialog.h"
@@ -181,6 +184,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;
@@ -214,7 +222,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;
@@ -237,14 +245,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);
}
}
@@ -265,8 +295,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;
}
@@ -279,14 +310,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 *);
@@ -361,14 +391,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;
@@ -407,7 +458,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);
@@ -1159,35 +1271,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;
}
@@ -1195,12 +1355,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
@@ -1208,18 +1370,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
@@ -1229,11 +1394,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))
@@ -1243,6 +1436,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
@@ -1275,8 +1494,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--;
}
@@ -1284,10 +1504,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;
}
@@ -1302,6 +1520,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);
}
@@ -1310,11 +1531,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;
}
@@ -1331,6 +1554,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
@@ -1374,16 +1599,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
@@ -1393,9 +1622,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
@@ -1522,6 +1752,7 @@ port_region_marked_for_delete (WInput *i
*in->buffer = 0;
in->point = 0;
in->first = 0;
+ in->charpoint = 0;
}
cb_ret_t
@@ -1550,7 +1781,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);
@@ -1584,6 +1819,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);
}
@@ -1624,7 +1862,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:
@@ -1648,7 +1886,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)
@@ -1705,7 +1943,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;
}
--- mc-4.6.1a/src/util.c.utf8 2005-11-03 03:18:38.000000000 +0100
+++ mc-4.6.1a/src/util.c 2005-11-16 14:03:46.000000000 +0100
@@ -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,21 @@
#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)
+{
+ while(n--)
+ SLsmg_write_char(*s++);
+}
+#endif
+
extern void str_replace(char *s, char from, char to)
{
for (; *s != '\0'; s++) {
@@ -78,9 +94,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 +211,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 +224,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 +332,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 +371,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 +886,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 +973,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 +985,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 +1005,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 +1030,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 +1160,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;
--- mc-4.6.1a/src/file.c.utf8 2005-09-17 13:45:13.000000000 +0200
+++ mc-4.6.1a/src/file.c 2005-11-16 14:03:46.000000000 +0100
@@ -164,15 +164,20 @@ static const char *
do_transform_source (FileOpContext *ctx, const char *source)
{
size_t j, k, l, len;
- const char *fnsource = x_basename (source);
+ const 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++) {
@@ -216,6 +221,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];
@@ -230,6 +236,7 @@ do_transform_source (FileOpContext *ctx,
}
}
fntarget[k] = 0;
+ g_free(fnsource);
return fntarget;
}
--- mc-4.6.1a/src/find.c.utf8 2005-07-07 21:34:56.000000000 +0200
+++ mc-4.6.1a/src/find.c 2005-11-16 14:03:46.000000000 +0100
@@ -217,7 +217,7 @@ find_parameters (char **start_dir, char
int l1, maxlen = 0;
while (i--) {
- l1 = strlen (labs[i] = _(labs[i]));
+ l1 = mbstrlen (labs[i] = _(labs[i]));
if (l1 > maxlen)
maxlen = l1;
}
@@ -226,7 +226,7 @@ find_parameters (char **start_dir, char
FIND_X = i;
for (i = sizeof (buts) / sizeof (buts[0]), l1 = 0; i--;) {
- l1 += strlen (buts[i] = _(buts[i]));
+ l1 += mbstrlen (buts[i] = _(buts[i]));
}
l1 += 21;
if (l1 > FIND_X)
@@ -235,8 +235,8 @@ find_parameters (char **start_dir, char
ilen = FIND_X - 7 - maxlen; /* for the case of very long buttons :) */
istart = FIND_X - 3 - ilen;
- b1 = b0 + strlen (buts[0]) + 7;
- b2 = FIND_X - (strlen (buts[2]) + 6);
+ b1 = b0 + mbstrlen (buts[0]) + 7;
+ b2 = FIND_X - (mbstrlen (buts[2]) + 6);
i18n_flag = 1;
case_label = _(case_label);
@@ -857,7 +857,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;
--- mc-4.6.1a/src/myslang.h.utf8 2005-09-05 05:22:04.000000000 +0200
+++ mc-4.6.1a/src/myslang.h 2005-11-16 14:03:46.000000000 +0100
@@ -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,
--- mc-4.6.1a/src/achown.c.utf8 2005-09-05 03:36:58.000000000 +0200
+++ mc-4.6.1a/src/achown.c 2005-11-16 14:03:46.000000000 +0100
@@ -584,6 +584,12 @@ init_chown_advanced (void)
b_att[2] = button_new (XTRACT (6));
b_user = button_new (XTRACT (5));
b_group = button_new (XTRACT (4));
+#ifdef UTF8
+ if (SLsmg_Is_Unicode) {
+ b_user->text = g_realloc (b_user->text, MB_CUR_MAX * 15 + 1);
+ b_group->text = g_realloc (b_group->text, MB_CUR_MAX * 15 + 1);
+ }
+#endif
add_widget (ch_dlg, b_group);
add_widget (ch_dlg, b_user);
--- mc-4.6.1a/src/dialog.c.utf8 2005-09-05 05:20:27.000000000 +0200
+++ mc-4.6.1a/src/dialog.c 2005-11-16 14:03:46.000000000 +0100
@@ -166,7 +166,7 @@ common_dialog_repaint (struct Dlg_head *
if (h->title) {
attrset (DLG_HOT_NORMALC (h));
- dlg_move (h, space, (h->cols - strlen (h->title)) / 2);
+ dlg_move (h, space, (h->cols - mbstrlen (h->title)) / 2);
addstr (h->title);
}
}
--- mc-4.6.1a/src/boxes.c.utf8 2005-06-14 15:02:31.000000000 +0200
+++ mc-4.6.1a/src/boxes.c 2005-11-16 14:03:46.000000000 +0100
@@ -153,23 +153,23 @@ display_init (int radio_sel, char *init_
display_title = _(display_title);
for (i = 0; i < LIST_TYPES; i++) {
displays[i] = _(displays[i]);
- if ((l = strlen (displays[i])) > maxlen)
+ if ((l = mbstrlen (displays[i])) > maxlen)
maxlen = l;
}
- i = strlen (ok_button) + 5;
- l = strlen (cancel_button) + 3;
+ i = mbstrlen (ok_button) + 5;
+ l = mbstrlen (cancel_button) + 3;
l = max (i, l);
i = maxlen + l + 16;
if (i > DISPLAY_X)
DISPLAY_X = i;
- i = strlen (user_mini_status) + 13;
+ i = mbstrlen (user_mini_status) + 13;
if (i > DISPLAY_X)
DISPLAY_X = i;
- i = strlen (display_title) + 10;
+ i = mbstrlen (display_title) + 10;
if (i > DISPLAY_X)
DISPLAY_X = i;
@@ -288,20 +288,20 @@ sort_box (sortfn *sort_fn, int *reverse,
int maxlen = 0;
for (i = SORT_TYPES - 1; i >= 0; i--) {
sort_orders_names[i] = _(sort_orders[i].sort_name);
- r = strlen (sort_orders_names[i]);
+ r = mbstrlen (sort_orders_names[i]);
if (r > maxlen)
maxlen = r;
}
check_pos = maxlen + 9;
- r = strlen (reverse_label) + 4;
- i = strlen (case_label) + 4;
+ r = mbstrlen (reverse_label) + 4;
+ i = mbstrlen (case_label) + 4;
if (i > r)
r = i;
- l = strlen (ok_button) + 6;
- i = strlen (cancel_button) + 4;
+ l = mbstrlen (ok_button) + 6;
+ i = mbstrlen (cancel_button) + 4;
if (i > l)
l = i;
@@ -310,7 +310,7 @@ sort_box (sortfn *sort_fn, int *reverse,
if (i > SORT_X)
SORT_X = i;
- i = strlen (sort_title) + 6;
+ i = mbstrlen (sort_title) + 6;
if (i > SORT_X)
SORT_X = i;
@@ -405,7 +405,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;
}
@@ -420,8 +420,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;
@@ -492,11 +492,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;
@@ -504,8 +504,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;
@@ -600,7 +600,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;
@@ -811,7 +811,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;
@@ -970,7 +970,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;
@@ -979,7 +979,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;
}
@@ -1037,7 +1037,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;
}
@@ -1047,7 +1047,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)
@@ -1056,7 +1056,7 @@ vfs_smb_get_authinfo (const char *host,
ilen = dialog_x - 7 - maxlen; /* for the case of very long buttons :) */
istart = dialog_x - 3 - ilen;
- b2 = dialog_x - (strlen(buts[1]) + 6);
+ b2 = dialog_x - (mbstrlen(buts[1]) + 6);
i18n_flag = 1;
}
--- mc-4.6.1a/src/learn.c.utf8 2005-05-27 05:35:15.000000000 +0200
+++ mc-4.6.1a/src/learn.c 2005-11-16 14:03:46.000000000 +0100
@@ -237,7 +237,7 @@ init_learn (void)
learn_but[0].x = 78 / 2 + 4;
learn_but[1].text = _(learn_but[1].text);
- learn_but[1].x = 78 / 2 - (strlen (learn_but[1].text) + 9);
+ learn_but[1].x = 78 / 2 - (mbstrlen (learn_but[1].text) + 9);
learn_title = _(learn_title);
i18n_flag = 1;
--- mc-4.6.1a/edit/edit-widget.h.utf8 2005-08-15 22:34:26.000000000 +0200
+++ mc-4.6.1a/edit/edit-widget.h 2005-11-16 14:03:46.000000000 +0100
@@ -30,6 +30,11 @@ typedef struct edit_key_map_type {
long command;
} edit_key_map_type;
+struct action {
+ mc_wchar_t ch;
+ long flags;
+};
+
struct WEdit {
Widget widget;
@@ -42,8 +47,17 @@ struct WEdit {
/* dynamic buffers and cursor position for editor: */
long curs1; /* position of the cursor from the beginning of the file. */
long curs2; /* position from the end of the file */
+#ifndef UTF8
unsigned char *buffers1[MAXBUFF + 1]; /* all data up to curs1 */
unsigned char *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */
+#else /* UTF8 */
+ mc_wchar_t *buffers1[MAXBUFF + 1]; /* all data up to curs1 */
+ mc_wchar_t *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */
+
+ unsigned char charbuf[MB_LEN_MAX];
+ int charpoint;
+#endif /* UTF8 */
+
/* search variables */
long search_start; /* First character to start searching from */
@@ -87,7 +101,7 @@ struct WEdit {
/* undo stack and pointers */
unsigned long stack_pointer;
- long *undo_stack;
+ struct action *undo_stack;
unsigned long stack_size;
unsigned long stack_size_mask;
unsigned long stack_bottom;
--- mc-4.6.1a/edit/editkeys.c.utf8 2005-08-10 18:47:44.000000000 +0200
+++ mc-4.6.1a/edit/editkeys.c 2005-11-16 14:03:46.000000000 +0100
@@ -181,10 +181,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;
@@ -241,9 +241,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;
}
}
@@ -282,7 +303,7 @@ edit_translate_key (WEdit *edit, long x_
*cmd = command;
*ch = char_for_insertion;
- if (command == CK_Insert_Char && char_for_insertion == -1) {
+ if (command == CK_Insert_Char && char_for_insertion == (mc_wint_t)-1) {
/* unchanged, key has no function here */
return 0;
}
--- mc-4.6.1a/edit/editwidget.c.utf8 2005-09-07 10:54:12.000000000 +0200
+++ mc-4.6.1a/edit/editwidget.c 2005-11-16 14:03:46.000000000 +0100
@@ -344,7 +344,8 @@ edit_callback (Widget *w, widget_msg_t m
case WIDGET_KEY:
{
- int cmd, ch;
+ int cmd;
+ mc_wint_t ch;
/* The user may override the access-keys for the menu bar. */
if (edit_translate_key (e, parm, &cmd, &ch)) {
--- mc-4.6.1a/edit/editcmd.c.utf8 2005-10-04 23:15:06.000000000 +0200
+++ mc-4.6.1a/edit/editcmd.c 2005-11-16 14:03:46.000000000 +0100
@@ -61,7 +61,7 @@
#define edit_get_save_file(f,h) input_expand_dialog (h, _(" Enter file name: "), f)
struct selection {
- unsigned char * text;
+ mc_wchar_t *text;
int len;
};
@@ -84,12 +84,16 @@ int edit_confirm_save = 1;
#define MAX_REPL_LEN 1024
static int edit_save_cmd (WEdit *edit);
-static unsigned char *edit_get_block (WEdit *edit, long start,
+static mc_wchar_t *edit_get_block (WEdit *edit, long start,
long finish, int *l);
-static inline int my_lower_case (int c)
+static inline mc_wchar_t my_lower_case (mc_wchar_t c)
{
+#ifndef UTF8
return tolower(c & 0xFF);
+#else
+ return towlower(c);
+#endif
}
static const char *
@@ -124,11 +128,11 @@ static void *memmove (void *dest, const
#endif /* !HAVE_MEMMOVE */
/* #define itoa MY_itoa <---- this line is now in edit.h */
-static char *
+static mc_wchar_t *
MY_itoa (int i)
{
- static char t[14];
- char *s = t + 13;
+ static mc_wchar_t t[14];
+ mc_wchar_t *s = t + 13;
int j = i;
*s-- = 0;
do {
@@ -213,6 +217,48 @@ void edit_refresh_cmd (WEdit * edit)
doupdate();
}
+#ifdef UTF8
+
+static size_t
+wchar_write(int fd, mc_wchar_t *buf, size_t len)
+{
+ char *tmpbuf = g_malloc(len + MB_LEN_MAX);
+ mbstate_t mbs;
+ size_t i;
+ size_t outlen = 0;
+ size_t res;
+
+ for (i = 0; i < len; i++) {
+ if (outlen >= len) {
+ if ((res = mc_write(fd, tmpbuf, outlen)) != outlen) {
+ g_free(tmpbuf);
+ return -1;
+ }
+ outlen = 0;
+ }
+ memset (&mbs, 0, sizeof (mbs));
+#ifdef __STDC_ISO_10646__
+ if (buf[i] >= BINARY_CHAR_OFFSET && buf[i] < (BINARY_CHAR_OFFSET + 256)) {
+ res = 1;
+ tmpbuf[outlen] = (char) (buf[i] - BINARY_CHAR_OFFSET);
+
+ } else
+#endif
+ res = wcrtomb(tmpbuf + outlen, buf[i], &mbs);
+ if (res > 0) {
+ outlen += res;
+ }
+ }
+ if ((res = mc_write(fd, tmpbuf, outlen)) != outlen) {
+ g_free(tmpbuf);
+ return -1;
+ }
+ g_free(tmpbuf);
+ return len;
+}
+
+#endif /* UTF8 */
+
/* If 0 (quick save) then a) create/truncate <filename> file,
b) save to <filename>;
if 1 (safe save) then a) save to <tempnam>,
@@ -320,32 +366,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;
@@ -658,13 +720,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");
}
}
@@ -697,7 +767,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) {
@@ -747,10 +821,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)
@@ -897,7 +979,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;
@@ -945,7 +1027,7 @@ edit_block_copy_cmd (WEdit *edit)
{
long start_mark, end_mark, current = edit->curs1;
int size, x;
- unsigned char *copy_buf;
+ mc_wchar_t *copy_buf;
edit_update_curs_col (edit);
x = edit->curs_col;
@@ -990,7 +1072,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;
@@ -1051,7 +1133,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;
@@ -1389,7 +1471,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;
@@ -1398,6 +1484,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;
@@ -1417,13 +1508,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);
}
@@ -1431,13 +1560,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... */
@@ -1446,19 +1591,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);
@@ -1472,20 +1620,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);
@@ -1499,7 +1663,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--;
@@ -1525,10 +1693,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 */
@@ -1539,15 +1713,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;
@@ -1557,36 +1743,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;
}
@@ -1600,9 +1809,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;
@@ -1634,6 +1848,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'; \
@@ -1641,33 +1856,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;
@@ -1695,45 +1925,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 **));
@@ -1742,10 +2005,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);
@@ -1924,8 +2194,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 || replace_regexp) {
- char repl_str[MAX_REPL_LEN + 2];
+ mc_wchar_t repl_str[MAX_REPL_LEN + 2];
int ret = 0;
/* we need to fill in sargs just like with scanf */
@@ -1934,17 +2207,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
-
@@ -1962,14 +2243,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 ==
@@ -1983,10 +2273,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) {
@@ -2161,16 +2459,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);
@@ -2203,11 +2502,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;
@@ -2215,15 +2518,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);
@@ -2561,17 +2868,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;
@@ -2665,15 +2975,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 */
@@ -2683,11 +2998,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 */
@@ -2720,7 +3043,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) {
@@ -2739,11 +3062,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 */
}
@@ -2751,7 +3079,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);
@@ -2765,6 +3093,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
@@ -2777,6 +3117,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;
@@ -2812,9 +3155,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);
@@ -2822,9 +3174,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 */
@@ -2841,8 +3201,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 */
@@ -2859,16 +3220,32 @@ edit_complete_word_cmd (WEdit *edit)
/* prepare match expression */
bufpos = &edit->buffers1[word_start >> S_EDIT_BUF_SIZE]
[word_start & M_EDIT_BUF_SIZE];
+
+ match_expr = g_malloc((word_len + 14) * sizeof(mc_wchar_t));
+#ifndef UTF8
match_expr = g_strdup_printf ("%.*s[a-zA-Z_0-9]+", word_len, bufpos);
+#else /* UTF8 */
+ wcsncpy (match_expr, bufpos, word_len);
+ match_expr[word_len] = '\0';
+ wcscat (match_expr, L"[a-zA-Z_0-9]+");
+#endif /* UTF8 */
/* init search: backward, regexp, whole word, case sensitive */
edit_set_search_parameters (0, 1, 1, 1, 1);
/* collect the possible completions */
/* start search from curs1 down to begin of file */
+#ifndef UTF8
max_len =
edit_collect_completions (edit, word_start, word_len, match_expr,
(struct selection *) &compl, &num_compl);
+#else /* UTF8 */
+ mbmatch_expr = wchar_to_mbstr(match_expr);
+ max_len =
+ edit_collect_completions (edit, word_start, word_len, mbmatch_expr,
+ (struct selection *) &compl, &num_compl);
+ g_free(mbmatch_expr);
+#endif /* UTF8 */
if (num_compl > 0) {
/* insert completed word if there is only one match */
--- mc-4.6.1a/edit/wordproc.c.utf8 2005-05-27 05:35:12.000000000 +0200
+++ mc-4.6.1a/edit/wordproc.c 2005-11-16 14:03:46.000000000 +0100
@@ -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)
+next_word_start (mc_wchar_t *t, int q)
{
int i;
for (i = q;; i++) {
@@ -220,7 +242,7 @@ next_word_start (unsigned char *t, int q
/* find the start of a word */
static int
-word_start (unsigned char *t, int q)
+word_start (mc_wchar_t *t, int q)
{
int i = q;
if (t[q] == ' ' || t[q] == '\t')
@@ -239,7 +261,7 @@ word_start (unsigned char *t, int q)
}
/* 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);
@@ -267,7 +289,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);
@@ -276,18 +298,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;
@@ -299,7 +330,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--;
@@ -332,7 +367,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;
@@ -342,17 +377,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;
}
--- mc-4.6.1a/edit/edit.h.utf8 2005-09-07 10:54:12.000000000 +0200
+++ mc-4.6.1a/edit/edit.h 2005-11-16 14:03:46.000000000 +0100
@@ -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);
@@ -146,11 +173,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);
@@ -181,7 +208,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);
@@ -231,7 +258,7 @@ void edit_mail_dialog (WEdit *edit);
void format_paragraph (WEdit *edit, int force);
/* either command or char_for_insertion must be passed as -1 */
-void edit_execute_cmd (WEdit *edit, int command, int char_for_insertion);
+void edit_execute_cmd (WEdit *edit, int command, mc_wint_t char_for_insertion);
#define get_sys_error(s) (s)
--- mc-4.6.1a/edit/editdraw.c.utf8 2005-09-05 04:14:29.000000000 +0200
+++ mc-4.6.1a/edit/editdraw.c 2005-11-16 14:03:46.000000000 +0100
@@ -69,11 +69,16 @@ static void status_string (WEdit * edit,
* as decimal and as hex.
*/
if (edit->curs1 < edit->last_byte) {
- unsigned char cur_byte = edit_get_byte (edit, edit->curs1);
+ mc_wchar_t cur_byte = edit_get_byte (edit, edit->curs1);
+#ifndef UTF8
g_snprintf (byte_str, sizeof (byte_str), "%c %3d 0x%02X",
is_printable (cur_byte) ? cur_byte : '.',
- (int) cur_byte,
- (unsigned) cur_byte);
+#else /* UTF8 */
+ g_snprintf (byte_str, sizeof(byte_str), "%lc %3d 0x%02X",
+ iswprint(cur_byte) ? cur_byte : '.',
+#endif /* UTF8 */
+ (int) cur_byte,
+ (unsigned) cur_byte);
} else {
strcpy (byte_str, "<EOF>");
}
@@ -205,11 +210,16 @@ void edit_scroll_screen_over_cursor (WEd
#define lowlevel_set_color(x) attrset(MY_COLOR_PAIR(color))
#endif
+struct line_s {
+ mc_wchar_t ch;
+ unsigned int style;
+};
+
static void
print_to_widget (WEdit *edit, long row, int start_col, int start_col_real,
- long end_col, unsigned int line[])
+ long end_col, struct line_s line[])
{
- unsigned int *p;
+ struct line_s *p;
int x = start_col_real + EDIT_TEXT_HORIZONTAL_OFFSET;
int x1 = start_col + EDIT_TEXT_HORIZONTAL_OFFSET;
@@ -223,9 +233,9 @@ print_to_widget (WEdit *edit, long row,
edit_move (x1 + FONT_OFFSET_X, y + FONT_OFFSET_Y);
p = line;
- while (*p) {
+ while (p->ch) {
int style;
- int textchar;
+ mc_wchar_t textchar;
int color;
if (cols_to_skip) {
@@ -234,9 +244,9 @@ print_to_widget (WEdit *edit, long row,
continue;
}
- style = *p & 0xFF00;
- textchar = *p & 0xFF;
- color = *p >> 16;
+ style = p->style & 0xFF00;
+ textchar = p->ch;
+ color = p->style >> 16;
if (style & MOD_ABNORMAL) {
/* Non-printable - use black background */
@@ -250,8 +260,11 @@ print_to_widget (WEdit *edit, long row,
} else {
lowlevel_set_color (color);
}
-
+#ifdef UTF8
+ SLsmg_write_char(textchar);
+#else
addch (textchar);
+#endif
p++;
}
}
@@ -261,11 +274,11 @@ static void
edit_draw_this_line (WEdit *edit, long b, long row, long start_col,
long end_col)
{
- static unsigned int line[MAX_LINE_LEN];
- unsigned int *p = line;
+ struct line_s line[MAX_LINE_LEN];
+ struct line_s *p = line;
long m1 = 0, m2 = 0, q, c1, c2;
int col, start_col_real;
- unsigned int c;
+ mc_wint_t c;
int color;
int i, book_mark = -1;
@@ -287,66 +300,96 @@ edit_draw_this_line (WEdit *edit, long b
if (row <= edit->total_lines - edit->start_line) {
while (col <= end_col - edit->start_col) {
- *p = 0;
+ p->ch = 0;
+ p->style = 0;
if (q == edit->curs1)
- *p |= MOD_CURSOR;
+ p->style |= MOD_CURSOR;
if (q >= m1 && q < m2) {
if (column_highlighting) {
int x;
x = edit_move_forward3 (edit, b, 0, q);
if (x >= c1 && x < c2)
- *p |= MOD_MARKED;
+ p->style |= MOD_MARKED;
} else
- *p |= MOD_MARKED;
+ p->style |= MOD_MARKED;
}
if (q == edit->bracket)
- *p |= MOD_BOLD;
+ p->style |= MOD_BOLD;
if (q >= edit->found_start
&& q < edit->found_start + edit->found_len)
- *p |= MOD_BOLD;
+ p->style |= MOD_BOLD;
c = edit_get_byte (edit, q);
/* we don't use bg for mc - fg contains both */
if (book_mark == -1) {
edit_get_syntax_color (edit, q, &color);
- *p |= color << 16;
+ p->style |= color << 16;
} else {
- *p |= book_mark << 16;
+ p->style |= book_mark << 16;
}
q++;
switch (c) {
case '\n':
col = end_col - edit->start_col + 1; /* quit */
- *(p++) |= ' ';
+ p->ch = ' ';
+ p++;
break;
case '\t':
i = TAB_SIZE - ((int) col % TAB_SIZE);
- *p |= ' ';
- c = *(p++) & ~MOD_CURSOR;
+ p->ch = ' ';
+ c = p->style & ~MOD_CURSOR;
+ p++;
col += i;
- while (--i)
- *(p++) = c;
+ while (--i) {
+ p->ch = ' '; p->style = c;
+ p++;
+ }
break;
default:
c = convert_to_display_c (c);
/* Caret notation for control characters */
if (c < 32) {
- *(p++) = '^' | MOD_ABNORMAL;
- *(p++) = (c + 0x40) | MOD_ABNORMAL;
+ p->ch = '^';
+ p->style = MOD_ABNORMAL;
+ p++;
+ p->ch = c + 0x40;
+ p->style = MOD_ABNORMAL;
col += 2;
break;
}
if (c == 127) {
- *(p++) = '^' | MOD_ABNORMAL;
- *(p++) = '?' | MOD_ABNORMAL;
+ p->ch = '^';
+ p->style = MOD_ABNORMAL;
+ p++;
+ p->ch = '?';
+ p->style = MOD_ABNORMAL;
+ p++;
col += 2;
break;
}
- if (is_printable (c)) {
- *(p++) |= c;
+#ifndef UTF8
+ if (is_printable (c)
+#else /* UTF8 */
+ if (iswprint (c)
+#ifdef __STDC_ISO_10646__
+ && (c < BINARY_CHAR_OFFSET || c >= (BINARY_CHAR_OFFSET + 256))
+#endif
+#endif /* UTF8 */
+ ) {
+ p->ch = c;
+ p++;
+
+#ifdef UTF8
+ i = wcwidth(c);
+ if (i > 1) {
+ col += i - 1;
+ }
+#endif /* UTF8 */
} else {
- *(p++) = '.' | MOD_ABNORMAL;
+ p->ch = '.';
+ p->style = MOD_ABNORMAL;
+ p++;
}
col++;
break;
@@ -356,7 +399,7 @@ edit_draw_this_line (WEdit *edit, long b
} else {
start_col_real = start_col = 0;
}
- *p = 0;
+ p->ch = 0;
print_to_widget (edit, row, start_col, start_col_real, end_col, line);
}
--- mc-4.6.1a/edit/edit.c.utf8 2005-09-07 10:54:11.000000000 +0200
+++ mc-4.6.1a/edit/edit.c 2005-11-16 14:03:46.000000000 +0100
@@ -103,7 +103,11 @@ char *option_backup_ext = NULL;
static void edit_move_to_prev_col (WEdit *edit, long p);
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)
@@ -132,7 +136,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));
}
/*
@@ -157,7 +161,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 -
@@ -167,7 +171,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);
}
@@ -240,9 +244,44 @@ edit_insert_stream (WEdit * edit, FILE *
{
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;
}
@@ -250,9 +289,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;
}
@@ -291,12 +353,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);
@@ -386,7 +482,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)
@@ -452,6 +552,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,13 +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;
@@ -710,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));
@@ -721,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;
}
}
@@ -734,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
@@ -758,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;
@@ -771,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;
}
@@ -783,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 */
@@ -827,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)
@@ -865,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++;
@@ -881,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;
@@ -904,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++;
@@ -914,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;
@@ -938,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')
@@ -952,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;
@@ -976,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--;
@@ -989,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;
@@ -1005,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;
@@ -1045,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);
}
@@ -1083,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);
}
@@ -1115,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];
@@ -1140,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];
@@ -1247,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;
@@ -1265,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;
}
@@ -1398,7 +1521,7 @@ 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) {
@@ -1770,13 +1893,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:
@@ -1797,31 +1920,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:;
@@ -2098,7 +2223,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;
@@ -2133,7 +2258,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;
@@ -2166,7 +2291,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);