POSIX asprintf() is unavailable on Windows.
Add eal_asprintf() wrapper for EAL internal use.
On Windows it's a function, on Unix it's a macro for asprintf().

Signed-off-by: Dmitry Kozlyuk <dmitry.kozl...@gmail.com>
Acked-by: Khoa To <k...@microsoft.com>
---
 lib/librte_eal/common/eal_common_lcore.c      |  2 +-
 lib/librte_eal/common/eal_common_options.c    |  8 ++---
 lib/librte_eal/common/eal_common_trace.c      |  2 +-
 lib/librte_eal/common/eal_common_trace_ctf.c  |  2 +-
 .../common/eal_common_trace_utils.c           |  2 +-
 lib/librte_eal/common/eal_private.h           | 18 +++++++++++
 lib/librte_eal/windows/eal.c                  | 30 +++++++++++++++++++
 7 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_lcore.c 
b/lib/librte_eal/common/eal_common_lcore.c
index 66d6bad1a..db16a34cc 100644
--- a/lib/librte_eal/common/eal_common_lcore.c
+++ b/lib/librte_eal/common/eal_common_lcore.c
@@ -282,7 +282,7 @@ rte_lcore_callback_register(const char *name, 
rte_lcore_init_cb init,
        callback = calloc(1, sizeof(*callback));
        if (callback == NULL)
                return NULL;
-       if (asprintf(&callback->name, "%s-%p", name, arg) == -1) {
+       if (eal_asprintf(&callback->name, "%s-%p", name, arg) == -1) {
                free(callback);
                return NULL;
        }
diff --git a/lib/librte_eal/common/eal_common_options.c 
b/lib/librte_eal/common/eal_common_options.c
index 622c7bc42..230bac9f3 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -1435,7 +1435,7 @@ available_cores(void)
                return NULL;
 
        /* first sequence */
-       if (asprintf(&str, "%d", idx) < 0)
+       if (eal_asprintf(&str, "%d", idx) < 0)
                return NULL;
        previous = idx;
        sequence = 0;
@@ -1452,7 +1452,7 @@ available_cores(void)
 
                /* finish current sequence */
                if (sequence) {
-                       if (asprintf(&tmp, "%s-%d", str, previous) < 0) {
+                       if (eal_asprintf(&tmp, "%s-%d", str, previous) < 0) {
                                free(str);
                                return NULL;
                        }
@@ -1461,7 +1461,7 @@ available_cores(void)
                }
 
                /* new sequence */
-               if (asprintf(&tmp, "%s,%d", str, idx) < 0) {
+               if (eal_asprintf(&tmp, "%s,%d", str, idx) < 0) {
                        free(str);
                        return NULL;
                }
@@ -1473,7 +1473,7 @@ available_cores(void)
 
        /* finish last sequence */
        if (sequence) {
-               if (asprintf(&tmp, "%s-%d", str, previous) < 0) {
+               if (eal_asprintf(&tmp, "%s-%d", str, previous) < 0) {
                        free(str);
                        return NULL;
                }
diff --git a/lib/librte_eal/common/eal_common_trace.c 
b/lib/librte_eal/common/eal_common_trace.c
index 24e27387b..d57bb8ecc 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -435,7 +435,7 @@ __rte_trace_point_emit_field(size_t sz, const char *in, 
const char *datatype)
        fixup = trace_metadata_fixup_field(in);
        if (fixup != NULL)
                in = fixup;
-       rc = asprintf(&field, "%s        %s %s;\n",
+       rc = eal_asprintf(&field, "%s        %s %s;\n",
                RTE_PER_LCORE(ctf_field) != NULL ?
                        RTE_PER_LCORE(ctf_field) : "",
                datatype, in);
diff --git a/lib/librte_eal/common/eal_common_trace_ctf.c 
b/lib/librte_eal/common/eal_common_trace_ctf.c
index 33e419aac..f64ca9496 100644
--- a/lib/librte_eal/common/eal_common_trace_ctf.c
+++ b/lib/librte_eal/common/eal_common_trace_ctf.c
@@ -389,7 +389,7 @@ char *trace_metadata_fixup_field(const char *field)
        for (i = 0; i < RTE_DIM(ctf_reserved_words); i++) {
                if (strcmp(field, ctf_reserved_words[i]) != 0)
                        continue;
-               if (asprintf(&out, "_%s", ctf_reserved_words[i]) == -1)
+               if (eal_asprintf(&out, "_%s", ctf_reserved_words[i]) == -1)
                        out = NULL;
                return out;
        }
diff --git a/lib/librte_eal/common/eal_common_trace_utils.c 
b/lib/librte_eal/common/eal_common_trace_utils.c
index 64f58fb66..e32237b8e 100644
--- a/lib/librte_eal/common/eal_common_trace_utils.c
+++ b/lib/librte_eal/common/eal_common_trace_utils.c
@@ -253,7 +253,7 @@ eal_trace_dir_args_save(char const *val)
                return -ENAMETOOLONG;
        }
 
-       if (asprintf(&dir_path, "%s/", val) == -1) {
+       if (eal_asprintf(&dir_path, "%s/", val) == -1) {
                trace_err("failed to copy directory: %s", strerror(errno));
                return -ENOMEM;
        }
diff --git a/lib/librte_eal/common/eal_private.h 
b/lib/librte_eal/common/eal_private.h
index b8a0d2002..323240dd7 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -745,4 +745,22 @@ void __rte_thread_init(unsigned int lcore_id, rte_cpuset_t 
*cpuset);
  */
 void __rte_thread_uninit(void);
 
+/**
+ * Allocate a buffer large enough to hold the formatted string
+ * and perform formatting, equivalent to Unix asprintf(3).
+ *
+ * @param buffer
+ *  Receives a pointer to allocated memory, call free(buffer) to deallocate.
+ * @param format
+ *  Format string.
+ * @return
+ *  Number of bytes allocated on success, (-1) on failure.
+ */
+#ifdef RTE_EXEC_ENV_WINDOWS
+__rte_format_printf(2, 3)
+int eal_asprintf(char **buffer, const char *format, ...);
+#else
+#define eal_asprintf asprintf
+#endif
+
 #endif /* _EAL_PRIVATE_H_ */
diff --git a/lib/librte_eal/windows/eal.c b/lib/librte_eal/windows/eal.c
index 2fc3d6141..162671f9c 100644
--- a/lib/librte_eal/windows/eal.c
+++ b/lib/librte_eal/windows/eal.c
@@ -2,6 +2,8 @@
  * Copyright(c) 2019 Intel Corporation
  */
 
+#include <stdarg.h>
+
 #include <fcntl.h>
 #include <io.h>
 #include <share.h>
@@ -411,6 +413,34 @@ rte_eal_init(int argc, char **argv)
        return fctret;
 }
 
+/* Don't use MinGW asprintf() to have identical code with all toolchains. */
+int
+eal_asprintf(char **buffer, const char *format, ...)
+{
+       int size, ret;
+       va_list arg;
+
+       va_start(arg, format);
+       size = vsnprintf(NULL, 0, format, arg);
+       va_end(arg);
+       if (size < 0)
+               return -1;
+       size++;
+
+       *buffer = malloc(size);
+       if (*buffer == NULL)
+               return -1;
+
+       va_start(arg, format);
+       ret = vsnprintf(*buffer, size, format, arg);
+       va_end(arg);
+       if (ret != size - 1) {
+               free(*buffer);
+               return -1;
+       }
+       return ret;
+}
+
 int
 rte_vfio_container_dma_map(__rte_unused int container_fd,
                        __rte_unused uint64_t vaddr,
-- 
2.29.2

Reply via email to