]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - ncurses/base/lib_addstr.c
ncurses 5.3
[ncurses.git] / ncurses / base / lib_addstr.c
index 59a3bae81c8cd91319b4dd5c2660521121ba01d8..d6f9345542e34427b3a4c061c418b0e0b8fc9934 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2001,2002 Free Software Foundation, Inc.              *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
 
 #include <curses.priv.h>
 
-MODULE_ID("$Id: lib_addstr.c,v 1.18 2000/07/29 16:42:41 tom Exp $")
+MODULE_ID("$Id: lib_addstr.c,v 1.34 2002/10/06 00:25:25 tom Exp $")
 
-int
-waddnstr(WINDOW *win, const char *const astr, int n)
+#if USE_WIDEC_SUPPORT
+#define CONV_DATA   mbstate_t state; wchar_t cached; int clen = 0
+#define CONV_INIT   memset (&state, '\0', sizeof (state)); cached = (wchar_t)WEOF
+#define NEXT_CHAR(s,ch, n)                                             \
+    {                                                                  \
+       int len, i = 0;                                                 \
+       memset(&ch, 0, sizeof(cchar_t));                                \
+       if (cached != (wchar_t) WEOF) {                                 \
+           ch.chars[i++] = cached;                                     \
+           cached = (wchar_t) WEOF;                                    \
+           n -= clen;                                                  \
+           s += clen;                                                  \
+       }                                                               \
+       for (; i < CCHARW_MAX && n > 0; ++i) {                          \
+           if ((len = mbrtowc(&ch.chars[i], s, n, &state)) < 0) {      \
+               code = ERR;                                             \
+               break;                                                  \
+           }                                                           \
+           if (i == 0 || wcwidth(ch.chars[i]) == 0) {                  \
+               n -= len;                                               \
+               s += len;                                               \
+           } else {                                                    \
+               cached = ch.chars[i];                                   \
+               clen = len;                                             \
+               ch.chars[i] = L'\0';                                    \
+               break;                                                  \
+           }                                                           \
+       }                                                               \
+       if (code == ERR)                                                \
+           break;                                                      \
+    }
+#else
+#define CONV_DATA
+#define CONV_INIT
+#define NEXT_CHAR(s,ch, n)                                             \
+    ch = *s++;                                                         \
+    --n
+#endif
+
+NCURSES_EXPORT(int)
+waddnstr(WINDOW *win, const char *astr, int n)
 {
     unsigned const char *str = (unsigned const char *) astr;
     int code = ERR;
+    CONV_DATA;
 
-    T((T_CALLED("waddnstr(%p,%s,%d)"), win, _nc_visbuf(astr), n));
+    T((T_CALLED("waddnstr(%p,%s,%d)"), win, _nc_visbufn(astr, n), n));
 
     if (win && (str != 0)) {
        TR(TRACE_VIRTPUT | TRACE_ATTRS, ("... current %s", _traceattr(win->_attrs)));
-       TR(TRACE_VIRTPUT, ("str is not null"));
        code = OK;
        if (n < 0)
            n = (int) strlen(astr);
 
-       while ((n-- > 0) && (*str != '\0')) {
+       TR(TRACE_VIRTPUT, ("str is not null, length = %d", n));
+       CONV_INIT;
+       while ((n > 0) && (*str != '\0')) {
+           NCURSES_CH_T ch;
            TR(TRACE_VIRTPUT, ("*str = %#x", *str));
-           if (_nc_waddch_nosync(win, (chtype) * str++) == ERR) {
+           NEXT_CHAR(str, ch, n);
+           if (_nc_waddch_nosync(win, ch) == ERR) {
                code = ERR;
                break;
            }
@@ -70,8 +113,8 @@ waddnstr(WINDOW *win, const char *const astr, int n)
     returnCode(code);
 }
 
-int
-waddchnstr(WINDOW *win, const chtype * const astr, int n)
+NCURSES_EXPORT(int)
+waddchnstr(WINDOW *win, const chtype * astr, int n)
 {
     NCURSES_SIZE_T y = win->_cury;
     NCURSES_SIZE_T x = win->_curx;
@@ -95,9 +138,116 @@ waddchnstr(WINDOW *win, const chtype * const astr, int n)
        returnCode(code);
 
     line = &(win->_line[y]);
+#if USE_WIDEC_SUPPORT
+    {
+       int i;
+       for (i = 0; i < n; ++i)
+           SetChar(line->text[i + x], ChCharOf(astr[i]), ChAttrOf(astr[i]));
+    }
+#else
     memcpy(line->text + x, astr, n * sizeof(*astr));
+#endif
     CHANGED_RANGE(line, x, x + n - 1);
 
     _nc_synchook(win);
     returnCode(code);
 }
+
+#if USE_WIDEC_SUPPORT
+
+int
+_nc_wchstrlen(const cchar_t * s)
+{
+    int result = 0;
+    while (CharOf(s[result]) != L'\0') {
+       result++;
+    }
+    return result;
+}
+
+NCURSES_EXPORT(int)
+wadd_wchnstr(WINDOW *win, const cchar_t * const astr, int n)
+{
+    NCURSES_SIZE_T y = win->_cury;
+    NCURSES_SIZE_T x = win->_curx;
+    int code = OK;
+    struct ldat *line;
+    int i, start, end;
+
+    T((T_CALLED("wadd_wchnstr(%p,%s,%d)"), win, _nc_viscbuf(astr, n), n));
+
+    if (!win)
+       returnCode(ERR);
+
+    if (n < 0) {
+       n = _nc_wchstrlen(astr);
+    }
+    if (n > win->_maxx - x + 1)
+       n = win->_maxx - x + 1;
+    if (n == 0)
+       returnCode(code);
+
+    line = &(win->_line[y]);
+    start = x;
+    end = x + n - 1;
+    if (isnac(line->text[x])) {
+       line->text[x - 1] = win->_nc_bkgd;
+       --start;
+    }
+    for (i = 0; i < n && x <= win->_maxx; ++i) {
+       line->text[x++] = astr[i];
+       if (wcwidth(CharOf(astr[i])) > 1) {
+           if (x <= win->_maxx)
+               AddAttr(line->text[x++], WA_NAC);
+           else
+               line->text[x - 1] = win->_nc_bkgd;
+       }
+    }
+    if (x <= win->_maxx && isnac(line->text[x])) {
+       line->text[x] = win->_nc_bkgd;
+       ++end;
+    }
+    CHANGED_RANGE(line, start, end);
+
+    _nc_synchook(win);
+    returnCode(code);
+}
+
+NCURSES_EXPORT(int)
+waddnwstr(WINDOW *win, const wchar_t * str, int n)
+{
+    int code = ERR;
+    int i;
+
+    T((T_CALLED("waddnwstr(%p,%s,%d)"), win, _nc_viswbufn(str,n), n));
+
+    if (win && (str != 0)) {
+       TR(TRACE_VIRTPUT | TRACE_ATTRS, ("... current %s", _traceattr(win->_attrs)));
+       code = OK;
+       if (n < 0)
+           n = (int) wcslen(str);
+
+       TR(TRACE_VIRTPUT, ("str is not null, length = %d", n));
+       while ((n-- > 0) && (*str != L('\0'))) {
+           NCURSES_CH_T ch;
+           TR(TRACE_VIRTPUT, ("*str[0] = %#lx", *str));
+           SetChar(ch, *str++, A_NORMAL);
+           i = 1;
+           while (i < CCHARW_MAX && n > 0 && (*str != L('\0'))
+                  && wcwidth(*str) == 0) {
+               TR(TRACE_VIRTPUT, ("*str[%d] = %#lx", i, *str));
+               ch.chars[i++] = *str++;
+               --n;
+           }
+           if (_nc_waddch_nosync(win, ch) == ERR) {
+               code = ERR;
+               break;
+           }
+       }
+       _nc_synchook(win);
+    }
+    TR(TRACE_VIRTPUT, ("waddnwstr returns %d", code));
+    returnCode(code);
+}
+
+#endif