GRASS 8 Programmer's Manual 8.6.0dev(2026)-55de52a352
Loading...
Searching...
No Matches
asprintf.c
Go to the documentation of this file.
1/*!
2 * \file lib/gis/asprintf.c
3 *
4 * \brief GIS Library - GRASS implementation of asprintf().
5 *
6 * Eric G. Miller - Thu, 2 May 2002 17:51:54 -0700
7 *
8 * Rewritten by Glynn Clements, Sat, 6 Feb 2010
9 * Assumes that vsnprintf() is available
10 *
11 * SPDX-FileCopyrightText: 2010 Glynn Clements
12 * SPDX-FileCopyrightText: 2002-2014 GRASS Development Team
13 * SPDX-License-Identifier: GPL-2.0-or-later
14 */
15
16#define _GNU_SOURCE /* enable asprintf */
17#include <stdio.h>
18#include <stdarg.h>
19#include <string.h>
20#include <grass/gis.h>
21
22#ifndef G_asprintf
23
24/**
25 * \brief Safe replacement for <i>asprintf()</i>.
26 *
27 * Allocate a string large enough to hold the new output, including the
28 * terminating NULL, and return the number of characters printed. The
29 * pointer out is set to the output string and should be passed to
30 * <i>G_free()</i> to release the allocated storage when it is no longer
31 * needed.
32 *
33 * \param[out] out
34 * \param[in] fmt
35 * \param ap
36 * \return number of bytes written
37 */
38int G_vasprintf(char **out, const char *fmt, va_list ap)
39{
40#ifdef HAVE_ASPRINTF
41 return vasprintf(out, fmt, ap);
42#else
43 size_t size = strlen(fmt) + 50;
44 char *buf = G_malloc(size);
45 int count;
46
47 for (;;) {
48 /* BUG: according to man vsnprintf,
49 * va_start() should be called immediately before vsnprintf(),
50 * and va_end() immediately after vsnprintf()
51 * otherwise there will be memory corruption */
52 count = vsnprintf(buf, size, fmt, ap);
53 if (count >= 0 && count < size)
54 break;
55 size *= 2;
56 buf = G_realloc(buf, size);
57 }
58
59 buf = G_realloc(buf, count + 1);
60 *out = buf;
61
62 return count;
63#endif /* HAVE_ASPRINTF */
64}
65
66int G_asprintf(char **out, const char *fmt, ...)
67{
68 va_list ap;
69 int count;
70
71 va_start(ap, fmt);
72 count = G_vasprintf(out, fmt, ap);
73 va_end(ap);
74
75 return count;
76}
77
78#endif /* G_asprintf */
79
80/**
81 * \brief Reallocating version of <i>asprintf()</i>.
82 *
83 * Reallocate a string large enough to hold the output, including the
84 * terminating NULL, and return the number of characters printed.
85 * Contrary to <i>G_asprintf()</i>, any existing buffer pointed to by
86 * out of size osize is used to hold the output and enlarged if
87 * necessary. This is useful when <i>G_rasprintf</i> is called many
88 * times in a loop.
89 *
90 * \param[out] out
91 * \param[out] size
92 * \param[in] fmt
93 * \param ap
94 * \return number of bytes written
95 */
96int G_rasprintf(char **out, size_t *size, const char *fmt, ...)
97{
98 va_list ap;
99 int count;
100 char *buf = *out;
101 size_t osize = *size;
102
103 if (osize < strlen(fmt) + 50) {
104 osize = strlen(fmt) + 50;
105 buf = G_realloc(buf, osize);
106 }
107
108 for (;;) {
109 va_start(ap, fmt);
110 count = vsnprintf(buf, osize, fmt, ap);
111 va_end(ap);
112 if (count >= 0 && (size_t)count < osize)
113 break;
114 if (count > -1)
115 osize = count + 1;
116 else
117 osize *= 2;
118
119 buf = G_realloc(buf, osize);
120 }
121
122 *out = buf;
123 *size = osize;
124
125 return count;
126}
int G_rasprintf(char **out, size_t *size, const char *fmt,...)
Reallocating version of asprintf().
Definition asprintf.c:96
int G_asprintf(char **out, const char *fmt,...)
Definition asprintf.c:66
int G_vasprintf(char **out, const char *fmt, va_list ap)
Safe replacement for asprintf().
Definition asprintf.c:38
#define G_realloc(p, n)
Definition defs/gis.h:138
#define G_malloc(n)
Definition defs/gis.h:136
int count