Import argp-fmtstream.{c,h} from glibc 2.33.

Also:
- use vsnprintf instead of __vsnprintf_internal
- don't cater to compilers which can't inline functions
This commit is contained in:
Érico Rolim 2021-02-10 17:02:12 -03:00
parent a5fcbcecd9
commit 3358bdadaf
2 changed files with 97 additions and 155 deletions

View file

@ -1,22 +1,21 @@
/* Word-wrapping and line-truncating streams /* Word-wrapping and line-truncating streams
Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc. Copyright (C) 1997-2021 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>. Written by Miles Bader <miles@gnu.ai.mit.edu>.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as modify it under the terms of the GNU Lesser General Public
published by the Free Software Foundation; either version 2 of the License as published by the Free Software Foundation; either
License, or (at your option) any later version. version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful, The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Library General Public You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; see the file COPYING.LIB. If not, License along with the GNU C Library; if not, see
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, <https://www.gnu.org/licenses/>. */
Boston, MA 02111-1307, USA. */
/* This package emulates glibc `line_wrap_stream' semantics for systems that /* This package emulates glibc `line_wrap_stream' semantics for systems that
don't have that. */ don't have that. */
@ -31,7 +30,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <ctype.h> #include <ctype.h>
#include "argp-fmtstream.h" #include <argp-fmtstream.h>
#include "argp-namefrob.h" #include "argp-namefrob.h"
#ifndef ARGP_FMTSTREAM_USE_LINEWRAP #ifndef ARGP_FMTSTREAM_USE_LINEWRAP
@ -40,9 +39,9 @@
#define isblank(ch) ((ch)==' ' || (ch)=='\t') #define isblank(ch) ((ch)==' ' || (ch)=='\t')
#endif #endif
#if defined _LIBC && defined USE_IN_LIBIO #if 0
# include <wchar.h>
# include <libio/libioP.h> # include <libio/libioP.h>
# define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
#endif #endif
#define INIT_BUF_SIZE 200 #define INIT_BUF_SIZE 200
@ -58,8 +57,10 @@ argp_fmtstream_t
__argp_make_fmtstream (FILE *stream, __argp_make_fmtstream (FILE *stream,
size_t lmargin, size_t rmargin, ssize_t wmargin) size_t lmargin, size_t rmargin, ssize_t wmargin)
{ {
argp_fmtstream_t fs = malloc (sizeof (struct argp_fmtstream)); argp_fmtstream_t fs;
if (fs)
fs = (struct argp_fmtstream *) malloc (sizeof (struct argp_fmtstream));
if (fs != NULL)
{ {
fs->stream = stream; fs->stream = stream;
@ -69,7 +70,7 @@ __argp_make_fmtstream (FILE *stream,
fs->point_col = 0; fs->point_col = 0;
fs->point_offs = 0; fs->point_offs = 0;
fs->buf = malloc (INIT_BUF_SIZE); fs->buf = (char *) malloc (INIT_BUF_SIZE);
if (! fs->buf) if (! fs->buf)
{ {
free (fs); free (fs);
@ -84,9 +85,12 @@ __argp_make_fmtstream (FILE *stream,
return fs; return fs;
} }
#if 0
/* Not exported. */
#ifdef weak_alias #ifdef weak_alias
weak_alias (__argp_make_fmtstream, argp_make_fmtstream) weak_alias (__argp_make_fmtstream, argp_make_fmtstream)
#endif #endif
#endif
/* Flush FS to its stream, and free it (but don't close the stream). */ /* Flush FS to its stream, and free it (but don't close the stream). */
void void
@ -94,13 +98,22 @@ __argp_fmtstream_free (argp_fmtstream_t fs)
{ {
__argp_fmtstream_update (fs); __argp_fmtstream_update (fs);
if (fs->p > fs->buf) if (fs->p > fs->buf)
FWRITE_UNLOCKED (fs->buf, 1, fs->p - fs->buf, fs->stream); {
#if 0
__fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
#else
fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
#endif
}
free (fs->buf); free (fs->buf);
free (fs); free (fs);
} }
#if 0
/* Not exported. */
#ifdef weak_alias #ifdef weak_alias
weak_alias (__argp_fmtstream_free, argp_fmtstream_free) weak_alias (__argp_fmtstream_free, argp_fmtstream_free)
#endif #endif
#endif
/* 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. */
@ -134,7 +147,14 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
/* No buffer space for spaces. Must flush. */ /* No buffer space for spaces. Must flush. */
size_t i; size_t i;
for (i = 0; i < pad; i++) for (i = 0; i < pad; i++)
PUTC_UNLOCKED (' ', fs->stream); {
#if 0
if (_IO_fwide (fs->stream, 0) > 0)
putwc_unlocked (L' ', fs->stream);
else
#endif
putc_unlocked (' ', fs->stream);
}
} }
fs->point_col = pad; fs->point_col = pad;
} }
@ -250,9 +270,10 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
at the end of the buffer, and NEXTLINE is in fact empty (and so at the end of the buffer, and NEXTLINE is in fact empty (and so
we need not be careful to maintain its contents). */ we need not be careful to maintain its contents). */
if (nextline == buf + len + 1 if ((nextline == buf + len + 1
? fs->end - nl < fs->wmargin + 1 ? fs->end - nl < fs->wmargin + 1
: nextline - (nl + 1) < fs->wmargin) : nextline - (nl + 1) < fs->wmargin)
&& 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 (fs->end - fs->p > fs->wmargin + 1)
@ -267,9 +288,15 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
else else
/* Output the first line so we can use the space. */ /* Output the first line so we can use the space. */
{ {
#if 0
__fxprintf (fs->stream, "%.*s\n",
(int) (nl - fs->buf), fs->buf);
#else
if (nl > fs->buf) if (nl > fs->buf)
FWRITE_UNLOCKED (fs->buf, 1, nl - fs->buf, fs->stream); fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream);
PUTC_UNLOCKED ('\n', fs->stream); putc_unlocked ('\n', fs->stream);
#endif
len += buf - fs->buf; len += buf - fs->buf;
nl = buf = fs->buf; nl = buf = fs->buf;
} }
@ -286,7 +313,12 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
*nl++ = ' '; *nl++ = ' ';
else else
for (i = 0; i < fs->wmargin; ++i) for (i = 0; i < fs->wmargin; ++i)
PUTC_UNLOCKED (' ', fs->stream); #if 0
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 /* Copy the tail of the original buffer into the current buffer
position. */ position. */
@ -323,7 +355,12 @@ __argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
/* Flush FS's buffer. */ /* Flush FS's buffer. */
__argp_fmtstream_update (fs); __argp_fmtstream_update (fs);
wrote = FWRITE_UNLOCKED (fs->buf, 1, fs->p - fs->buf, fs->stream); #if 0
__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) if (wrote == fs->p - fs->buf)
{ {
fs->p = fs->buf; fs->p = fs->buf;
@ -340,10 +377,11 @@ __argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
if ((size_t) (fs->end - fs->buf) < amount) if ((size_t) (fs->end - fs->buf) < amount)
/* Gotta grow the buffer. */ /* Gotta grow the buffer. */
{ {
size_t new_size = fs->end - fs->buf + amount; size_t old_size = fs->end - fs->buf;
char *new_buf = realloc (fs->buf, new_size); size_t new_size = old_size + amount;
char *new_buf;
if (! new_buf) if (new_size < old_size || ! (new_buf = realloc (fs->buf, new_size)))
{ {
__set_errno (ENOMEM); __set_errno (ENOMEM);
return 0; return 0;
@ -361,7 +399,7 @@ __argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
ssize_t ssize_t
__argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...) __argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...)
{ {
size_t out; int out;
size_t avail; size_t avail;
size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */ size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */
@ -374,102 +412,22 @@ __argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...)
va_start (args, fmt); va_start (args, fmt);
avail = fs->end - fs->p; avail = fs->end - fs->p;
out = __vsnprintf (fs->p, avail, fmt, args); out = vsnprintf (fs->p, avail, fmt, args);
va_end (args); va_end (args);
if (out >= avail) if ((size_t) out >= avail)
size_guess = out + 1; size_guess = out + 1;
} }
while (out >= avail); while ((size_t) out >= avail);
fs->p += out; fs->p += out;
return out; return out;
} }
#if 0
/* Not exported. */
#ifdef weak_alias #ifdef weak_alias
weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf) weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf)
#endif #endif
#endif
/* Duplicate the inline definitions in argp-fmtstream.h, for compilers
* that don't do inlining. */
size_t
__argp_fmtstream_write (argp_fmtstream_t __fs,
__const char *__str, size_t __len)
{
if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len))
{
memcpy (__fs->p, __str, __len);
__fs->p += __len;
return __len;
}
else
return 0;
}
int
__argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str)
{
size_t __len = strlen (__str);
if (__len)
{
size_t __wrote = __argp_fmtstream_write (__fs, __str, __len);
return __wrote == __len ? 0 : -1;
}
else
return 0;
}
int
__argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch)
{
if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1))
return *__fs->p++ = __ch;
else
return EOF;
}
/* Set __FS's left margin to __LMARGIN and return the old value. */
size_t
__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin)
{
size_t __old;
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
__argp_fmtstream_update (__fs);
__old = __fs->lmargin;
__fs->lmargin = __lmargin;
return __old;
}
/* Set __FS's right margin to __RMARGIN and return the old value. */
size_t
__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin)
{
size_t __old;
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
__argp_fmtstream_update (__fs);
__old = __fs->rmargin;
__fs->rmargin = __rmargin;
return __old;
}
/* Set FS's wrap margin to __WMARGIN and return the old value. */
size_t
__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin)
{
size_t __old;
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
__argp_fmtstream_update (__fs);
__old = __fs->wmargin;
__fs->wmargin = __wmargin;
return __old;
}
/* Return the column number of the current output point in __FS. */
size_t
__argp_fmtstream_point (argp_fmtstream_t __fs)
{
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
__argp_fmtstream_update (__fs);
return __fs->point_col >= 0 ? __fs->point_col : 0;
}
#endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */ #endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */

View file

@ -1,22 +1,21 @@
/* Word-wrapping and line-truncating streams. /* Word-wrapping and line-truncating streams.
Copyright (C) 1997, 2003 Free Software Foundation, Inc. Copyright (C) 1997-2021 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>. Written by Miles Bader <miles@gnu.ai.mit.edu>.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as modify it under the terms of the GNU Lesser General Public
published by the Free Software Foundation; either version 2 of the License as published by the Free Software Foundation; either
License, or (at your option) any later version. version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful, The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Library General Public You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; see the file COPYING.LIB. If not, License along with the GNU C Library; if not, see
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, <https://www.gnu.org/licenses/>. */
Boston, MA 02111-1307, USA. */
/* This package emulates glibc `line_wrap_stream' semantics for systems that /* This package emulates glibc `line_wrap_stream' semantics for systems that
don't have that. If the system does have it, it is just a wrapper for don't have that. If the system does have it, it is just a wrapper for
@ -30,25 +29,15 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#if _LIBC || (defined (HAVE_FLOCKFILE) && defined(HAVE_PUTC_UNLOCKED) \ #ifndef PRINTF_STYLE
&& defined (HAVE_FPUTS_UNLOCKED) && defined (HAVE_FWRITE_UNLOCKED) ) # if __GNUC__ >= 2
/* Use locking funxtions */ # define PRINTF_STYLE(f, a) __attribute__ ((__format__ (__printf__, f, a)))
# define FLOCKFILE(f) flockfile(f)
# define FUNLOCKFILE(f) funlockfile(f)
# define PUTC_UNLOCKED(c, f) putc_unlocked((c), (f))
# define FPUTS_UNLOCKED(s, f) fputs_unlocked((s), (f))
# define FWRITE_UNLOCKED(b, s, n, f) fwrite_unlocked((b), (s), (n), (f))
# else # else
/* Disable stdio locking */ # define PRINTF_STYLE(f, a)
# define FLOCKFILE(f) # endif
# define FUNLOCKFILE(f) #endif
# define PUTC_UNLOCKED(c, f) putc((c), (f))
# define FPUTS_UNLOCKED(s, f) fputs((s), (f))
# define FWRITE_UNLOCKED(b, s, n, f) fwrite((b), (s), (n), (f))
#endif /* No thread safe i/o */
#if (_LIBC - 0 && !defined (USE_IN_LIBIO)) \ #if 0
|| (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H))
/* line_wrap_stream is available, so use that. */ /* line_wrap_stream is available, so use that. */
#define ARGP_FMTSTREAM_USE_LINEWRAP #define ARGP_FMTSTREAM_USE_LINEWRAP
#endif #endif
@ -95,10 +84,6 @@ typedef FILE *argp_fmtstream_t;
#else /* !ARGP_FMTSTREAM_USE_LINEWRAP */ #else /* !ARGP_FMTSTREAM_USE_LINEWRAP */
/* Guess we have to define our own version. */ /* Guess we have to define our own version. */
#ifndef __const
#define __const const
#endif
struct argp_fmtstream struct argp_fmtstream
{ {
@ -139,22 +124,22 @@ extern void __argp_fmtstream_free (argp_fmtstream_t __fs);
extern void argp_fmtstream_free (argp_fmtstream_t __fs); extern void argp_fmtstream_free (argp_fmtstream_t __fs);
extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs, extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs,
__const char *__fmt, ...) const char *__fmt, ...)
PRINTF_STYLE(2,3); PRINTF_STYLE(2,3);
extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs, extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs,
__const char *__fmt, ...) const char *__fmt, ...)
PRINTF_STYLE(2,3); PRINTF_STYLE(2,3);
extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str); extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str);
extern int argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str); extern int argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str);
extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs, extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs,
__const char *__str, size_t __len); const char *__str, size_t __len);
extern size_t argp_fmtstream_write (argp_fmtstream_t __fs, extern size_t argp_fmtstream_write (argp_fmtstream_t __fs,
__const char *__str, size_t __len); const char *__str, size_t __len);
/* Access macros for various bits of state. */ /* Access macros for various bits of state. */
#define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin) #define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin)
@ -212,8 +197,7 @@ extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
#endif #endif
ARGP_FS_EI size_t ARGP_FS_EI size_t
__argp_fmtstream_write (argp_fmtstream_t __fs, __argp_fmtstream_write (argp_fmtstream_t __fs, const char *__str, size_t __len)
__const char *__str, size_t __len)
{ {
if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len)) if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len))
{ {
@ -226,7 +210,7 @@ __argp_fmtstream_write (argp_fmtstream_t __fs,
} }
ARGP_FS_EI int ARGP_FS_EI int
__argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str) __argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str)
{ {
size_t __len = strlen (__str); size_t __len = strlen (__str);
if (__len) if (__len)