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 |