Add CFCUtil_sprintf utility function

Works like sprintf but returns a dynamically allocated string similar to
asprintf.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/2f96f72c
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/2f96f72c
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/2f96f72c

Branch: refs/heads/master
Commit: 2f96f72c108921b0609ae6885827ec8a25e186f5
Parents: e80ba0d
Author: Nick Wellnhofer <[email protected]>
Authored: Wed Dec 26 19:55:52 2012 +0100
Committer: Nick Wellnhofer <[email protected]>
Committed: Fri Dec 28 22:23:10 2012 +0100

----------------------------------------------------------------------
 clownfish/compiler/src/CFCUtil.c |   46 +++++++++++++++++++++++++++++++++
 clownfish/compiler/src/CFCUtil.h |    6 ++++
 2 files changed, 52 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/2f96f72c/clownfish/compiler/src/CFCUtil.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCUtil.c b/clownfish/compiler/src/CFCUtil.c
index f76c9a8..5316f00 100644
--- a/clownfish/compiler/src/CFCUtil.c
+++ b/clownfish/compiler/src/CFCUtil.c
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include "charmony.h"
+
 #include <string.h>
 #include <stdlib.h>
 #include <ctype.h>
@@ -52,6 +54,50 @@ CFCUtil_strndup(const char *string, size_t len) {
     return copy;
 }
 
+#if defined(CHY_HAS_C99_SNPRINTF) || defined(CHY_HAS__SCPRINTF)
+
+char*
+CFCUtil_sprintf(const char *fmt, ...) {
+    va_list args;
+
+    va_start(args, fmt);
+#if defined(CHY_HAS_C99_SNPRINTF)
+    int size = vsnprintf(NULL, 0, fmt, args);
+    if (size < 0) { CFCUtil_die("snprintf failed"); }
+#else
+    int size = _vscprintf(fmt, args);
+    if (size < 0) { CFCUtil_die("_scprintf failed"); }
+#endif
+    va_end(args);
+
+    char *string = (char*)MALLOCATE((size_t)size + 1);
+    va_start(args, fmt);
+    vsprintf(string, fmt, args);
+    va_end(args);
+
+    return string;
+}
+
+#elif defined(CHY_HAS__SNPRINTF)
+
+char*
+CFCUtil_sprintf(const char *fmt, ...) {
+    for (size_t size = 32; size * 2 > size; size *= 2) {
+        char *string = (char*)MALLOCATE(size);
+        va_list args;
+        va_start(args, fmt);
+        int result = _vsnprintf(string, size, fmt, args);
+        va_end(args);
+        if (result >= 0 && (size_t)result < size) { return string; }
+    }
+    CFCUtil_die("_snprintf failed");
+    return NULL;
+}
+
+#else
+  #error "snprintf or replacement not available."
+#endif
+
 char*
 CFCUtil_cat(char *string, ...) {
     va_list args;

http://git-wip-us.apache.org/repos/asf/lucy/blob/2f96f72c/clownfish/compiler/src/CFCUtil.h
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCUtil.h b/clownfish/compiler/src/CFCUtil.h
index 0d714c5..df78500 100644
--- a/clownfish/compiler/src/CFCUtil.h
+++ b/clownfish/compiler/src/CFCUtil.h
@@ -52,6 +52,12 @@ CFCUtil_strdup(const char *string);
 char*
 CFCUtil_strndup(const char *string, size_t len);
 
+/** Return a dynamically allocated string with content defined by a printf
+ * format string and additional arguments. Similar to asprintf().
+ */
+char*
+CFCUtil_sprintf(const char *fmt, ...);
+
 /** Concatenate a NULL-terminated list of strings onto the first, reallocating
  * with each argument.
  */

Reply via email to