1 /********************* */
4 ** Top contributors (to current version):
5 ** Andres Noetzli, Mathias Preiner
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8 ** in the top-level source directory and their institutional affiliations.
9 ** All rights reserved. See the file COPYING in the top-level source
10 ** directory for licensing information.\endverbatim
12 ** \brief Print functions that are safe to use in a signal handler.
14 ** Signal handlers only allow a very limited set of operations, e.g. dynamic
15 ** memory allocation is not possible. This set of functions can be used to
16 ** print information from a signal handler.
18 ** The safe_print function takes a template parameter T and prints an argument
19 ** of type const T& to avoid copying, e.g. when printing std::strings. For
20 ** consistency, we also pass primitive types by reference (otherwise, functions
21 ** in statistics_registry.h would require specialization or we would have to
22 ** use function overloading).
24 ** If there exists a function `toString(obj)` for a given object, it will be
25 ** used automatically. This is useful for printing enum values for example.
26 ** IMPORTANT: The `toString(obj)` function *must not* perform any allocations
27 ** or call other functions that are not async-signal-safe.
29 ** This header is a "cvc4_private_library.h" header because it is private but
30 ** the safe_print functions are used in the driver. See also the description
31 ** of "statistics_registry.h" for more information on
32 ** "cvc4_private_library.h".
35 #include "cvc4_private_library.h"
37 #ifndef CVC4__SAFE_PRINT_H
38 #define CVC4__SAFE_PRINT_H
45 #include "cvc4_export.h"
50 * Prints arrays of chars (e.g. string literals) of length N. Safe to use in a
54 void CVC4_EXPORT
safe_print(int fd
, const char (&msg
)[N
])
57 if (write(fd
, msg
, nb
) != nb
) {
63 * The default method for converting an object to a string for safe printing.
64 * This method simply returns "<unsupported>". The `long` argument is used to
65 * indicate that we do not prefer this method over the version that calls
69 const char* toStringImpl(const T
& obj
, long)
71 return "<unsupported>";
75 * Returns the result of calling `toString(obj)`. This method is only defined
76 * if such an overload of `toString()` exists. To detect the existence of such
77 * a method, we use SFINAE and a trailing return type. The trailing return type
78 * is necessary because it allows us to refer to `obj`. The `int` argument is
79 * used to prefer this version of the function instead of the one that prints
83 auto toStringImpl(const T
& obj
, int) -> decltype(toString(obj
))
89 * Prints a variable of type T. Safe to use in a signal handler. The default
90 * implementation either prints "<unsupported>" or the result of calling
91 * `toString(obj)` if such a method exists (this is useful for printing enum
92 * values for example without implementing a template specialization here).
94 * @param fd The file descriptor to print to
95 * @param obj The object to print
98 void CVC4_EXPORT
safe_print(int fd
, const T
& obj
)
101 toStringImpl(obj
, /* prefer the method that uses `toString()` */ 0);
102 ssize_t slen
= static_cast<ssize_t
>(strlen(s
));
103 if (write(fd
, s
, slen
) != slen
)
110 void CVC4_EXPORT
safe_print(int fd
, const std::string
& msg
);
112 void CVC4_EXPORT
safe_print(int fd
, const int64_t& _i
);
114 void CVC4_EXPORT
safe_print(int fd
, const int32_t& i
);
116 void CVC4_EXPORT
safe_print(int fd
, const uint64_t& _i
);
118 void CVC4_EXPORT
safe_print(int fd
, const uint32_t& i
);
120 void CVC4_EXPORT
safe_print(int fd
, const double& _d
);
122 void CVC4_EXPORT
safe_print(int fd
, const float& f
);
124 void CVC4_EXPORT
safe_print(int fd
, const bool& b
);
126 void CVC4_EXPORT
safe_print(int fd
, void* const& addr
);
128 void CVC4_EXPORT
safe_print(int fd
, const timespec
& t
);
130 /** Prints an integer in hexadecimal. Safe to use in a signal handler. */
131 void safe_print_hex(int fd
, uint64_t i
);
134 * Prints a right aligned number. Fills up remaining space with zeros. Safe to
135 * use in a signal handler.
137 void safe_print_right_aligned(int fd
, uint64_t i
, ssize_t width
);
141 #endif /* CVC4__SAFE_PRINT_H */