[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#237675: patch for UTF-8 support



Package: dselect
Version: 1.10.20
Severity: normal
Tags: patch

  dselect does not support UTF-8 so I have prepared a patch (attached) to fix it.

What this patch do:
  - compile dselect with libncursesw5 instead of libncurses
  - calculate and use string widths in colums instead of sizes in bytes
    when needed (use standart C99 functions for this).
  - text wrapping code is too complicated for me to rewrite it, so i
    have used libtextwrap for that.

Problems:
  - textwrap hangs if string contains illegal symbols (in UTF-8), this
    is bug #237630. So debconf hangs while displaying description for
    some packages (doc-linux-text-pt -- is it a bug in this package
    too?).
  - text wrapping is different for some packages (manpages - is its'
    dsecription (indentation) correct?)
  - it does not display horisontal lines around section descriptions in
    linux terminal with KOI8-U encoding (but displays them in jfbterm
    and konsole and with UTF-8 encoding -- may be bug in libncursesw?)
  - some format strings was changed, requires new translations.

I have tested this patch with ru_RU and ja_JP locales. I have not found
other problems. Text with both languages looks same with different
encodings (KOI8-R and UTF-8 for Russian, EUC-JP and UTF-8 for Japanese).

-- System Information:
Debian Release: testing/unstable
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)
Kernel: Linux 2.4.25
Locale: LANG=uk_UA, LC_CTYPE=uk_UA

Versions of packages dselect depends on:
ii  libc6                       2.3.2.ds1-11 GNU C Library: Shared libraries an
ii  libgcc1                     1:3.3.3-2    GCC support library
ii  libncursesw5                5.4-2        Shared libraries for terminal hand
ii  libstdc++5                  1:3.3.3-2    The GNU Standard C++ Library v3
ii  libtextwrap1                0.1-1        text-wrapping library with i18n - 

-- no debconf information
diff -urN orig/dpkg-1.10.20/configure.in dpkg-1.10.20/configure.in
--- orig/dpkg-1.10.20/configure.in	2004-03-11 13:27:12.000000000 +0200
+++ dpkg-1.10.20/configure.in	2004-03-12 14:19:26.000000000 +0200
@@ -182,12 +182,18 @@
 
 # check for the proper curses library. This can be either
 # -lcurses or -lncurses, we need to check for either one.
-AC_CHECK_LIB(ncurses,initscr, CURSES_LIBS="-lncurses $CURSES_LIBS", AC_CHECK_LIB(curses,initscr, CURSES_LIBS="-lcurses $CURSES_LIBS"))
+AC_CHECK_LIB(ncursesw,initscr, CURSES_LIBS="-lncursesw $CURSES_LIBS", AC_CHECK_LIB(cursesw,initscr, CURSES_LIBS="-lcursesw $CURSES_LIBS"))
 if test "x$CURSES_LIBS" = "x"; then
  AC_MSG_WARN(no curses library found)
 fi
 AC_SUBST(CURSES_LIBS)
 
+AC_CHECK_LIB(textwrap,textwrap,TEXTWRAP_LIBS="-ltextwrap $TEXTWRAP_LIBS")
+if test "x$TEXTWRAP_LIBS" = "x"; then
+ AC_MSG_WARN(not textwrap library found)
+fi
+AC_SUBST(TEXTWRAP_LIBS)
+
 DPKG_CHECK_DEFINE(TIOCNOTTY,sys/ioctl.h)
 
 ZLIB_CFLAGS=
@@ -462,7 +468,7 @@
 
 ])
 
-AC_OUTPUT( po/Makefile.in 
+AC_OUTPUT( po/Makefile.in
 Makefile.conf
 Makefile
 include/Makefile
diff -urN orig/dpkg-1.10.20/debian/control dpkg-1.10.20/debian/control
--- orig/dpkg-1.10.20/debian/control	2004-03-08 20:11:11.000000000 +0200
+++ dpkg-1.10.20/debian/control	2004-03-12 14:08:42.000000000 +0200
@@ -6,7 +6,7 @@
 Origin: debian
 Bugs: debbugs://bugs.debian.org
 Standards-Version: 3.5.8
-Build-Depends: debiandoc-sgml, sgml-base (>= 1.9.1), sgmltools-lite, libncurses-dev, gettext (>= 0.12.1-3), zlib1g-dev (>= 1:1.1.3-19.1), autotools-dev
+Build-Depends: debiandoc-sgml, sgml-base (>= 1.9.1), sgmltools-lite, libncursesw5-dev, gettext (>= 0.12.1-3), zlib1g-dev (>= 1:1.1.3-19.1), autotools-dev, libtextwrap-dev
 
 Package: dpkg
 Architecture: any
diff -urN orig/dpkg-1.10.20/dselect/baselist.cc dpkg-1.10.20/dselect/baselist.cc
--- orig/dpkg-1.10.20/dselect/baselist.cc	2003-10-25 23:03:21.000000000 +0300
+++ dpkg-1.10.20/dselect/baselist.cc	2004-03-12 18:59:52.000000000 +0200
@@ -30,6 +30,7 @@
 #include <unistd.h>
 #include <sys/ioctl.h>
 #include <sys/termios.h>
+#include <textwrap.h>
 
 extern "C" {
 #include <dpkg.h>
@@ -318,54 +319,47 @@
   }
 }
 
-void baselist::wordwrapinfo(int offset, const char *m) {
-  int usemax= xmax-5;
-  if (debug) fprintf(debug,"baselist[%p]::wordwrapinfo(%d, `%s')\n",this,offset,m);
-  int wrapping=0;
+static char *reformat(int offset, const char *s)
+{
+  int pos = 0;
+  /* if offset == 0:
+   *   all '^.\n -> '\n\n'
+   *   all '^\n' -> '\n\n'
+   *   so we may need 2 times more space
+   * if offset > 1
+   *   we need le amount of space
+   */
+  char *news = (char *)malloc(2*strlen(s)+1);
+  const char *p = s;
   for (;;) {
-    int offleft=offset; while (*m == ' ' && offleft>0) { m++; offleft--; }
-    const char *p= strchr(m,'\n');
-    int l= p ? (int)(p-m) : strlen(m);
-    while (l && isspace(m[l-1])) l--;
-    if (!l || *m == '.' && l == 1) {
-      if (wrapping) waddch(infopad,'\n');
-      waddch(infopad,'\n');
-      wrapping= 0;
-    } else if (*m == ' ' || usemax < 10) {
-      if (wrapping) waddch(infopad,'\n');
-      waddnstr(infopad, m, l);
-      waddch(infopad,'\n'); wrapping= 0;
-    } else {
-      int x,y;
-      if (wrapping) {
-        getyx(infopad, y,x);
-        if (x+1 >= usemax) {
-          waddch(infopad,'\n');
-        } else {
-          waddch(infopad,' ');
-        }
-      }
-      for (;;) {
-        getyx(infopad, y,x);
-        int dosend= usemax-x;
-        if (l <= dosend) {
-          dosend=l;
-        } else {
-          int i=dosend;
-          while (i > 0 && m[i] != ' ') i--;
-          if (i > 0 || x > 0) dosend=i;
-        }
-        if (dosend) waddnstr(infopad, m, dosend);
-        while (dosend < l && m[dosend] == ' ') dosend++;
-        l-= dosend; m+= dosend;
-        if (l <= 0) break;
-        waddch(infopad,'\n');
-      }
-      wrapping= 1;
+    int offleft = offset;
+    if (*p == ' ' && offleft > 0) {p++; offleft--;};
+    const char *e = strchr(p, '\n');
+    int l = e ? e-p : strlen(p);
+    if ((l == 1 && *p == '.') || l==0 ) { news[pos++] = '\n'; news[pos++] = '\n'; }
+    else { 
+      if (p > s && *p == ' ')
+        news[pos-1] = '\n';
+      memcpy(news+pos, p, l); pos += l; news[pos++]=' ';
     }
-    if (!p) break;
-    m= ++p;
+    if (!e) break;
+    p = ++e;
   }
+  news[pos] = 0;
+  return news;
+}
+
+void baselist::wordwrapinfo(int offset, const char *s) {
+  int usemax= xmax-5;
+  if (debug) fprintf(debug,"baselist[%p]::wordwrapinfo(%d, `%s')\n",this,offset,s);
+  textwrap_t prop;
+  textwrap_init(&prop);
+  textwrap_columns(&prop, usemax);
+  char *rs = reformat(offset, s);
+  char *os = textwrap(&prop, rs);
+  waddstr(infopad, os);
+  free(os);
+  free(rs);
   if (debug) fprintf(debug,"baselist[%p]::wordwrapinfo() done\n",this);
 }
 
diff -urN orig/dpkg-1.10.20/dselect/dselect.h dpkg-1.10.20/dselect/dselect.h
--- orig/dpkg-1.10.20/dselect/dselect.h	2002-05-06 19:18:16.000000000 +0300
+++ dpkg-1.10.20/dselect/dselect.h	2004-03-12 17:41:44.000000000 +0200
@@ -28,7 +28,7 @@
 
 #include <signal.h>
 #undef ERR
-#include <curses.h>
+#include <ncursesw/curses.h>
 
 struct helpmenuentry {
   char key;
@@ -183,5 +183,7 @@
 
 urqresult falliblesubprocess(const char *exepath, const char *name,
                              const char *const *args);
+extern int addstrwidth(WINDOW *, const char *, int);
+extern void helper_printleft(WINDOW*, const char *, int);
 
 #endif /* DSELECT_H */
diff -urN orig/dpkg-1.10.20/dselect/main.cc dpkg-1.10.20/dselect/main.cc
--- orig/dpkg-1.10.20/dselect/main.cc	2003-10-25 23:03:21.000000000 +0300
+++ dpkg-1.10.20/dselect/main.cc	2004-03-12 18:28:40.000000000 +0200
@@ -35,8 +35,8 @@
 #include <limits.h>
 #include <ctype.h>
 #include <assert.h>
-
-#include <term.h>
+#include <wchar.h>
+#include <ncursesw/term.h>
 
 extern "C" {
 #include <dpkg.h>
@@ -164,6 +164,38 @@
   if (fprintf(stdout,gettext(copyrightstring), DPKG_VERSION_ARCH) == EOF) werr("stdout");
 }
 
+/*
+ * print multibyte string with max width
+ */
+int addstrwidth(WINDOW *win, const char *s, int w) {
+  int prw = 0;
+  mbstate_t state;
+  int len = strlen(s);
+  const char *p = s;
+  
+  memset(&state, 0, sizeof(state));
+  for (;;) {
+    int ret, cw;
+    wchar_t sym;
+    ret = mbrtowc(&sym, p, len, &state);
+    if (ret <= 0) break;
+    len -= ret;
+    cw = wcwidth(sym);
+    if (cw < 0) break;
+    prw += cw;
+    if (prw > w) {
+      prw -= cw;
+      break;
+    }
+    if (win)
+      waddnwstr(win,&sym,1);
+    else 
+      addnwstr(&sym,1);
+    p += ret;
+  }
+  return prw;
+}
+
 static void usage(void) {
   int i;
   if (!fputs(
@@ -348,16 +380,22 @@
 void dme(int i, int so) {
   char buf[120];
   const menuentry *me= &menuentries[i];
-  sprintf(buf," %c %d. %-11.11s %-80.80s ",
-          so ? '*' : ' ', i,
-          gettext(me->option),
-          gettext(me->menuent));
-  
+  snprintf(buf, sizeof(buf)/sizeof(*buf), " %c %d. ",
+          so ? '*' : ' ', i);
   int y,x;
   getmaxyx(stdscr,y,x);
+  int rwidth = x-1; 
 
+  move(i+2, 0);
   attrset(so ? A_REVERSE : A_NORMAL);
-  mvaddnstr(i+2,0, buf,x-1);
+  int ret = addstrwidth(NULL, buf, rwidth);
+  rwidth -= ret;
+  if (rwidth > 0) {
+    helper_printleft(NULL, gettext(me->option), rwidth < 11? rwidth : 11);
+    if (rwidth > 11) addch(' ');
+    rwidth -= 12;
+    if (rwidth > 0) helper_printleft(NULL, gettext(me->menuent), rwidth);
+  }
   attrset(A_NORMAL);
 }
 
@@ -374,7 +412,8 @@
   clear();
   attrset(A_BOLD);
   sprintf(buf,gettext(programdesc),DSELECT);
-  mvaddnstr(0,0,buf,x-1);
+  move(0,0);
+  addstrwidth(NULL,buf,x-1);
 
   attrset(A_NORMAL);
   const struct menuentry *mep; int i;
diff -urN orig/dpkg-1.10.20/dselect/Makefile.in dpkg-1.10.20/dselect/Makefile.in
--- orig/dpkg-1.10.20/dselect/Makefile.in	2003-09-15 01:28:18.000000000 +0300
+++ dpkg-1.10.20/dselect/Makefile.in	2004-03-12 18:15:43.000000000 +0200
@@ -5,7 +5,6 @@
 
 default: all
 include ../Makefile.conf
-
 CXX_SOURCES	= basecmds.cc baselist.cc basetop.cc bindings.cc curkeys.cc \
 		  main.cc methkeys.cc methlist.cc method.cc methparse.cc \
 		  pkgcmds.cc pkgdepcon.cc pkgdisplay.cc pkginfo.cc pkgkeys.cc \
@@ -47,13 +46,13 @@
 	done
 
 dselect: $(OBJECTS) ../lib/libdpkg.a
-	$(CXX) $(LDFLAGS) -o $@ $(OBJECTS) $(CURSES_LIBS) $(LIBS) $(NLS_LIBS)
+	$(CXX) $(LDFLAGS) -o $@ $(OBJECTS) $(TEXTWRAP_LIBS) $(CURSES_LIBS) $(LIBS) $(NLS_LIBS)
 
 basecmds.o: helpmsgs.h
 curkeys.o: curkeys.h
 
 curkeys.h: keyoverride $(srcdir)/mkcurkeys.pl
-	cursesfile=`echo '#include <curses.h>' | \
+	cursesfile=`echo '#include <ncursesw/curses.h>' | \
 		 $(CC) -E - | grep 'curses.h' | head -n 1 | \
 		 $(SED) -e 's/^[^"]*"//; s/".*$$//'`; \
 	if [ "$$cursesfile" = "" ]; then echo "can't find curses file"; exit 1; fi; \
diff -urN orig/dpkg-1.10.20/dselect/methlist.cc dpkg-1.10.20/dselect/methlist.cc
--- orig/dpkg-1.10.20/dselect/methlist.cc	2004-03-08 19:05:11.000000000 +0200
+++ dpkg-1.10.20/dselect/methlist.cc	2004-03-12 17:34:31.000000000 +0200
@@ -75,7 +75,8 @@
 void methodlist::redrawtitle() {
   if (title_height) {
     mywerase(titlewin);
-    mvwaddnstr(titlewin,0,0,_("dselect - list of access methods"),xmax);
+    wmove(titlewin,0,0);
+    addstrwidth(titlewin, _("dselect - list of access methods"),xmax);
     wnoutrefresh(titlewin);
   }
 }
@@ -98,8 +99,9 @@
   mvwaddch(listpad,index,0,
            table[index] == coption ? '*' : ' ');
   wattrset(listpad, selected ? listsel_attr : list_attr);
-  mvwprintw(listpad,index,name_column-1, " %-*.*s ",
-            name_width, name_width, table[index]->name);
+  wmove(listpad,index,name_column-1);
+  helper_printleft(listpad,table[index]->name, name_width);
+  waddch(listpad, ' ');
   
   i= description_width;
   p= table[index]->summary ? table[index]->summary : "";
@@ -118,8 +120,10 @@
     wattrset(colheadspad,colheads_attr);
     mywerase(colheadspad);
     mvwaddstr(colheadspad,0,0, "  ");
-    mvwaddnstr(colheadspad,0,name_column, _("Abbrev."), name_width);
-    mvwaddnstr(colheadspad,0,description_column, _("Description"), description_width);
+    wmove(colheadspad, 0, name_column);
+    addstrwidth(colheadspad,_("Abbrev."),name_width);
+    wmove(colheadspad,0,description_column);
+    addstrwidth(colheadspad, _("Description"),description_width);
   }
   refreshcolheads();
 }
diff -urN orig/dpkg-1.10.20/dselect/pkgdisplay.cc dpkg-1.10.20/dselect/pkgdisplay.cc
--- orig/dpkg-1.10.20/dselect/pkgdisplay.cc	2004-03-08 19:05:11.000000000 +0200
+++ dpkg-1.10.20/dselect/pkgdisplay.cc	2004-03-12 13:59:28.000000000 +0200
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <assert.h>
+#include <wchar.h>
 
 extern "C" {
 #include <dpkg.h>
@@ -119,12 +120,38 @@
                          N_("Removed"),
                          N_("Purged") };
 
-static int maximumstring(const char *const *array) {
+int stringwidthlen(const char *s, int len) {
+  mbstate_t state;
+  int n, w = 0;
+  wchar_t wc;
+  int ret;
+  
+  memset(&state, 0, sizeof(state));
+  while (len>0) {
+    ret = mbrtowc(&wc, s, len, &state);
+    if (ret <= 0)
+      break;
+    len -= ret;
+    s += ret;
+    n = wcwidth(wc);
+    if (n == -1) break;
+    w += n;
+  }
+  return w;
+}
+
+int stringwidth(const char *s) {
+  return stringwidthlen(s, strlen(s));
+}
+
+static int maximumstringwidth(const char *const *array) {
   int maxlen= 0;
   while (*array) {
-    int l= strlen(gettext(*array));
+    const char *s = gettext(*array);
+    int l= stringwidth(s);
     const char *p= strchr(*array, '(');
-    if (p && p > *array && *--p == ' ') l= p - *array;
+    if (p && p > *array && *--p == ' ') l = p - *array;
+    l = stringwidthlen(*array, l);
     if (l > maxlen) maxlen= l;
     array++;
   }
@@ -136,8 +163,8 @@
 
   if (verbose) {
     status_hold_width= 9;
-    status_status_width= maximumstring(statusstrings);
-    status_want_width= maximumstring(wantstrings);
+    status_status_width= maximumstringwidth(statusstrings);
+    status_want_width= maximumstringwidth(wantstrings);
     status_width= status_hold_width+status_status_width+status_want_width*2+3;
     priority_width= 8;
     package_width= 16;
@@ -196,7 +223,8 @@
   
   if (title_height) {
     mywerase(titlewin);
-    mvwaddnstr(titlewin,0,0,
+    wmove(titlewin, 0, 0);
+    addstrwidth(titlewin,
                recursive ?  _("dselect - recursive package listing") :
                !readwrite ? _("dselect - inspection of package states") :
                             _("dselect - main package listing"),
@@ -207,13 +235,13 @@
       case so_section:
         switch (statsortorder) {
         case sso_unsorted:
-          waddnstr(titlewin, _(" (by section)"), xmax-x);
+          addstrwidth(titlewin, _(" (by section)"), xmax-x);
           break;
         case sso_avail:
-          waddnstr(titlewin, _(" (avail., section)"), xmax-x);
+          addstrwidth(titlewin, _(" (avail., section)"), xmax-x);
           break;
         case sso_state:
-          waddnstr(titlewin, _(" (status, section)"), xmax-x);
+          addstrwidth(titlewin, _(" (status, section)"), xmax-x);
           break;
         default:
           internerr("bad statsort in redrawtitle/so_section");
@@ -222,13 +250,13 @@
       case so_priority:
         switch (statsortorder) {
         case sso_unsorted:
-          waddnstr(titlewin, _(" (by priority)"), xmax-x);
+          addstrwidth(titlewin, _(" (by priority)"), xmax-x);
           break;
         case sso_avail:
-          waddnstr(titlewin, _(" (avail., priority)"), xmax-x);
+          addstrwidth(titlewin, _(" (avail., priority)"), xmax-x);
           break;
         case sso_state:
-          waddnstr(titlewin, _(" (status, priority)"), xmax-x);
+          addstrwidth(titlewin, _(" (status, priority)"), xmax-x);
           break;
         default:
           internerr("bad statsort in redrawtitle/so_priority");
@@ -237,19 +265,19 @@
       case so_alpha:
         switch (statsortorder) {
         case sso_unsorted:
-          waddnstr(titlewin, _(" (alphabetically)"), xmax-x);
+          addstrwidth(titlewin, _(" (alphabetically)"), xmax-x);
           break;
         case sso_avail:
-          waddnstr(titlewin, _(" (by availability)"), xmax-x);
+          addstrwidth(titlewin, _(" (by availability)"), xmax-x);
           break;
         case sso_state:
-          waddnstr(titlewin, _(" (by status)"), xmax-x);
+          addstrwidth(titlewin, _(" (by status)"), xmax-x);
           break;
         default:
           internerr("bad statsort in redrawtitle/so_priority");
         }
         break;
-        waddnstr(titlewin, _(" (alphabetically)"), xmax-x);
+        addstrwidth(titlewin, _(" (alphabetically)"), xmax-x);
         break;
       case so_unsorted:
         break;
@@ -261,7 +289,7 @@
                                                  : _(" mark:+/=/- verbose:v help:?"))
                                       : (verbose ? _(" terse:v help:?")
                                                  : _(" verbose:v help:?"));
-    int l= strlen(helpstring);
+    int l= stringwidth(helpstring);
     getyx(titlewin,y,x);
     if (xmax-l > 0) {
       mvwaddstr(titlewin,0,xmax-l, helpstring);
diff -urN orig/dpkg-1.10.20/dselect/pkglist.h dpkg-1.10.20/dselect/pkglist.h
--- orig/dpkg-1.10.20/dselect/pkglist.h	2002-05-06 19:18:16.000000000 +0300
+++ dpkg-1.10.20/dselect/pkglist.h	2004-03-12 17:46:13.000000000 +0200
@@ -233,4 +233,8 @@
 
 extern modstatdb_rw readwrite;
 
+/* helper functions */
+extern int stringwidth(const char *);
+extern int stringwidthlen(const char *, int);
+
 #endif /* PKGLIST_H */
diff -urN orig/dpkg-1.10.20/dselect/pkgtop.cc dpkg-1.10.20/dselect/pkgtop.cc
--- orig/dpkg-1.10.20/dselect/pkgtop.cc	2003-10-25 23:03:21.000000000 +0300
+++ dpkg-1.10.20/dselect/pkgtop.cc	2004-03-12 18:25:10.000000000 +0200
@@ -34,6 +34,17 @@
 #include "dselect.h"
 #include "pkglist.h"
 
+void helper_printleft(WINDOW *win, const char *s, int w) {
+  int i;
+  int width = addstrwidth(win, s, w);
+  int spcs = w - width;
+  for (i = 0; i < spcs; i++)
+    if (win)
+      waddch(win, ' ');
+    else
+      addch(' ');
+};
+
 const char *pkgprioritystring(const struct pkginfo *pkg) {
   if (pkg->priority == pkginfo::pri_unset) {
     return 0;
@@ -106,16 +117,18 @@
 
   const char *section= table[cursorline]->pkg->section;
   const char *priority= pkgprioritystring(table[cursorline]->pkg);
-  char *buf= new char[500+
-                      greaterint((table[cursorline]->pkg->name
+  int buflen = 500+ greaterint((table[cursorline]->pkg->name
                                   ? strlen(table[cursorline]->pkg->name) : 0),
                                  (section ? strlen(section) : 0) +
-                                 (priority ? strlen(priority) : 0))];
+                                 (priority ? strlen(priority) : 0));
     
   if (table[cursorline]->pkg->name) {
-    sprintf(buf,
-            _("%-*s %s%s%s;  %s (was: %s).  %s"),
-            package_width,
+    const char *format = _("%s %s%s%s;  %s (was: %s).  %s");
+    char *buf = new char[buflen];
+    buf[0] = 0;
+    snprintf(buf, buflen,
+            format,
+            /*package_width,*/
             table[cursorline]->pkg->name,
             gettext(statusstrings[table[cursorline]->pkg->status]),
             ((eflagstrings[table[cursorline]->pkg->eflag][0]==' ') &&
@@ -124,14 +137,18 @@
             gettext(wantstrings[table[cursorline]->selected]),
             gettext(wantstrings[table[cursorline]->original]),
             priority);
+    wmove(thisstatepad,0,0);
+    addstrwidth(thisstatepad, buf, total_width);
+    delete [] buf;
+    delete [] format;
   } else {
+    char *buf =new char[buflen];
     describemany(buf,priority,section,table[cursorline]->pkg->clientdata);
+    mvwaddnstr(thisstatepad,0,0, buf, total_width);
+    delete[] buf;
   }
-  mvwaddnstr(thisstatepad,0,0, buf, total_width);
   pnoutrefresh(thisstatepad, 0,leftofscreen, thisstate_row,0,
                thisstate_row, lesserint(total_width - 1, xmax - 1));
-
-  delete[] buf;
 }
 
 void packagelist::redraw1itemsel(int index, int selected) {
@@ -141,33 +158,30 @@
   const struct pkginfoperfile *info= &pkg->available;
 
   wattrset(listpad, selected ? listsel_attr : list_attr);
-
   if (pkg->name) {
 
     if (verbose) {
-
-      mvwprintw(listpad,index,0, "%-*.*s ",
-                status_hold_width, status_hold_width,
-                gettext(eflagstrings[pkg->eflag]));
-      wprintw(listpad, "%-*.*s ",
-              status_status_width, status_status_width,
-              gettext(statusstrings[pkg->status]));
-      wprintw(listpad, "%-*.*s ",
-              status_want_width, status_want_width,
+      wmove(listpad,index,0);
+      helper_printleft(listpad,gettext(eflagstrings[pkg->eflag]),
+		      status_hold_width);
+      waddch(listpad, ' ');
+      helper_printleft(listpad,gettext(statusstrings[pkg->status]),
+		      status_status_width);
+      waddch(listpad, ' ');
+      helper_printleft(listpad,
               /* fixme: keep this ? */
               /*table[index]->original == table[index]->selected ? "(same)"
-              : */gettext(wantstrings[table[index]->original]));
+              : */gettext(wantstrings[table[index]->original]),status_want_width);
+      waddch(listpad, ' ');
       wattrset(listpad, selected ? selstatesel_attr : selstate_attr);
-      wprintw(listpad, "%-*.*s",
-              status_want_width, status_want_width,
-              gettext(wantstrings[table[index]->selected]));
+      helper_printleft(listpad,gettext(wantstrings[table[index]->selected]),
+		      status_want_width);
       wattrset(listpad, selected ? listsel_attr : list_attr);
       waddch(listpad, ' ');
-  
-      mvwprintw(listpad,index,priority_column-1, " %-*.*s",
-                priority_width, priority_width,
-                pkg->priority == pkginfo::pri_other ? pkg->otherpriority :
-                gettext(prioritystrings[pkg->priority]));
+      wmove(listpad,index,priority_column-1); 
+      waddch(listpad, ' ');
+      helper_printleft(listpad,pkg->priority == pkginfo::pri_other ? pkg->otherpriority :
+                gettext(prioritystrings[pkg->priority]),priority_width);
 
     } else {
 
@@ -189,33 +203,39 @@
         for (i=priority_width, p=pkg->otherpriority;
              i > 0 && *p;
              i--, p++)
+	  /* FIXME priority is ASCII string */
           waddch(listpad, tolower(*p));
         while (i-- > 0) waddch(listpad,' ');
       } else {
-        wprintw(listpad, "%-*.*s", priority_width, priority_width,
-                gettext(priorityabbrevs[pkg->priority]));
+        helper_printleft(listpad,gettext(priorityabbrevs[pkg->priority]),
+			priority_width);
       }
 
     }
 
-    mvwprintw(listpad,index,section_column-1, " %-*.*s",
-              section_width, section_width,
-              pkg->section ? pkg->section : "?");
-  
-    mvwprintw(listpad,index,package_column-1, " %-*.*s ",
-              package_width, package_width, pkg->name);
-
-    if (versioninstalled_width)
-      mvwprintw(listpad,index,versioninstalled_column, "%-*.*s ",
-                versioninstalled_width, versioninstalled_width,
-                versiondescribe(&pkg->installed.version,vdew_never));
+    wmove(listpad, index, section_column-1);
+    waddch(listpad, ' ');
+    helper_printleft(listpad,pkg->section ? pkg->section : "?", section_width);
+    wmove(listpad, index, package_column-1);
+    waddch(listpad, ' ');
+    helper_printleft(listpad,pkg->name, package_width);
+    waddch(listpad, ' ');
+
+    if (versioninstalled_width) {
+      wmove(listpad,index,versioninstalled_column);
+      helper_printleft(listpad,
+		      versiondescribe(&pkg->installed.version,vdew_never),
+		      versioninstalled_width);
+      waddch(listpad, ' '); 
+    }
     if (versionavailable_width) {
       if (informativeversion(&pkg->available.version) &&
           versioncompare(&pkg->available.version,&pkg->installed.version) > 0)
         wattrset(listpad, selected ? selstatesel_attr : selstate_attr);
-      mvwprintw(listpad,index,versionavailable_column, "%-*.*s",
-                versionavailable_width, versionavailable_width,
-                versiondescribe(&pkg->available.version,vdew_never));
+      wmove(listpad,index,versionavailable_column);
+      helper_printleft(listpad,
+		      versiondescribe(&pkg->available.version,vdew_never),
+		      versionavailable_width);
       wattrset(listpad, selected ? listsel_attr : list_attr);
       waddch(listpad,' ');
     }
@@ -255,6 +275,7 @@
   }
 
   while (i>0) { waddch(listpad,' '); i--; }
+  
 }
 
 void packagelist::redrawcolheads() {
diff -urN orig/dpkg-1.10.20/Makefile.conf.in dpkg-1.10.20/Makefile.conf.in
--- orig/dpkg-1.10.20/Makefile.conf.in	2003-09-14 02:43:49.000000000 +0300
+++ dpkg-1.10.20/Makefile.conf.in	2004-03-12 14:40:50.000000000 +0200
@@ -74,6 +74,7 @@
 SSD_LIBS		= @SSD_LIBS@
 
 CURSES_LIBS		= @CURSES_LIBS@
+TEXTWRAP_LIBS		= @TEXTWRAP_LIBS@
 
 ZLIB_CFLAGS		= @ZLIB_CFLAGS@
 ZLIB_LIBS		= @ZLIB_LIBS@

Reply to: