gnulib: fix argp --help formatting
This is a patch that was sent by Simon Reinhardt to gnulib and has never been applied. It fixes a several formatting issues in --help. https://lists.gnu.org/archive/html/bug-gnulib/2016-02/msg00013.html * lib/argp-fmtstream.c (__argp_fmtstream_update): Flush output as soon as possible. * lib/argp-fmtstream.h (struct argp_fmtstream): Member point_offs is no longer needed. * lib/argp-help.c (indent_to): Flush output to avoid a spurious newline before an overlong word.
This commit is contained in:
parent
27fb175276
commit
d0e404fec0
3 changed files with 56 additions and 157 deletions
|
|
@ -68,7 +68,6 @@ __argp_make_fmtstream (FILE *stream,
|
||||||
fs->rmargin = rmargin;
|
fs->rmargin = rmargin;
|
||||||
fs->wmargin = wmargin;
|
fs->wmargin = wmargin;
|
||||||
fs->point_col = 0;
|
fs->point_col = 0;
|
||||||
fs->point_offs = 0;
|
|
||||||
|
|
||||||
fs->buf = (char *) malloc (INIT_BUF_SIZE);
|
fs->buf = (char *) malloc (INIT_BUF_SIZE);
|
||||||
if (! fs->buf)
|
if (! fs->buf)
|
||||||
|
|
@ -115,8 +114,19 @@ weak_alias (__argp_fmtstream_free, argp_fmtstream_free)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 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. */
|
static void
|
||||||
|
write_block (argp_fmtstream_t fs, char *buf, int len)
|
||||||
|
{
|
||||||
|
#ifdef _LIBC
|
||||||
|
__fxprintf (fs->stream, "%.*s", len, buf);
|
||||||
|
#else
|
||||||
|
fwrite_unlocked (buf, 1, len, fs->stream);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process FS's buffer so that line wrapping is done and flush all of it. So
|
||||||
|
after return fs->p will be set to fb->buf. */
|
||||||
void
|
void
|
||||||
__argp_fmtstream_update (argp_fmtstream_t fs)
|
__argp_fmtstream_update (argp_fmtstream_t fs)
|
||||||
{
|
{
|
||||||
|
|
@ -124,7 +134,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
/* Scan the buffer for newlines. */
|
/* Scan the buffer for newlines. */
|
||||||
buf = fs->buf + fs->point_offs;
|
buf = fs->buf;
|
||||||
while (buf < fs->p)
|
while (buf < fs->p)
|
||||||
{
|
{
|
||||||
size_t r;
|
size_t r;
|
||||||
|
|
@ -132,31 +142,10 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
|
||||||
if (fs->point_col == 0 && fs->lmargin != 0)
|
if (fs->point_col == 0 && fs->lmargin != 0)
|
||||||
{
|
{
|
||||||
/* We are starting a new line. Print spaces to the left margin. */
|
/* We are starting a new line. Print spaces to the left margin. */
|
||||||
const size_t pad = fs->lmargin;
|
|
||||||
if (fs->p + pad < fs->end)
|
|
||||||
{
|
|
||||||
/* We can fit in them in the buffer by moving the
|
|
||||||
buffer text up and filling in the beginning. */
|
|
||||||
memmove (buf + pad, buf, fs->p - buf);
|
|
||||||
fs->p += pad; /* Compensate for bigger buffer. */
|
|
||||||
memset (buf, ' ', pad); /* Fill in the spaces. */
|
|
||||||
buf += pad; /* Don't bother searching them. */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* No buffer space for spaces. Must flush. */
|
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < pad; i++)
|
for (i = 0; i < fs->lmargin; i++)
|
||||||
{
|
write_block(fs, " ", 1);
|
||||||
#ifdef _LIBC
|
fs->point_col = fs->lmargin;
|
||||||
if (_IO_fwide (fs->stream, 0) > 0)
|
|
||||||
putwc_unlocked (L' ', fs->stream);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
putc_unlocked (' ', fs->stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fs->point_col = pad;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
len = fs->p - buf;
|
len = fs->p - buf;
|
||||||
|
|
@ -172,8 +161,9 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
|
||||||
if (fs->point_col + len < fs->rmargin)
|
if (fs->point_col + 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. Output the line and increment
|
||||||
characters to be written and stop scanning. */
|
point. */
|
||||||
|
write_block(fs, buf, len);
|
||||||
fs->point_col += len;
|
fs->point_col += len;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -185,7 +175,9 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
|
||||||
else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin)
|
else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin)
|
||||||
{
|
{
|
||||||
/* The buffer contains a full line that fits within the maximum
|
/* The buffer contains a full line that fits within the maximum
|
||||||
line width. Reset point and scan the next line. */
|
line width. Output the line, reset point and scan the next
|
||||||
|
line. */
|
||||||
|
write_block(fs, buf, nl + 1 - buf);
|
||||||
fs->point_col = 0;
|
fs->point_col = 0;
|
||||||
buf = nl + 1;
|
buf = nl + 1;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -196,23 +188,23 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
|
||||||
|
|
||||||
if (fs->wmargin < 0)
|
if (fs->wmargin < 0)
|
||||||
{
|
{
|
||||||
/* Truncate the line by overwriting the excess with the
|
/* Truncated everything past the right margin. */
|
||||||
newline and anything after it in the buffer. */
|
|
||||||
if (nl < fs->p)
|
if (nl < fs->p)
|
||||||
{
|
{
|
||||||
memmove (buf + (r - fs->point_col), nl, fs->p - nl);
|
write_block(fs, buf, r - fs->point_col);
|
||||||
fs->p -= buf + (r - fs->point_col) - nl;
|
write_block(fs, "\n", 1);
|
||||||
/* Reset point for the next line and start scanning it. */
|
/* Reset point for the next line and start scanning it. */
|
||||||
fs->point_col = 0;
|
fs->point_col = 0;
|
||||||
buf += r + 1; /* Skip full line plus \n. */
|
buf = nl + 1; /* Skip full line plus \n. */
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The buffer ends with a partial line that is beyond the
|
/* The buffer ends with a partial line that is beyond the
|
||||||
maximum line width. Advance point for the characters
|
maximum line width. Advance point for the characters
|
||||||
written, and discard those past the max from the buffer. */
|
written, and discard those past the max from the buffer. */
|
||||||
|
write_block(fs, buf, r - fs->point_col);
|
||||||
fs->point_col += len;
|
fs->point_col += len;
|
||||||
fs->p -= fs->point_col - r;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -249,99 +241,26 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
|
||||||
do
|
do
|
||||||
++p;
|
++p;
|
||||||
while (p < nl && !isblank ((unsigned char) *p));
|
while (p < nl && !isblank ((unsigned char) *p));
|
||||||
if (p == nl)
|
|
||||||
{
|
|
||||||
/* It already ends a line. No fussing required. */
|
|
||||||
fs->point_col = 0;
|
|
||||||
buf = nl + 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* We will move the newline to replace the first blank. */
|
|
||||||
nl = p;
|
nl = p;
|
||||||
/* Swallow separating blanks. */
|
nextline = nl + 1;
|
||||||
do
|
|
||||||
++p;
|
|
||||||
while (isblank ((unsigned char) *p));
|
|
||||||
/* The next line will start here. */
|
|
||||||
nextline = p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note: There are a bunch of tests below for
|
write_block(fs, buf, nl - buf);
|
||||||
NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall
|
if (nextline < fs->p)
|
||||||
at the end of the buffer, and NEXTLINE is in fact empty (and so
|
|
||||||
we need not be careful to maintain its contents). */
|
|
||||||
|
|
||||||
if ((nextline == buf + len + 1
|
|
||||||
? fs->end - nl < fs->wmargin + 1
|
|
||||||
: nextline - (nl + 1) < fs->wmargin)
|
|
||||||
&& fs->p > nextline)
|
|
||||||
{
|
{
|
||||||
/* The margin needs more blanks than we removed. */
|
/* There are more lines to process. Do line break and print
|
||||||
if (fs->end - fs->p > fs->wmargin + 1)
|
blanks up to the wrap margin. */
|
||||||
/* Make some space for them. */
|
write_block(fs, "\n", 1);
|
||||||
{
|
|
||||||
size_t mv = fs->p - nextline;
|
|
||||||
memmove (nl + 1 + fs->wmargin, nextline, mv);
|
|
||||||
nextline = nl + 1 + fs->wmargin;
|
|
||||||
len = nextline + mv - buf;
|
|
||||||
*nl++ = '\n';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
/* Output the first line so we can use the space. */
|
|
||||||
{
|
|
||||||
#ifdef _LIBC
|
|
||||||
__fxprintf (fs->stream, "%.*s\n",
|
|
||||||
(int) (nl - fs->buf), fs->buf);
|
|
||||||
#else
|
|
||||||
if (nl > fs->buf)
|
|
||||||
fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream);
|
|
||||||
putc_unlocked ('\n', fs->stream);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
len += buf - fs->buf;
|
|
||||||
nl = buf = fs->buf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
/* We can fit the newline and blanks in before
|
|
||||||
the next word. */
|
|
||||||
*nl++ = '\n';
|
|
||||||
|
|
||||||
if (nextline - nl >= fs->wmargin
|
|
||||||
|| (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin))
|
|
||||||
/* Add blanks up to the wrap margin column. */
|
|
||||||
for (i = 0; i < fs->wmargin; ++i)
|
for (i = 0; i < fs->wmargin; ++i)
|
||||||
*nl++ = ' ';
|
write_block(fs, " ", 1);
|
||||||
else
|
fs->point_col = fs->wmargin;
|
||||||
for (i = 0; i < fs->wmargin; ++i)
|
}
|
||||||
#ifdef _LIBC
|
buf = nextline;
|
||||||
if (_IO_fwide (fs->stream, 0) > 0)
|
|
||||||
putwc_unlocked (L' ', fs->stream);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
putc_unlocked (' ', fs->stream);
|
|
||||||
|
|
||||||
/* Copy the tail of the original buffer into the current buffer
|
|
||||||
position. */
|
|
||||||
if (nl < nextline)
|
|
||||||
memmove (nl, nextline, buf + len - nextline);
|
|
||||||
len -= nextline - buf;
|
|
||||||
|
|
||||||
/* Continue the scan on the remaining lines in the buffer. */
|
|
||||||
buf = nl;
|
|
||||||
|
|
||||||
/* Restore bufp to include all the remaining text. */
|
|
||||||
fs->p = nl + len;
|
|
||||||
|
|
||||||
/* Reset the counter of what has been output this line. If wmargin
|
|
||||||
is 0, we want to avoid the lmargin getting added, so we set
|
|
||||||
point_col to a magic value of -1 in that case. */
|
|
||||||
fs->point_col = fs->wmargin ? fs->wmargin : -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember that we've scanned as far as the end of the buffer. */
|
/* Remember that we've flushed everything. */
|
||||||
fs->point_offs = fs->p - fs->buf;
|
fs->p = fs->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure that FS has space for AMOUNT more bytes in its buffer, either by
|
/* Ensure that FS has space for AMOUNT more bytes in its buffer, either by
|
||||||
|
|
@ -351,30 +270,9 @@ __argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
|
||||||
{
|
{
|
||||||
if ((size_t) (fs->end - fs->p) < amount)
|
if ((size_t) (fs->end - fs->p) < amount)
|
||||||
{
|
{
|
||||||
ssize_t wrote;
|
|
||||||
|
|
||||||
/* Flush FS's buffer. */
|
/* Flush FS's buffer. */
|
||||||
__argp_fmtstream_update (fs);
|
__argp_fmtstream_update (fs);
|
||||||
|
|
||||||
#ifdef _LIBC
|
|
||||||
__fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
|
|
||||||
wrote = fs->p - fs->buf;
|
|
||||||
#else
|
|
||||||
wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
|
|
||||||
#endif
|
|
||||||
if (wrote == fs->p - fs->buf)
|
|
||||||
{
|
|
||||||
fs->p = fs->buf;
|
|
||||||
fs->point_offs = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fs->p -= wrote;
|
|
||||||
fs->point_offs -= wrote;
|
|
||||||
memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((size_t) (fs->end - fs->buf) < amount)
|
if ((size_t) (fs->end - fs->buf) < amount)
|
||||||
/* Gotta grow the buffer. */
|
/* Gotta grow the buffer. */
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -95,9 +95,7 @@ struct argp_fmtstream
|
||||||
size_t lmargin, rmargin; /* Left and right margins. */
|
size_t lmargin, rmargin; /* Left and right margins. */
|
||||||
ssize_t wmargin; /* Margin to wrap to, or -1 to truncate. */
|
ssize_t wmargin; /* Margin to wrap to, or -1 to truncate. */
|
||||||
|
|
||||||
/* Point in buffer to which we've processed for wrapping, but not output. */
|
/* Output column at buf, or -1 meaning 0 but don't add lmargin. */
|
||||||
size_t point_offs;
|
|
||||||
/* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin. */
|
|
||||||
ssize_t point_col;
|
ssize_t point_col;
|
||||||
|
|
||||||
char *buf; /* Output buffer. */
|
char *buf; /* Output buffer. */
|
||||||
|
|
@ -250,7 +248,7 @@ ARGP_FS_EI size_t
|
||||||
__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin)
|
__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin)
|
||||||
{
|
{
|
||||||
size_t __old;
|
size_t __old;
|
||||||
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
|
if (__fs->p > __fs->buf)
|
||||||
__argp_fmtstream_update (__fs);
|
__argp_fmtstream_update (__fs);
|
||||||
__old = __fs->lmargin;
|
__old = __fs->lmargin;
|
||||||
__fs->lmargin = __lmargin;
|
__fs->lmargin = __lmargin;
|
||||||
|
|
@ -262,7 +260,7 @@ ARGP_FS_EI size_t
|
||||||
__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin)
|
__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin)
|
||||||
{
|
{
|
||||||
size_t __old;
|
size_t __old;
|
||||||
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
|
if (__fs->p > __fs->buf)
|
||||||
__argp_fmtstream_update (__fs);
|
__argp_fmtstream_update (__fs);
|
||||||
__old = __fs->rmargin;
|
__old = __fs->rmargin;
|
||||||
__fs->rmargin = __rmargin;
|
__fs->rmargin = __rmargin;
|
||||||
|
|
@ -274,7 +272,7 @@ ARGP_FS_EI size_t
|
||||||
__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin)
|
__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin)
|
||||||
{
|
{
|
||||||
size_t __old;
|
size_t __old;
|
||||||
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
|
if (__fs->p > __fs->buf)
|
||||||
__argp_fmtstream_update (__fs);
|
__argp_fmtstream_update (__fs);
|
||||||
__old = __fs->wmargin;
|
__old = __fs->wmargin;
|
||||||
__fs->wmargin = __wmargin;
|
__fs->wmargin = __wmargin;
|
||||||
|
|
@ -285,7 +283,7 @@ __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin)
|
||||||
ARGP_FS_EI size_t
|
ARGP_FS_EI size_t
|
||||||
__argp_fmtstream_point (argp_fmtstream_t __fs)
|
__argp_fmtstream_point (argp_fmtstream_t __fs)
|
||||||
{
|
{
|
||||||
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
|
if (__fs->p > __fs->buf)
|
||||||
__argp_fmtstream_update (__fs);
|
__argp_fmtstream_update (__fs);
|
||||||
return __fs->point_col >= 0 ? __fs->point_col : 0;
|
return __fs->point_col >= 0 ? __fs->point_col : 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -931,6 +931,9 @@ indent_to (argp_fmtstream_t stream, unsigned col)
|
||||||
int needed = col - __argp_fmtstream_point (stream);
|
int needed = col - __argp_fmtstream_point (stream);
|
||||||
while (needed-- > 0)
|
while (needed-- > 0)
|
||||||
__argp_fmtstream_putc (stream, ' ');
|
__argp_fmtstream_putc (stream, ' ');
|
||||||
|
/* Flush stream to avoid spurious newline before overlong word
|
||||||
|
(see argp-test.c). */
|
||||||
|
__argp_fmtstream_update(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output to STREAM either a space, or a newline if there isn't room for at
|
/* Output to STREAM either a space, or a newline if there isn't room for at
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue