* grub-core/gnulib/argp-fmtstream.c (__argp_get_display_len):
New function. (add_length): Likewise. (__argp_fmtstream_update): Handle strings with non-ASCII chars. * grub-core/gnulib/argp-fmtstream.h (__argp_get_display_len): New proto. * grub-core/gnulib/argp-help.c (argp_args_usage): Use __argp_get_display_len.
This commit is contained in:
parent
7e8fac16ad
commit
585031cb92
4 changed files with 82 additions and 14 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2012-02-25 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/gnulib/argp-fmtstream.c (__argp_get_display_len):
|
||||||
|
New function.
|
||||||
|
(add_length): Likewise.
|
||||||
|
(__argp_fmtstream_update): Handle strings with non-ASCII chars.
|
||||||
|
* grub-core/gnulib/argp-fmtstream.h (__argp_get_display_len): New
|
||||||
|
proto.
|
||||||
|
* grub-core/gnulib/argp-help.c (argp_args_usage): Use
|
||||||
|
__argp_get_display_len.
|
||||||
|
|
||||||
2012-02-25 Vladimir Serbinenko <phcoder@gmail.com>
|
2012-02-25 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
$"..." support in scripts.
|
$"..." support in scripts.
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
#include "argp-fmtstream.h"
|
#include "argp-fmtstream.h"
|
||||||
#include "argp-namefrob.h"
|
#include "argp-namefrob.h"
|
||||||
|
@ -116,6 +117,54 @@ weak_alias (__argp_fmtstream_free, argp_fmtstream_free)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
size_t
|
||||||
|
__argp_get_display_len (char *beg, char *end)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
size_t r = 0;
|
||||||
|
mbstate_t ps;
|
||||||
|
|
||||||
|
memset (&ps, 0, sizeof (ps));
|
||||||
|
|
||||||
|
for (ptr = beg; ptr < end; )
|
||||||
|
{
|
||||||
|
wchar_t wc;
|
||||||
|
size_t s;
|
||||||
|
|
||||||
|
s = mbrtowc (&wc, ptr, end - ptr, &ps);
|
||||||
|
if (s == (size_t) -1)
|
||||||
|
break;
|
||||||
|
r += wcwidth (wc);
|
||||||
|
ptr += s;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char *
|
||||||
|
add_length (char *ptr, char *end, size_t l)
|
||||||
|
{
|
||||||
|
mbstate_t ps;
|
||||||
|
|
||||||
|
memset (&ps, 0, sizeof (ps));
|
||||||
|
|
||||||
|
while (ptr < end)
|
||||||
|
{
|
||||||
|
wchar_t wc;
|
||||||
|
size_t s, k;
|
||||||
|
|
||||||
|
s = mbrtowc (&wc, ptr, end - ptr, &ps);
|
||||||
|
if (s == (size_t) -1)
|
||||||
|
break;
|
||||||
|
k = wcwidth (wc);
|
||||||
|
if (k >= l)
|
||||||
|
break;
|
||||||
|
l -= k;
|
||||||
|
ptr += s;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
/* Process FS's buffer so that line wrapping is done from POINT_OFFS to the
|
/* Process FS's buffer so that line wrapping is done from POINT_OFFS to the
|
||||||
end of its buffer. This code is mostly from glibc stdio/linewrap.c. */
|
end of its buffer. This code is mostly from glibc stdio/linewrap.c. */
|
||||||
void
|
void
|
||||||
|
@ -168,14 +217,15 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
|
||||||
|
|
||||||
if (!nl)
|
if (!nl)
|
||||||
{
|
{
|
||||||
|
size_t display_len = __argp_get_display_len (buf, fs->p);
|
||||||
/* The buffer ends in a partial line. */
|
/* The buffer ends in a partial line. */
|
||||||
|
|
||||||
if (fs->point_col + len < fs->rmargin)
|
if (fs->point_col + display_len < fs->rmargin)
|
||||||
{
|
{
|
||||||
/* The remaining buffer text is a partial line and fits
|
/* The remaining buffer text is a partial line and fits
|
||||||
within the maximum line width. Advance point for the
|
within the maximum line width. Advance point for the
|
||||||
characters to be written and stop scanning. */
|
characters to be written and stop scanning. */
|
||||||
fs->point_col += len;
|
fs->point_col += display_len;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -183,14 +233,18 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
|
||||||
the end of the buffer. */
|
the end of the buffer. */
|
||||||
nl = fs->p;
|
nl = fs->p;
|
||||||
}
|
}
|
||||||
else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin)
|
else
|
||||||
{
|
{
|
||||||
/* The buffer contains a full line that fits within the maximum
|
size_t display_len = __argp_get_display_len (buf, nl);
|
||||||
line width. Reset point and scan the next line. */
|
if (display_len < (ssize_t) fs->rmargin)
|
||||||
fs->point_col = 0;
|
{
|
||||||
buf = nl + 1;
|
/* The buffer contains a full line that fits within the maximum
|
||||||
continue;
|
line width. Reset point and scan the next line. */
|
||||||
}
|
fs->point_col = 0;
|
||||||
|
buf = nl + 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* This line is too long. */
|
/* This line is too long. */
|
||||||
r = fs->rmargin - 1;
|
r = fs->rmargin - 1;
|
||||||
|
@ -226,7 +280,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
|
||||||
char *p, *nextline;
|
char *p, *nextline;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
p = buf + (r + 1 - fs->point_col);
|
p = add_length (buf, fs->p, (r + 1 - fs->point_col));
|
||||||
while (p >= buf && !isblank ((unsigned char) *p))
|
while (p >= buf && !isblank ((unsigned char) *p))
|
||||||
--p;
|
--p;
|
||||||
nextline = p + 1; /* This will begin the next line. */
|
nextline = p + 1; /* This will begin the next line. */
|
||||||
|
@ -244,7 +298,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
|
||||||
{
|
{
|
||||||
/* A single word that is greater than the maximum line width.
|
/* A single word that is greater than the maximum line width.
|
||||||
Oh well. Put it on an overlong line by itself. */
|
Oh well. Put it on an overlong line by itself. */
|
||||||
p = buf + (r + 1 - fs->point_col);
|
p = add_length (buf, fs->p, (r + 1 - fs->point_col));
|
||||||
/* Find the end of the long word. */
|
/* Find the end of the long word. */
|
||||||
if (p < nl)
|
if (p < nl)
|
||||||
do
|
do
|
||||||
|
@ -278,7 +332,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
|
||||||
&& fs->p > nextline)
|
&& fs->p > nextline)
|
||||||
{
|
{
|
||||||
/* The margin needs more blanks than we removed. */
|
/* The margin needs more blanks than we removed. */
|
||||||
if (fs->end - fs->p > fs->wmargin + 1)
|
if (__argp_get_display_len (fs->p, fs->end) > fs->wmargin + 1)
|
||||||
/* Make some space for them. */
|
/* Make some space for them. */
|
||||||
{
|
{
|
||||||
size_t mv = fs->p - nextline;
|
size_t mv = fs->p - nextline;
|
||||||
|
|
|
@ -335,6 +335,9 @@ __argp_fmtstream_point (argp_fmtstream_t __fs)
|
||||||
return __fs->point_col >= 0 ? __fs->point_col : 0;
|
return __fs->point_col >= 0 ? __fs->point_col : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
__argp_get_display_len (char *beg, char *end);
|
||||||
|
|
||||||
#if !_LIBC
|
#if !_LIBC
|
||||||
#undef __argp_fmtstream_putc
|
#undef __argp_fmtstream_putc
|
||||||
#undef __argp_fmtstream_puts
|
#undef __argp_fmtstream_puts
|
||||||
|
|
|
@ -1448,7 +1448,7 @@ argp_args_usage (const struct argp *argp, const struct argp_state *state,
|
||||||
|
|
||||||
/* Manually do line wrapping so that it (probably) won't get wrapped at
|
/* Manually do line wrapping so that it (probably) won't get wrapped at
|
||||||
any embedded spaces. */
|
any embedded spaces. */
|
||||||
space (stream, 1 + nl - cp);
|
space (stream, 1 + __argp_get_display_len (cp, nl));
|
||||||
|
|
||||||
__argp_fmtstream_write (stream, cp, nl - cp);
|
__argp_fmtstream_write (stream, cp, nl - cp);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue