1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright © 2017 Google, Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * This is part of HarfBuzz, a text shaping library. 5cb93a386Sopenharmony_ci * 6cb93a386Sopenharmony_ci * Permission is hereby granted, without written agreement and without 7cb93a386Sopenharmony_ci * license or royalty fees, to use, copy, modify, and distribute this 8cb93a386Sopenharmony_ci * software and its documentation for any purpose, provided that the 9cb93a386Sopenharmony_ci * above copyright notice and the following two paragraphs appear in 10cb93a386Sopenharmony_ci * all copies of this software. 11cb93a386Sopenharmony_ci * 12cb93a386Sopenharmony_ci * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13cb93a386Sopenharmony_ci * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14cb93a386Sopenharmony_ci * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15cb93a386Sopenharmony_ci * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16cb93a386Sopenharmony_ci * DAMAGE. 17cb93a386Sopenharmony_ci * 18cb93a386Sopenharmony_ci * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19cb93a386Sopenharmony_ci * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20cb93a386Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21cb93a386Sopenharmony_ci * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22cb93a386Sopenharmony_ci * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23cb93a386Sopenharmony_ci * 24cb93a386Sopenharmony_ci * Google Author(s): Behdad Esfahbod 25cb93a386Sopenharmony_ci */ 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ci#ifndef HB_DEBUG_HH 28cb93a386Sopenharmony_ci#define HB_DEBUG_HH 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ci#include "hb.hh" 31cb93a386Sopenharmony_ci#include "hb-atomic.hh" 32cb93a386Sopenharmony_ci#include "hb-algs.hh" 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_ci#ifndef HB_DEBUG 36cb93a386Sopenharmony_ci#define HB_DEBUG 0 37cb93a386Sopenharmony_ci#endif 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_ci/* 41cb93a386Sopenharmony_ci * Global runtime options. 42cb93a386Sopenharmony_ci */ 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_cistruct hb_options_t 45cb93a386Sopenharmony_ci{ 46cb93a386Sopenharmony_ci bool unused : 1; /* In-case sign bit is here. */ 47cb93a386Sopenharmony_ci bool initialized : 1; 48cb93a386Sopenharmony_ci bool uniscribe_bug_compatible : 1; 49cb93a386Sopenharmony_ci}; 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_ciunion hb_options_union_t { 52cb93a386Sopenharmony_ci int i; 53cb93a386Sopenharmony_ci hb_options_t opts; 54cb93a386Sopenharmony_ci}; 55cb93a386Sopenharmony_cistatic_assert ((sizeof (hb_atomic_int_t) >= sizeof (hb_options_union_t)), ""); 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ciHB_INTERNAL void 58cb93a386Sopenharmony_ci_hb_options_init (); 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ciextern HB_INTERNAL hb_atomic_int_t _hb_options; 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_cistatic inline hb_options_t 63cb93a386Sopenharmony_cihb_options () 64cb93a386Sopenharmony_ci{ 65cb93a386Sopenharmony_ci#ifdef HB_NO_GETENV 66cb93a386Sopenharmony_ci return hb_options_t (); 67cb93a386Sopenharmony_ci#endif 68cb93a386Sopenharmony_ci /* Make a local copy, so we can access bitfield threadsafely. */ 69cb93a386Sopenharmony_ci hb_options_union_t u; 70cb93a386Sopenharmony_ci u.i = _hb_options.get_relaxed (); 71cb93a386Sopenharmony_ci 72cb93a386Sopenharmony_ci if (unlikely (!u.i)) 73cb93a386Sopenharmony_ci { 74cb93a386Sopenharmony_ci _hb_options_init (); 75cb93a386Sopenharmony_ci u.i = _hb_options.get_relaxed (); 76cb93a386Sopenharmony_ci } 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ci return u.opts; 79cb93a386Sopenharmony_ci} 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ci/* 83cb93a386Sopenharmony_ci * Debug output (needs enabling at compile time.) 84cb93a386Sopenharmony_ci */ 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_cistatic inline bool 87cb93a386Sopenharmony_ci_hb_debug (unsigned int level, 88cb93a386Sopenharmony_ci unsigned int max_level) 89cb93a386Sopenharmony_ci{ 90cb93a386Sopenharmony_ci return level < max_level; 91cb93a386Sopenharmony_ci} 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_ci#define DEBUG_LEVEL_ENABLED(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT)) 94cb93a386Sopenharmony_ci#define DEBUG_ENABLED(WHAT) (DEBUG_LEVEL_ENABLED (WHAT, 0)) 95cb93a386Sopenharmony_ci 96cb93a386Sopenharmony_cistatic inline void 97cb93a386Sopenharmony_ci_hb_print_func (const char *func) 98cb93a386Sopenharmony_ci{ 99cb93a386Sopenharmony_ci if (func) 100cb93a386Sopenharmony_ci { 101cb93a386Sopenharmony_ci unsigned int func_len = strlen (func); 102cb93a386Sopenharmony_ci /* Skip "static" */ 103cb93a386Sopenharmony_ci if (0 == strncmp (func, "static ", 7)) 104cb93a386Sopenharmony_ci func += 7; 105cb93a386Sopenharmony_ci /* Skip "typename" */ 106cb93a386Sopenharmony_ci if (0 == strncmp (func, "typename ", 9)) 107cb93a386Sopenharmony_ci func += 9; 108cb93a386Sopenharmony_ci /* Skip return type */ 109cb93a386Sopenharmony_ci const char *space = strchr (func, ' '); 110cb93a386Sopenharmony_ci if (space) 111cb93a386Sopenharmony_ci func = space + 1; 112cb93a386Sopenharmony_ci /* Skip parameter list */ 113cb93a386Sopenharmony_ci const char *paren = strchr (func, '('); 114cb93a386Sopenharmony_ci if (paren) 115cb93a386Sopenharmony_ci func_len = paren - func; 116cb93a386Sopenharmony_ci fprintf (stderr, "%.*s", func_len, func); 117cb93a386Sopenharmony_ci } 118cb93a386Sopenharmony_ci} 119cb93a386Sopenharmony_ci 120cb93a386Sopenharmony_citemplate <int max_level> static inline void 121cb93a386Sopenharmony_ci_hb_debug_msg_va (const char *what, 122cb93a386Sopenharmony_ci const void *obj, 123cb93a386Sopenharmony_ci const char *func, 124cb93a386Sopenharmony_ci bool indented, 125cb93a386Sopenharmony_ci unsigned int level, 126cb93a386Sopenharmony_ci int level_dir, 127cb93a386Sopenharmony_ci const char *message, 128cb93a386Sopenharmony_ci va_list ap) HB_PRINTF_FUNC(7, 0); 129cb93a386Sopenharmony_citemplate <int max_level> static inline void 130cb93a386Sopenharmony_ci_hb_debug_msg_va (const char *what, 131cb93a386Sopenharmony_ci const void *obj, 132cb93a386Sopenharmony_ci const char *func, 133cb93a386Sopenharmony_ci bool indented, 134cb93a386Sopenharmony_ci unsigned int level, 135cb93a386Sopenharmony_ci int level_dir, 136cb93a386Sopenharmony_ci const char *message, 137cb93a386Sopenharmony_ci va_list ap) 138cb93a386Sopenharmony_ci{ 139cb93a386Sopenharmony_ci if (!_hb_debug (level, max_level)) 140cb93a386Sopenharmony_ci return; 141cb93a386Sopenharmony_ci 142cb93a386Sopenharmony_ci fprintf (stderr, "%-10s", what ? what : ""); 143cb93a386Sopenharmony_ci 144cb93a386Sopenharmony_ci if (obj) 145cb93a386Sopenharmony_ci fprintf (stderr, "(%*p) ", (unsigned int) (2 * sizeof (void *)), obj); 146cb93a386Sopenharmony_ci else 147cb93a386Sopenharmony_ci fprintf (stderr, " %*s ", (unsigned int) (2 * sizeof (void *)), ""); 148cb93a386Sopenharmony_ci 149cb93a386Sopenharmony_ci if (indented) { 150cb93a386Sopenharmony_ci#define VBAR "\342\224\202" /* U+2502 BOX DRAWINGS LIGHT VERTICAL */ 151cb93a386Sopenharmony_ci#define VRBAR "\342\224\234" /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ 152cb93a386Sopenharmony_ci#define DLBAR "\342\225\256" /* U+256E BOX DRAWINGS LIGHT ARC DOWN AND LEFT */ 153cb93a386Sopenharmony_ci#define ULBAR "\342\225\257" /* U+256F BOX DRAWINGS LIGHT ARC UP AND LEFT */ 154cb93a386Sopenharmony_ci#define LBAR "\342\225\264" /* U+2574 BOX DRAWINGS LIGHT LEFT */ 155cb93a386Sopenharmony_ci static const char bars[] = 156cb93a386Sopenharmony_ci VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR 157cb93a386Sopenharmony_ci VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR 158cb93a386Sopenharmony_ci VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR 159cb93a386Sopenharmony_ci VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR 160cb93a386Sopenharmony_ci VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR; 161cb93a386Sopenharmony_ci fprintf (stderr, "%2u %s" VRBAR "%s", 162cb93a386Sopenharmony_ci level, 163cb93a386Sopenharmony_ci bars + sizeof (bars) - 1 - hb_min ((unsigned int) sizeof (bars) - 1, (unsigned int) (sizeof (VBAR) - 1) * level), 164cb93a386Sopenharmony_ci level_dir ? (level_dir > 0 ? DLBAR : ULBAR) : LBAR); 165cb93a386Sopenharmony_ci } else 166cb93a386Sopenharmony_ci fprintf (stderr, " " VRBAR LBAR); 167cb93a386Sopenharmony_ci 168cb93a386Sopenharmony_ci _hb_print_func (func); 169cb93a386Sopenharmony_ci 170cb93a386Sopenharmony_ci if (message) 171cb93a386Sopenharmony_ci { 172cb93a386Sopenharmony_ci fprintf (stderr, ": "); 173cb93a386Sopenharmony_ci vfprintf (stderr, message, ap); 174cb93a386Sopenharmony_ci } 175cb93a386Sopenharmony_ci 176cb93a386Sopenharmony_ci fprintf (stderr, "\n"); 177cb93a386Sopenharmony_ci} 178cb93a386Sopenharmony_citemplate <> inline void HB_PRINTF_FUNC(7, 0) 179cb93a386Sopenharmony_ci_hb_debug_msg_va<0> (const char *what HB_UNUSED, 180cb93a386Sopenharmony_ci const void *obj HB_UNUSED, 181cb93a386Sopenharmony_ci const char *func HB_UNUSED, 182cb93a386Sopenharmony_ci bool indented HB_UNUSED, 183cb93a386Sopenharmony_ci unsigned int level HB_UNUSED, 184cb93a386Sopenharmony_ci int level_dir HB_UNUSED, 185cb93a386Sopenharmony_ci const char *message HB_UNUSED, 186cb93a386Sopenharmony_ci va_list ap HB_UNUSED) {} 187cb93a386Sopenharmony_ci 188cb93a386Sopenharmony_citemplate <int max_level> static inline void 189cb93a386Sopenharmony_ci_hb_debug_msg (const char *what, 190cb93a386Sopenharmony_ci const void *obj, 191cb93a386Sopenharmony_ci const char *func, 192cb93a386Sopenharmony_ci bool indented, 193cb93a386Sopenharmony_ci unsigned int level, 194cb93a386Sopenharmony_ci int level_dir, 195cb93a386Sopenharmony_ci const char *message, 196cb93a386Sopenharmony_ci ...) HB_PRINTF_FUNC(7, 8); 197cb93a386Sopenharmony_citemplate <int max_level> static inline void HB_PRINTF_FUNC(7, 8) 198cb93a386Sopenharmony_ci_hb_debug_msg (const char *what, 199cb93a386Sopenharmony_ci const void *obj, 200cb93a386Sopenharmony_ci const char *func, 201cb93a386Sopenharmony_ci bool indented, 202cb93a386Sopenharmony_ci unsigned int level, 203cb93a386Sopenharmony_ci int level_dir, 204cb93a386Sopenharmony_ci const char *message, 205cb93a386Sopenharmony_ci ...) 206cb93a386Sopenharmony_ci{ 207cb93a386Sopenharmony_ci va_list ap; 208cb93a386Sopenharmony_ci va_start (ap, message); 209cb93a386Sopenharmony_ci _hb_debug_msg_va<max_level> (what, obj, func, indented, level, level_dir, message, ap); 210cb93a386Sopenharmony_ci va_end (ap); 211cb93a386Sopenharmony_ci} 212cb93a386Sopenharmony_citemplate <> inline void 213cb93a386Sopenharmony_ci_hb_debug_msg<0> (const char *what HB_UNUSED, 214cb93a386Sopenharmony_ci const void *obj HB_UNUSED, 215cb93a386Sopenharmony_ci const char *func HB_UNUSED, 216cb93a386Sopenharmony_ci bool indented HB_UNUSED, 217cb93a386Sopenharmony_ci unsigned int level HB_UNUSED, 218cb93a386Sopenharmony_ci int level_dir HB_UNUSED, 219cb93a386Sopenharmony_ci const char *message HB_UNUSED, 220cb93a386Sopenharmony_ci ...) HB_PRINTF_FUNC(7, 8); 221cb93a386Sopenharmony_citemplate <> inline void HB_PRINTF_FUNC(7, 8) 222cb93a386Sopenharmony_ci_hb_debug_msg<0> (const char *what HB_UNUSED, 223cb93a386Sopenharmony_ci const void *obj HB_UNUSED, 224cb93a386Sopenharmony_ci const char *func HB_UNUSED, 225cb93a386Sopenharmony_ci bool indented HB_UNUSED, 226cb93a386Sopenharmony_ci unsigned int level HB_UNUSED, 227cb93a386Sopenharmony_ci int level_dir HB_UNUSED, 228cb93a386Sopenharmony_ci const char *message HB_UNUSED, 229cb93a386Sopenharmony_ci ...) {} 230cb93a386Sopenharmony_ci 231cb93a386Sopenharmony_ci#define DEBUG_MSG_LEVEL(WHAT, OBJ, LEVEL, LEVEL_DIR, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), nullptr, true, (LEVEL), (LEVEL_DIR), __VA_ARGS__) 232cb93a386Sopenharmony_ci#define DEBUG_MSG(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), nullptr, false, 0, 0, __VA_ARGS__) 233cb93a386Sopenharmony_ci#define DEBUG_MSG_FUNC(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), HB_FUNC, false, 0, 0, __VA_ARGS__) 234cb93a386Sopenharmony_ci 235cb93a386Sopenharmony_ci 236cb93a386Sopenharmony_ci/* 237cb93a386Sopenharmony_ci * Printer 238cb93a386Sopenharmony_ci */ 239cb93a386Sopenharmony_ci 240cb93a386Sopenharmony_citemplate <typename T> 241cb93a386Sopenharmony_cistruct hb_printer_t { 242cb93a386Sopenharmony_ci const char *print (const T&) { return "something"; } 243cb93a386Sopenharmony_ci}; 244cb93a386Sopenharmony_ci 245cb93a386Sopenharmony_citemplate <> 246cb93a386Sopenharmony_cistruct hb_printer_t<bool> { 247cb93a386Sopenharmony_ci const char *print (bool v) { return v ? "true" : "false"; } 248cb93a386Sopenharmony_ci}; 249cb93a386Sopenharmony_ci 250cb93a386Sopenharmony_citemplate <> 251cb93a386Sopenharmony_cistruct hb_printer_t<hb_empty_t> { 252cb93a386Sopenharmony_ci const char *print (hb_empty_t) { return ""; } 253cb93a386Sopenharmony_ci}; 254cb93a386Sopenharmony_ci 255cb93a386Sopenharmony_ci 256cb93a386Sopenharmony_ci/* 257cb93a386Sopenharmony_ci * Trace 258cb93a386Sopenharmony_ci */ 259cb93a386Sopenharmony_ci 260cb93a386Sopenharmony_citemplate <typename T> 261cb93a386Sopenharmony_cistatic inline void _hb_warn_no_return (bool returned) 262cb93a386Sopenharmony_ci{ 263cb93a386Sopenharmony_ci if (unlikely (!returned)) { 264cb93a386Sopenharmony_ci fprintf (stderr, "OUCH, returned with no call to return_trace(). This is a bug, please report.\n"); 265cb93a386Sopenharmony_ci } 266cb93a386Sopenharmony_ci} 267cb93a386Sopenharmony_citemplate <> 268cb93a386Sopenharmony_ci/*static*/ inline void _hb_warn_no_return<hb_empty_t> (bool returned HB_UNUSED) 269cb93a386Sopenharmony_ci{} 270cb93a386Sopenharmony_ci 271cb93a386Sopenharmony_citemplate <int max_level, typename ret_t> 272cb93a386Sopenharmony_cistruct hb_auto_trace_t 273cb93a386Sopenharmony_ci{ 274cb93a386Sopenharmony_ci explicit inline hb_auto_trace_t (unsigned int *plevel_, 275cb93a386Sopenharmony_ci const char *what_, 276cb93a386Sopenharmony_ci const void *obj_, 277cb93a386Sopenharmony_ci const char *func, 278cb93a386Sopenharmony_ci const char *message, 279cb93a386Sopenharmony_ci ...) HB_PRINTF_FUNC(6, 7) 280cb93a386Sopenharmony_ci : plevel (plevel_), what (what_), obj (obj_), returned (false) 281cb93a386Sopenharmony_ci { 282cb93a386Sopenharmony_ci if (plevel) ++*plevel; 283cb93a386Sopenharmony_ci 284cb93a386Sopenharmony_ci va_list ap; 285cb93a386Sopenharmony_ci va_start (ap, message); 286cb93a386Sopenharmony_ci _hb_debug_msg_va<max_level> (what, obj, func, true, plevel ? *plevel : 0, +1, message, ap); 287cb93a386Sopenharmony_ci va_end (ap); 288cb93a386Sopenharmony_ci } 289cb93a386Sopenharmony_ci ~hb_auto_trace_t () 290cb93a386Sopenharmony_ci { 291cb93a386Sopenharmony_ci _hb_warn_no_return<ret_t> (returned); 292cb93a386Sopenharmony_ci if (!returned) { 293cb93a386Sopenharmony_ci _hb_debug_msg<max_level> (what, obj, nullptr, true, plevel ? *plevel : 1, -1, " "); 294cb93a386Sopenharmony_ci } 295cb93a386Sopenharmony_ci if (plevel) --*plevel; 296cb93a386Sopenharmony_ci } 297cb93a386Sopenharmony_ci 298cb93a386Sopenharmony_ci template <typename T> 299cb93a386Sopenharmony_ci T ret (T&& v, 300cb93a386Sopenharmony_ci const char *func = "", 301cb93a386Sopenharmony_ci unsigned int line = 0) 302cb93a386Sopenharmony_ci { 303cb93a386Sopenharmony_ci if (unlikely (returned)) { 304cb93a386Sopenharmony_ci fprintf (stderr, "OUCH, double calls to return_trace(). This is a bug, please report.\n"); 305cb93a386Sopenharmony_ci return std::forward<T> (v); 306cb93a386Sopenharmony_ci } 307cb93a386Sopenharmony_ci 308cb93a386Sopenharmony_ci _hb_debug_msg<max_level> (what, obj, func, true, plevel ? *plevel : 1, -1, 309cb93a386Sopenharmony_ci "return %s (line %d)", 310cb93a386Sopenharmony_ci hb_printer_t<hb_decay<decltype (v)>>().print (v), line); 311cb93a386Sopenharmony_ci if (plevel) --*plevel; 312cb93a386Sopenharmony_ci plevel = nullptr; 313cb93a386Sopenharmony_ci returned = true; 314cb93a386Sopenharmony_ci return std::forward<T> (v); 315cb93a386Sopenharmony_ci } 316cb93a386Sopenharmony_ci 317cb93a386Sopenharmony_ci private: 318cb93a386Sopenharmony_ci unsigned int *plevel; 319cb93a386Sopenharmony_ci const char *what; 320cb93a386Sopenharmony_ci const void *obj; 321cb93a386Sopenharmony_ci bool returned; 322cb93a386Sopenharmony_ci}; 323cb93a386Sopenharmony_citemplate <typename ret_t> /* Make sure we don't use hb_auto_trace_t when not tracing. */ 324cb93a386Sopenharmony_cistruct hb_auto_trace_t<0, ret_t> 325cb93a386Sopenharmony_ci{ 326cb93a386Sopenharmony_ci explicit inline hb_auto_trace_t (unsigned int *plevel_, 327cb93a386Sopenharmony_ci const char *what_, 328cb93a386Sopenharmony_ci const void *obj_, 329cb93a386Sopenharmony_ci const char *func, 330cb93a386Sopenharmony_ci const char *message, 331cb93a386Sopenharmony_ci ...) HB_PRINTF_FUNC(6, 7) {} 332cb93a386Sopenharmony_ci 333cb93a386Sopenharmony_ci template <typename T> 334cb93a386Sopenharmony_ci T ret (T&& v, 335cb93a386Sopenharmony_ci const char *func HB_UNUSED = nullptr, 336cb93a386Sopenharmony_ci unsigned int line HB_UNUSED = 0) { return std::forward<T> (v); } 337cb93a386Sopenharmony_ci}; 338cb93a386Sopenharmony_ci 339cb93a386Sopenharmony_ci/* For disabled tracing; optimize out everything. 340cb93a386Sopenharmony_ci * https://github.com/harfbuzz/harfbuzz/pull/605 */ 341cb93a386Sopenharmony_citemplate <typename ret_t> 342cb93a386Sopenharmony_cistruct hb_no_trace_t { 343cb93a386Sopenharmony_ci template <typename T> 344cb93a386Sopenharmony_ci T ret (T&& v, 345cb93a386Sopenharmony_ci const char *func HB_UNUSED = nullptr, 346cb93a386Sopenharmony_ci unsigned int line HB_UNUSED = 0) { return std::forward<T> (v); } 347cb93a386Sopenharmony_ci}; 348cb93a386Sopenharmony_ci 349cb93a386Sopenharmony_ci#define return_trace(RET) return trace.ret (RET, HB_FUNC, __LINE__) 350cb93a386Sopenharmony_ci 351cb93a386Sopenharmony_ci 352cb93a386Sopenharmony_ci/* 353cb93a386Sopenharmony_ci * Instances. 354cb93a386Sopenharmony_ci */ 355cb93a386Sopenharmony_ci 356cb93a386Sopenharmony_ci#ifndef HB_DEBUG_ARABIC 357cb93a386Sopenharmony_ci#define HB_DEBUG_ARABIC (HB_DEBUG+0) 358cb93a386Sopenharmony_ci#endif 359cb93a386Sopenharmony_ci 360cb93a386Sopenharmony_ci#ifndef HB_DEBUG_BLOB 361cb93a386Sopenharmony_ci#define HB_DEBUG_BLOB (HB_DEBUG+0) 362cb93a386Sopenharmony_ci#endif 363cb93a386Sopenharmony_ci 364cb93a386Sopenharmony_ci#ifndef HB_DEBUG_CORETEXT 365cb93a386Sopenharmony_ci#define HB_DEBUG_CORETEXT (HB_DEBUG+0) 366cb93a386Sopenharmony_ci#endif 367cb93a386Sopenharmony_ci 368cb93a386Sopenharmony_ci#ifndef HB_DEBUG_DIRECTWRITE 369cb93a386Sopenharmony_ci#define HB_DEBUG_DIRECTWRITE (HB_DEBUG+0) 370cb93a386Sopenharmony_ci#endif 371cb93a386Sopenharmony_ci 372cb93a386Sopenharmony_ci#ifndef HB_DEBUG_FT 373cb93a386Sopenharmony_ci#define HB_DEBUG_FT (HB_DEBUG+0) 374cb93a386Sopenharmony_ci#endif 375cb93a386Sopenharmony_ci 376cb93a386Sopenharmony_ci#ifndef HB_DEBUG_OBJECT 377cb93a386Sopenharmony_ci#define HB_DEBUG_OBJECT (HB_DEBUG+0) 378cb93a386Sopenharmony_ci#endif 379cb93a386Sopenharmony_ci 380cb93a386Sopenharmony_ci#ifndef HB_DEBUG_SHAPE_PLAN 381cb93a386Sopenharmony_ci#define HB_DEBUG_SHAPE_PLAN (HB_DEBUG+0) 382cb93a386Sopenharmony_ci#endif 383cb93a386Sopenharmony_ci 384cb93a386Sopenharmony_ci#ifndef HB_DEBUG_UNISCRIBE 385cb93a386Sopenharmony_ci#define HB_DEBUG_UNISCRIBE (HB_DEBUG+0) 386cb93a386Sopenharmony_ci#endif 387cb93a386Sopenharmony_ci 388cb93a386Sopenharmony_ci/* 389cb93a386Sopenharmony_ci * With tracing. 390cb93a386Sopenharmony_ci */ 391cb93a386Sopenharmony_ci 392cb93a386Sopenharmony_ci#ifndef HB_DEBUG_APPLY 393cb93a386Sopenharmony_ci#define HB_DEBUG_APPLY (HB_DEBUG+0) 394cb93a386Sopenharmony_ci#endif 395cb93a386Sopenharmony_ci#if HB_DEBUG_APPLY 396cb93a386Sopenharmony_ci#define TRACE_APPLY(this) \ 397cb93a386Sopenharmony_ci hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \ 398cb93a386Sopenharmony_ci (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 399cb93a386Sopenharmony_ci "idx %d gid %u lookup %d", \ 400cb93a386Sopenharmony_ci c->buffer->idx, c->buffer->cur().codepoint, (int) c->lookup_index) 401cb93a386Sopenharmony_ci#else 402cb93a386Sopenharmony_ci#define TRACE_APPLY(this) hb_no_trace_t<bool> trace 403cb93a386Sopenharmony_ci#endif 404cb93a386Sopenharmony_ci 405cb93a386Sopenharmony_ci#ifndef HB_DEBUG_SANITIZE 406cb93a386Sopenharmony_ci#define HB_DEBUG_SANITIZE (HB_DEBUG+0) 407cb93a386Sopenharmony_ci#endif 408cb93a386Sopenharmony_ci#if HB_DEBUG_SANITIZE 409cb93a386Sopenharmony_ci#define TRACE_SANITIZE(this) \ 410cb93a386Sopenharmony_ci hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \ 411cb93a386Sopenharmony_ci (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 412cb93a386Sopenharmony_ci " ") 413cb93a386Sopenharmony_ci#else 414cb93a386Sopenharmony_ci#define TRACE_SANITIZE(this) hb_no_trace_t<bool> trace 415cb93a386Sopenharmony_ci#endif 416cb93a386Sopenharmony_ci 417cb93a386Sopenharmony_ci#ifndef HB_DEBUG_SERIALIZE 418cb93a386Sopenharmony_ci#define HB_DEBUG_SERIALIZE (HB_DEBUG+0) 419cb93a386Sopenharmony_ci#endif 420cb93a386Sopenharmony_ci#if HB_DEBUG_SERIALIZE 421cb93a386Sopenharmony_ci#define TRACE_SERIALIZE(this) \ 422cb93a386Sopenharmony_ci hb_auto_trace_t<HB_DEBUG_SERIALIZE, bool> trace \ 423cb93a386Sopenharmony_ci (&c->debug_depth, "SERIALIZE", c, HB_FUNC, \ 424cb93a386Sopenharmony_ci " ") 425cb93a386Sopenharmony_ci#else 426cb93a386Sopenharmony_ci#define TRACE_SERIALIZE(this) hb_no_trace_t<bool> trace 427cb93a386Sopenharmony_ci#endif 428cb93a386Sopenharmony_ci 429cb93a386Sopenharmony_ci#ifndef HB_DEBUG_SUBSET 430cb93a386Sopenharmony_ci#define HB_DEBUG_SUBSET (HB_DEBUG+0) 431cb93a386Sopenharmony_ci#endif 432cb93a386Sopenharmony_ci#if HB_DEBUG_SUBSET 433cb93a386Sopenharmony_ci#define TRACE_SUBSET(this) \ 434cb93a386Sopenharmony_ci hb_auto_trace_t<HB_DEBUG_SUBSET, bool> trace \ 435cb93a386Sopenharmony_ci (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 436cb93a386Sopenharmony_ci " ") 437cb93a386Sopenharmony_ci#else 438cb93a386Sopenharmony_ci#define TRACE_SUBSET(this) hb_no_trace_t<bool> trace 439cb93a386Sopenharmony_ci#endif 440cb93a386Sopenharmony_ci 441cb93a386Sopenharmony_ci#ifndef HB_DEBUG_SUBSET_REPACK 442cb93a386Sopenharmony_ci#define HB_DEBUG_SUBSET_REPACK (HB_DEBUG+0) 443cb93a386Sopenharmony_ci#endif 444cb93a386Sopenharmony_ci 445cb93a386Sopenharmony_ci#ifndef HB_DEBUG_DISPATCH 446cb93a386Sopenharmony_ci#define HB_DEBUG_DISPATCH ( \ 447cb93a386Sopenharmony_ci HB_DEBUG_APPLY + \ 448cb93a386Sopenharmony_ci HB_DEBUG_SANITIZE + \ 449cb93a386Sopenharmony_ci HB_DEBUG_SERIALIZE + \ 450cb93a386Sopenharmony_ci HB_DEBUG_SUBSET + \ 451cb93a386Sopenharmony_ci 0) 452cb93a386Sopenharmony_ci#endif 453cb93a386Sopenharmony_ci#if HB_DEBUG_DISPATCH 454cb93a386Sopenharmony_ci#define TRACE_DISPATCH(this, format) \ 455cb93a386Sopenharmony_ci hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \ 456cb93a386Sopenharmony_ci (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 457cb93a386Sopenharmony_ci "format %d", (int) format) 458cb93a386Sopenharmony_ci#else 459cb93a386Sopenharmony_ci#define TRACE_DISPATCH(this, format) hb_no_trace_t<typename context_t::return_t> trace 460cb93a386Sopenharmony_ci#endif 461cb93a386Sopenharmony_ci 462cb93a386Sopenharmony_ci 463cb93a386Sopenharmony_ci#endif /* HB_DEBUG_HH */ 464