OSDN Git Service

part 3 of darwin64 PPC ABI changes
[pf3gnuchains/gcc-fork.git] / libiberty / vsnprintf.c
index 9328e43..5470df2 100644 (file)
@@ -1,5 +1,5 @@
 /* Implement the vsnprintf function.
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
    Written by Kaveh R. Ghazi <ghazi@caip.rutgers.edu>.
 
 This file is part of the libiberty library.  This library is free
@@ -15,7 +15,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 
 As a special exception, if you link this library with files
 compiled with a GNU compiler to produce an executable, this does not cause
@@ -27,13 +27,15 @@ the executable file might be covered by the GNU General Public License. */
 
 @deftypefn Supplemental int vsnprintf (char *@var{buf}, size_t @var{n}, const char *@var{format}, va_list @var{ap})
 
-This function is similar to vsprintf, but it will print at most
-@var{n} characters.  On error the return value is -1, otherwise it
-returns the number of characters that would have been printed had
-@var{n} been sufficiently large, regardless of the actual value of
-@var{n}.  Note some pre-C99 system libraries do not implement this
-correctly so users cannot generally rely on the return value if the
-system version of this function is used.
+This function is similar to @code{vsprintf}, but it will write to
+@var{buf} at most @code{@var{n}-1} bytes of text, followed by a
+terminating null byte, for a total of @var{n} bytes.  On error the
+return value is -1, otherwise it returns the number of characters that
+would have been printed had @var{n} been sufficiently large,
+regardless of the actual value of @var{n}.  Note some pre-C99 system
+libraries do not implement this correctly so users cannot generally
+rely on the return value if the system version of this function is
+used.
 
 @end deftypefn
 
@@ -42,11 +44,7 @@ system version of this function is used.
 #include "config.h"
 #include "ansidecl.h"
 
-#ifdef ANSI_PROTOTYPES
 #include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
@@ -58,11 +56,7 @@ system version of this function is used.
 
 /* This implementation relies on a working vasprintf.  */
 int
-vsnprintf (s, n, format, ap)
-     char * s;
-     size_t n;
-     const char *format;
-     va_list ap;
+vsnprintf (char *s, size_t n, const char *format, va_list ap)
 {
   char *buf = 0;
   int result = vasprintf (&buf, format, ap);
@@ -78,9 +72,13 @@ vsnprintf (s, n, format, ap)
   result = strlen (buf);
   if (n > 0)
     {
-      strncpy (s, buf, n);
-      if (n - 1 < (size_t) result)
-       s[n - 1] = 0;
+      if ((long) n > result)
+       memcpy (s, buf, result+1);
+      else
+        {
+         memcpy (s, buf, n-1);
+         s[n - 1] = 0;
+       }
     }
   free (buf);
   return result;
@@ -93,7 +91,7 @@ vsnprintf (s, n, format, ap)
 #define VERIFY(P) do { if (!(P)) abort(); } while (0)
 
 static int ATTRIBUTE_PRINTF_3
-checkit VPARAMS ((char *s, size_t n, const char *format, ...))
+checkit (char *s, size_t n, const char *format, ...)
 {
   int result;
   VA_OPEN (ap, format);
@@ -105,44 +103,44 @@ checkit VPARAMS ((char *s, size_t n, const char *format, ...))
   return result;
 }
 
-extern int main PARAMS ((void));
+extern int main (void);
 int
-main ()
+main (void)
 {
   char buf[128];
   int status;
   
   CLEAR (buf);
   status = checkit (buf, 10, "%s:%d", "foobar", 9);
-  VERIFY (status==8 && strcmp (buf, "foobar:9") == 0);
+  VERIFY (status==8 && memcmp (buf, "foobar:9\0XXXXX\0", 15) == 0);
 
   CLEAR (buf);
   status = checkit (buf, 9, "%s:%d", "foobar", 9);
-  VERIFY (status==8 && strcmp (buf, "foobar:9") == 0);
+  VERIFY (status==8 && memcmp (buf, "foobar:9\0XXXXX\0", 15) == 0);
 
   CLEAR (buf);
   status = checkit (buf, 8, "%s:%d", "foobar", 9);
-  VERIFY (status==8 && strcmp (buf, "foobar:") == 0);
+  VERIFY (status==8 && memcmp (buf, "foobar:\0XXXXXX\0", 15) == 0);
 
   CLEAR (buf);
   status = checkit (buf, 7, "%s:%d", "foobar", 9);
-  VERIFY (status==8 && strcmp (buf, "foobar") == 0);
+  VERIFY (status==8 && memcmp (buf, "foobar\0XXXXXXX\0", 15) == 0);
 
   CLEAR (buf);
   status = checkit (buf, 6, "%s:%d", "foobar", 9);
-  VERIFY (status==8 && strcmp (buf, "fooba") == 0);
+  VERIFY (status==8 && memcmp (buf, "fooba\0XXXXXXXX\0", 15) == 0);
 
   CLEAR (buf);
   status = checkit (buf, 2, "%s:%d", "foobar", 9);
-  VERIFY (status==8 && strcmp (buf, "f") == 0);
+  VERIFY (status==8 && memcmp (buf, "f\0XXXXXXXXXXXX\0", 15) == 0);
 
   CLEAR (buf);
   status = checkit (buf, 1, "%s:%d", "foobar", 9);
-  VERIFY (status==8 && strcmp (buf, "") == 0);
+  VERIFY (status==8 && memcmp (buf, "\0XXXXXXXXXXXXX\0", 15) == 0);
 
   CLEAR (buf);
   status = checkit (buf, 0, "%s:%d", "foobar", 9);
-  VERIFY (status==8 && strcmp (buf, "XXXXXXXXXXXXXX") == 0);
+  VERIFY (status==8 && memcmp (buf, "XXXXXXXXXXXXXX\0", 15) == 0);
 
   return 0;
 }