1 /*********************                                                        */
2 /*! \file safe_print.h
3  ** \verbatim
4  ** Top contributors (to current version):
5  **   Andres Noetzli
6  ** This file is part of the CVC4 project.
7  ** Copyright (c) 2009-2019 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
11  **
12  ** \brief Print functions that are safe to use in a signal handler.
13  **
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.
17  **
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).
23  **
24  ** This header is a "cvc4_private_library.h" header because it is private but
25  ** the safe_print functions are used in the driver. See also the description
26  ** of "statistics_registry.h" for more information on
27  ** "cvc4_private_library.h".
28  **/
29 
30 #include "cvc4_private_library.h"
31 
32 #ifndef __CVC4__SAFE_PRINT_H
33 #define __CVC4__SAFE_PRINT_H
34 
35 #if __cplusplus >= 201103L
36 // For c++11 and newer
37 #include <cstdint>
38 #else
39 #include <stdint.h>
40 #endif
41 
42 #include <unistd.h>
43 
44 #include "lib/clock_gettime.h"
45 #include "util/result.h"
46 
47 namespace CVC4 {
48 
49 /**
50  * Prints arrays of chars (e.g. string literals) of length N. Safe to use in a
51  * signal handler.
52  */
53 template <size_t N>
safe_print(int fd,const char (& msg)[N])54 void CVC4_PUBLIC safe_print(int fd, const char (&msg)[N]) {
55   ssize_t nb = N - 1;
56   if (write(fd, msg, nb) != nb) {
57     abort();
58   }
59 }
60 
61 /** Prints a variable of type T. Safe to use in a signal handler. */
62 template <typename T>
safe_print(int fd,const T & msg)63 void CVC4_PUBLIC safe_print(int fd, const T& msg) {
64   safe_print(fd, "<unsupported>");
65 }
66 
67 template <>
68 void CVC4_PUBLIC safe_print(int fd, const std::string& msg);
69 template <>
70 void CVC4_PUBLIC safe_print(int fd, const int64_t& _i);
71 template <>
72 void CVC4_PUBLIC safe_print(int fd, const int32_t& i);
73 template <>
74 void CVC4_PUBLIC safe_print(int fd, const uint64_t& _i);
75 template <>
76 void CVC4_PUBLIC safe_print(int fd, const uint32_t& i);
77 template <>
78 void CVC4_PUBLIC safe_print(int fd, const double& _d);
79 template <>
80 void CVC4_PUBLIC safe_print(int fd, const float& f);
81 template <>
82 void CVC4_PUBLIC safe_print(int fd, const bool& b);
83 template <>
84 void CVC4_PUBLIC safe_print(int fd, void* const& addr);
85 template <>
86 void CVC4_PUBLIC safe_print(int fd, const timespec& t);
87 
88 /** Prints an integer in hexadecimal. Safe to use in a signal handler. */
89 void safe_print_hex(int fd, uint64_t i);
90 
91 /**
92  * Prints a right aligned number. Fills up remaining space with zeros. Safe to
93  * use in a signal handler.
94  */
95 void safe_print_right_aligned(int fd, uint64_t i, ssize_t width);
96 
97 } /* CVC4 namespace */
98 
99 #endif /* __CVC4__SAFE_PRINT_H */
100