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