source: trunk/libs/newlib/src/newlib/libc/stdio/asnprintf.c @ 471

Last change on this file since 471 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 2.7 KB
Line 
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
16char *
17_asnprintf_r (struct _reent *__restrict ptr,
18       char *buf,
19       size_t *lenp,
20       const char *__restrict fmt, ...)
21{
22  int ret;
23  va_list ap;
24  FILE f;
25  size_t len = *lenp;
26
27  if (buf && len)
28    {
29      /* mark an existing buffer, but allow allocation of larger string */
30      f._flags = __SWR | __SSTR | __SOPT;
31    }
32  else
33    {
34      /* mark a zero-length reallocatable buffer */
35      f._flags = __SWR | __SSTR | __SMBF;
36      len = 0;
37      buf = NULL;
38    }
39  f._bf._base = f._p = (unsigned char *) buf;
40  /* For now, inherit the 32-bit signed limit of FILE._bf._size.
41     FIXME - it would be nice to rewrite sys/reent.h to support size_t
42     for _size.  */
43  if (len > INT_MAX)
44    {
45      ptr->_errno = EOVERFLOW;
46      return NULL;
47    }
48  f._bf._size = f._w = len;
49  f._file = -1;  /* No file. */
50  va_start (ap, fmt);
51  ret = _svfprintf_r (ptr, &f, fmt, ap);
52  va_end (ap);
53  if (ret < 0)
54    return NULL;
55  *lenp = ret;
56  *f._p = '\0';
57  return (char *) f._bf._base;
58}
59
60#ifdef _NANO_FORMATTED_IO
61char *
62_asniprintf_r (struct _reent *, char *, size_t *, const char *, ...)
63       _ATTRIBUTE ((__alias__("_asnprintf_r")));
64#endif
65
66#ifndef _REENT_ONLY
67
68char *
69asnprintf (char *__restrict buf,
70       size_t *__restrict lenp,
71       const char *__restrict fmt, ...)
72{
73  int ret;
74  va_list ap;
75  FILE f;
76  size_t len = *lenp;
77  struct _reent *ptr = _REENT;
78
79  if (buf && len)
80    {
81      /* mark an existing buffer, but allow allocation of larger string */
82      f._flags = __SWR | __SSTR | __SOPT;
83    }
84  else
85    {
86      /* mark a zero-length reallocatable buffer */
87      f._flags = __SWR | __SSTR | __SMBF;
88      len = 0;
89      buf = NULL;
90    }
91  f._bf._base = f._p = (unsigned char *) buf;
92  /* For now, inherit the 32-bit signed limit of FILE._bf._size.
93     FIXME - it would be nice to rewrite sys/reent.h to support size_t
94     for _size.  */
95  if (len > INT_MAX)
96    {
97      ptr->_errno = EOVERFLOW;
98      return NULL;
99    }
100  f._bf._size = f._w = len;
101  f._file = -1;  /* No file. */
102  va_start (ap, fmt);
103  ret = _svfprintf_r (ptr, &f, fmt, ap);
104  va_end (ap);
105  if (ret < 0)
106    return NULL;
107  *lenp = ret;
108  *f._p = '\0';
109  return (char *) f._bf._base;
110}
111
112#ifdef _NANO_FORMATTED_IO
113char *
114asniprintf (char *, size_t *, const char *, ...)
115       _ATTRIBUTE ((__alias__("asnprintf")));
116#endif
117#endif /* ! _REENT_ONLY */
Note: See TracBrowser for help on using the repository browser.