Skip to contentSkip to conversation

kconfig: multibyte character support for lxdialog

PATCH In review EGRY Gabor 2 participants 2 messages Jan 12, 2008

Subsystems (2)
lore
Share & tools
lore

EGRY Gabor

author
#0 lore raw

PATCH 1/1 kconfig: multibyte character support for lxdialog

UTF-8 support for lxdialog with wchar. The installed wide ncurses (ncursesw) is optional.

---

 kbuild-szilard/scripts/kconfig/lxdialog/check-lxdialog.sh |    6 
 kbuild-szilard/scripts/kconfig/lxdialog/checklist.c       |   13 -
 kbuild-szilard/scripts/kconfig/lxdialog/dialog.h          |   60 ++++++
 kbuild-szilard/scripts/kconfig/lxdialog/inputbox.c        |   32 ++-
 kbuild-szilard/scripts/kconfig/lxdialog/menubox.c         |   25 +-
 kbuild-szilard/scripts/kconfig/lxdialog/textbox.c         |   31 +--
 kbuild-szilard/scripts/kconfig/lxdialog/util.c            |  124 +++++++++++---
 kbuild-szilard/scripts/kconfig/lxdialog/yesno.c           |    5 
 8 files changed, 223 insertions(+), 73 deletions(-)
scripts/kconfig/lxdialog/checklist.c renamed from scripts/kconfig/lxdialog/checklist.c~kconfig-i18n-04-lxdialog-multibyte +7 -6
diff -puN scripts/kconfig/lxdialog/checklist.c~kconfig-i18n-04-lxdialog-multibyte scripts/kconfig/lxdialog/checklist.c
@@ -44,9 +44,9 @@ static void print_item(WINDOW * win, int
 	wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
 
 	wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
-	mvwaddch(win, choice, item_x, item_str()[0]);
+	LXD_MVWADDCH(win, choice, item_x, item_str()[0]);
 	wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
-	waddstr(win, (char *)item_str() + 1);
+	LXD_WADDSTR(win, &item_str()[1]);
 	if (selected) {
 		wmove(win, choice, check_x + 1);
 		wrefresh(win);
@@ -112,8 +112,9 @@ int dialog_checklist(const char *title, 
 		     int width, int list_height)
 {
 	int i, x, y, box_x, box_y;
-	int key = 0, button = 0, choice = 0, scroll = 0, max_choice;
+	int button = 0, choice = 0, scroll = 0, max_choice;
 	WINDOW *dialog, *list;
+	LXD_KEYTYPE key = 0;
 
 	/* which item to highlight */
 	item_foreach() {
@@ -173,7 +174,7 @@ do_resize:
 	/* Find length of longest item in order to center checklist */
 	check_x = 0;
 	item_foreach()
-		check_x = MAX(check_x, strlen(item_str()) + 4);
+		check_x = MAX(check_x, MIN(list_width, LXD_STRLEN(item_str()) + 4));
 
 	check_x = (list_width - check_x) / 2;
 	item_x = check_x + 4;
@@ -199,11 +200,11 @@ do_resize:
 	doupdate();
 
 	while (key != KEY_ESC) {
-		key = wgetch(dialog);
+		LXD_WGETCH(dialog, key);
 
 		for (i = 0; i < max_choice; i++) {
 			item_set(i + scroll);
-			if (toupper(key) == toupper(item_str()[0]))
+			if (LXD_TOUPPER(key) == LXD_TOUPPER(item_str()[0]))
 				break;
 		}
 
scripts/kconfig/lxdialog/dialog.h renamed from scripts/kconfig/lxdialog/dialog.h~kconfig-i18n-04-lxdialog-multibyte +57 -3

84 lines not on this page · raw message

scripts/kconfig/lxdialog/inputbox.c renamed from scripts/kconfig/lxdialog/inputbox.c~kconfig-i18n-04-lxdialog-multibyte +18 -14
diff -puN scripts/kconfig/lxdialog/inputbox.c~kconfig-i18n-04-lxdialog-multibyte scripts/kconfig/lxdialog/inputbox.c
@@ -45,14 +45,15 @@ int dialog_inputbox(const char *title, c
                     const char *init)
 {
 	int i, x, y, box_y, box_x, box_width;
-	int input_x = 0, scroll = 0, key = 0, button = -1;
-	char *instr = dialog_input_result;
+	int input_x = 0, scroll = 0, button = -1;
+	LXD_CHAR instr[MAX_LEN + 1];
+	LXD_KEYTYPE key = 0;
 	WINDOW *dialog;
 
 	if (!init)
 		instr[0] = '\0';
 	else
-		strcpy(instr, init);
+		LXD_STRADDWCS(instr, init, MAX_LEN + 1);
 
 do_resize:
 	if (getmaxy(stdscr) <= (height - 2))
@@ -97,15 +98,15 @@ do_resize:
 	wmove(dialog, box_y, box_x);
 	wattrset(dialog, dlg.inputbox.atr);
 
-	input_x = strlen(instr);
+	input_x = LXD_STRLEN(instr);
 
 	if (input_x >= box_width) {
 		scroll = input_x - box_width + 1;
 		input_x = box_width - 1;
 		for (i = 0; i < box_width - 1; i++)
-			waddch(dialog, instr[scroll + i]);
+			LXD_WADDCH(dialog, instr[scroll + i]);
 	} else {
-		waddstr(dialog, instr);
+		LXD_WADDSTR(dialog, instr);
 	}
 
 	wmove(dialog, box_y, box_x + input_x);
@@ -113,7 +114,7 @@ do_resize:
 	wrefresh(dialog);
 
 	while (key != KEY_ESC) {
-		key = wgetch(dialog);
+		LXD_WGETCH(dialog, key);
 
 		if (button == -1) {	/* Input box selected */
 			switch (key) {
@@ -133,10 +134,10 @@ do_resize:
 						scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1);
 						wmove(dialog, box_y, box_x);
 						for (i = 0; i < box_width; i++)
-							waddch(dialog,
-							       instr[scroll + input_x + i] ?
-							       instr[scroll + input_x + i] : ' ');
-						input_x = strlen(instr) - scroll;
+							instr[scroll + input_x + i] ?
+								LXD_WADDCH(dialog, instr[scroll + input_x + i]) :
+								waddch(dialog, ' ');
+						input_x = LXD_STRLEN(instr) - scroll;
 					} else
 						input_x--;
 					instr[scroll + input_x] = '\0';
@@ -146,7 +147,7 @@ do_resize:
 				}
 				continue;
 			default:
-				if (key < 0x100 && isprint(key)) {
+				if (LXD_ISPRINT(key)) {
 					if (scroll + input_x < MAX_LEN) {
 						wattrset(dialog, dlg.inputbox.atr);
 						instr[scroll + input_x] = key;
@@ -155,10 +156,10 @@ do_resize:
 							scroll++;
 							wmove(dialog, box_y, box_x);
 							for (i = 0; i < box_width - 1; i++)
-								waddch(dialog, instr [scroll + i]);
+								LXD_WADDCH(dialog, instr[scroll + i]);
 						} else {
 							wmove(dialog, box_y, input_x++ + box_x);
-							waddch(dialog, key);
+							LXD_WADDCH(dialog, key);
 						}
 						wrefresh(dialog);
 					} else
@@ -170,10 +171,12 @@ do_resize:
 		switch (key) {
 		case 'O':
 		case 'o':
+			LXD_WCSADDSTR(dialog_input_result, instr, MAX_LEN + 1);
 			delwin(dialog);
 			return 0;
 		case 'H':
 		case 'h':
+			LXD_WCSADDSTR(dialog_input_result, instr, MAX_LEN + 1);
 			delwin(dialog);
 			return 1;
 		case KEY_UP:
@@ -217,6 +220,7 @@ do_resize:
 			break;
 		case ' ':
 		case '\n':
+			LXD_WCSADDSTR(dialog_input_result, instr, MAX_LEN + 1);
 			delwin(dialog);
 			return (button == -1 ? 0 : button);
 		case 'X':
scripts/kconfig/lxdialog/menubox.c renamed from scripts/kconfig/lxdialog/menubox.c~kconfig-i18n-04-lxdialog-multibyte +13 -12
diff -puN scripts/kconfig/lxdialog/menubox.c~kconfig-i18n-04-lxdialog-multibyte scripts/kconfig/lxdialog/menubox.c
@@ -63,13 +63,13 @@ static int menu_width, item_x;
 /*
  * Print menu item
  */
-static void do_print_item(WINDOW * win, const char *item, int line_y,
+static void do_print_item(WINDOW * win, const LXD_CHAR *item, int line_y,
                           int selected, int hotkey)
 {
 	int j;
-	char *menu_item = malloc(menu_width + 1);
+	LXD_CHAR *menu_item = malloc((menu_width + 1) * sizeof(LXD_CHAR));
 
-	strncpy(menu_item, item, menu_width - item_x);
+	LXD_STRNCPY(menu_item, item, menu_width - item_x);
 	menu_item[menu_width - item_x] = '\0';
 	j = first_alpha(menu_item, "YyNnMmHh");
 
@@ -86,11 +86,11 @@ static void do_print_item(WINDOW * win, 
 	wclrtoeol(win);
 #endif
 	wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
-	mvwaddstr(win, line_y, item_x, menu_item);
+	LXD_MVWADDSTR(win, line_y, item_x, menu_item);
 	if (hotkey) {
 		wattrset(win, selected ? dlg.tag_key_selected.atr
 			 : dlg.tag_key.atr);
-		mvwaddch(win, line_y, item_x + j, menu_item[j]);
+		LXD_MVWADDCH(win, line_y, item_x + j, menu_item[j]);
 	}
 	if (selected) {
 		wmove(win, line_y, item_x + 1);
@@ -184,9 +184,10 @@ int dialog_menu(const char *title, const
 {
 	int i, j, x, y, box_x, box_y;
 	int height, width, menu_height;
-	int key = 0, button = 0, scroll = 0, choice = 0;
+	int button = 0, scroll = 0, choice = 0;
 	int first_item =  0, max_choice;
 	WINDOW *dialog, *menu;
+	LXD_KEYTYPE key = 0;
 
 do_resize:
 	height = getmaxy(stdscr);
@@ -278,25 +279,25 @@ do_resize:
 	wrefresh(menu);
 
 	while (key != KEY_ESC) {
-		key = wgetch(menu);
+		LXD_WGETCH(menu, key);
 
-		if (key < 256 && isalpha(key))
-			key = tolower(key);
+		if (key < 256 && LXD_ISALPHA(key))
+			key = LXD_TOLOWER(key);
 
-		if (strchr("ynmh", key))
+		if (strchr("ynmh", (int)key))
 			i = max_choice;
 		else {
 			for (i = choice + 1; i < max_choice; i++) {
 				item_set(scroll + i);
 				j = first_alpha(item_str(), "YyNnMmHh");
-				if (key == tolower(item_str()[j]))
+				if (key == LXD_TOLOWER(item_str()[j]))
 					break;
 			}
 			if (i == max_choice)
 				for (i = 0; i < max_choice; i++) {
 					item_set(scroll + i);
 					j = first_alpha(item_str(), "YyNnMmHh");
-					if (key == tolower(item_str()[j]))
+					if (key == LXD_TOLOWER(item_str()[j]))
 						break;
 				}
 		}
scripts/kconfig/lxdialog/textbox.c renamed from scripts/kconfig/lxdialog/textbox.c~kconfig-i18n-04-lxdialog-multibyte +16 -15
diff -puN scripts/kconfig/lxdialog/textbox.c~kconfig-i18n-04-lxdialog-multibyte scripts/kconfig/lxdialog/textbox.c
@@ -24,13 +24,13 @@
 static void back_lines(int n);
 static void print_page(WINDOW * win, int height, int width);
 static void print_line(WINDOW * win, int row, int width);
-static char *get_line(void);
+static LXD_CHAR *get_line(void);
 static void print_position(WINDOW * win);
 
 static int hscroll;
 static int begin_reached, end_reached, page_length;
-static const char *buf;
-static const char *page;
+static LXD_CHAR *buf;
+static const LXD_CHAR *page;
 
 /*
  * refresh window content
@@ -51,16 +51,17 @@ static void refresh_text_box(WINDOW *dia
 int dialog_textbox(const char *title, const char *tbuf,
 		   int initial_height, int initial_width)
 {
-	int i, x, y, cur_x, cur_y, key = 0;
+	int i, x, y, cur_x, cur_y;
 	int height, width, boxh, boxw;
 	int passed_end;
 	WINDOW *dialog, *box;
+	LXD_KEYTYPE key = 0;
 
 	begin_reached = 1;
 	end_reached = 0;
 	page_length = 0;
 	hscroll = 0;
-	buf = tbuf;
+	LXD_STR2WCS(buf, tbuf);
 	page = buf;	/* page is pointer to start of page to be displayed */
 
 do_resize:
@@ -123,7 +124,7 @@ do_resize:
 	refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
 
 	while ((key != KEY_ESC) && (key != '\n')) {
-		key = wgetch(dialog);
+		LXD_WGETCH(dialog, key);
 		switch (key) {
 		case 'E':	/* Exit */
 		case 'e':
@@ -146,7 +147,7 @@ do_resize:
 
 			end_reached = 1;
 			/* point to last char in buf */
-			page = buf + strlen(buf);
+			page = &buf[LXD_STRLEN(buf)];
 			back_lines(boxh);
 			refresh_text_box(dialog, box, boxh, boxw,
 					 cur_y, cur_x);
@@ -321,13 +322,13 @@ static void print_page(WINDOW * win, int
 static void print_line(WINDOW * win, int row, int width)
 {
 	int y, x;
-	char *line;
+	LXD_CHAR *line;
 
 	line = get_line();
-	line += MIN(strlen(line), hscroll);	/* Scroll horizontally */
+	line += MIN(LXD_STRLEN(line), hscroll) * sizeof(LXD_CHAR);	/* Scroll horizontally */
 	wmove(win, row, 0);	/* move cursor to correct line */
 	waddch(win, ' ');
-	waddnstr(win, line, MIN(strlen(line), width - 2));
+	LXD_WADDNSTR(win, line, MIN(LXD_STRLEN(line), width - 2));
 
 	getyx(win, y, x);
 	/* Clear 'residue' of previous line */
@@ -337,9 +338,9 @@ static void print_line(WINDOW * win, int
 		for (i = 0; i < width - x; i++)
 			waddch(win, ' ');
 	}
-#else
+#else /* OLD_NCURSES */
 	wclrtoeol(win);
-#endif
+#endif /* OLD_NCURSES */
 }
 
 /*
@@ -347,10 +348,10 @@ static void print_line(WINDOW * win, int
  * 'page' should point to start of current line before calling, and will be
  * updated to point to start of next line.
  */
-static char *get_line(void)
+static LXD_CHAR *get_line(void)
 {
 	int i = 0;
-	static char line[MAX_LEN + 1];
+	static LXD_CHAR line[MAX_LEN + 1];
 
 	end_reached = 0;
 	while (*page != '\n') {
@@ -385,7 +386,7 @@ static void print_position(WINDOW * win)
 
 	wattrset(win, dlg.position_indicator.atr);
 	wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
-	percent = (page - buf) * 100 / strlen(buf);
+	percent = (page - buf) * 100 / LXD_STRLEN(buf);
 	wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
 	wprintw(win, "(%3d%%)", percent);
 }
scripts/kconfig/lxdialog/util.c renamed from scripts/kconfig/lxdialog/util.c~kconfig-i18n-04-lxdialog-multibyte +104 -20

240 lines not on this page · raw message

scripts/kconfig/lxdialog/yesno.c renamed from scripts/kconfig/lxdialog/yesno.c~kconfig-i18n-04-lxdialog-multibyte +3 -2
diff -puN scripts/kconfig/lxdialog/yesno.c~kconfig-i18n-04-lxdialog-multibyte scripts/kconfig/lxdialog/yesno.c
@@ -41,8 +41,9 @@ static void print_buttons(WINDOW * dialo
  */
 int dialog_yesno(const char *title, const char *prompt, int height, int width)
 {
-	int i, x, y, key = 0, button = 0;
+	int i, x, y, button = 0;
 	WINDOW *dialog;
+	LXD_KEYTYPE key = 0;
 
 do_resize:
 	if (getmaxy(stdscr) < (height + 4))
@@ -76,7 +77,7 @@ do_resize:
 	print_buttons(dialog, height, width, 0);
 
 	while (key != KEY_ESC) {
-		key = wgetch(dialog);
+		LXD_WGETCH(dialog, key);
 		switch (key) {
 		case 'Y':
 		case 'y':
scripts/kconfig/lxdialog/check-lxdialog.sh renamed from scripts/kconfig/lxdialog/check-lxdialog.sh~kconfig-i18n-04-lxdialog-multibyte +5 -1
diff -puN scripts/kconfig/lxdialog/check-lxdialog.sh~kconfig-i18n-04-lxdialog-multibyte scripts/kconfig/lxdialog/check-lxdialog.sh
@@ -19,7 +19,11 @@ ldflags()
 # Where is ncurses.h?
 ccflags()
 {
-	if [ -f /usr/include/ncurses/ncurses.h ]; then
+	if [ -f /usr/include/ncursesw/curses.h ]; then
+		echo '-DCURSES_LOC="<ncursesw/curses.h>" -DUSE_WIDE_CURSES'
+	elif [ -f /usr/include/ncursesw/ncurses.h ]; then
+		echo '-DCURSES_LOC="<ncursesw/ncurses.h>" -DUSE_WIDE_CURSES'
+	elif [ -f /usr/include/ncurses/ncurses.h ]; then
 		echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"'
 	elif [ -f /usr/include/ncurses/curses.h ]; then
 		echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"'

_

#1 lore raw
Quoted 2 lines · EGRY Gabor

UTF-8 support for lxdialog with wchar. The installed wide ncurses (ncursesw) is optional.

Building this on my 64 bit box with ncursesw support I saw several warnings. Adding the following to dialog.h decreased the number:
#ifdef USE_WIDE_CURSES
#define _XOPEN_SOURCE_EXTENDED
#endif

But it was not warning free.

In addition in your patch below you assume that
ncurses wide char support and wide char support follows each other. This assumption makes things overly complicated.

Can we assume we have wide char support everywhere today where we will support building Linux?
I am mostly concerned about sun, cygwin and MingW here...

If we can assume wide char support everywhere your patch will become simplerAnd adding wide char support should be a separate step.

I tried to take a look at varous source packages and they do not need this long list of redefinitions of the ncurses functions. Do we do something fundamentally different than for example dialog since this indirection is needed?

Sam