- Subject: Re: [slang-users] Bug in SLutf8_skip_chars?
- From: "John E. Davis" <davis@xxxxxxxxxxxxx>
- Date: Sun, 19 Nov 2006 00:29:08 -0500
I wrote:
>using this function incorrectly. If either SLsmg_write_nstring or
>SLsmg_write_string is doing something wrong, then I will make every
>effort to correct the problem. But as far as SLutf8_skip_chars goes,
>it is ok and should not have been patched.
I did find a problem with SLsmg_write_nstring when used with
double-width characters. I encourage the debian slang maintainers to
back out the patch they added to SLutf8_skip_chars and add the patch
that is now in slang's svn repository to the SLsmg_write_nstring and
SLsmg_write_wrapped_string functions.
Here is the patch with repect to slang-2.0.7:
--- slang-2.0.7/src/slsmg.c 2006-11-04 10:57:31.000000000 -0500
+++ slsmg.c 2006-11-19 00:03:00.000000000 -0500
@@ -808,34 +808,6 @@
(unsigned char *)str + strlen (str));
}
-void SLsmg_write_nstring (char *str, unsigned int n)
-{
- unsigned int width;
- unsigned char *blank = (unsigned char *)" ";
- unsigned char *u = (unsigned char *)str;
-
- /* Avoid a problem if a user accidently passes a negative value */
- if ((int) n < 0)
- return;
-
- if (u == NULL) width = 0;
- else
- {
- unsigned char *umax;
-
- width = strlen ((char *)u);
- if (UTF8_Mode)
- umax = SLutf8_skip_chars (u, u+width, n, &width, 0);
- else
- {
- if (width > n) width = n;
- umax = u + width;
- }
- SLsmg_write_chars (u, umax);
- }
-
- while (width++ < n) SLsmg_write_chars (blank, blank+1);
-}
void SLsmg_write_wrapped_string (SLuchar_Type *u, int r, int c,
unsigned int dr, unsigned int dc,
@@ -844,15 +816,26 @@
int maxc = (int) dc;
unsigned char *p, *pmax;
int utf8_mode = UTF8_Mode;
+ unsigned char display_8bit = (unsigned char) SLsmg_Display_Eight_Bit;
+
+ if (utf8_mode)
+ display_8bit = 0xA0;
if ((dr == 0) || (dc == 0)) return;
+ if (u == NULL)
+ u = (unsigned char *)"";
+
p = u;
pmax = u + strlen ((char *)u);
dc = 0;
while (1)
{
+ SLwchar_Type wc;
+ unsigned int nconsumed;
unsigned char ch = *p;
+ unsigned int ddc;
+
if ((ch == 0) || (ch == '\n'))
{
int diff;
@@ -876,27 +859,82 @@
continue;
}
- if ((int) dc == maxc)
- {
- SLsmg_gotorc (r, c);
- SLsmg_write_chars (u, p);
- if (dr == 1) break;
+ /* If the width of the characters buffered so far extend to or beyond
+ * the width of the box, then write them out and goto the
+ * next line. Note that dc > maxc if the displayable width of
+ * the last character to be written is greater than the width
+ * of the box. This will be the case if (maxc<ddc) -- see below
+ */
+ if ((int) dc >= maxc)
+ goto write_chars_and_reset;
- r++;
- dc = 0;
- dr--;
- u = p;
+ nconsumed = 1;
+ if (ch < 0x80)
+ {
+ p++;
+ if ((ch >= 0x20) && (ch != 0x7F))
+ {
+ dc++;
+ continue;
+ }
+ /* Otherwise display as ^X */
+ dc += 2;
continue;
}
- dc++;
- if (utf8_mode)
- p = SLutf8_skip_chars (p, pmax, 1, NULL, 0);
+ nconsumed = 1;
+ if ((utf8_mode == 0)
+ || (NULL == SLutf8_decode (p, pmax, &wc, &nconsumed)))
+ {
+ if ((utf8_mode == 0)
+ && (display_8bit && (*p >= display_8bit)))
+ {
+ dc++;
+ p += nconsumed;
+ continue;
+ }
+
+ ddc = 4*nconsumed; /* <XX> */
+ }
+ else if (wc < (SLwchar_Type)display_8bit)
+ ddc = 4; /* displays as <XX> */
else
- p++;
+ ddc = SLwchar_wcwidth (wc);
+
+ dc += ddc;
+ if (((int)dc > maxc) && (maxc > (int)ddc))
+ {
+ dc -= ddc;
+ goto write_chars_and_reset;
+ }
+ p += nconsumed;
+ continue;
+
+ write_chars_and_reset:
+ SLsmg_gotorc (r, c);
+ SLsmg_write_chars (u, p);
+ while ((int)dc < maxc)
+ {
+ SLsmg_write_char (' ');
+ dc++;
+ }
+ if (dr == 1) break;
+ r++;
+ dc = 0;
+ dr--;
+ u = p;
}
}
+void SLsmg_write_nstring (char *str, unsigned int n)
+{
+ /* Avoid a problem if a user accidently passes a negative value */
+ if ((int) n < 0)
+ return;
+
+ SLsmg_write_wrapped_string ((unsigned char *)str, This_Row, This_Col, 1, n, 1);
+}
+
int SLsmg_Tab_Width = 8;
/* Minimum value for which eight bit char is displayed as is. */
_______________________________________________
To unsubscribe, visit http://jedsoft.org/slang/mailinglists.html
[2006 date index]
[2006 thread index]
[Thread Prev] [Thread Next]
[Date Prev] [Date Next]