source: trunk/libs/newlib/src/newlib/libc/stdio/asniprintf.c @ 577

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

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

File size: 2.3 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 siprintf.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_asniprintf_r (struct _reent *ptr,
18       char *buf,
19       size_t *lenp,
20       const char *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 = _svfiprintf_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#ifndef _REENT_ONLY
61
62char *
63asniprintf (char *buf,
64       size_t *lenp,
65       const char *fmt, ...)
66{
67  int ret;
68  va_list ap;
69  FILE f;
70  size_t len = *lenp;
71  struct _reent *ptr = _REENT;
72
73  if (buf && len)
74    {
75      /* mark an existing buffer, but allow allocation of larger string */
76      f._flags = __SWR | __SSTR | __SOPT;
77    }
78  else
79    {
80      /* mark a zero-length reallocatable buffer */
81      f._flags = __SWR | __SSTR | __SMBF;
82      len = 0;
83      buf = NULL;
84    }
85  f._bf._base = f._p = (unsigned char *) buf;
86  /* For now, inherit the 32-bit signed limit of FILE._bf._size.
87     FIXME - it would be nice to rewrite sys/reent.h to support size_t
88     for _size.  */
89  if (len > INT_MAX)
90    {
91      ptr->_errno = EOVERFLOW;
92      return NULL;
93    }
94  f._bf._size = f._w = len;
95  f._file = -1;  /* No file. */
96  va_start (ap, fmt);
97  ret = _svfiprintf_r (ptr, &f, fmt, ap);
98  va_end (ap);
99  if (ret < 0)
100    return NULL;
101  *lenp = ret;
102  *f._p = '\0';
103  return (char *) f._bf._base;
104}
105
106#endif /* ! _REENT_ONLY */
Note: See TracBrowser for help on using the repository browser.