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