From 10878d21118576b997540670ba0b83d327839aca Mon Sep 17 00:00:00 2001 From: zhangbing Date: Thu, 9 Oct 2025 17:23:07 +0800 Subject: [PATCH] Fix MSVC-specific syntax issues --- example/pthread/pthread.c | 8 ++- iniparser/inistring.h | 11 +++- src/sc.c | 14 ++++- src/sc.h | 128 ++++++++++++++++++++------------------ src/sc_mpi.h | 8 ++- src/sc_string.h | 4 +- 6 files changed, 105 insertions(+), 68 deletions(-) diff --git a/example/pthread/pthread.c b/example/pthread/pthread.c index d42206ed9..a6833091d 100644 --- a/example/pthread/pthread.c +++ b/example/pthread/pthread.c @@ -1,4 +1,4 @@ -/* +/* This file is part of the SC Library. The SC Library provides support for parallel scientific applications. @@ -21,6 +21,12 @@ 02110-1301, USA. */ +#ifdef _MSC_VER +#define WIN32_LEAN_AND_MEAN +#include +#define sleep Sleep +#endif + #include #include diff --git a/iniparser/inistring.h b/iniparser/inistring.h index 6072cf339..a17dd1054 100644 --- a/iniparser/inistring.h +++ b/iniparser/inistring.h @@ -1,4 +1,4 @@ -/* +/* This file is part of the SC Library, version 3. The SC Library provides support for parallel scientific applications. @@ -38,6 +38,10 @@ #endif #include +#ifdef _MSC_VER +#include /* _Printf_format_string_ */ +#endif + #ifdef __cplusplus extern "C" { @@ -66,9 +70,14 @@ void ini_strcopy (char *dest, size_t size, const char *src); * \param [in] size Allocation length of \a str. * \param [in] format Format string as in man (3) snprintf. */ +#ifdef _MSC_VER +void ini_snprintf(char* str, size_t size, + _Printf_format_string_ const char* format, ...); +#else void ini_snprintf (char *str, size_t size, const char *format, ...) __attribute__((format (printf, 3, 4))); +#endif #ifdef __cplusplus #if 0 diff --git a/src/sc.c b/src/sc.c index b3df5d683..700d75794 100644 --- a/src/sc.c +++ b/src/sc.c @@ -46,6 +46,7 @@ typedef void (*sc_sig_t) (int); #ifdef _MSC_VER #define WIN32_LEAN_AND_MEAN #include +#include #endif #if _POSIX_C_SOURCE >= 199309L @@ -410,7 +411,8 @@ sc_malloc_aligned (size_t alignment, size_t size) "Returned NULL from aligned_alloc"); return data; } -#elif defined SC_HAVE_ANY_MEMALIGN && defined SC_HAVE_ALIGNED_MALLOC +#elif (defined SC_HAVE_ANY_MEMALIGN && defined SC_HAVE_ALIGNED_MALLOC) \ + || defined(_MSC_VER) /* MinGW, MSVC */ { void *data = _aligned_malloc (size, alignment); @@ -479,7 +481,9 @@ sc_free_aligned (void *ptr, size_t alignment) SC_ASSERT (sizeof (char **) >= sizeof (size_t)); SC_ASSERT (alignment > 0 && alignment % sizeof (void *) == 0); -#if defined SC_HAVE_ANY_MEMALIGN && \ +#ifdef _MSC_VER + _aligned_free(ptr); +#elif defined SC_HAVE_ANY_MEMALIGN && \ (defined SC_HAVE_POSIX_MEMALIGN || defined SC_HAVE_ALIGNED_ALLOC) free (ptr); #else @@ -542,7 +546,11 @@ sc_realloc_aligned (void *ptr, size_t alignment, size_t size) SC_ASSERT (alignment > 0 && alignment % sizeof (void *) == 0); SC_ASSERT (alignment == SC_MEMALIGN_BYTES); -#if defined SC_HAVE_ANY_MEMALIGN && \ +#ifdef _MSC_VER + /* alignment must be power of 2 */ + SC_ASSERT((alignment > 0) && ((alignment & (alignment - 1)) == 0)); + return _aligned_realloc(ptr, size, alignment); +#elif defined SC_HAVE_ANY_MEMALIGN && \ (defined SC_HAVE_POSIX_MEMALIGN || defined SC_HAVE_ALIGNED_ALLOC) /* the result is no longer aligned */ return realloc (ptr, size); diff --git a/src/sc.h b/src/sc.h index 9bd827c35..f70464ad4 100644 --- a/src/sc.h +++ b/src/sc.h @@ -236,6 +236,18 @@ typedef SSIZE_T ssize_t; #define SC_NOARGS #endif +/** ​Platform-specific noreturn and printf format string checks​​ */ +#ifdef _MSC_VER +#include /* _Printf_format_string_ */ +#define SC_NORETURN __declspec(noreturn) +#define SC_PRINTF_LIKE(fmt_idx, first_arg) +#define SC_PRINTF_FMT _Printf_format_string_ +#else +#define SC_NORETURN __attribute__((noreturn)) +#define SC_PRINTF_LIKE(fmt_idx, first_arg) __attribute__((format(printf, fmt_idx, first_arg))) +#define SC_PRINTF_FMT +#endif + /* this header is always included */ #include @@ -286,11 +298,9 @@ extern SC_DLL_PUBLIC int sc_trace_prio; * 2. Use macros in C instead of the function * This loses __FILE__ and __LINE__ in the C++ ..F log functions */ -void SC_ABORTF (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))) - __attribute__ ((noreturn)); -void SC_CHECK_ABORTF (int success, const char *fmt, ...) - __attribute__ ((format (printf, 2, 3))); +SC_NORETURN void SC_ABORTF(SC_PRINTF_FMT const char* fmt, ...) SC_PRINTF_LIKE(1, 2); +void SC_CHECK_ABORTF(int success, SC_PRINTF_FMT const char* fmt, ...) SC_PRINTF_LIKE(2, 3); + #ifndef __cplusplus #define SC_ABORTF(fmt,...) \ sc_abort_verbosef (__FILE__, __LINE__, (fmt), __VA_ARGS__) @@ -478,12 +488,12 @@ void SC_CHECK_ABORTF (int success, const char *fmt, ...) #define SC_GLOBAL_LOG(p,s) SC_GEN_LOG (sc_package_id, SC_LC_GLOBAL, (p), (s)) #define SC_LOG(p,s) SC_GEN_LOG (sc_package_id, SC_LC_NORMAL, (p), (s)) void SC_GEN_LOGF (int package, int category, int priority, - const char *fmt, ...) - __attribute__ ((format (printf, 4, 5))); -void SC_GLOBAL_LOGF (int priority, const char *fmt, ...) - __attribute__ ((format (printf, 2, 3))); -void SC_LOGF (int priority, const char *fmt, ...) - __attribute__ ((format (printf, 2, 3))); + SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(4, 5); +void SC_GLOBAL_LOGF (int priority, SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(2, 3); +void SC_LOGF (int priority, SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(2, 3); #ifndef __cplusplus #define SC_GEN_LOGF(package,category,priority,fmt,...) \ ((priority) < SC_LP_THRESHOLD ? (void) 0 : \ @@ -504,22 +514,22 @@ void SC_LOGF (int priority, const char *fmt, ...) #define SC_GLOBAL_PRODUCTION(s) SC_GLOBAL_LOG (SC_LP_PRODUCTION, (s)) #define SC_GLOBAL_ESSENTIAL(s) SC_GLOBAL_LOG (SC_LP_ESSENTIAL, (s)) #define SC_GLOBAL_LERROR(s) SC_GLOBAL_LOG (SC_LP_ERROR, (s)) -void SC_GLOBAL_TRACEF (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -void SC_GLOBAL_LDEBUGF (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -void SC_GLOBAL_VERBOSEF (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -void SC_GLOBAL_INFOF (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -void SC_GLOBAL_STATISTICSF (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -void SC_GLOBAL_PRODUCTIONF (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -void SC_GLOBAL_ESSENTIALF (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -void SC_GLOBAL_LERRORF (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); +void SC_GLOBAL_TRACEF (SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(1, 2); +void SC_GLOBAL_LDEBUGF (SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(1, 2); +void SC_GLOBAL_VERBOSEF (SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(1, 2); +void SC_GLOBAL_INFOF (SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(1, 2); +void SC_GLOBAL_STATISTICSF (SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(1, 2); +void SC_GLOBAL_PRODUCTIONF (SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(1, 2); +void SC_GLOBAL_ESSENTIALF (SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(1, 2); +void SC_GLOBAL_LERRORF (SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(1, 2); #ifndef __cplusplus #define SC_GLOBAL_TRACEF(fmt,...) \ SC_GLOBAL_LOGF (SC_LP_TRACE, (fmt), __VA_ARGS__) @@ -548,22 +558,22 @@ void SC_GLOBAL_LERRORF (const char *fmt, ...) #define SC_PRODUCTION(s) SC_LOG (SC_LP_PRODUCTION, (s)) #define SC_ESSENTIAL(s) SC_LOG (SC_LP_ESSENTIAL, (s)) #define SC_LERROR(s) SC_LOG (SC_LP_ERROR, (s)) -void SC_TRACEF (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -void SC_LDEBUGF (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -void SC_VERBOSEF (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -void SC_INFOF (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -void SC_STATISTICSF (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -void SC_PRODUCTIONF (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -void SC_ESSENTIALF (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -void SC_LERRORF (const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); +void SC_TRACEF (SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(1, 2); +void SC_LDEBUGF (SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(1, 2); +void SC_VERBOSEF (SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(1, 2); +void SC_INFOF (SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(1, 2); +void SC_STATISTICSF (SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(1, 2); +void SC_PRODUCTIONF (SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(1, 2); +void SC_ESSENTIALF (SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(1, 2); +void SC_LERRORF (SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(1, 2); #ifndef __cplusplus #define SC_TRACEF(fmt,...) \ SC_LOGF (SC_LP_TRACE, (fmt), __VA_ARGS__) @@ -676,8 +686,8 @@ void sc_log (const char *filename, int lineno, */ void sc_logf (const char *filename, int lineno, int package, int category, int priority, - const char *fmt, ...) - __attribute__ ((format (printf, 6, 7))); + SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(6, 7); /** The vprintf-style log function to be called by all packages. * Dispatches the log calls by package and filters by category and priority. @@ -706,28 +716,28 @@ void sc_log_indent_push (void); void sc_log_indent_pop (void); /** Print a stack trace, call the abort handler and then call abort (). */ -void sc_abort (void) - __attribute__ ((noreturn)); +SC_NORETURN +void sc_abort(void); /** Print a message to stderr and then call sc_abort (). */ +SC_NORETURN void sc_abort_verbose (const char *filename, int lineno, - const char *msg) - __attribute__ ((noreturn)); + const char *msg); /** Print a message to stderr and then call sc_abort (). */ +SC_NORETURN void sc_abort_verbosef (const char *filename, int lineno, - const char *fmt, ...) - __attribute__ ((format (printf, 3, 4))) - __attribute__ ((noreturn)); + SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(3, 4); /** Print a message to stderr and then call sc_abort (). */ +SC_NORETURN void sc_abort_verbosev (const char *filename, int lineno, - const char *fmt, va_list ap) - __attribute__ ((noreturn)); + const char *fmt, va_list ap); /** Collective abort where only root prints a message */ -void sc_abort_collective (const char *msg) - __attribute__ ((noreturn)); +SC_NORETURN +void sc_abort_collective (const char *msg); /** Register a software package with SC. * This function must only be called before additional threads are created. @@ -885,11 +895,11 @@ void sc_strcopy (char *dest, size_t size, const char *src); * if the allocation length of the string that is * defined by \a format is shorter than \a size. * \param [in] size Allocation length of \a str. - * \param [in] format Format string as in man (3) snprintf. + * \param [in] fmt Format string as in man (3) snprintf. */ void sc_snprintf (char *str, size_t size, - const char *format, ...) - __attribute__ ((format (printf, 3, 4))); + SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE(3, 4); /** Return the full version of libsc. * diff --git a/src/sc_mpi.h b/src/sc_mpi.h index 04f6e8101..0345a89e5 100644 --- a/src/sc_mpi.h +++ b/src/sc_mpi.h @@ -482,8 +482,12 @@ int sc_MPI_Finalize (void); * \param [in] mpicomm Communicator across which to abort. * \param [in] ecode Error code returned to the system. */ -int sc_MPI_Abort (sc_MPI_Comm mpicomm, int ecode) - __attribute__ ((noreturn)); +#ifdef _MSC_VER +__declspec(noreturn) +#else +__attribute__((noreturn)) +#endif +int sc_MPI_Abort (sc_MPI_Comm mpicomm, int ecode); /** Duplicate an MPI communicator. * \param [in] mpicomm Communicator to duplicate. diff --git a/src/sc_string.h b/src/sc_string.h index e535e2006..63b68c9e2 100644 --- a/src/sc_string.h +++ b/src/sc_string.h @@ -83,8 +83,8 @@ int sc_string_puts (sc_string_t * scs, const char *s); * \return Zero if everything has been appended and a * negative value when the input was truncated. */ -int sc_string_putf (sc_string_t * scs, const char *fmt, ...) - __attribute__ ((format (printf, 2, 3))); +int sc_string_putf (sc_string_t * scs, SC_PRINTF_FMT const char *fmt, ...) + SC_PRINTF_LIKE (2, 3); /** Append to the string object using a format string and a vararg pointer. * The maximum length will not be exceeded.