1 /*
2  * Macros.hpp
3  *
4  * Copyright (C) 2021 by RStudio, PBC
5  *
6  * Unless you have received this program directly from RStudio pursuant
7  * to the terms of a commercial license agreement with RStudio, then
8  * this program is licensed to you under the terms of version 3 of the
9  * GNU Affero General Public License. This program is distributed WITHOUT
10  * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
11  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
12  * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
13  *
14  */
15 
16 #ifndef CORE_MACROS_HPP
17 #define CORE_MACROS_HPP
18 
19 #include <iostream>
20 #include <iomanip>
21 
22 #define RS_CALL_ONCE()                                                         \
23    do                                                                          \
24    {                                                                           \
25       static bool s_once = false;                                              \
26       if (s_once) return;                                                      \
27       s_once = true;                                                           \
28    } while (0)
29 
30 /* Work around Xcode indentation rules */
31 #define RS_BEGIN_NAMESPACE(__X__) namespace __X__ {
32 #define RS_END_NAMESPACE(__X__) }
33 
34 /* Compatibility Macros */
35 #if defined(_MSVC_LANG) && _MSVC_LANG >= 201103L
36 # define MOVE_THREAD(t) (std::move(t))
37 #elif __cplusplus < 201103L
38 # define MOVE_THREAD(t) (t.move())
39 #else
40 # define MOVE_THREAD(t) (std::move(t))
41 #endif
42 
43 /* Utility Macros */
44 
45 #if defined(__GNUC__)
46 # define LIKELY(x)   __builtin_expect(!!(x), 1)
47 # define UNLIKELY(x) __builtin_expect(!!(x), 0)
48 #else
49 # define LIKELY(x)   (x)
50 # define UNLIKELY(x) (x)
51 #endif
52 
53 /* Logging Macros */
54 
55 // re-define this in implementation files for labelled debugging
56 #ifndef RSTUDIO_DEBUG_LABEL
57 # define RSTUDIO_DEBUG_LABEL "rstudio"
58 #endif
59 
60 /* Debug logging macros */
61 #ifndef RSTUDIO_ENABLE_DEBUG_MACROS
62 
63 # define RSTUDIO_DEBUG(x) do {} while (0)
64 # define RSTUDIO_DEBUG_LINE(x) do {} while (0)
65 # define RSTUDIO_DEBUG_BLOCK(x) if (false)
66 # define RSTUDIO_LOG_OBJECT(x)
67 
68 #else
69 
70 #include <core/Debug.hpp>
71 
72 #define RSTUDIO_DEBUG(x)                                                       \
73    do                                                                          \
74    {                                                                           \
75          std::cerr << "(" << RSTUDIO_DEBUG_LABEL << ":" << std::setw(4)        \
76                    << std::setfill('0') << __LINE__ << "): " << x              \
77                    << std::endl;                                               \
78    } while (0)
79 
80 # define RSTUDIO_DEBUG_LINE(x)                                                 \
81    do                                                                          \
82    {                                                                           \
83       std::string file = std::string(__FILE__);                                \
84       std::string shortFile = file.substr(file.rfind("/") + 1);                \
85       std::cerr << "(" << RSTUDIO_DEBUG_LABEL << ")"                           \
86                 << "[" << shortFile << ":" << __LINE__ << "]: " << std::endl   \
87                 << x << std::endl;                                             \
88    } while (0)
89 
90 # define RSTUDIO_DEBUG_BLOCK(x)                                                \
91    if (strlen(x))                                                              \
92       std::cerr << "(" << RSTUDIO_DEBUG_LABEL << ":" << std::setw(4)           \
93                 << std::setfill('0') << __LINE__ << "): " << x << std::endl;   \
94    if (true)
95 
96 # define RSTUDIO_LOG_OBJECT(x)                                                 \
97    do                                                                          \
98    {                                                                           \
99       ::rstudio::core::debug::print(x);                                        \
100    } while (0)
101 
102 #endif /* Debug logging macros */
103 
104 #ifndef RSTUDIO_DEBUG_MACROS_DISABLED
105 
106 # ifndef DEBUG
107 #  define DEBUG RSTUDIO_DEBUG
108 # endif
109 
110 # ifndef DEBUG_LINE
111 #  define DEBUG_LINE RSTUDIO_DEBUG_LINE
112 # endif
113 
114 # ifndef DEBUG_BLOCK
115 #  define DEBUG_BLOCK RSTUDIO_DEBUG_BLOCK
116 # endif
117 
118 # ifndef LOG_OBJECT
119 #  define LOG_OBJECT(x) RSTUDIO_LOG_OBJECT(x)
120 # endif
121 
122 #endif
123 
124 #endif
125