From c040749e67f58c116dfe37bf55aa488ee7d58e8d Mon Sep 17 00:00:00 2001 From: William McBrine Date: Thu, 18 Jan 2007 01:42:31 +0000 Subject: [PATCH] For the string-handling functions -- the addstr(), getstr(), insstr() and instr() families -- X/Open says to support multibyte characters. This also means that the locale has meaning, that the native code page in Windows is still used with narrow functions, and that we actually save some code overall, especially in wgetnstr(). Now it works the same as ncurses... more or less. UTF-8 is still no good under Windows, though. Inspired by Thomas Dickey. --- pdcurses/addstr.c | 31 +++++++++++++++++------- pdcurses/getstr.c | 17 +++++++++++++- pdcurses/insstr.c | 60 +++++++++++++++++++++++++++++++++-------------- pdcurses/instr.c | 45 +++++++++++++++++++++++------------ 4 files changed, 110 insertions(+), 43 deletions(-) diff --git a/pdcurses/addstr.c b/pdcurses/addstr.c index 78d2cee8..55716c6b 100644 --- a/pdcurses/addstr.c +++ b/pdcurses/addstr.c @@ -12,8 +12,11 @@ ************************************************************************/ #include +#ifdef PDC_WIDE +# include +#endif -RCSID("$Id: addstr.c,v 1.36 2006/12/25 14:27:12 wmcbrine Exp $"); +RCSID("$Id: addstr.c,v 1.37 2007/01/18 01:42:31 wmcbrine Exp $"); /*man-start************************************************************** @@ -71,16 +74,27 @@ RCSID("$Id: addstr.c,v 1.36 2006/12/25 14:27:12 wmcbrine Exp $"); int waddnstr(WINDOW *win, const char *str, int n) { - int ic; + int i = 0; PDC_LOG(("waddnstr() - called: string=\"%s\" n %d \n", str, n)); if (!win || !str) return ERR; - for (ic = 0; *str && (ic < n || n < 0); ic++) + while (str[i] && (i < n || n < 0)) { - if (waddch(win, (unsigned char)(*str++)) == ERR) +#ifdef PDC_WIDE + wchar_t wch; + int retval = mbtowc(&wch, str + i, n >= 0 ? n - i : 6); + + if (retval <= 0) + return OK; + + i += retval; +#else + chtype wch = (unsigned char)(str[i++]); +#endif + if (waddch(win, wch) == ERR) return ERR; } @@ -153,19 +167,18 @@ int mvwaddnstr(WINDOW *win, int y, int x, const char *str, int n) #ifdef PDC_WIDE int waddnwstr(WINDOW *win, const wchar_t *wstr, int n) { - chtype cn; - int ic; + int i = 0; PDC_LOG(("waddnwstr() - called\n")); if (!win || !wstr) return ERR; - for (ic = 0; *wstr && (ic < n || n < 0); ic++) + while (wstr[i] && (i < n || n < 0)) { - cn = *wstr++; + chtype wch = wstr[i++]; - if (waddch(win, cn) == ERR) + if (waddch(win, wch) == ERR) return ERR; } diff --git a/pdcurses/getstr.c b/pdcurses/getstr.c index e81fcf45..872e9011 100644 --- a/pdcurses/getstr.c +++ b/pdcurses/getstr.c @@ -12,8 +12,11 @@ ************************************************************************/ #include +#ifdef PDC_WIDE +# include +#endif -RCSID("$Id: getstr.c,v 1.42 2006/12/25 14:27:12 wmcbrine Exp $"); +RCSID("$Id: getstr.c,v 1.43 2007/01/18 01:42:31 wmcbrine Exp $"); /*man-start************************************************************** @@ -84,6 +87,17 @@ RCSID("$Id: getstr.c,v 1.42 2006/12/25 14:27:12 wmcbrine Exp $"); int wgetnstr(WINDOW *win, char *str, int n) { +#ifdef PDC_WIDE + wchar_t wstr[MAXLINE + 1]; + + if (n < 0 || n > MAXLINE) + n = MAXLINE; + + if (wgetn_wstr(win, (wint_t *)wstr, n) == ERR) + return ERR; + + return wcstombs(str, wstr, n); +#else int ch, i, num, x, chars; char *p; bool stop, oldecho, oldcbreak, oldnodelay; @@ -215,6 +229,7 @@ int wgetnstr(WINDOW *win, char *str, int n) win->_nodelay = oldnodelay; return OK; +#endif } int getstr(char *str) diff --git a/pdcurses/insstr.c b/pdcurses/insstr.c index 4215aedf..24c403e0 100644 --- a/pdcurses/insstr.c +++ b/pdcurses/insstr.c @@ -12,9 +12,12 @@ ************************************************************************/ #include +#ifdef PDC_WIDE +# include +#endif #include -RCSID("$Id: insstr.c,v 1.37 2006/12/25 14:27:12 wmcbrine Exp $"); +RCSID("$Id: insstr.c,v 1.38 2007/01/18 01:42:31 wmcbrine Exp $"); /*man-start************************************************************** @@ -74,22 +77,45 @@ RCSID("$Id: insstr.c,v 1.37 2006/12/25 14:27:12 wmcbrine Exp $"); int winsnstr(WINDOW *win, const char *str, int n) { - int ic; +#ifdef PDC_WIDE + wchar_t wstr[513], *p; + int i; +#endif + int len; PDC_LOG(("winsnstr() - called: string=\"%s\" n %d \n", str, n)); if (!win || !str) return ERR; - ic = strlen(str); + len = strlen(str); - if (n > 0) - ic = ((ic < n) ? ic : n) - 1; - else - --ic; + if (n < 0 || n < len) + n = len; - for (; ic >= 0; ic--) - if (winsch(win, str[ic]) == ERR) +#ifdef PDC_WIDE + if (n > 512) + n = 512; + + p = wstr; + i = 0; + + while (str[i] && i < n) + { + int retval = mbtowc(p, str + i, n - i); + + if (retval <= 0) + break; + p++; + i += retval; + } + + while (p > wstr) + if (winsch(win, *--p) == ERR) +#else + while (n) + if (winsch(win, (unsigned char)(str[--n])) == ERR) +#endif return ERR; return OK; @@ -163,23 +189,21 @@ int mvwinsnstr(WINDOW *win, int y, int x, const char *str, int n) int wins_nwstr(WINDOW *win, const wchar_t *wstr, int n) { const wchar_t *p; - int ic; + int len; PDC_LOG(("wins_nwstr() - called\n")); if (!win || !wstr) return ERR; - for (ic = 0, p = wstr; *p; p++) - ic++; + for (len = 0, p = wstr; *p; p++) + len++; - if (n > 0) - ic = ((ic < n) ? ic : n) - 1; - else - --ic; + if (n < 0 || n < len) + n = len; - for (; ic >= 0; ic--) - if (winsch(win, wstr[ic]) == ERR) + while (n) + if (winsch(win, wstr[--n]) == ERR) return ERR; return OK; diff --git a/pdcurses/instr.c b/pdcurses/instr.c index d0f290d8..a002dd6a 100644 --- a/pdcurses/instr.c +++ b/pdcurses/instr.c @@ -12,8 +12,11 @@ ************************************************************************/ #include +#ifdef PDC_WIDE +# include +#endif -RCSID("$Id: instr.c,v 1.33 2006/12/25 14:27:12 wmcbrine Exp $"); +RCSID("$Id: instr.c,v 1.34 2007/01/18 01:42:31 wmcbrine Exp $"); /*man-start************************************************************** @@ -73,8 +76,19 @@ RCSID("$Id: instr.c,v 1.33 2006/12/25 14:27:12 wmcbrine Exp $"); int winnstr(WINDOW *win, char *str, int n) { +#ifdef PDC_WIDE + wchar_t wstr[513]; + + if (n < 0 || n > 512) + n = 512; + + if (winnwstr(win, wstr, n) == ERR) + return ERR; + + return wcstombs(str, wstr, n); +#else chtype tmp; - int oldy, oldx, imax, ic; + int oldy, oldx, imax, i; PDC_LOG(("winnstr() - called: n %d \n", n)); @@ -88,24 +102,25 @@ int winnstr(WINDOW *win, char *str, int n) if (n > 0) imax = ((imax < n) ? imax : n); - for (ic = 0; ic < imax; ic++) + for (i = 0; i < imax; i++) { - tmp = mvwinch(win, oldy, oldx + ic); + tmp = mvwinch(win, oldy, oldx + i); if (tmp == (chtype)ERR) { - str[ic] = '\0'; + str[i] = '\0'; return ERR; } - str[ic] = tmp & A_CHARTEXT; + str[i] = tmp & A_CHARTEXT; } - str[ic] = '\0'; + str[i] = '\0'; win->_curx = oldx; - return ic; + return i; +#endif } int instr(char *str) @@ -173,7 +188,7 @@ int mvwinnstr(WINDOW *win, int y, int x, char *str, int n) int winnwstr(WINDOW *win, wchar_t *wstr, int n) { chtype tmp; - int oldy, oldx, imax, ic; + int oldy, oldx, imax, i; PDC_LOG(("winnstr() - called: n %d \n", n)); @@ -187,24 +202,24 @@ int winnwstr(WINDOW *win, wchar_t *wstr, int n) if (n > 0) imax = ((imax < n) ? imax : n); - for (ic = 0; ic < imax; ic++) + for (i = 0; i < imax; i++) { - tmp = mvwinch(win, oldy, oldx + ic); + tmp = mvwinch(win, oldy, oldx + i); if (tmp == (chtype)ERR) { - wstr[ic] = L'\0'; + wstr[i] = L'\0'; return ERR; } - wstr[ic] = tmp & A_CHARTEXT; + wstr[i] = tmp & A_CHARTEXT; } - wstr[ic] = L'\0'; + wstr[i] = L'\0'; win->_curx = oldx; - return ic; + return i; } int inwstr(wchar_t *wstr)