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