NCBI C++ ToolKit
vasprintf.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /*
2  * vasprintf(3)
3  * 20020809 entropy@tappedin.com
4  * public domain. no warranty. use at your own risk. have a nice day.
5  */
6 
7 #include <config.h>
8 
9 #include <stdarg.h>
10 #include <stdio.h>
11 
12 #if HAVE_STDLIB_H
13 #include <stdlib.h>
14 #endif /* HAVE_STDLIB_H */
15 
16 #if HAVE_ERRNO_H
17 #include <errno.h>
18 #endif /* HAVE_ERRNO_H */
19 
20 #if HAVE_STRING_H
21 #include <string.h>
22 #endif /* HAVE_STRING_H */
23 
24 #if HAVE_UNISTD_H
25 #include <unistd.h>
26 #endif /* HAVE_UNISTD_H */
27 
28 #if HAVE_PATHS_H
29 #include <paths.h>
30 #endif /* HAVE_PATHS_H */
31 
32 #include <freetds/sysdep_private.h>
33 #include "replacements.h"
34 
35 #if defined(HAVE__VSNPRINTF) && !defined(HAVE_VSNPRINTF)
36 #undef HAVE_VSNPRINTF
37 #undef vsnprintf
38 #define HAVE_VSNPRINTF 1
39 #define vsnprintf _vsnprintf
40 #endif
41 
42 #ifndef _PATH_DEVNULL
43 #define _PATH_DEVNULL "/dev/null"
44 #endif
45 
46 #define CHUNKSIZE 512
47 int
48 tds_vasprintf(char **ret, const char *fmt, va_list ap)
49 {
50 #if HAVE__VSCPRINTF
51  int len = _vscprintf(fmt, ap);
52 
53  if (len >= 0) {
54  *ret = malloc(len + 1);
55  if (*ret) {
56  vsprintf(*ret, fmt, ap);
57  return len;
58  }
59  errno = ENOMEM;
60  }
61  *ret = NULL;
62  return -1;
63 #elif HAVE_VSNPRINTF
64  size_t chunks;
65  size_t buflen;
66  char *buf;
67  int len;
68 
69  chunks = ((strlen(fmt) + 1) / CHUNKSIZE) + 1;
70  buflen = chunks * CHUNKSIZE;
71  for (;;) {
72  if ((buf = malloc(buflen)) == NULL) {
73  errno = ENOMEM;
74  *ret = NULL;
75  return -1;
76  }
77  len = vsnprintf(buf, buflen, fmt, ap);
78  if (0 <= len && (size_t) len < buflen - 1) {
79  break;
80  }
81  free(buf);
82  buflen = (++chunks) * CHUNKSIZE;
83  /*
84  * len >= 0 is required for vsnprintf implementations that
85  * return -1 for insufficient buffer
86  */
87  if (len >= 0 && buflen <= (size_t) len) {
88  buflen = len + 1;
89  }
90  }
91  *ret = buf;
92  return len;
93 #else /* HAVE_VSNPRINTF */
94 #ifdef _REENTRANT
95  FILE *fp;
96 #else /* !_REENTRANT */
97  static FILE *fp = NULL;
98 #endif /* !_REENTRANT */
99  int len;
100  char *buf;
101 
102  *ret = NULL;
103 
104 #ifdef _REENTRANT
105 
106 # ifdef _WIN32
107 # error Win32 do not have /dev/null, should use vsnprintf version
108 # endif
109 
110  if ((fp = fopen(_PATH_DEVNULL, "w")) == NULL)
111  return -1;
112 #else /* !_REENTRANT */
113  if ((fp == NULL) && ((fp = fopen(_PATH_DEVNULL, "w")) == NULL))
114  return -1;
115 #endif /* !_REENTRANT */
116 
117  len = vfprintf(fp, fmt, ap);
118 
119 #ifdef _REENTRANT
120  if (fclose(fp) != 0)
121  return -1;
122 #endif /* _REENTRANT */
123 
124  if (len < 0)
125  return len;
126  if ((buf = malloc(len + 1)) == NULL) {
127  errno = ENOMEM;
128  return -1;
129  }
130  if (vsprintf(buf, fmt, ap) != len)
131  return -1;
132  *ret = buf;
133  return len;
134 #endif /* HAVE_VSNPRINTF */
135 }
static const char fp[]
Definition: des.c:87
#define _PATH_DEVNULL
Definition: vasprintf.c:43
#define CHUNKSIZE
Definition: vasprintf.c:46
int tds_vasprintf(char **ret, const char *fmt, va_list ap)
Definition: vasprintf.c:48
#define NULL
Definition: ncbistd.hpp:225
char * buf
int len
#define vsnprintf
Definition: ncbiconf_msvc.h:66
void free(voidpf ptr)
voidp malloc(uInt size)
Modified on Fri Sep 20 14:57:42 2024 by modify_doxy.py rev. 669887