15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2007,2008,2009 Red Hat, Inc. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2011,2012 Google, Inc. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is part of HarfBuzz, a text shaping library. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, without written agreement and without 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * license or royalty fees, to use, copy, modify, and distribute this 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * software and its documentation for any purpose, provided that the 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * above copyright notice and the following two paragraphs appear in 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all copies of this software. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DAMAGE. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Red Hat Author(s): Behdad Esfahbod 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Google Author(s): Behdad Esfahbod 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HB_PRIVATE_HH 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_PRIVATE_HH 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_CONFIG_H 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "config.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_H_IN 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_OT 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-ot.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_OT_H_IN 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stddef.h> 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h> 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* We only use these two for debug output. However, the debug code is 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * always seen by the compiler (and optimized out in non-debug builds. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If including these becomes a problem, we can start thinking about 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * someway around that. */ 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h> 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)/* Compiler attributes */ 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0) 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1)) 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0)) 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define likely(expr) (expr) 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define unlikely(expr) (expr) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifndef __GNUC__ 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#undef __attribute__ 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define __attribute__(x) 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if __GNUC__ >= 3 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define HB_PURE_FUNC __attribute__((pure)) 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define HB_CONST_FUNC __attribute__((const)) 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define HB_PURE_FUNC 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define HB_CONST_FUNC 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define HB_PRINTF_FUNC(format_idx, arg_idx) 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if __GNUC__ >= 4 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define HB_UNUSED __attribute__((unused)) 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define HB_UNUSED 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifndef HB_INTERNAL 9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# if !defined(__MINGW32__) && !defined(__CYGWIN__) 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# define HB_INTERNAL __attribute__((__visibility__("hidden"))) 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# else 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# define HB_INTERNAL 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# endif 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER) 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define snprintf _snprintf 9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)/* Windows CE only has _strdup, while rest of Windows has both. */ 10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#define strdup _strdup 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifdef _MSC_VER 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#undef inline 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define inline __inline 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifdef __STRICT_ANSI__ 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#undef inline 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define inline __inline__ 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if __GNUC__ >= 3 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define HB_FUNC __PRETTY_FUNCTION__ 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#elif defined(_MSC_VER) 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define HB_FUNC __FUNCSIG__ 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define HB_FUNC __func__ 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(_WIN32) || defined(__CYGWIN__) 12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /* We need Windows Vista for both Uniscribe backend and for 12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * MemoryBarrier. We don't support compiling on Windows XP, 12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * though we run on it fine. */ 12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600 12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# undef _WIN32_WINNT 12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# endif 12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# ifndef _WIN32_WINNT 12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# define _WIN32_WINNT 0x0600 13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# endif 13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# ifndef WIN32_LEAN_AND_MEAN 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# define WIN32_LEAN_AND_MEAN 1 13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# endif 13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# ifndef STRICT 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# define STRICT 1 13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# endif 13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#ifdef _WIN32_WCE 14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)/* Some things not defined on Windows CE. */ 14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#define MemoryBarrier() 14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#define getenv(Name) NULL 14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#define setlocale(Category, Locale) "C" 14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)static int errno = 0; /* Use something better? */ 14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif 14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if HAVE_ATEXIT 14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)/* atexit() is only safe to be called from shared libraries on certain 14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * platforms. Whitelist. 15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * https://bugs.freedesktop.org/show_bug.cgi?id=82246 */ 15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# if defined(__linux) && defined(__GLIBC_PREREQ) 15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# if __GLIBC_PREREQ(2,3) 15303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)/* From atexit() manpage, it's safe with glibc 2.2.3 on Linux. */ 15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# define HB_USE_ATEXIT 1 15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# endif 15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# elif defined(_MSC_VER) || defined(__MINGW32__) 15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)/* For MSVC: 15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * http://msdn.microsoft.com/en-ca/library/tze57ck3.aspx 15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * http://msdn.microsoft.com/en-ca/library/zk17ww08.aspx 16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * mingw32 headers say atexit is safe to use in shared libraries. 16103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# define HB_USE_ATEXIT 1 16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# elif defined(__ANDROID__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) 16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)/* This was fixed in Android NKD r8 or r8b: 16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * https://code.google.com/p/android/issues/detail?id=6455 16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * which introduced GCC 4.6: 16703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * https://developer.android.com/tools/sdk/ndk/index.html 16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 16903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# define HB_USE_ATEXIT 1 17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)# endif 17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Basics */ 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifndef NULL 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# define NULL ((void *) 0) 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef MIN 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type> 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef MAX 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type> 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b) 189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ return (a + (b - 1)) / b; } 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef ARRAY_LENGTH 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type, unsigned int n> 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* A const version, but does not detect erratically being called on pointers. */ 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0]))) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_STMT_START do 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_STMT_END while (0) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define _ASSERT_STATIC1(_line, _cond) HB_UNUSED typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1] 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond)) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond)) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_STATIC_EXPR(_cond)((void) sizeof (char[(_cond) ? 1 : -1])) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * sizeof (char[(_cond) ? 1 : -1])) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _PASTE1(a,b) a##b 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PASTE(a,b) _PASTE1(a,b) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Lets assert int types. Saves trouble down the road. */ 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (int8_t) == 1); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (uint8_t) == 1); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (int16_t) == 2); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (uint16_t) == 2); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (int32_t) == 4); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (uint32_t) == 4); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (int64_t) == 8); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (uint64_t) == 8); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (hb_codepoint_t) == 4); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (hb_position_t) == 4); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (hb_mask_t) == 4); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (hb_var_int_t) == 4); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* We like our types POD */ 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _ASSERT_TYPE_POD1(_line, _type) union _type_##_type##_on_line_##_line##_is_not_POD { _type instance; } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _ASSERT_TYPE_POD0(_line, _type) _ASSERT_TYPE_POD1 (_line, _type) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_TYPE_POD(_type) _ASSERT_TYPE_POD0 (__LINE__, _type) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __GNUC__ 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define _ASSERT_INSTANCE_POD1(_line, _instance) \ 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_STMT_START { \ 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef __typeof__(_instance) _type_##_line; \ 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _ASSERT_TYPE_POD1 (_line, _type_##_line); \ 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } HB_STMT_END 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define _ASSERT_INSTANCE_POD1(_line, _instance) typedef int _assertion_on_line_##_line##_not_tested 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define _ASSERT_INSTANCE_POD0(_line, _instance) _ASSERT_INSTANCE_POD1 (_line, _instance) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define ASSERT_INSTANCE_POD(_instance) _ASSERT_INSTANCE_POD0 (__LINE__, _instance) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Check _assertion in a method environment */ 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _ASSERT_POD1(_line) \ 2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) HB_UNUSED inline void _static_assertion_on_line_##_line (void) const \ 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { _ASSERT_INSTANCE_POD1 (_line, *this); /* Make sure it's POD. */ } 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define _ASSERT_POD0(_line) _ASSERT_POD1 (_line) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define ASSERT_POD() _ASSERT_POD0 (__LINE__) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Misc */ 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)/* Void! */ 2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)struct _hb_void_t {}; 2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)typedef const _hb_void_t &hb_void_t; 2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define HB_VOID (* (const _hb_void_t *) NULL) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return the number of 1 bits in mask. */ 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline HB_CONST_FUNC unsigned int 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_popcount32 (uint32_t mask) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return __builtin_popcount (mask); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* "HACKMEM 169" */ 27023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) uint32_t y; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y = (mask >> 1) &033333333333; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y = mask - y - ((y >>1) & 033333333333); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (((y + (y >> 3)) & 030707070707) % 077); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Returns the number of bits needed to store number */ 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline HB_CONST_FUNC unsigned int 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_bit_storage (unsigned int number) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return likely (number) ? (sizeof (unsigned int) * 8 - __builtin_clz (number)) : 0; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 28423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) unsigned int n_bits = 0; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (number) { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n_bits++; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number >>= 1; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return n_bits; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Returns the number of zero bits in the least significant side of number */ 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline HB_CONST_FUNC unsigned int 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_ctz (unsigned int number) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return likely (number) ? __builtin_ctz (number) : 0; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 30023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) unsigned int n_bits = 0; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!number)) return 0; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!(number & 1)) { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n_bits++; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number >>= 1; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return n_bits; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_unsigned_int_mul_overflows (unsigned int count, unsigned int size) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (size > 0) && (count >= ((unsigned int) -1) / size); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Type of bsearch() / qsort() compare function */ 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int (*hb_compare_func_t) (const void *, const void *); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* arrays and maps */ 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#define HB_PREALLOCED_ARRAY_INIT {0, 0, NULL} 3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)template <typename Type, unsigned int StaticSize=16> 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_prealloced_array_t 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int allocated; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type *array; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type static_array[StaticSize]; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void init (void) { memset (this, 0, sizeof (*this)); } 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline Type& operator [] (unsigned int i) { return array[i]; } 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Type& operator [] (unsigned int i) const { return array[i]; } 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline Type *push (void) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!array) { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array = static_array; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allocated = ARRAY_LENGTH (static_array); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (len < allocated)) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &array[len++]; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Need to reallocate */ 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int new_allocated = allocated + (allocated >> 1) + 8; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type *new_array = NULL; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (array == static_array) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_array = (Type *) calloc (new_allocated, sizeof (Type)); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_array) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy (new_array, array, len * sizeof (Type)); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool overflows = (new_allocated < allocated) || _hb_unsigned_int_mul_overflows (new_allocated, sizeof (Type)); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (!overflows)) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_array = (Type *) realloc (array, new_allocated * sizeof (Type)); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!new_array)) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array = new_array; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allocated = new_allocated; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &array[len++]; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void pop (void) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len--; 375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) inline void remove (unsigned int i) 378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (unlikely (i >= len)) 380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memmove (static_cast<void *> (&array[i]), 382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static_cast<void *> (&array[i + 1]), 383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (len - i - 1) * sizeof (Type)); 384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) len--; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void shrink (unsigned int l) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (l < len) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = l; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline Type *find (T v) { 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < len; i++) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (array[i] == v) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &array[i]; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Type *find (T v) const { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < len; i++) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (array[i] == v) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &array[i]; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) inline void qsort (void) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ::qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) inline void qsort (unsigned int start, unsigned int end) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ::qsort (array + start, end - start, sizeof (Type), (hb_compare_func_t) Type::cmp); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline Type *bsearch (T *key) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Type *bsearch (T *key) const 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (const Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void finish (void) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (array != static_array) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free (array); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array = NULL; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allocated = len = 0; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template <typename Type> 4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)struct hb_auto_array_t : hb_prealloced_array_t <Type> 440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hb_auto_array_t (void) { hb_prealloced_array_t<Type>::init (); } 4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ~hb_auto_array_t (void) { hb_prealloced_array_t<Type>::finish (); } 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT} 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename item_t, typename lock_t> 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_lockable_set_t 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_prealloced_array_t <item_t, 2> items; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void init (void) { items.init (); } 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline item_t *replace_or_insert (T v, lock_t &l, bool replace) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.lock (); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_t *item = items.find (v); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (item) { 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (replace) { 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_t old = *item; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *item = v; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old.finish (); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item = NULL; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item = items.push (); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (item)) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *item = v; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return item; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void remove (T v, lock_t &l) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.lock (); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_t *item = items.find (v); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (item) { 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_t old = *item; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *item = items[items.len - 1]; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items.pop (); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old.finish (); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool find (T v, item_t *i, lock_t &l) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.lock (); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_t *item = items.find (v); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (item) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *i = *item; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !!item; 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline item_t *find_or_insert (T v, lock_t &l) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.lock (); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_t *item = items.find (v); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!item) { 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item = items.push (); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (item)) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *item = v; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return item; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void finish (lock_t &l) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!items.len) { 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* No need for locking. */ 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items.finish (); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.lock (); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (items.len) { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_t old = items[items.len - 1]; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items.pop (); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old.finish (); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.lock (); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items.finish (); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Big-endian handling */ 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline uint16_t hb_be_uint16 (const uint16_t v) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8_t *V = (const uint8_t *) &v; 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (V[0] << 8) | V[1]; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline uint16_t hb_uint16_swap (const uint16_t v) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (v >> 8) | (v << 8); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline uint32_t hb_uint32_swap (const uint32_t v) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Note, of the following macros, uint16_get is the one called many many times. 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If there is any optimizations to be done, it's in that macro. However, I 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * already confirmed that on my T400 ThinkPad at least, using bswap_16(), which 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * results in a single ror instruction, does NOT speed this up. In fact, it 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * resulted in a minor slowdown. At any rate, note that v may not be correctly 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * aligned, so I think the current implementation is optimal. 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_be_uint16_put(v,V) HB_STMT_START { v[0] = (V>>8); v[1] = (V); } HB_STMT_END 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_be_uint16_get(v) (uint16_t) ((v[0] << 8) + v[1]) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_be_uint16_eq(a,b) (a[0] == b[0] && a[1] == b[1]) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_be_uint32_put(v,V) HB_STMT_START { v[0] = (V>>24); v[1] = (V>>16); v[2] = (V>>8); v[3] = (V); } HB_STMT_END 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_be_uint32_get(v) (uint32_t) ((v[0] << 24) + (v[1] << 16) + (v[2] << 8) + v[3]) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_be_uint32_eq(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3]) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#define hb_be_uint24_put(v,V) HB_STMT_START { v[0] = (V>>16); v[1] = (V>>8); v[2] = (V); } HB_STMT_END 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define hb_be_uint24_get(v) (uint32_t) ((v[0] << 16) + (v[1] << 8) + v[2]) 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define hb_be_uint24_eq(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]) 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ASCII tag/character handling */ 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static inline bool ISALPHA (unsigned char c) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } 587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static inline bool ISALNUM (unsigned char c) 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); } 589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static inline bool ISSPACE (unsigned char c) 590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; } 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline unsigned char TOUPPER (unsigned char c) 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; } 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline unsigned char TOLOWER (unsigned char c) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; } 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_TAG_CHAR4(s) (HB_TAG(((const char *) s)[0], \ 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((const char *) s)[1], \ 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((const char *) s)[2], \ 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((const char *) s)[3])) 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* C++ helpers */ 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Makes class uncopyable. Use in private: section. */ 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NO_COPY(T) \ 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T (const T &o); \ 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T &operator = (const T &o) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Debug */ 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HB_DEBUG 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_DEBUG 0 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_debug (unsigned int level, 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int max_level) 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return level < max_level; 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#define DEBUG_LEVEL_ENABLED(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT)) 6257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#define DEBUG_ENABLED(WHAT) (DEBUG_LEVEL_ENABLED (WHAT, 0)) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <int max_level> static inline void 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_debug_msg_va (const char *what, 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj, 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *func, 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool indented, 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int level, 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int level_dir, 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *message, 63503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) va_list ap) HB_PRINTF_FUNC(7, 0); 63603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)template <int max_level> static inline void 63703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)_hb_debug_msg_va (const char *what, 63803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const void *obj, 63903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const char *func, 64003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool indented, 64103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) unsigned int level, 64203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) int level_dir, 64303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const char *message, 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_list ap) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!_hb_debug (level, max_level)) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf (stderr, "%-10s", what ? what : ""); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (obj) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf (stderr, "(%0*lx) ", (unsigned int) (2 * sizeof (void *)), (unsigned long) obj); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf (stderr, " %*s ", (unsigned int) (2 * sizeof (void *)), ""); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (indented) { 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* One may want to add ASCII version of these. See: 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * https://bugs.freedesktop.org/show_bug.cgi?id=50970 */ 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VBAR "\342\224\202" /* U+2502 BOX DRAWINGS LIGHT VERTICAL */ 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VRBAR "\342\224\234" /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLBAR "\342\225\256" /* U+256E BOX DRAWINGS LIGHT ARC DOWN AND LEFT */ 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ULBAR "\342\225\257" /* U+256F BOX DRAWINGS LIGHT ARC UP AND LEFT */ 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LBAR "\342\225\264" /* U+2574 BOX DRAWINGS LIGHT LEFT */ 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char bars[] = VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR; 665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) fprintf (stderr, "%2u %s" VRBAR "%s", 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level, 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bars + sizeof (bars) - 1 - MIN ((unsigned int) sizeof (bars), (unsigned int) (sizeof (VBAR) - 1) * level), 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level_dir ? (level_dir > 0 ? DLBAR : ULBAR) : LBAR); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf (stderr, " " VRBAR LBAR); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (func) 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int func_len = strlen (func); 675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifndef HB_DEBUG_VERBOSE 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* Skip "typename" */ 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (0 == strncmp (func, "typename ", 9)) 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) func += 9; 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Skip return type */ 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *space = strchr (func, ' '); 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (space) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) func = space + 1; 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Skip parameter list */ 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *paren = strchr (func, '('); 685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (paren) 686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) func_len = paren - func; 687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf (stderr, "%.*s: ", func_len, func); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message) 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfprintf (stderr, message, ap); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf (stderr, "\n"); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> inline void 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_debug_msg_va<0> (const char *what HB_UNUSED, 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj HB_UNUSED, 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *func HB_UNUSED, 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool indented HB_UNUSED, 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int level HB_UNUSED, 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int level_dir HB_UNUSED, 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *message HB_UNUSED, 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_list ap HB_UNUSED) {} 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <int max_level> static inline void 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_debug_msg (const char *what, 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj, 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *func, 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool indented, 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int level, 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int level_dir, 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *message, 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ...) HB_PRINTF_FUNC(7, 8); 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <int max_level> static inline void 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_debug_msg (const char *what, 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj, 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *func, 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool indented, 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int level, 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int level_dir, 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *message, 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ...) 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_list ap; 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_start (ap, message); 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _hb_debug_msg_va<max_level> (what, obj, func, indented, level, level_dir, message, ap); 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_end (ap); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> inline void 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_debug_msg<0> (const char *what HB_UNUSED, 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj HB_UNUSED, 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *func HB_UNUSED, 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool indented HB_UNUSED, 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int level HB_UNUSED, 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int level_dir HB_UNUSED, 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *message HB_UNUSED, 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ...) HB_PRINTF_FUNC(7, 8); 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> inline void 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_debug_msg<0> (const char *what HB_UNUSED, 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj HB_UNUSED, 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *func HB_UNUSED, 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool indented HB_UNUSED, 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int level HB_UNUSED, 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int level_dir HB_UNUSED, 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *message HB_UNUSED, 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ...) {} 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEBUG_MSG_LEVEL(WHAT, OBJ, LEVEL, LEVEL_DIR, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL, true, (LEVEL), (LEVEL_DIR), __VA_ARGS__) 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEBUG_MSG(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL, false, 0, 0, __VA_ARGS__) 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEBUG_MSG_FUNC(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), HB_FUNC, false, 0, 0, __VA_ARGS__) 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Printer 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename T> 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct hb_printer_t {}; 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <> 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct hb_printer_t<bool> { 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char *print (bool v) { return v ? "true" : "false"; } 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <> 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct hb_printer_t<hb_void_t> { 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char *print (hb_void_t) { return ""; } 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Trace 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename T> 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline void _hb_warn_no_return (bool returned) 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unlikely (!returned)) { 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fprintf (stderr, "OUCH, returned with no call to TRACE_RETURN. This is a bug, please report.\n"); 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <> 7845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)/*static*/ inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED) 7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){} 7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <int max_level, typename ret_t> 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_auto_trace_t { 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit inline hb_auto_trace_t (unsigned int *plevel_, 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *what_, 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj_, 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *func, 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *message, 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ...) : plevel (plevel_), what (what_), obj (obj_), returned (false) 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (plevel) ++*plevel; 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_list ap; 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_start (ap, message); 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _hb_debug_msg_va<max_level> (what, obj, func, true, plevel ? *plevel : 0, +1, message, ap); 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_end (ap); 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline ~hb_auto_trace_t (void) 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _hb_warn_no_return<ret_t> (returned); 8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!returned) { 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1, " "); 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (plevel) --*plevel; 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline ret_t ret (ret_t v, unsigned int line = 0) 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (returned)) { 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf (stderr, "OUCH, double calls to TRACE_RETURN. This is a bug, please report.\n"); 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return v; 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1, 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "return %s (line %d)", 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_printer_t<ret_t>().print (v), line); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (plevel) --*plevel; 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plevel = NULL; 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) returned = true; 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return v; 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int *plevel; 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *what; 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj; 8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool returned; 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename ret_t> /* Optimize when tracing is disabled */ 8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct hb_auto_trace_t<0, ret_t> { 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit inline hb_auto_trace_t (unsigned int *plevel_ HB_UNUSED, 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *what HB_UNUSED, 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj HB_UNUSED, 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *func HB_UNUSED, 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *message HB_UNUSED, 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ...) {} 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; } 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACE_RETURN(RET) trace.ret (RET, __LINE__) 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Misc */ 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)template <typename T> class hb_assert_unsigned_t; 8515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)template <> class hb_assert_unsigned_t<unsigned char> {}; 8525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)template <> class hb_assert_unsigned_t<unsigned short> {}; 8535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)template <> class hb_assert_unsigned_t<unsigned int> {}; 8545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)template <> class hb_assert_unsigned_t<unsigned long> {}; 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> static inline bool 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_in_range (T u, T lo, T hi) 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /* The sizeof() is here to force template instantiation. 8605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * I'm sure there are better ways to do this but can't think of 8615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * one right now. Declaring a variable won't work as HB_UNUSED 8625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * is unsable on some platforms and unused types are less likely 8635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * to generate a warning than unused variables. */ 8645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSERT_STATIC (sizeof (hb_assert_unsigned_t<T>) >= 0); 8655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 86603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /* The casts below are important as if T is smaller than int, 86703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * the subtract results will become a signed int! */ 86803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return (T)(u - lo) <= (T)(hi - lo); 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> static inline bool 87223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2) 87323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles){ 87423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2); 87523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 87623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 87723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)template <typename T> static inline bool 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3); 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Useful for set-operations on small enums. 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For example, for testing "x ∈ {x1, x2, x3}" use: 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (FLAG(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FLAG(x) (1<<(x)) 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x)) 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T, typename T2> inline void 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_bubble_sort (T *array, unsigned int len, int(*compar)(const T *, const T *), T2 *array2) 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!len)) 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int k = len - 1; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int new_k = 0; 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int j = 0; j < k; j++) 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (compar (&array[j], &array[j+1]) > 0) 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T t; 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = array[j]; 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array[j] = array[j + 1]; 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array[j + 1] = t; 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (array2) 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T2 t; 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = array2[j]; 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array2[j] = array2[j + 1]; 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array2[j + 1] = t; 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_k = j; 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) k = new_k; 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (k); 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> inline void 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_bubble_sort (T *array, unsigned int len, int(*compar)(const T *, const T *)) 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_bubble_sort (array, len, compar, (int *) NULL); 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline hb_bool_t 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out) 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Pain because we don't know whether s is nul-terminated. */ 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buf[64]; 936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) len = MIN (ARRAY_LENGTH (buf) - 1, len); 937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) strncpy (buf, s, len); 938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) buf[len] = '\0'; 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *end; 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errno = 0; 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long v = strtoul (buf, &end, base); 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (errno) return false; 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*end) return false; 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out = v; 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/* Global runtime options. */ 951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)struct hb_options_t 953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int initialized : 1; 955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int uniscribe_bug_compatible : 1; 956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)union hb_options_union_t { 959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int i; 960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_options_t opts; 961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ASSERT_STATIC (sizeof (int) == sizeof (hb_options_union_t)); 963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)HB_INTERNAL void 965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)_hb_options_init (void); 966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)extern HB_INTERNAL hb_options_union_t _hb_options; 968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static inline hb_options_t 970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)hb_options (void) 971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (unlikely (!_hb_options.i)) 973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) _hb_options_init (); 974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return _hb_options.opts; 976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* HB_PRIVATE_HH */ 980