This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: Libiberty's snprintf for v3?
- From: "Kaveh R. Ghazi" <ghazi at caip dot rutgers dot edu>
- To: pcarlini at unitus dot it
- Cc: dj at redhat dot com, gcc at gcc dot gnu dot org, libstdc++ at gcc dot gnu dot org
- Date: Mon, 21 Apr 2003 20:41:27 -0400 (EDT)
- Subject: Re: Libiberty's snprintf for v3?
- References: <3EA44576.90708@unitus.it>
> From: Paolo Carlini <pcarlini at unitus dot it>
>
> Hi Kaveh, hi everyone,
>
> now that snprintf is available in libiberty we can consider actually
> using it in v3.
>
> I briefly recall (for Kaveh and the accidental readers) that currently
> we use either snprintf or the unsafe sprintf depending on
> _GLIBCPP_USE_C99 (see config/locale/gnu/c_locale.h).
>
> Having snprintf unconditionally available would simplify and made safer
> a few functions in include/bits/locale_facets.tcc
>
> Do we really want that? In case, I volunteer to do the needed work
> (provided you guys help me a little bit ;).
> Paolo.
Hi Paolo,
I'd like to see this happen, but there's a license snag. I think I
mentioned this last time snprintf came up, but in case not:
While the new files I added for [v]snprintf use GPL plus special
exception, the implementation I wrote relies on libiberty's
vasprintf.c or a working system vasprintf. I think vasprintf is more
rare than [v]snprintf since I believe vasprintf didn't make it into
c99. So if we just suck [v]snprintf.c into libstdc++, it probably
won't be very useful since any system which needs it probably also
needs vasprintf.c.
The vasprintf.c file in libiberty uses LGPL which has different terms
than the special exception clause used in libstdc++ and [v]snprintf.c.
I see two remedies.
1. Someone (not me, probably Paolo :-) ) needs to write to
assign at gnu dot org, explain the situation and ask them to change the
license on vasprintf.c to GPL + special exception. This isn't so
bad, I've found them to be reasonable and responsive. Then you
can suck in that file too.
Or:
2. Someone (probably me) needs to rewrite [v]snprintf.c to avoid
using vasprintf. E.g. we can use vfprintf to /dev/null to get the
length of the resulting string. I imagine something like this for
vsnprintf.c:
(Assume `s' is the buffer, `n' is the max length, and `msg' is the
format and `ap' is the va_list.)
len = vfprintf (dev_null_stream, msg, ap)
if (len < n)
vsprintf (s, msg, ap)
else
{
buf = alloca (len+1)
vsprintf (buf, msg, ap)
memcpy (s, buf, n);
}
(It's probably more complicated in reality, but you get the idea.)
The downsides to this approach are:
A. We assume /dev/null exists.
B. We either open and close the stream every time (very slow) or
cache the open /dev/null stream (close it with atexit) and waste
one open file descriptor and one atexit slot for the entire run of
any program which uses libiberty's [v]snprintf.c.
C. I'm not sure if it's legal (portable) to traverse the va_list
twice inside vsnprintf.c, once with vfprintf and once is vsprintf.
But, on the upside we won't need vasprintf.c, and the resulting code
will probably be faster than the current implementation if we cache
the fd.
If this doesn't work, perhaps someone can come up with another
approach? Comments?
--Kaveh
--
Kaveh R. Ghazi ghazi at caip dot rutgers dot edu