| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright © 2007,2008,2009 Red Hat, Inc. | 2 * Copyright © 2007,2008,2009 Red Hat, Inc. |
| 3 * Copyright © 2011,2012 Google, Inc. | 3 * Copyright © 2011,2012 Google, Inc. |
| 4 * | 4 * |
| 5 * This is part of HarfBuzz, a text shaping library. | 5 * This is part of HarfBuzz, a text shaping library. |
| 6 * | 6 * |
| 7 * Permission is hereby granted, without written agreement and without | 7 * Permission is hereby granted, without written agreement and without |
| 8 * license or royalty fees, to use, copy, modify, and distribute this | 8 * license or royalty fees, to use, copy, modify, and distribute this |
| 9 * software and its documentation for any purpose, provided that the | 9 * software and its documentation for any purpose, provided that the |
| 10 * above copyright notice and the following two paragraphs appear in | 10 * above copyright notice and the following two paragraphs appear in |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 | 47 |
| 48 /* We only use these two for debug output. However, the debug code is | 48 /* We only use these two for debug output. However, the debug code is |
| 49 * always seen by the compiler (and optimized out in non-debug builds. | 49 * always seen by the compiler (and optimized out in non-debug builds. |
| 50 * If including these becomes a problem, we can start thinking about | 50 * If including these becomes a problem, we can start thinking about |
| 51 * someway around that. */ | 51 * someway around that. */ |
| 52 #include <stdio.h> | 52 #include <stdio.h> |
| 53 #include <errno.h> | 53 #include <errno.h> |
| 54 #include <stdarg.h> | 54 #include <stdarg.h> |
| 55 | 55 |
| 56 | 56 |
| 57 /* Compile-time custom allocator support. */ |
| 58 |
| 59 #if defined(hb_malloc_impl) \ |
| 60 && defined(hb_calloc_impl) \ |
| 61 && defined(hb_realloc_impl) \ |
| 62 && defined(hb_free_impl) |
| 63 extern "C" void* hb_malloc_impl(size_t size); |
| 64 extern "C" void* hb_calloc_impl(size_t nmemb, size_t size); |
| 65 extern "C" void* hb_realloc_impl(void *ptr, size_t size); |
| 66 extern "C" void hb_free_impl(void *ptr); |
| 67 #define malloc hb_malloc_impl |
| 68 #define calloc hb_calloc_impl |
| 69 #define realloc hb_realloc_impl |
| 70 #define free hb_free_impl |
| 71 #endif |
| 72 |
| 73 |
| 57 /* Compiler attributes */ | 74 /* Compiler attributes */ |
| 58 | 75 |
| 59 | 76 |
| 60 #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) | 77 #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) |
| 61 #define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0) | 78 #define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0) |
| 62 #define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1)) | 79 #define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1)) |
| 63 #define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0)) | 80 #define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0)) |
| 64 #else | 81 #else |
| 65 #define likely(expr) (expr) | 82 #define likely(expr) (expr) |
| 66 #define unlikely(expr) (expr) | 83 #define unlikely(expr) (expr) |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 | 750 |
| 734 | 751 |
| 735 /* | 752 /* |
| 736 * Trace | 753 * Trace |
| 737 */ | 754 */ |
| 738 | 755 |
| 739 template <typename T> | 756 template <typename T> |
| 740 static inline void _hb_warn_no_return (bool returned) | 757 static inline void _hb_warn_no_return (bool returned) |
| 741 { | 758 { |
| 742 if (unlikely (!returned)) { | 759 if (unlikely (!returned)) { |
| 743 fprintf (stderr, "OUCH, returned with no call to TRACE_RETURN. This is a bu
g, please report.\n"); | 760 fprintf (stderr, "OUCH, returned with no call to return_trace(). This is a
bug, please report.\n"); |
| 744 } | 761 } |
| 745 } | 762 } |
| 746 template <> | 763 template <> |
| 747 /*static*/ inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED) | 764 /*static*/ inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED) |
| 748 {} | 765 {} |
| 749 | 766 |
| 750 template <int max_level, typename ret_t> | 767 template <int max_level, typename ret_t> |
| 751 struct hb_auto_trace_t { | 768 struct hb_auto_trace_t { |
| 752 explicit inline hb_auto_trace_t (unsigned int *plevel_, | 769 explicit inline hb_auto_trace_t (unsigned int *plevel_, |
| 753 const char *what_, | 770 const char *what_, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 768 _hb_warn_no_return<ret_t> (returned); | 785 _hb_warn_no_return<ret_t> (returned); |
| 769 if (!returned) { | 786 if (!returned) { |
| 770 _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1,
" "); | 787 _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1,
" "); |
| 771 } | 788 } |
| 772 if (plevel) --*plevel; | 789 if (plevel) --*plevel; |
| 773 } | 790 } |
| 774 | 791 |
| 775 inline ret_t ret (ret_t v, unsigned int line = 0) | 792 inline ret_t ret (ret_t v, unsigned int line = 0) |
| 776 { | 793 { |
| 777 if (unlikely (returned)) { | 794 if (unlikely (returned)) { |
| 778 fprintf (stderr, "OUCH, double calls to TRACE_RETURN. This is a bug, plea
se report.\n"); | 795 fprintf (stderr, "OUCH, double calls to return_trace(). This is a bug, pl
ease report.\n"); |
| 779 return v; | 796 return v; |
| 780 } | 797 } |
| 781 | 798 |
| 782 _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1, | 799 _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1, |
| 783 "return %s (line %d)", | 800 "return %s (line %d)", |
| 784 hb_printer_t<ret_t>().print (v), line); | 801 hb_printer_t<ret_t>().print (v), line); |
| 785 if (plevel) --*plevel; | 802 if (plevel) --*plevel; |
| 786 plevel = NULL; | 803 plevel = NULL; |
| 787 returned = true; | 804 returned = true; |
| 788 return v; | 805 return v; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 799 explicit inline hb_auto_trace_t (unsigned int *plevel_ HB_UNUSED, | 816 explicit inline hb_auto_trace_t (unsigned int *plevel_ HB_UNUSED, |
| 800 const char *what HB_UNUSED, | 817 const char *what HB_UNUSED, |
| 801 const void *obj HB_UNUSED, | 818 const void *obj HB_UNUSED, |
| 802 const char *func HB_UNUSED, | 819 const char *func HB_UNUSED, |
| 803 const char *message HB_UNUSED, | 820 const char *message HB_UNUSED, |
| 804 ...) {} | 821 ...) {} |
| 805 | 822 |
| 806 inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; } | 823 inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; } |
| 807 }; | 824 }; |
| 808 | 825 |
| 809 #define TRACE_RETURN(RET) trace.ret (RET, __LINE__) | 826 #define return_trace(RET) return trace.ret (RET, __LINE__) |
| 810 | 827 |
| 811 /* Misc */ | 828 /* Misc */ |
| 812 | 829 |
| 813 template <typename T> class hb_assert_unsigned_t; | 830 template <typename T> class hb_assert_unsigned_t; |
| 814 template <> class hb_assert_unsigned_t<unsigned char> {}; | 831 template <> class hb_assert_unsigned_t<unsigned char> {}; |
| 815 template <> class hb_assert_unsigned_t<unsigned short> {}; | 832 template <> class hb_assert_unsigned_t<unsigned short> {}; |
| 816 template <> class hb_assert_unsigned_t<unsigned int> {}; | 833 template <> class hb_assert_unsigned_t<unsigned int> {}; |
| 817 template <> class hb_assert_unsigned_t<unsigned long> {}; | 834 template <> class hb_assert_unsigned_t<unsigned long> {}; |
| 818 | 835 |
| 819 template <typename T> static inline bool | 836 template <typename T> static inline bool |
| (...skipping 28 matching lines...) Expand all Loading... |
| 848 * For example, for testing "x ∈ {x1, x2, x3}" use: | 865 * For example, for testing "x ∈ {x1, x2, x3}" use: |
| 849 * (FLAG_SAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) | 866 * (FLAG_SAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) |
| 850 */ | 867 */ |
| 851 #define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((x) < 32) + (1U << (x))) | 868 #define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((x) < 32) + (1U << (x))) |
| 852 #define FLAG_SAFE(x) (1U << (x)) | 869 #define FLAG_SAFE(x) (1U << (x)) |
| 853 #define FLAG_UNSAFE(x) ((x) < 32 ? FLAG_SAFE(x) : 0) | 870 #define FLAG_UNSAFE(x) ((x) < 32 ? FLAG_SAFE(x) : 0) |
| 854 #define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(
x)) | 871 #define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(
x)) |
| 855 | 872 |
| 856 | 873 |
| 857 template <typename T, typename T2> static inline void | 874 template <typename T, typename T2> static inline void |
| 858 hb_bubble_sort (T *array, unsigned int len, int(*compar)(const T *, const T *),
T2 *array2) | 875 hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *),
T2 *array2) |
| 859 { | 876 { |
| 860 if (unlikely (!len)) | 877 for (unsigned int i = 1; i < len; i++) |
| 861 return; | 878 { |
| 862 | 879 unsigned int j = i; |
| 863 unsigned int k = len - 1; | 880 while (j && compar (&array[j - 1], &array[i]) > 0) |
| 864 do { | 881 j--; |
| 865 unsigned int new_k = 0; | 882 if (i == j) |
| 866 | 883 continue; |
| 867 for (unsigned int j = 0; j < k; j++) | 884 /* Move item i to occupy place for item j, shift what's in between. */ |
| 868 if (compar (&array[j], &array[j+1]) > 0) | 885 { |
| 869 { | 886 T t = array[i]; |
| 870 { | 887 memmove (&array[j + 1], &array[j], (i - j) * sizeof (T)); |
| 871 » T t; | 888 array[j] = t; |
| 872 » t = array[j]; | 889 } |
| 873 » array[j] = array[j + 1]; | 890 if (array2) |
| 874 » array[j + 1] = t; | 891 { |
| 875 » } | 892 T2 t = array2[i]; |
| 876 if (array2) | 893 memmove (&array2[j + 1], &array2[j], (i - j) * sizeof (T2)); |
| 877 { | 894 array2[j] = t; |
| 878 » T2 t; | 895 } |
| 879 » t = array2[j]; | 896 } |
| 880 » array2[j] = array2[j + 1]; | |
| 881 » array2[j + 1] = t; | |
| 882 » } | |
| 883 | |
| 884 » new_k = j; | |
| 885 } | |
| 886 k = new_k; | |
| 887 } while (k); | |
| 888 } | 897 } |
| 889 | 898 |
| 890 template <typename T> static inline void | 899 template <typename T> static inline void |
| 891 hb_bubble_sort (T *array, unsigned int len, int(*compar)(const T *, const T *)) | 900 hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *)) |
| 892 { | 901 { |
| 893 hb_bubble_sort (array, len, compar, (int *) NULL); | 902 hb_stable_sort (array, len, compar, (int *) NULL); |
| 894 } | 903 } |
| 895 | 904 |
| 896 static inline hb_bool_t | 905 static inline hb_bool_t |
| 897 hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *o
ut) | 906 hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *o
ut) |
| 898 { | 907 { |
| 899 /* Pain because we don't know whether s is nul-terminated. */ | 908 /* Pain because we don't know whether s is nul-terminated. */ |
| 900 char buf[64]; | 909 char buf[64]; |
| 901 len = MIN (ARRAY_LENGTH (buf) - 1, len); | 910 len = MIN (ARRAY_LENGTH (buf) - 1, len); |
| 902 strncpy (buf, s, len); | 911 strncpy (buf, s, len); |
| 903 buf[len] = '\0'; | 912 buf[len] = '\0'; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 hb_options (void) | 944 hb_options (void) |
| 936 { | 945 { |
| 937 if (unlikely (!_hb_options.i)) | 946 if (unlikely (!_hb_options.i)) |
| 938 _hb_options_init (); | 947 _hb_options_init (); |
| 939 | 948 |
| 940 return _hb_options.opts; | 949 return _hb_options.opts; |
| 941 } | 950 } |
| 942 | 951 |
| 943 | 952 |
| 944 #endif /* HB_PRIVATE_HH */ | 953 #endif /* HB_PRIVATE_HH */ |
| OLD | NEW |