Subversion Repositories Kolibri OS

Rev

Rev 4921 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /* Copyright (C) 2007, 2008 Eric Blake
  2.  * Permission to use, copy, modify, and distribute this software
  3.  * is freely granted, provided that this notice is preserved.
  4.  */
  5. /* This code was derived from asprintf.c */
  6. /* doc in sprintf.c */
  7.  
  8. #include <_ansi.h>
  9. #include <reent.h>
  10. #include <stdio.h>
  11. #include <stdarg.h>
  12. #include <limits.h>
  13. #include <errno.h>
  14. #include "local.h"
  15.  
  16. char *
  17. _DEFUN(_asnprintf_r, (ptr, buf, lenp, fmt),
  18.        struct _reent *__restrict ptr _AND
  19.        char *buf _AND
  20.        size_t *lenp _AND
  21.        const char *__restrict fmt _DOTS)
  22. {
  23.   int ret;
  24.   va_list ap;
  25.   FILE f;
  26.   size_t len = *lenp;
  27.  
  28.   if (buf && len)
  29.     {
  30.       /* mark an existing buffer, but allow allocation of larger string */
  31.       f._flags = __SWR | __SSTR | __SOPT;
  32.     }
  33.   else
  34.     {
  35.       /* mark a zero-length reallocatable buffer */
  36.       f._flags = __SWR | __SSTR | __SMBF;
  37.       len = 0;
  38.       buf = NULL;
  39.     }
  40.   f._bf._base = f._p = (unsigned char *) buf;
  41.   /* For now, inherit the 32-bit signed limit of FILE._bf._size.
  42.      FIXME - it would be nice to rewrite sys/reent.h to support size_t
  43.      for _size.  */
  44.   if (len > INT_MAX)
  45.     {
  46.       ptr->_errno = EOVERFLOW;
  47.       return NULL;
  48.     }
  49.   f._bf._size = f._w = len;
  50.   f._file = -1;  /* No file. */
  51.   va_start (ap, fmt);
  52.   ret = _svfprintf_r (ptr, &f, fmt, ap);
  53.   va_end (ap);
  54.   if (ret < 0)
  55.     return NULL;
  56.   *lenp = ret;
  57.   *f._p = '\0';
  58.   return (char *) f._bf._base;
  59. }
  60.  
  61. #ifdef _NANO_FORMATTED_IO
  62. char *
  63. _EXFUN(_asniprintf_r, (struct _reent *, char *, size_t *, const char *, ...)
  64.        _ATTRIBUTE ((__alias__("_asnprintf_r"))));
  65. #endif
  66.  
  67. #ifndef _REENT_ONLY
  68.  
  69. char *
  70. _DEFUN(asnprintf, (buf, lenp, fmt),
  71.        char *__restrict buf _AND
  72.        size_t *__restrict lenp _AND
  73.        const char *__restrict fmt _DOTS)
  74. {
  75.   int ret;
  76.   va_list ap;
  77.   FILE f;
  78.   size_t len = *lenp;
  79.   struct _reent *ptr = _REENT;
  80.  
  81.   if (buf && len)
  82.     {
  83.       /* mark an existing buffer, but allow allocation of larger string */
  84.       f._flags = __SWR | __SSTR | __SOPT;
  85.     }
  86.   else
  87.     {
  88.       /* mark a zero-length reallocatable buffer */
  89.       f._flags = __SWR | __SSTR | __SMBF;
  90.       len = 0;
  91.       buf = NULL;
  92.     }
  93.   f._bf._base = f._p = (unsigned char *) buf;
  94.   /* For now, inherit the 32-bit signed limit of FILE._bf._size.
  95.      FIXME - it would be nice to rewrite sys/reent.h to support size_t
  96.      for _size.  */
  97.   if (len > INT_MAX)
  98.     {
  99.       ptr->_errno = EOVERFLOW;
  100.       return NULL;
  101.     }
  102.   f._bf._size = f._w = len;
  103.   f._file = -1;  /* No file. */
  104.   va_start (ap, fmt);
  105.   ret = _svfprintf_r (ptr, &f, fmt, ap);
  106.   va_end (ap);
  107.   if (ret < 0)
  108.     return NULL;
  109.   *lenp = ret;
  110.   *f._p = '\0';
  111.   return (char *) f._bf._base;
  112. }
  113.  
  114. #ifdef _NANO_FORMATTED_IO
  115. char *
  116. _EXFUN(asniprintf, (char *, size_t *, const char *, ...)
  117.        _ATTRIBUTE ((__alias__("asnprintf"))));
  118. #endif
  119. #endif /* ! _REENT_ONLY */
  120.