NEURON
wrap_sprintf.h
Go to the documentation of this file.
1 #include <cstdio>
2 #include <utility> // std::forward
3 #include <stdexcept>
4 #include <assert.h>
5 
6 namespace neuron {
7 /**
8  * @brief Redirect sprintf to snprintf if the buffer size can be deduced.
9  *
10  * This is useful to avoid deprecation warnings for sprintf. In general it works if the buffer is
11  * something like char buf[512] in the calling scope, but not if it is char* or char buf[].
12  */
13 template <std::size_t N, typename... Args>
14 int Sprintf(char (&buf)[N], const char* fmt, Args&&... args) {
15  if constexpr (sizeof...(Args) == 0) {
16  // try and work around a false positive from -Wformat-security when there are no arguments
17  return std::snprintf(buf, N, "%s", fmt);
18  } else {
19  return std::snprintf(buf, N, fmt, std::forward<Args>(args)...);
20  }
21 }
22 
23 /**
24  * @brief assert if the Sprintf format data does not fit into buf
25  */
26 template <std::size_t N, typename... Args>
27 void SprintfAsrt(char (&buf)[N], const char* fmt, Args&&... args) {
28  int sz = Sprintf(buf, fmt, std::forward<Args>(args)...);
29 #ifdef UNIT_TESTING
30  if (sz < 0 || std::size_t(sz) >= N) {
31  throw std::runtime_error("SprintfAsrt buffer too small or snprintf error");
32  }
33 #else
34  assert(sz >= 0 && std::size_t(sz) < N);
35 #endif
36 }
37 
38 } // namespace neuron
char buf[512]
Definition: init.cpp:13
#define assert(ex)
Definition: hocassrt.h:24
In mechanism libraries, cannot use auto const token = nrn_ensure_model_data_are_sorted(); because the...
Definition: tnode.hpp:17
void SprintfAsrt(char(&buf)[N], const char *fmt, Args &&... args)
assert if the Sprintf format data does not fit into buf
Definition: wrap_sprintf.h:27
int Sprintf(char(&buf)[N], const char *fmt, Args &&... args)
Redirect sprintf to snprintf if the buffer size can be deduced.
Definition: wrap_sprintf.h:14