ReactOS 0.4.15-dev-7934-g1dc8d80
asprintf.c
Go to the documentation of this file.
1/* Copyright (c) 2004 Darren Tucker.
2 *
3 * Based originally on asprintf.c from OpenBSD:
4 * Copyright (c) 1997 Todd C. Miller <Todd.Miller AT courtesan.com>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19//extern int vsnprintf();
20#include <wintirpc.h>
21#include <stdio.h>
22#ifndef __REACTOS__
23#include <varargs.h>
24#endif
25
26/* Include vasprintf() if not on your OS. */
27#ifndef HAVE_VASPRINTF
28
29#include <errno.h>
30#include <limits.h>
31#include <stdarg.h>
32#include <stdlib.h>
33
34#ifndef VA_COPY
35# ifdef HAVE_VA_COPY
36# define VA_COPY(dest, src) va_copy(dest, src)
37# else
38# ifdef HAVE___VA_COPY
39# define VA_COPY(dest, src) __va_copy(dest, src)
40# else
41# define VA_COPY(dest, src) (dest) = (src)
42# endif
43# endif
44#endif
45
46#define INIT_SZ 128
47
48int
49vasprintf(char **str, const char *fmt, va_list ap)
50{
51 int ret = -1;
52 va_list ap2;
53 char *string, *newstr;
54 size_t len;
55
56 VA_COPY(ap2, ap);
57 if ((string = malloc(INIT_SZ)) == NULL)
58 goto fail;
59
60 ret = _vsnprintf(string, INIT_SZ, fmt, ap2);
61 if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */
62 *str = string;
63 } else if (ret == INT_MAX || ret < 0) { /* Bad length */
64 goto fail;
65 } else { /* bigger than initial, realloc allowing for nul */
66 len = (size_t)ret + 1;
67 if ((newstr = realloc(string, len)) == NULL) {
68 free(string);
69 goto fail;
70 } else {
71 va_end(ap2);
72 VA_COPY(ap2, ap);
73 ret = _vsnprintf(newstr, len, fmt, ap2);
74 if (ret >= 0 && (size_t)ret < len) {
75 *str = newstr;
76 } else { /* failed with realloc'ed string, give up */
77 free(newstr);
78 goto fail;
79 }
80 }
81 }
82 va_end(ap2);
83 return (ret);
84
85fail:
86 *str = NULL;
87 errno = ENOMEM;
88 va_end(ap2);
89 return (-1);
90}
91#endif
92
93/* Include asprintf() if not on your OS. */
94#ifndef HAVE_ASPRINTF
95int asprintf(char **str, const char *fmt, ...)
96{
97 va_list ap;
98 int ret;
99
100 *str = NULL;
101 va_start(ap, fmt);
102 ret = vasprintf(str, fmt, ap);
103 va_end(ap);
104
105 return ret;
106}
107#endif
#define ENOMEM
Definition: acclib.h:84
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
int vasprintf(char **str, const char *fmt, va_list ap)
Definition: asprintf.c:49
int asprintf(char **str, const char *fmt,...)
Definition: asprintf.c:95
#define INIT_SZ
Definition: asprintf.c:46
#define VA_COPY(dest, src)
Definition: asprintf.c:41
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
__kernel_size_t size_t
Definition: linux.h:237
GLenum GLsizei len
Definition: glext.h:6722
#define INT_MAX
Definition: limits.h:40
char string[160]
Definition: util.h:11
const WCHAR * str
#define errno
Definition: errno.h:18
Definition: dsound.c:943
int ret
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36
#define _vsnprintf
Definition: xmlstorage.h:202