• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2007,2008,2009  Red Hat, Inc.
3  * Copyright © 2011,2012  Google, Inc.
4  *
5  *  This is part of HarfBuzz, a text shaping library.
6  *
7  * Permission is hereby granted, without written agreement and without
8  * license or royalty fees, to use, copy, modify, and distribute this
9  * software and its documentation for any purpose, provided that the
10  * above copyright notice and the following two paragraphs appear in
11  * all copies of this software.
12  *
13  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17  * DAMAGE.
18  *
19  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
22  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24  *
25  * Red Hat Author(s): Behdad Esfahbod
26  * Google Author(s): Behdad Esfahbod
27  */
28 
29 #ifndef HB_HH
30 #define HB_HH
31 
32 #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC
33 #ifdef _MSC_VER
34 #pragma warning( disable: 4068 ) /* Unknown pragma */
35 #endif
36 #if defined(__GNUC__) || defined(__clang__)
37 /* Rules:
38  *
39  * - All pragmas are declared GCC even if they are clang ones.  Otherwise GCC
40  *   nags, even though we instruct it to ignore -Wunknown-pragmas. ¯\_(ツ)_/¯
41  *
42  * - Within each category, keep sorted.
43  *
44  * - Warnings whose scope can be expanded in future compiler versions shall
45  *   be declared as "warning".  Otherwise, either ignored or error.
46  */
47 
48 /* Setup.  Don't sort order within this category. */
49 #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING
50 #pragma GCC diagnostic warning "-Wall"
51 #pragma GCC diagnostic warning "-Wextra"
52 #endif
53 #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_IGNORED
54 #pragma GCC diagnostic ignored "-Wpragmas"
55 #pragma GCC diagnostic ignored "-Wunknown-pragmas"
56 #pragma GCC diagnostic ignored "-Wunknown-warning-option"
57 #endif
58 #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING
59 //#pragma GCC diagnostic warning "-Weverything"
60 #endif
61 
62 /* Error.  Should never happen. */
63 #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR
64 #pragma GCC diagnostic error   "-Wbitwise-instead-of-logical"
65 #pragma GCC diagnostic error   "-Wcast-align"
66 #pragma GCC diagnostic error   "-Wcast-function-type"
67 #pragma GCC diagnostic error   "-Wcomma"
68 #pragma GCC diagnostic error   "-Wdelete-non-virtual-dtor"
69 #pragma GCC diagnostic error   "-Wembedded-directive"
70 #pragma GCC diagnostic error   "-Wextra-semi-stmt"
71 #pragma GCC diagnostic error   "-Wformat-security"
72 #pragma GCC diagnostic error   "-Wimplicit-function-declaration"
73 #pragma GCC diagnostic error   "-Winit-self"
74 #pragma GCC diagnostic error   "-Winjected-class-name"
75 #pragma GCC diagnostic error   "-Wmissing-braces"
76 #pragma GCC diagnostic error   "-Wmissing-declarations"
77 #pragma GCC diagnostic error   "-Wmissing-prototypes"
78 #pragma GCC diagnostic error   "-Wnarrowing"
79 #pragma GCC diagnostic error   "-Wnested-externs"
80 #pragma GCC diagnostic error   "-Wold-style-definition"
81 #pragma GCC diagnostic error   "-Wpointer-arith"
82 #pragma GCC diagnostic error   "-Wredundant-decls"
83 #pragma GCC diagnostic error   "-Wreorder"
84 #pragma GCC diagnostic error   "-Wsign-compare"
85 #pragma GCC diagnostic error   "-Wstrict-prototypes"
86 #pragma GCC diagnostic error   "-Wstring-conversion"
87 #pragma GCC diagnostic error   "-Wswitch-enum"
88 #pragma GCC diagnostic error   "-Wtautological-overlap-compare"
89 #pragma GCC diagnostic error   "-Wunneeded-internal-declaration"
90 #pragma GCC diagnostic error   "-Wunused"
91 #pragma GCC diagnostic error   "-Wunused-local-typedefs"
92 #pragma GCC diagnostic error   "-Wunused-value"
93 #pragma GCC diagnostic error   "-Wunused-variable"
94 #pragma GCC diagnostic error   "-Wvla"
95 #pragma GCC diagnostic error   "-Wwrite-strings"
96 #endif
97 
98 /* Warning.  To be investigated if happens. */
99 #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING
100 #pragma GCC diagnostic warning "-Wbuiltin-macro-redefined"
101 #pragma GCC diagnostic warning "-Wdeprecated"
102 #pragma GCC diagnostic warning "-Wdeprecated-declarations"
103 #pragma GCC diagnostic warning "-Wdisabled-optimization"
104 #pragma GCC diagnostic warning "-Wdouble-promotion"
105 #pragma GCC diagnostic warning "-Wformat=2"
106 #pragma GCC diagnostic warning "-Wignored-pragma-optimize"
107 #pragma GCC diagnostic warning "-Wlogical-op"
108 #pragma GCC diagnostic warning "-Wmaybe-uninitialized"
109 #pragma GCC diagnostic warning "-Wmissing-format-attribute"
110 #pragma GCC diagnostic warning "-Wundef"
111 #pragma GCC diagnostic warning "-Wunused-but-set-variable"
112 #endif
113 
114 /* Ignored currently, but should be fixed at some point. */
115 #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_IGNORED
116 #pragma GCC diagnostic ignored "-Wconversion"			// TODO fix
117 #pragma GCC diagnostic ignored "-Wformat-signedness"		// TODO fix
118 #pragma GCC diagnostic ignored "-Wshadow"			// TODO fix
119 #pragma GCC diagnostic ignored "-Wunsafe-loop-optimizations"	// TODO fix
120 #pragma GCC diagnostic ignored "-Wunused-parameter"		// TODO fix
121 #if defined(__GNUC__) && !defined(__clang__)
122 #pragma GCC diagnostic ignored "-Wunused-result"		// TODO fix
123 #endif
124 #endif
125 
126 /* Ignored intentionally. */
127 #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_IGNORED
128 #pragma GCC diagnostic ignored "-Wclass-memaccess"
129 #pragma GCC diagnostic ignored "-Wcast-function-type-strict" // https://github.com/harfbuzz/harfbuzz/pull/3859#issuecomment-1295409126
130 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
131 #pragma GCC diagnostic ignored "-Wformat-zero-length"
132 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
133 #pragma GCC diagnostic ignored "-Wpacked" // Erratic impl in clang
134 #pragma GCC diagnostic ignored "-Wrange-loop-analysis" // https://github.com/harfbuzz/harfbuzz/issues/2834
135 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
136 #pragma GCC diagnostic ignored "-Wtype-limits"
137 #pragma GCC diagnostic ignored "-Wc++11-compat" // only gcc raises it
138 #endif
139 
140 #endif
141 #endif
142 
143 
144 #include "hb-config.hh"
145 
146 
147 /*
148  * Following added based on what AC_USE_SYSTEM_EXTENSIONS adds to
149  * config.h.in.  Copied here for the convenience of those embedding
150  * HarfBuzz and not using our build system.
151  */
152 /* Enable extensions on AIX 3, Interix.  */
153 #ifndef _ALL_SOURCE
154 # define _ALL_SOURCE 1
155 #endif
156 /* Enable GNU extensions on systems that have them.  */
157 #ifndef _GNU_SOURCE
158 # define _GNU_SOURCE 1
159 #endif
160 /* Enable threading extensions on Solaris.  */
161 #ifndef _POSIX_PTHREAD_SEMANTICS
162 # define _POSIX_PTHREAD_SEMANTICS 1
163 #endif
164 /* Enable extensions on HP NonStop.  */
165 #ifndef _TANDEM_SOURCE
166 # define _TANDEM_SOURCE 1
167 #endif
168 /* Enable general extensions on Solaris.  */
169 #ifndef __EXTENSIONS__
170 # define __EXTENSIONS__ 1
171 #endif
172 
173 #if defined (_MSC_VER) && defined (HB_DLL_EXPORT)
174 #define HB_EXTERN __declspec (dllexport) extern
175 #endif
176 
177 #include "hb.h"
178 #define HB_H_IN
179 #include "hb-ot.h"
180 #define HB_OT_H_IN
181 #include "hb-aat.h"
182 #define HB_AAT_H_IN
183 
184 #include <cassert>
185 #include <cfloat>
186 #include <climits>
187 #if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES)
188 # define _USE_MATH_DEFINES
189 #endif
190 #include <cmath>
191 #include <cstdarg>
192 #include <cstddef>
193 #include <cstdio>
194 #include <cstdlib>
195 #include <cstring>
196 
197 #if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
198 #ifdef __MINGW32_VERSION
199 #ifndef WIN32_LEAN_AND_MEAN
200 #define WIN32_LEAN_AND_MEAN 1
201 #endif
202 #else
203 #include <intrin.h>
204 #endif
205 #endif
206 
207 #ifdef _WIN32
208 #include <windows.h>
209 #include <winapifamily.h>
210 #endif
211 
212 #define HB_PASTE1(a,b) a##b
213 #define HB_PASTE(a,b) HB_PASTE1(a,b)
214 
215 
216 /* Compile-time custom allocator support. */
217 
218 #if !defined(HB_CUSTOM_MALLOC) \
219   && defined(hb_malloc_impl) \
220   && defined(hb_calloc_impl) \
221   && defined(hb_realloc_impl) \
222   && defined(hb_free_impl)
223 #define HB_CUSTOM_MALLOC
224 #endif
225 
226 #ifdef HB_CUSTOM_MALLOC
227 extern "C" void* hb_malloc_impl(size_t size);
228 extern "C" void* hb_calloc_impl(size_t nmemb, size_t size);
229 extern "C" void* hb_realloc_impl(void *ptr, size_t size);
230 extern "C" void  hb_free_impl(void *ptr);
231 #define hb_malloc hb_malloc_impl
232 #define hb_calloc hb_calloc_impl
233 #define hb_realloc hb_realloc_impl
234 #define hb_free hb_free_impl
235 #else
236 #define hb_malloc malloc
237 #define hb_calloc calloc
238 #define hb_realloc realloc
239 #define hb_free free
240 #endif
241 
242 
243 /*
244  * Compiler attributes
245  */
246 
247 #if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE__)
248 #define likely(expr) (__builtin_expect (!!(expr), 1))
249 #define unlikely(expr) (__builtin_expect (!!(expr), 0))
250 #else
251 #define likely(expr) (expr)
252 #define unlikely(expr) (expr)
253 #endif
254 
255 #if !defined(__GNUC__) && !defined(__clang__)
256 #undef __attribute__
257 #define __attribute__(x)
258 #endif
259 
260 #if defined(__GNUC__) && (__GNUC__ >= 3)
261 #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx)))
262 #else
263 #define HB_PRINTF_FUNC(format_idx, arg_idx)
264 #endif
265 #if defined(__GNUC__) && (__GNUC__ >= 4) || (__clang__)
266 #define HB_UNUSED	__attribute__((unused))
267 #elif defined(_MSC_VER) /* https://github.com/harfbuzz/harfbuzz/issues/635 */
268 #define HB_UNUSED __pragma(warning(suppress: 4100 4101))
269 #else
270 #define HB_UNUSED
271 #endif
272 
273 #ifndef HB_INTERNAL
274 # if !defined(HB_NO_VISIBILITY) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_MSC_VER) && !defined(__SUNPRO_CC)
275 #  define HB_INTERNAL __attribute__((__visibility__("hidden")))
276 # elif defined(__MINGW32__)
277    /* We use -export-symbols on mingw32, since it does not support visibility attributes. */
278 #  define HB_INTERNAL
279 # elif defined (_MSC_VER) && defined (HB_DLL_EXPORT)
280    /* We do not try to export internal symbols on Visual Studio */
281 #  define HB_INTERNAL
282 #else
283 #  define HB_INTERNAL
284 #  define HB_NO_VISIBILITY 1
285 # endif
286 #endif
287 
288 /* https://github.com/harfbuzz/harfbuzz/issues/1651 */
289 #if defined(__clang__) && __clang_major__ < 10
290 #define static_const static
291 #else
292 #define static_const static const
293 #endif
294 
295 #if defined(__GNUC__) && (__GNUC__ >= 3)
296 #define HB_FUNC __PRETTY_FUNCTION__
297 #elif defined(_MSC_VER)
298 #define HB_FUNC __FUNCSIG__
299 #else
300 #define HB_FUNC __func__
301 #endif
302 
303 #if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5140)
304 /* https://github.com/harfbuzz/harfbuzz/issues/630 */
305 #define __restrict
306 #endif
307 
308 /*
309  * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411
310  * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch
311  * cases that fall through without a break or return statement. HB_FALLTHROUGH
312  * is only needed on cases that have code:
313  *
314  * switch (foo) {
315  *   case 1: // These cases have no code. No fallthrough annotations are needed.
316  *   case 2:
317  *   case 3:
318  *     foo = 4; // This case has code, so a fallthrough annotation is needed:
319  *     HB_FALLTHROUGH;
320  *   default:
321  *     return foo;
322  * }
323  */
324 #if defined(__clang__) && __cplusplus >= 201103L
325    /* clang's fallthrough annotations are only available starting in C++11. */
326 #  define HB_FALLTHROUGH [[clang::fallthrough]]
327 #elif defined(__GNUC__) && (__GNUC__ >= 7)
328    /* GNU fallthrough attribute is available from GCC7 */
329 #  define HB_FALLTHROUGH __attribute__((fallthrough))
330 #elif defined(_MSC_VER)
331    /*
332     * MSVC's __fallthrough annotations are checked by /analyze (Code Analysis):
333     * https://msdn.microsoft.com/en-us/library/ms235402%28VS.80%29.aspx
334     */
335 #  include <sal.h>
336 #  define HB_FALLTHROUGH __fallthrough
337 #else
338 #  define HB_FALLTHROUGH /* FALLTHROUGH */
339 #endif
340 
341 /* A tag to enforce use of return value for a function */
342 #if __cplusplus >= 201703L
343 #  define HB_NODISCARD [[nodiscard]]
344 #elif defined(__GNUC__) || defined(__clang__)
345 #  define HB_NODISCARD __attribute__((warn_unused_result))
346 #elif defined(_MSC_VER)
347 #  define HB_NODISCARD _Check_return_
348 #else
349 #  define HB_NODISCARD
350 #endif
351 
352 /* https://github.com/harfbuzz/harfbuzz/issues/1852 */
353 #if defined(__clang__) && !(defined(_AIX) && (defined(__IBMCPP__) || defined(__ibmxl__)))
354 /* Disable certain sanitizer errors. */
355 /* https://github.com/harfbuzz/harfbuzz/issues/1247 */
356 #define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW __attribute__((no_sanitize("signed-integer-overflow")))
357 #else
358 #define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
359 #endif
360 
361 
362 #ifdef _WIN32
363    /* We need Windows Vista for both Uniscribe backend and for
364     * MemoryBarrier.  We don't support compiling on Windows XP,
365     * though we run on it fine. */
366 #  if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600
367 #    undef _WIN32_WINNT
368 #  endif
369 #  ifndef _WIN32_WINNT
370 #    if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
371 #      define _WIN32_WINNT 0x0600
372 #    endif
373 #  endif
374 #  ifndef WIN32_LEAN_AND_MEAN
375 #    define WIN32_LEAN_AND_MEAN 1
376 #  endif
377 #  ifndef STRICT
378 #    define STRICT 1
379 #  endif
380 
381 #  if defined(_WIN32_WCE)
382      /* Some things not defined on Windows CE. */
383 #    define vsnprintf _vsnprintf
384 #    ifndef HB_NO_GETENV
385 #      define HB_NO_GETENV
386 #    endif
387 #    if _WIN32_WCE < 0x800
388 #      define HB_NO_SETLOCALE
389 #      define HB_NO_ERRNO
390 #    endif
391 #  elif !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
392 #    ifndef HB_NO_GETENV
393 #      define HB_NO_GETENV
394 #    endif
395 #  endif
396 #  if defined(_MSC_VER) && _MSC_VER < 1900
397 #    define snprintf _snprintf
398 #  endif
399 #endif
400 
401 #ifdef HB_NO_GETENV
402 #define getenv(Name) nullptr
403 #endif
404 
405 #ifndef HB_NO_ERRNO
406 #  include <cerrno>
407 #else
408 static int HB_UNUSED _hb_errno = 0;
409 #  undef errno
410 #  define errno _hb_errno
411 #endif
412 
413 #define HB_STMT_START do
414 #define HB_STMT_END   while (0)
415 
416 #if defined(HAVE_ATEXIT) && !defined(HB_USE_ATEXIT)
417 /* atexit() is only safe to be called from shared libraries on certain
418  * platforms.  Whitelist.
419  * https://bugs.freedesktop.org/show_bug.cgi?id=82246 */
420 #  if defined(__linux) && defined(__GLIBC_PREREQ)
421 #    if __GLIBC_PREREQ(2,3)
422 /* From atexit() manpage, it's safe with glibc 2.2.3 on Linux. */
423 #      define HB_USE_ATEXIT 1
424 #    endif
425 #  elif defined(_MSC_VER) || defined(__MINGW32__)
426 /* For MSVC:
427  * https://msdn.microsoft.com/en-us/library/tze57ck3.aspx
428  * https://msdn.microsoft.com/en-us/library/zk17ww08.aspx
429  * mingw32 headers say atexit is safe to use in shared libraries.
430  */
431 #    define HB_USE_ATEXIT 1
432 #  elif defined(__ANDROID__)
433 /* This is available since Android NKD r8 or r8b:
434  * https://issuetracker.google.com/code/p/android/issues/detail?id=6455
435  */
436 #    define HB_USE_ATEXIT 1
437 #  elif defined(__APPLE__)
438 /* For macOS and related platforms, the atexit man page indicates
439  * that it will be invoked when the library is unloaded, not only
440  * at application exit.
441  */
442 #    define HB_USE_ATEXIT 1
443 #  endif
444 #endif /* defined(HAVE_ATEXIT) && !defined(HB_USE_ATEXIT) */
445 #ifdef HB_NO_ATEXIT
446 #  undef HB_USE_ATEXIT
447 #endif
448 #ifndef HB_USE_ATEXIT
449 #  define HB_USE_ATEXIT 0
450 #endif
451 #ifndef hb_atexit
452 #if !HB_USE_ATEXIT
453 #  define hb_atexit(_) HB_STMT_START { if (0) (_) (); } HB_STMT_END
454 #else /* HB_USE_ATEXIT */
455 #  ifdef HAVE_ATEXIT
456 #    define hb_atexit atexit
457 #  else
~hb_atexit_thb_atexit_t458      template <void (*function) (void)> struct hb_atexit_t { ~hb_atexit_t () { function (); } };
459 #    define hb_atexit(f) static hb_atexit_t<f> _hb_atexit_##__LINE__;
460 #  endif
461 #endif
462 #endif
463 
464 /* Lets assert int types.  Saves trouble down the road. */
465 static_assert ((sizeof (hb_codepoint_t) == 4), "");
466 static_assert ((sizeof (hb_position_t) == 4), "");
467 static_assert ((sizeof (hb_mask_t) == 4), "");
468 static_assert ((sizeof (hb_var_int_t) == 4), "");
469 
470 
471 /* Headers we include for everyone.  Keep topologically sorted by dependency.
472  * They express dependency amongst themselves, but no other file should include
473  * them directly.*/
474 #include "hb-cplusplus.hh"
475 #include "hb-meta.hh"
476 #include "hb-mutex.hh"
477 #include "hb-number.hh"
478 #include "hb-atomic.hh"	// Requires: hb-meta
479 #include "hb-null.hh"	// Requires: hb-meta
480 #include "hb-algs.hh"	// Requires: hb-meta hb-null hb-number
481 #include "hb-iter.hh"	// Requires: hb-algs hb-meta
482 #include "hb-debug.hh"	// Requires: hb-algs hb-atomic
483 #include "hb-array.hh"	// Requires: hb-algs hb-iter hb-null
484 #include "hb-vector.hh"	// Requires: hb-array hb-null
485 #include "hb-object.hh"	// Requires: hb-atomic hb-mutex hb-vector
486 
487 #endif /* HB_HH */
488