diff options
author | behdad <behdad> | 2004-05-03 22:05:19 +0000 |
---|---|---|
committer | behdad <behdad> | 2004-05-03 22:05:19 +0000 |
commit | 2a3c067871dcd2b595a1f3d0d79c3e0660270653 (patch) | |
tree | 2d13e8174254144be0c37ba12e7d6032480a1f82 | |
parent | 3961e54d055a45b4ed096a08c661bf2a00a77a41 (diff) | |
download | fribidi-2a3c067871dcd2b595a1f3d0d79c3e0660270653.tar.gz |
Changed the run data structure from a double-terminated deque, to a
circular deque with a single sentinel. To debug that, also added some assert
stuff, added function attributes, deprecated old interfaces, and humm, that it
for now.
41 files changed, 1348 insertions, 1011 deletions
diff --git a/.indent.pro b/.indent.pro index 35a5cb6..53cc4ff 100644 --- a/.indent.pro +++ b/.indent.pro @@ -1,7 +1,6 @@ -gnu -bfda -bfde --T TypeLink -T LevelInfo -T FriBidiChar -T FriBidiStrIndex @@ -13,6 +12,7 @@ -T FriBidiCharSetHandler -T FriBidiMemChunk -T FriBidiEnv +-T FriBidiRun -T fribidi_uint8 -T fribidi_uint16 -T fribidi_uint32 @@ -16,3 +16,7 @@ Implementation issues: * Design better apis to do reorder based on available levels, remove explicit marks then calculate position maps, .... + +* Add more tests. For: + - Checking that not removing explicit marks in analyze is not changing the + output in anyway. diff --git a/bin/fribidi-benchmark.c b/bin/fribidi-benchmark.c index 9fd015c..7c9bd2d 100644 --- a/bin/fribidi-benchmark.c +++ b/bin/fribidi-benchmark.c @@ -1,10 +1,10 @@ /* FriBidi * fribidi-benchmark.c - command line benchmark tool for libfribidi * - * $Id: fribidi-benchmark.c,v 1.1 2004-04-25 18:47:57 behdad Exp $ + * $Id: fribidi-benchmark.c,v 1.2 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-25 18:47:57 $ - * $Revision: 1.1 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.2 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/bin/fribidi-benchmark.c,v $ * * Authors: @@ -33,10 +33,10 @@ * For licensing issues, contact <license@farsiweb.info>. */ -#include <fribidi.h> - #include <common.h> +#include <fribidi.h> + #include <stdio.h> #if STDC_HEADERS # include <stdlib.h> diff --git a/bin/fribidi-main.c b/bin/fribidi-main.c index 1f64156..06a9f56 100644 --- a/bin/fribidi-main.c +++ b/bin/fribidi-main.c @@ -1,10 +1,10 @@ /* FriBidi * fribidi-main.c - command line program for libfribidi * - * $Id: fribidi-main.c,v 1.2 2004-04-28 03:20:22 behdad Exp $ + * $Id: fribidi-main.c,v 1.3 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-28 03:20:22 $ - * $Revision: 1.2 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.3 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/bin/fribidi-main.c,v $ * * Authors: @@ -33,6 +33,8 @@ * For licensing issues, contact <license@farsiweb.info>. */ +#include <common.h> + #include <fribidi.h> #if !FRIBIDI_CHARSETS # if FRIBIDI_MAIN_USE_ICONV_H @@ -42,8 +44,6 @@ # endif /* FRIBIDI_MAIN_USE_ICONV_H */ #endif /* !FRIBIDI_CHARSETS */ -#include <common.h> - #include <stdio.h> #if STDC_HEADERS # include <stdlib.h> @@ -254,8 +254,8 @@ main ( {"nomirror", 0, &do_mirror, false}, {"reordernsm", 0, &do_reorder_nsm, true}, {"clean", 0, &do_clean, true}, - {"ltr", 0, (int *) (void *) &input_base_direction, FRIBIDI_TYPE_L}, - {"rtl", 0, (int *) (void *) &input_base_direction, FRIBIDI_TYPE_R}, + {"ltr", 0, (int *) (void *) &input_base_direction, FRIBIDI_TYPE_LTR}, + {"rtl", 0, (int *) (void *) &input_base_direction, FRIBIDI_TYPE_RTL}, {"wltr", 0, (int *) (void *) &input_base_direction, FRIBIDI_TYPE_WL}, {"wrtl", 0, (int *) (void *) &input_base_direction, FRIBIDI_TYPE_WR}, {"basedir", 0, &show_basedir, true}, @@ -481,9 +481,9 @@ main ( while (wid > 0 && idx < len) { wid -= - fribidi_get_type (visual[idx]) & - (FRIBIDI_MASK_BN | FRIBIDI_MASK_NSM) ? 0 : - 1; + FRIBIDI_IS_EXPLICIT_OR_BN_OR_NSM + (fribidi_get_bidi_type (visual[idx])) ? 0 + : 1; idx++; } #if !FRIBIDI_MAIN_USE_ICONV_H diff --git a/charset/fribidi-char-sets-cap-rtl.c b/charset/fribidi-char-sets-cap-rtl.c index 9fb46ea..560c58c 100644 --- a/charset/fribidi-char-sets-cap-rtl.c +++ b/charset/fribidi-char-sets-cap-rtl.c @@ -1,10 +1,10 @@ /* FriBidi * fribidi-char-sets-cap-rtl.c - CapRTL character set conversion routines * - * $Id: fribidi-char-sets-cap-rtl.c,v 1.1 2004-04-25 18:47:57 behdad Exp $ + * $Id: fribidi-char-sets-cap-rtl.c,v 1.2 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-25 18:47:57 $ - * $Revision: 1.1 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.2 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/charset/fribidi-char-sets-cap-rtl.c,v $ * * Authors: @@ -33,13 +33,14 @@ * For licensing issues, contact <license@farsiweb.info>. */ +#include <common.h> + #include <fribidi-char-sets-cap-rtl.h> #include <fribidi-unicode.h> #include <fribidi-mirroring.h> #include <fribidi-bidi-type.h> -#include <common.h> #include <bidi-types.h> #include <stdio.h> @@ -241,7 +242,7 @@ fribidi_unicode_to_cap_rtl ( for (i = 0; i < len; i++) { FriBidiChar ch = us[i]; - if (!FRIBIDI_IS_EXPLICIT (fribidi_get_type (ch)) && ch != '_' + if (!FRIBIDI_IS_EXPLICIT (fribidi_get_bidi_type (ch)) && ch != '_' && ch != FRIBIDI_CHAR_LRM && ch != FRIBIDI_CHAR_RLM) s[j++] = fribidi_unicode_to_cap_rtl_c (ch); else diff --git a/charset/fribidi-char-sets-cp1255.c b/charset/fribidi-char-sets-cp1255.c index 02a72ba..3dc19c9 100644 --- a/charset/fribidi-char-sets-cp1255.c +++ b/charset/fribidi-char-sets-cp1255.c @@ -1,10 +1,10 @@ /* FriBidi * fribidi-char-sets-cp1255.c - CP1255 character set conversion routines * - * $Id: fribidi-char-sets-cp1255.c,v 1.1 2004-04-25 18:47:57 behdad Exp $ + * $Id: fribidi-char-sets-cp1255.c,v 1.2 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-25 18:47:57 $ - * $Revision: 1.1 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.2 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/charset/fribidi-char-sets-cp1255.c,v $ * * Authors: @@ -33,10 +33,10 @@ * For licensing issues, contact <license@farsiweb.info>. */ -#include <fribidi-char-sets-cp1255.h> - #include <common.h> +#include <fribidi-char-sets-cp1255.h> + #define ISO_ALEF 0xE0 #define ISO_TAV 0xFA #define CP1255_SHEVA 0xC0 diff --git a/charset/fribidi-char-sets-cp1256.c b/charset/fribidi-char-sets-cp1256.c index 1470da3..692bd87 100644 --- a/charset/fribidi-char-sets-cp1256.c +++ b/charset/fribidi-char-sets-cp1256.c @@ -1,10 +1,10 @@ /* FriBidi * fribidi-char-sets-cp1256.c - CP1256 character set conversion routines * - * $Id: fribidi-char-sets-cp1256.c,v 1.1 2004-04-25 18:47:57 behdad Exp $ + * $Id: fribidi-char-sets-cp1256.c,v 1.2 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-25 18:47:57 $ - * $Revision: 1.1 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.2 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/charset/fribidi-char-sets-cp1256.c,v $ * * Authors: @@ -33,10 +33,10 @@ * For licensing issues, contact <license@farsiweb.info>. */ -#include <fribidi-char-sets-cp1256.h> - #include <common.h> +#include <fribidi-char-sets-cp1256.h> + #define ISO_HAMZA 0xc1 #define CP1256_DAD 0xD6 diff --git a/charset/fribidi-char-sets-iso8859-6.c b/charset/fribidi-char-sets-iso8859-6.c index e238a4b..ac1b058 100644 --- a/charset/fribidi-char-sets-iso8859-6.c +++ b/charset/fribidi-char-sets-iso8859-6.c @@ -1,10 +1,10 @@ /* FriBidi * fribidi-char-sets-iso8859-6.c - ISO8859-6 character set conversion routines * - * $Id: fribidi-char-sets-iso8859-6.c,v 1.1 2004-04-25 18:47:57 behdad Exp $ + * $Id: fribidi-char-sets-iso8859-6.c,v 1.2 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-25 18:47:57 $ - * $Revision: 1.1 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.2 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/charset/fribidi-char-sets-iso8859-6.c,v $ * * Authors: @@ -33,10 +33,10 @@ * For licensing issues, contact <license@farsiweb.info>. */ -#include <fribidi-char-sets-iso8859-6.h> - #include <common.h> +#include <fribidi-char-sets-iso8859-6.h> + #define ISO_HAMZA 0xc1 #define ISO_SUKUN 0xf2 diff --git a/charset/fribidi-char-sets-iso8859-8.c b/charset/fribidi-char-sets-iso8859-8.c index 4b86b94..5a5bcf4 100644 --- a/charset/fribidi-char-sets-iso8859-8.c +++ b/charset/fribidi-char-sets-iso8859-8.c @@ -1,10 +1,10 @@ /* FriBidi * fribidi-char-sets-iso8859-8.c - ISO8859-8 character set conversion routines * - * $Id: fribidi-char-sets-iso8859-8.c,v 1.1 2004-04-25 18:47:57 behdad Exp $ + * $Id: fribidi-char-sets-iso8859-8.c,v 1.2 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-25 18:47:57 $ - * $Revision: 1.1 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.2 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/charset/fribidi-char-sets-iso8859-8.c,v $ * * Authors: @@ -33,12 +33,12 @@ * For licensing issues, contact <license@farsiweb.info>. */ +#include <common.h> + #include <fribidi-char-sets-iso8859-8.h> #include <fribidi-unicode.h> -#include <common.h> - /* The following are proposed extensions to ISO8859-8. */ #define ISO_8859_8_LRM 0xFD #define ISO_8859_8_RLM 0xFE diff --git a/charset/fribidi-char-sets-utf8.c b/charset/fribidi-char-sets-utf8.c index 79d1ab9..3933aea 100644 --- a/charset/fribidi-char-sets-utf8.c +++ b/charset/fribidi-char-sets-utf8.c @@ -1,10 +1,10 @@ /* FriBidi * fribidi-char-sets-utf8.c - UTF-8 character set conversion routines * - * $Id: fribidi-char-sets-utf8.c,v 1.1 2004-04-25 18:47:57 behdad Exp $ + * $Id: fribidi-char-sets-utf8.c,v 1.2 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-25 18:47:57 $ - * $Revision: 1.1 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.2 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/charset/fribidi-char-sets-utf8.c,v $ * * Authors: @@ -33,12 +33,12 @@ * For licensing issues, contact <license@farsiweb.info>. */ +#include <common.h> + #include <fribidi-char-sets-utf8.h> #include <fribidi-unicode.h> -#include <common.h> - FriBidiStrIndex fribidi_utf8_to_unicode ( /* input */ diff --git a/charset/fribidi-char-sets.c b/charset/fribidi-char-sets.c index 8ef5482..c1ebc39 100644 --- a/charset/fribidi-char-sets.c +++ b/charset/fribidi-char-sets.c @@ -1,10 +1,10 @@ /* FriBidi * fribidi-char-sets.c - character set conversion routines * - * $Id: fribidi-char-sets.c,v 1.1 2004-04-25 18:47:57 behdad Exp $ + * $Id: fribidi-char-sets.c,v 1.2 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-25 18:47:57 $ - * $Revision: 1.1 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.2 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/charset/fribidi-char-sets.c,v $ * * Authors: @@ -33,10 +33,10 @@ * For licensing issues, contact <license@farsiweb.info>. */ -#include <fribidi-char-sets.h> - #include <common.h> +#include <fribidi-char-sets.h> + typedef struct { FriBidiChar ( diff --git a/charset/fribidi-char-sets.h b/charset/fribidi-char-sets.h index 5508da9..1f1c6d4 100644 --- a/charset/fribidi-char-sets.h +++ b/charset/fribidi-char-sets.h @@ -1,10 +1,10 @@ /* FriBidi * fribidi-char-sets.h - character set conversion routines * - * $Id: fribidi-char-sets.h,v 1.1 2004-04-25 18:47:57 behdad Exp $ + * $Id: fribidi-char-sets.h,v 1.2 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-25 18:47:57 $ - * $Revision: 1.1 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.2 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/charset/fribidi-char-sets.h,v $ * * Authors: @@ -80,7 +80,7 @@ FRIBIDI_ENTRY FriBidiStrIndex fribidi_charset_to_unicode ( /* fribidi_unicode_to_charset - convert string from Unicode * * This function converts a Unicode string to an string in another character - * set. It also zero-terminates the output string. + * set. It also null-terminates the output string. * * Returns: The length of the new string. */ diff --git a/configure.ac b/configure.ac index 6b02b3b..5387e16 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ ############################################################################## -## $Id: configure.ac,v 1.3 2004-04-25 19:13:04 behdad Exp $ +## $Id: configure.ac,v 1.4 2004-05-03 22:05:19 behdad Exp $ ## $Auther: behdad $ -## $Date: 2004-04-25 19:13:04 $ -## $Revision: 1.3 $ +## $Date: 2004-05-03 22:05:19 $ +## $Revision: 1.4 $ ## $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/configure.ac,v $ ############################################################################## ## -*- Autoconf -*- @@ -41,7 +41,7 @@ m4_define(fribidi_rpm_release, 1)dnl dnl AC_INIT([GNU FriBidi],fribidi_version(),[http://freedesktop.org/cgi-bin/bugzilla/enter_bug.cgi?product=FriBidi]) -AC_REVISION([$Id: configure.ac,v 1.3 2004-04-25 19:13:04 behdad Exp $]) +AC_REVISION([$Id: configure.ac,v 1.4 2004-05-03 22:05:19 behdad Exp $]) AC_CONFIG_SRCDIR(lib/fribidi.h) AC_CONFIG_HEADERS(config.h) AM_INIT_AUTOMAKE([gnits]) @@ -101,11 +101,12 @@ AC_PROG_LIBTOOL # Checks for header files. AC_HEADER_STDC AC_HEADER_TIME -AC_CHECK_HEADERS([stdlib.h string.h strings.h inttypes.h stdbool.h wchar.h sys/times.h]) +AC_CHECK_HEADERS([stdlib.h string.h strings.h inttypes.h stdbool.h wchar.h sys/times.h asm/page.h]) # Checks for typedefs and structures. AC_C_CONST AC_C_INLINE +AC_C_STRINGIZE AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(short) AC_CHECK_SIZEOF(void *) diff --git a/doc/Makefile.am b/doc/Makefile.am index 41b46d2..45792b2 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -33,13 +33,17 @@ man3 = $(dist_man_MANS) $(dist_noinst_MANS) MAINTAINERCLEANFILES = $(man3) -C2MANFLAGS = $(includepath) -DDONT_HAVE_FRIBIDI_CONFIG_H -M "$(PACKAGE_NAME)" +C2MANFLAGS = $(includepath) \ + -DDONT_HAVE_FRIBIDI_CONFIG_H \ + -M "Programmer's Manual" \ + -m "$(PACKAGE_NAME) $(PACKAGE_VERSION)" + VPATH += $(includevpath) c2man.stamp: $(headers) @$(RM) $@.tmp @touch $@.tmp - $(top_srcdir)/missing --run c2man -T n $(C2MANFLAGS) $^ + $(top_srcdir)/missing --run c2man -T n $(C2MANFLAGS) $^ || true @mv $@.tmp $@ $(man3): c2man.stamp @@ -47,5 +51,6 @@ $(man3): c2man.stamp touch $@; \ else \ $(RM) $<; \ - $(MAKE) $(AM_MAKEFLAGS) $<; \ + $(MAKE) $(AM_MAKEFLAGS) $< || true; \ + touch $@; \ fi diff --git a/lib/Headers.mk b/lib/Headers.mk index 226d726..e1bd9b7 100644 --- a/lib/Headers.mk +++ b/lib/Headers.mk @@ -13,16 +13,4 @@ libfribidi_la_headers = \ fribidi-unicode-version.h \ fribidi.h -libfribidi_la_symbols = \ - fribidi_get_bidi_type \ - fribidi_get_bidi_types \ - fribidi_log2vis \ - fribidi_log2vis_get_embedding_levels \ - fribidi_remove_bidi_marks \ - fribidi_get_mirror_char \ - fribidi_debug_status \ - fribidi_set_debug \ - fribidi_mirroring_status \ - fribidi_set_mirroring \ - fribidi_reorder_nsm_status \ - fribidi_set_reorder_nsm +include $(top_srcdir)/lib/fribidi.def diff --git a/lib/Makefile.am b/lib/Makefile.am index 042dbb3..defe22a 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -10,9 +10,9 @@ if PLATFORM_WIN32 libfribidi_la_LDFLAGS += -no-undefined endif # PLATFORM_WIN32 -#if OS_WIN32 -#libfribidi_la_LDFLAGS += -export-symbols $(srcdir)/fribidi.sym -#endif # OS_WIN32 +if OS_WIN32 +libfribidi_la_LDFLAGS += -export-symbols $(srcdir)/fribidi.def +endif # OS_WIN32 if FRIBIDI_CHARSETS diff --git a/lib/bidi-type-table.i b/lib/bidi-type-table.i index c37c962..41eb47f 100644 --- a/lib/bidi-type-table.i +++ b/lib/bidi-type-table.i @@ -3,8 +3,8 @@ by fribidi_create_char_types */ -#ifndef FRIBIDI_TAB_CHAR_TYPE_2_I -#define FRIBIDI_TAB_CHAR_TYPE_2_I +#ifndef BIDI_TYPE_TABLE_I +#define BIDI_TYPE_TABLE_I #include "bidi-types.h" @@ -5211,7 +5211,7 @@ static const PACKTAB_UINT16 FriBidiPropertyBlockLevel0[4352*1] = { #undef RTL #undef LTR -static FriBidiCharType +static inline FriBidiCharType get_bidi_type ( /* input */ FriBidiChar uch @@ -5225,4 +5225,4 @@ get_bidi_type ( } -#endif /* FRIBIDI_TAB_CHAR_TYPE_2_I */ +#endif /* BIDI_TYPE_TABLE_I */ diff --git a/lib/bidi-types-list.h b/lib/bidi-types-list.h index fa39118..f1cea12 100644 --- a/lib/bidi-types-list.h +++ b/lib/bidi-types-list.h @@ -2,10 +2,10 @@ /* FriBidi * bidi-types-list.h - list of bidi types * - * $Id: bidi-types-list.h,v 1.2 2004-04-27 16:47:22 behdad Exp $ + * $Id: bidi-types-list.h,v 1.3 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-27 16:47:22 $ - * $Revision: 1.2 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.3 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/Attic/bidi-types-list.h,v $ * * Author: @@ -57,12 +57,11 @@ _FRIBIDI_ADD_TYPE (PDF, '-') /* Pop Directional Flag */ /* The following two types are not official Unicode bidi types, but used for * paragraph direction handling only. */ -_FRIBIDI_ADD_TYPE (WL, 'l') /* Weak Left to right */ -_FRIBIDI_ADD_TYPE (WR, 'r') /* Weak Right to left */ +_FRIBIDI_ADD_TYPE (WLTR, 'l') /* Weak Left to right */ +_FRIBIDI_ADD_TYPE (WRTL, 'r') /* Weak Right to left */ -/* The following two types are used internally only. */ -_FRIBIDI_ADD_TYPE (SOT, '^') /* Start Of Text */ -_FRIBIDI_ADD_TYPE (EOT, '$') /* End Of Text */ +/* The following type is used internally only. */ +_FRIBIDI_ADD_TYPE (SENTINEL, '$') /* Start Of Text */ #ifndef __C2MAN__ /* *INDENT-ON* */ diff --git a/lib/bidi-types.h b/lib/bidi-types.h index fed3125..98a8d58 100644 --- a/lib/bidi-types.h +++ b/lib/bidi-types.h @@ -1,10 +1,10 @@ /* FriBidi * bidi-types.h - define internal bidi types * - * $Id: bidi-types.h,v 1.2 2004-04-28 02:37:56 behdad Exp $ + * $Id: bidi-types.h,v 1.3 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-28 02:37:56 $ - * $Revision: 1.2 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.3 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/bidi-types.h,v $ * * Author: @@ -33,18 +33,15 @@ #ifndef _BIDI_TYPES_H #define _BIDI_TYPES_H -#include <fribidi-common.h> +#include "common.h" #include <fribidi-types.h> #include <fribidi-bidi-types.h> -#include "common.h" - #include <fribidi-begindecls.h> -#define FRIBIDI_LEVEL_REMOVED -3 -#define FRIBIDI_LEVEL_START -2 -#define FRIBIDI_LEVEL_END -1 +#define FRIBIDI_LEVEL_INVALID FRIBIDI_BIDI_MAX_RESOLVED_LEVELS +#define FRIBIDI_SENTINEL -1 /* * Define character types that char_type_tables use. @@ -68,9 +65,10 @@ extern const FriBidiCharType fribidi_prop_to_type_[]; #if DEBUG #define fribidi_char_from_bidi_type FRIBIDI_PRIVATESPACE(char_from_bidi_type) -FRIBIDI_ENTRY char fribidi_char_from_bidi_type ( +char +fribidi_char_from_bidi_type ( FriBidiCharType t /* input bidi type */ -); +) FRIBIDI_GNUC_HIDDEN; #endif /* DEBUG */ diff --git a/lib/common.h b/lib/common.h index f8f0a50..4a7d53d 100644 --- a/lib/common.h +++ b/lib/common.h @@ -1,10 +1,10 @@ /* FriBidi * common.h - common include for library sources * - * $Id: common.h,v 1.4 2004-04-28 02:37:56 behdad Exp $ + * $Id: common.h,v 1.5 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-28 02:37:56 $ - * $Revision: 1.4 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.5 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/common.h,v $ * * Author: @@ -73,6 +73,26 @@ # define fribidi_malloc g_malloc # define fribidi_free g_free # endif /* !fribidi_malloc */ +# ifndef fribidi_assert +# ifndef __C2MAN__ +# include <glib/gmessages.h> +# endif /* !__C2MAN__ */ +# define fribidi_assert g_assert +# endif /* !fribidi_assert */ +# ifndef FRIBIDI_BEGIN_STMT +# ifndef __C2MAN__ +# include <glib/gmacros.h> +# endif /* !__C2MAN__ */ +# define FRIBIDI_BEGIN_STMT G_STMT_START { +# define FRIBIDI_END_STMT } G_STMT_END +# endif /* !FRIBIDI_BEGIN_STMT */ +# ifndef LIKELY +# ifndef __C2MAN__ +# include <glib/gmacros.h> +# endif /* !__C2MAN__ */ +# define LIKELY G_LIKELY +# define UNLIKELY G_UNLIKELY +# endif /* !LIKELY */ #endif /* FRIBIDI_USE_GLIB */ /* fribidi_malloc and fribidi_free should be used instead of malloc and free. @@ -92,7 +112,14 @@ /* FRIBIDI_CHUNK_SIZE is the number of bytes in each chunk of memory being * allocated for data structure pools. */ #ifndef FRIBIDI_CHUNK_SIZE -# define FRIBIDI_CHUNK_SIZE 4096 +# if HAVE_ASM_PAGE_H +# ifndef __C2MAN__ +# include <asm/page.h> +# endif /* __C2MAN__ */ +# define FRIBIDI_CHUNK_SIZE (PAGE_SIZE - 16) +# else /* !HAVE_ASM_PAGE_H */ +# define FRIBIDI_CHUNK_SIZE (4096 - 16) +# endif /* !HAVE_ASM_PAGE_H */ #else /* FRIBIDI_CHUNK_SIZE */ # if FRIBIDI_CHUNK_SIZE < 256 # error FRIBIDI_CHUNK_SIZE now should define the size of a chunk in bytes. @@ -101,12 +128,23 @@ /* FRIBIDI_BEGIN_STMT should be used at the beginning of your macro * definitions that are to behave like simple statements. Use - * FRIBIDI_END_STMT at the end of the macro after the semicolon or brace */ + * FRIBIDI_END_STMT at the end of the macro after the semicolon or brace. */ #ifndef FRIBIDI_BEGIN_STMT # define FRIBIDI_BEGIN_STMT do { # define FRIBIDI_END_STMT } while (0) #endif /* !FRIBIDI_BEGIN_STMT */ +/* LIKEYLY and UNLIKELY are used to give a hint on branch prediction to the + * compiler. */ +#ifndef LIKELY +# define LIKELY(expr) (expr) +# define UNLIKELY(expr) (expr) +#endif /* !LIKELY */ + +#ifndef FRIBIDI_EMPTY_STMT +# define FRIBIDI_EMPTY_STMT FRIBIDI_BEGIN_STMT (void) 0; FRIBIDI_END_STMT +#endif /* !FRIBIDI_EMPTY_STMT */ + #include "debug.h" #endif /* !_COMMON_H */ diff --git a/lib/debug.h b/lib/debug.h index d17921c..e59b288 100644 --- a/lib/debug.h +++ b/lib/debug.h @@ -1,10 +1,10 @@ /* FriBidi * debug.h - debug-only interfaces * - * $Id: debug.h,v 1.2 2004-04-27 16:47:22 behdad Exp $ + * $Id: debug.h,v 1.3 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-27 16:47:22 $ - * $Revision: 1.2 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.3 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/debug.h,v $ * * Author: @@ -33,16 +33,27 @@ #ifndef _DEBUG_H #define _DEBUG_H -#include <fribidi-common.h> +#include "common.h" #include <fribidi-types.h> -#include "common.h" - #include <fribidi-begindecls.h> #if DEBUG +/* These definitions should only be used in DEBUG mode: */ +#if HAVE_STRINGIZE +# define STRINGIZE(symbol) #symbol +#else /* !HAVE_STRINGIZE */ +# define STRINGIZE(symbol) +#endif /* !HAVE_STRINGIZE */ +#ifndef __LINE__ +# define __LINE__ 0 +#endif /* !__LINE__ */ +#ifndef __FILE__ +# define __FILE__ "unknown" +#endif /* !__FILE__ */ + #ifndef FRIBIDI_FPRINTF # ifndef __C2MAN__ # include <stdio.h> @@ -51,31 +62,50 @@ # define FRIBIDI_STDERR_ stderr, #endif /* !FRIBIDI_FPRINTF */ -#define MSG(s) FRIBIDI_BEGIN_STMT \ - FRIBIDI_FPRINTF(FRIBIDI_STDERR_ s); \ +#ifndef MSG +#define MSG(s) \ + FRIBIDI_BEGIN_STMT \ + FRIBIDI_FPRINTF(FRIBIDI_STDERR_ s); \ FRIBIDI_END_STMT - -#define MSG2(s, t) FRIBIDI_BEGIN_STMT \ - FRIBIDI_FPRINTF(FRIBIDI_STDERR_ s, t); \ +#define MSG2(s, t) \ + FRIBIDI_BEGIN_STMT \ + FRIBIDI_FPRINTF(FRIBIDI_STDERR_ s, t); \ FRIBIDI_END_STMT - -#define MSG5(s, t, u, v, w) FRIBIDI_BEGIN_STMT \ - FRIBIDI_FPRINTF(FRIBIDI_STDERR_ s, t, u, v, w); \ +#define MSG5(s, t, u, v, w) \ + FRIBIDI_BEGIN_STMT \ + FRIBIDI_FPRINTF(FRIBIDI_STDERR_ s, t, u, v, w); \ FRIBIDI_END_STMT +#endif /* !MSG */ #ifndef DBG -# define DBG(s) FRIBIDI_BEGIN_STMT \ +# define DBG(s) \ + FRIBIDI_BEGIN_STMT \ if (fribidi_debug_status()) MSG(FRIBIDI ": " s "\n"); \ FRIBIDI_END_STMT -# define DBG2(s, t) FRIBIDI_BEGIN_STMT \ +# define DBG2(s, t) \ + FRIBIDI_BEGIN_STMT \ if (fribidi_debug_status()) MSG2(FRIBIDI ": " s "\n", t); \ FRIBIDI_END_STMT #endif /* !DBG */ +#ifndef fribidi_assert +# define fribidi_assert(cond) \ + FRIBIDI_BEGIN_STMT \ + if (!(cond)) \ + DBG("file " __FILE__ ": line " STRINGIZE(__LINE__) ": " \ + "assertion failed (" STRINGIZE(cond) ")"); \ + FRIBIDI_END_STMT +#endif /* !fribidi_assert */ + #else /* !DEBUG */ -#define DBG(s) /* empty */ -#define DBG2(s, t) /* empty */ +#ifndef DBG +# define DBG(s) FRIBIDI_EMPTY_STMT +# define DBG2(s, t) FRIBIDI_EMPTY_STMT +#endif /* !DBG */ +#ifndef fribidi_assert +# define fribidi_assert(cond) FRIBIDI_EMPTY_STMT +#endif /* !fribidi_assert */ #endif /* !DEBUG */ @@ -1,10 +1,10 @@ /* FriBidi * env.h - private state variables * - * $Id: env.h,v 1.1 2004-04-28 02:37:56 behdad Exp $ + * $Id: env.h,v 1.2 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-28 02:37:56 $ - * $Revision: 1.1 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.2 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/Attic/env.h,v $ * * Author: @@ -35,14 +35,12 @@ #ifndef _ENV_H #define _ENV_H -#include <fribidi-common.h> +#include "common.h" #include <fribidi-bidi-types.h> #include "mem.h" -#include "common.h" - #include <fribidi-begindecls.h> #if !USE_SIMPLE_MALLOC diff --git a/lib/fribidi-bidi-type.c b/lib/fribidi-bidi-type.c index b593c7b..a636c4a 100644 --- a/lib/fribidi-bidi-type.c +++ b/lib/fribidi-bidi-type.c @@ -1,10 +1,10 @@ /* FriBidi * fribidi-bidi-type.c - get character bidi type * - * $Id: fribidi-bidi-type.c,v 1.2 2004-04-28 02:37:56 behdad Exp $ + * $Id: fribidi-bidi-type.c,v 1.3 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-28 02:37:56 $ - * $Revision: 1.2 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.3 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/Attic/fribidi-bidi-type.c,v $ * * Authors: @@ -31,13 +31,13 @@ * For licensing issues, contact <license@farsiweb.info>. */ +#include "common.h" + #include <fribidi-bidi-type.h> #include "bidi-types.h" #include "bidi-type-table.i" -#include "common.h" - FRIBIDI_ENTRY FriBidiCharType fribidi_get_bidi_type ( /* input */ @@ -48,8 +48,17 @@ fribidi_get_bidi_type ( } /* The following is only defined for binary compatibility */ +FriBidiCharType +fribidi_get_type ( + FriBidiChar ch +) +{ + return fribidi_get_bidi_type (ch); +} + +/* The following is only defined for binary compatibility */ #define fribidi_get_type_internal FRIBIDI_NAMESPACE(get_type_internal) -FRIBIDI_ENTRY FriBidiCharType +FriBidiCharType fribidi_get_type_internal ( /* input */ FriBidiChar ch @@ -67,8 +76,20 @@ fribidi_get_bidi_types ( FriBidiCharType *type ) { - for (; len; len--) - *type++ = fribidi_get_bidi_type (*str++); + register FriBidiStrIndex i = len; + for (; i; i--) + *type++ = get_bidi_type (*str++); +} + +/* The following is only defined for binary compatibility */ +void +fribidi_get_types ( + const FriBidiChar *str, + FriBidiStrIndex len, + FriBidiCharType *type +) +{ + fribidi_get_bidi_types (str, len, type); } /* Map fribidi_prop_types to fribidi_types. */ diff --git a/lib/fribidi-bidi-type.h b/lib/fribidi-bidi-type.h index 6a0f20b..79e07d4 100644 --- a/lib/fribidi-bidi-type.h +++ b/lib/fribidi-bidi-type.h @@ -1,10 +1,10 @@ /* FriBidi * fribidi-bidi-type.h - get character bidi type * - * $Id: fribidi-bidi-type.h,v 1.1 2004-04-25 18:47:57 behdad Exp $ + * $Id: fribidi-bidi-type.h,v 1.2 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-25 18:47:57 $ - * $Revision: 1.1 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.2 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/Attic/fribidi-bidi-type.h,v $ * * Author: @@ -40,32 +40,43 @@ #include "fribidi-begindecls.h" -/* fribidi_get_type is the old name of fribidi_get_bidi_type */ -#define fribidi_get_type fribidi_get_bidi_type - #define fribidi_get_bidi_type FRIBIDI_NAMESPACE(get_bidi_type) /* fribidi_get_bidi_type - get character bidi type * * This function returns the bidi type of a character. */ -FRIBIDI_ENTRY FriBidiCharType fribidi_get_bidi_type ( +FRIBIDI_ENTRY FriBidiCharType +fribidi_get_bidi_type ( FriBidiChar ch /* input character */ -); +) FRIBIDI_GNUC_CONST; -/* fribidi_get_types is the old name of fribidi_get_bidi_types */ -#define fribidi_get_types fribidi_get_bidi_types +/* fribidi_get_type is the old name of fribidi_get_bidi_type */ +#define fribidi_get_type FRIBIDI_NAMESPACE(get_type) + FriBidiCharType fribidi_get_type ( + FriBidiChar ch +) + FRIBIDI_GNUC_CONST FRIBIDI_GNUC_DEPRECATED; #define fribidi_get_bidi_types FRIBIDI_NAMESPACE(get_bidi_types) /* fribidi_get_bidi_types - get bidi types for an string of characters * * This function finds the bidi types of an string of characters. */ -FRIBIDI_ENTRY void fribidi_get_bidi_types ( + FRIBIDI_ENTRY void fribidi_get_bidi_types ( const FriBidiChar *str, /* input string */ FriBidiStrIndex len, /* input string length */ FriBidiCharType *type /* output bidi types */ ); +/* fribidi_get_types is the old name of fribidi_get_bidi_types */ +#define fribidi_get_types FRIBIDI_NAMESPACE(get_types) + void fribidi_get_bidi_types ( + const FriBidiChar *str, + FriBidiStrIndex len, + FriBidiCharType *type +) + FRIBIDI_GNUC_CONST FRIBIDI_GNUC_DEPRECATED; + #include "fribidi-enddecls.h" #endif /* !_FRIBIDI_BIDI_TYPE_H */ diff --git a/lib/fribidi-bidi-types.c b/lib/fribidi-bidi-types.c index b148afe..a89dfb1 100644 --- a/lib/fribidi-bidi-types.c +++ b/lib/fribidi-bidi-types.c @@ -1,10 +1,10 @@ /* FriBidi * fribidi-bidi-types.c - character bidi types * - * $Id: fribidi-bidi-types.c,v 1.2 2004-04-28 02:37:56 behdad Exp $ + * $Id: fribidi-bidi-types.c,v 1.3 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-28 02:37:56 $ - * $Revision: 1.2 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.3 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi-bidi-types.c,v $ * * Authors: @@ -31,15 +31,15 @@ * For licensing issues, contact <license@farsiweb.info>. */ +#include "common.h" + #include <fribidi-bidi-types.h> #include "bidi-types.h" -#include "common.h" - #ifdef DEBUG -FRIBIDI_ENTRY char +char fribidi_char_from_bidi_type ( /* input */ FriBidiCharType t diff --git a/lib/fribidi-bidi-types.h b/lib/fribidi-bidi-types.h index 37af7f5..161dcbe 100644 --- a/lib/fribidi-bidi-types.h +++ b/lib/fribidi-bidi-types.h @@ -1,10 +1,10 @@ /* FriBidi * fribidi-bidi-types.h - character bidi types * - * $Id: fribidi-bidi-types.h,v 1.2 2004-04-28 02:37:56 behdad Exp $ + * $Id: fribidi-bidi-types.h,v 1.3 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-28 02:37:56 $ - * $Revision: 1.2 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.3 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi-bidi-types.h,v $ * * Author: @@ -60,7 +60,7 @@ typedef FriBidiMaskType FriBidiCharType; #define FRIBIDI_MASK_STRONG 0x00000010L /* Is strong */ #define FRIBIDI_MASK_WEAK 0x00000020L /* Is weak */ #define FRIBIDI_MASK_NEUTRAL 0x00000040L /* Is neutral */ -#define FRIBIDI_MASK_SENTINEL 0x00000080L /* Is sentinel: SOT, EOT */ +#define FRIBIDI_MASK_SENTINEL 0x00000080L /* Is sentinel */ /* Sentinels are not valid chars, just identify the start and end of strings. */ /* Each char can be only one of the five following. */ @@ -151,23 +151,26 @@ typedef FriBidiMaskType FriBidiCharType; /* Other Neutral */ #define FRIBIDI_TYPE_ON ( FRIBIDI_MASK_NEUTRAL ) -/* The following are used to identify the paragraph direction, - types L, R, N are not used internally anymore, and recommended to use - LTR, RTL and ON instead, didn't removed because of compatability. */ -#define FRIBIDI_TYPE_L ( FRIBIDI_TYPE_LTR ) -#define FRIBIDI_TYPE_R ( FRIBIDI_TYPE_RTL ) -#define FRIBIDI_TYPE_N ( FRIBIDI_TYPE_ON ) + +/* The following are used in specifying paragraph direction only, not real + * types. */ + /* Weak left to right */ -#define FRIBIDI_TYPE_WL ( FRIBIDI_MASK_WEAK ) +#define FRIBIDI_TYPE_WLTR ( FRIBIDI_MASK_WEAK ) /* Weak right to left */ -#define FRIBIDI_TYPE_WR ( FRIBIDI_MASK_WEAK + FRIBIDI_MASK_RTL ) +#define FRIBIDI_TYPE_WRTL ( FRIBIDI_MASK_WEAK + FRIBIDI_MASK_RTL ) -/* The following are only used internally */ +/* Just for compatibility */ +#define FRIBIDI_TYPE_WL FRIBIDI_TYPE_WLTR +#define FRIBIDI_TYPE_WR FRIBIDI_TYPE_WRTL +#define FRIBIDI_TYPE_L FRIBIDI_TYPE_LTR +#define FRIBIDI_TYPE_R FRIBIDI_TYPE_RTL +#define FRIBIDI_TYPE_N FRIBIDI_TYPE_ON -/* Start of text */ -#define FRIBIDI_TYPE_SOT ( FRIBIDI_MASK_SENTINEL ) -/* End of text */ -#define FRIBIDI_TYPE_EOT ( FRIBIDI_MASK_SENTINEL + FRIBIDI_MASK_RTL ) +/* The following is only used internally */ + +/* Start or end of text (run list) */ +#define FRIBIDI_TYPE_SENTINEL ( FRIBIDI_MASK_SENTINEL ) /* * End of define values for FriBidiCharType @@ -242,6 +245,11 @@ typedef FriBidiMaskType FriBidiCharType; #define FRIBIDI_IS_EXPLICIT_OR_BN(p) \ ((p) & (FRIBIDI_MASK_EXPLICIT | FRIBIDI_MASK_BN)) +/* Is explicit or BN or NSM: LRE, RLE, LRO, RLO, PDF, BN, NSM? + * This is a good approximation of being zero-width. */ +#define FRIBIDI_IS_EXPLICIT_OR_BN_OR_NSM(p) \ + ((p) & (FRIBIDI_MASK_EXPLICIT | FRIBIDI_MASK_BN | FRIBIDI_MASK_NSM)) + /* Is explicit or separator or BN or WS: LRE, RLE, LRO, RLO, PDF, BS, SS, BN, WS? */ #define FRIBIDI_IS_EXPLICIT_OR_SEPARATOR_OR_BN_OR_WS(p) \ ((p) & (FRIBIDI_MASK_EXPLICIT | FRIBIDI_MASK_SEPARATOR \ @@ -253,7 +261,8 @@ typedef FriBidiMaskType FriBidiCharType; #define FRIBIDI_CHANGE_NUMBER_TO_RTL(p) \ (FRIBIDI_IS_NUMBER(p) ? FRIBIDI_TYPE_RTL : (p)) -/* Override status of an explicit mark: LRO->LTR, RLO->RTL, otherwise->ON. */ +/* Override status of an explicit mark: + * LRO,LRE->LTR, RLO,RLE->RTL, otherwise->ON. */ #define FRIBIDI_EXPLICIT_TO_OVERRIDE_DIR(p) \ (FRIBIDI_IS_OVERRIDE(p) ? FRIBIDI_LEVEL_TO_DIR(FRIBIDI_DIR_TO_LEVEL(p)) \ : FRIBIDI_TYPE_ON) @@ -268,9 +277,10 @@ typedef FriBidiMaskType FriBidiCharType; * This function returns the bidi type name of a character type. The * returned string is a static string and should not be freed. */ -FRIBIDI_ENTRY const char *fribidi_bidi_type_name ( +FRIBIDI_ENTRY const char * +fribidi_bidi_type_name ( FriBidiCharType t /* input bidi type */ -); +) FRIBIDI_GNUC_CONST; #include "fribidi-enddecls.h" diff --git a/lib/fribidi-bidi.c b/lib/fribidi-bidi.c index e4cb741..1c58b36 100644 --- a/lib/fribidi-bidi.c +++ b/lib/fribidi-bidi.c @@ -1,10 +1,10 @@ /* FriBidi * fribidi-bidi.c - bidirectional algorithm * - * $Id: fribidi-bidi.c,v 1.4 2004-04-28 02:37:56 behdad Exp $ + * $Id: fribidi-bidi.c,v 1.5 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-28 02:37:56 $ - * $Revision: 1.4 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.5 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi-bidi.c,v $ * * Authors: @@ -33,6 +33,8 @@ * For licensing issues, contact <license@farsiweb.info>. */ +#include "common.h" + #include <fribidi-bidi.h> #include <fribidi-bidi-type.h> #include <fribidi-mirroring.h> @@ -44,10 +46,9 @@ #include "bidi-types.h" #include "run.h" -#include "common.h" - -#undef MAX -#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#ifndef MAX +# define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif /* !MAX */ typedef struct { @@ -56,69 +57,6 @@ typedef struct } LevelInfo; -static void -bidi_string_reverse ( - FriBidiChar *str, - FriBidiStrIndex len -) -{ - FriBidiStrIndex i; - for (i = 0; i < len / 2; i++) - { - FriBidiChar tmp = str[i]; - str[i] = str[len - 1 - i]; - str[len - 1 - i] = tmp; - } -} - -static void -index_array_reverse ( - FriBidiStrIndex *arr, - FriBidiStrIndex len -) -{ - FriBidiStrIndex i; - for (i = 0; i < len / 2; i++) - { - FriBidiStrIndex tmp = arr[i]; - arr[i] = arr[len - 1 - i]; - arr[len - 1 - i] = tmp; - } -} - -/* explicits_list is a list like type_rl_list, that holds the explicit - codes that are removed from rl_list, to reinsert them later by calling - the override_list. -*/ -static void -init_list ( - FriBidiRun ** start, - FriBidiRun ** end -) -{ - FriBidiRun *list; - FriBidiRun *link; - - /* Add the starting link */ - list = new_run (); - list->type = FRIBIDI_TYPE_SOT; - list->level = FRIBIDI_LEVEL_START; - list->len = 0; - list->pos = 0; - - /* Add the ending link */ - link = new_run (); - link->type = FRIBIDI_TYPE_EOT; - link->level = FRIBIDI_LEVEL_END; - link->len = 0; - link->pos = 0; - list->next = link; - link->prev = list; - - *start = list; - *end = link; -} - /* Some convenience macros */ #define RL_TYPE(list) ((list)->type) #define RL_LEN(list) ((list)->len) @@ -127,10 +65,16 @@ init_list ( static FriBidiRun * merge_with_prev ( - FriBidiRun * second + FriBidiRun *second ) { - FriBidiRun *first = second->prev; + FriBidiRun *first; + + fribidi_assert (second); + fribidi_assert (second->next); + first = second->prev; + fribidi_assert (first); + first->next = second->next; first->next->prev = first; RL_LEN (first) += RL_LEN (second); @@ -140,33 +84,37 @@ merge_with_prev ( static void compact_list ( - FriBidiRun * list + FriBidiRun *list ) { + fribidi_assert (list); + if (list->next) - for (list = list->next; list; list = list->next) + for_run_list (list, list) if (RL_TYPE (list->prev) == RL_TYPE (list) && RL_LEVEL (list->prev) == RL_LEVEL (list)) - list = merge_with_prev (list); + list = merge_with_prev (list); } static void compact_neutrals ( - FriBidiRun * list + FriBidiRun *list ) { + fribidi_assert (list); + if (list->next) { - for (list = list->next; list; list = list->next) - { - if (RL_LEVEL (list->prev) == RL_LEVEL (list) - && - ((RL_TYPE - (list->prev) == RL_TYPE (list) - || (FRIBIDI_IS_NEUTRAL (RL_TYPE (list->prev)) - && FRIBIDI_IS_NEUTRAL (RL_TYPE (list)))))) - list = merge_with_prev (list); - } + for_run_list (list, list) + { + if (RL_LEVEL (list->prev) == RL_LEVEL (list) + && + ((RL_TYPE + (list->prev) == RL_TYPE (list) + || (FRIBIDI_IS_NEUTRAL (RL_TYPE (list->prev)) + && FRIBIDI_IS_NEUTRAL (RL_TYPE (list)))))) + list = merge_with_prev (list); + } } } @@ -175,20 +123,21 @@ compact_neutrals ( *-------------------------------------------------------------------------*/ /* There's some little points in pushing and poping into the status stack: - 1. when the embedding level is not valid (more than FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL=61), - you must reject it, and not to push into the stack, but when you see a - PDF, you must find the matching code, and if it was pushed in the stack, - pop it, it means you must pop if and only if you have pushed the - matching code, the over_pushed var counts the number of rejected codes yet. + 1. when the embedding level is not valid (more than + FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL=61), you must reject it, and not to push + into the stack, but when you see a PDF, you must find the matching code, + and if it was pushed in the stack, pop it, it means you must pop if and + only if you have pushed the matching code, the over_pushed var counts the + number of rejected codes yet. 2. there's a more confusing point too, when the embedding level is exactly - FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL-1=60, an LRO or LRE must be rejected because the new - level would be FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL+1=62, that is invalid, but an RLO or RLE - must be accepted because the new level is FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL=61, that is - valid, so the rejected codes may be not continuous in the logical order, - in fact there is at most two continuous intervals of codes, with a RLO or - RLE between them. To support this case, the first_interval var counts the - number of rejected codes in the first interval, when it is 0, means that - there is only one interval yet. + FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL-1=60, an LRO or LRE must be rejected + because the new level would be FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL+1=62, that + is invalid, but an RLO or RLE must be accepted because the new level is + FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL=61, that is valid, so the rejected codes + may be not continuous in the logical order, in fact there is at most two + continuous intervals of codes, with a RLO or RLE between them. To support + this case, the first_interval var counts the number of rejected codes in + the first interval, when it is 0, means that there is only one interval yet. */ /* a. If this new level would be valid, then this embedding code is valid. @@ -200,9 +149,9 @@ compact_neutrals ( */ #define PUSH_STATUS \ FRIBIDI_BEGIN_STMT \ - if (new_level <= FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL) \ + if LIKELY(new_level <= FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL) \ { \ - if (level == FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL - 1) \ + if UNLIKELY(level == FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL - 1) \ first_interval = over_pushed; \ status_stack[stack_size].level = level; \ status_stack[stack_size].override = override; \ @@ -218,13 +167,13 @@ compact_neutrals ( */ #define POP_STATUS \ FRIBIDI_BEGIN_STMT \ - if (over_pushed || stack_size) \ + if (stack_size) \ { \ - if (over_pushed > first_interval) \ + if UNLIKELY(over_pushed > first_interval) \ over_pushed--; \ else \ { \ - if (over_pushed == first_interval) \ + if LIKELY(over_pushed == first_interval) \ first_interval = 0; \ stack_size--; \ level = status_stack[stack_size].level; \ @@ -238,25 +187,22 @@ compact_neutrals ( * Levels, so define macros, to support them, with as less change as needed. *--------------------------------------------------------------------------*/ -/* Return the type of previous char or the sor, if already at the start of - a run level. */ +/* Return the type of previous run or the SOR, if already at the start of + a level run. */ #define PREV_TYPE_OR_SOR(pp) \ ( \ - RL_LEVEL(pp->prev) == RL_LEVEL(pp) ? \ - RL_TYPE(pp->prev) : \ - FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(pp->prev), RL_LEVEL(pp))) \ + RL_LEVEL(pp->prev) == RL_LEVEL(pp) ? \ + RL_TYPE(pp->prev) : \ + FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(pp->prev), RL_LEVEL(pp))) \ ) -/* Return the type of next char or the eor, if already at the end of - a run level. */ +/* Return the type of next run or the EOR, if already at the end of + a level run. */ #define NEXT_TYPE_OR_EOR(pp) \ ( \ - !pp->next ? \ - FRIBIDI_LEVEL_TO_DIR(RL_LEVEL(pp)) : \ - (RL_LEVEL(pp->next) == RL_LEVEL(pp) ? \ + RL_LEVEL(pp->next) == RL_LEVEL(pp) ? \ RL_TYPE(pp->next) : \ FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(pp->next), RL_LEVEL(pp))) \ - ) \ ) @@ -271,11 +217,10 @@ compact_neutrals ( *----------------------------------------------------------------------*/ static char char_from_level_array[] = { - '!', /* FRIBIDI_LEVEL_REMOVED, internal error, this level shouldn't be seen. */ - '^', /* FRIBIDI_LEVEL_START, indicating start of string. */ - '$', /* FRIBIDI_LEVEL_END, indicating end of string. */ - /* 0-9,a-z,A-Z are the the only valid levels before resolving implicits. - after that the level @ may be appear too. */ + '$', /* -1 == FRIBIDI_SENTINEL, indicating + * start or end of string. */ + /* 0-61 == 0-9,a-z,A-Z are the the only valid levels before resolving + * implicits. after that the level @ may be appear too. */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', @@ -284,56 +229,65 @@ static char char_from_level_array[] = { 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - '@', /* only must appear after resolving implicits. */ - '*', '*', '*' /* overflows, this levels and higher levels show a bug!. */ + '@', /* 62 == only must appear after resolving + * implicits. */ + + '!', /* 63 == FRIBIDI_LEVEL_INVALID, internal error, + * this level shouldn't be seen. */ + + '*', '*', '*', '*', '*' /* >= 64 == overflows, this levels and higher + * levels show a real bug!. */ }; -#define fribidi_char_from_level(level) char_from_level_array[(level) + 3] +#define fribidi_char_from_level(level) char_from_level_array[(level) + 1] static void print_types_re ( - FriBidiRun * pp + FriBidiRun *pp ) { + fribidi_assert (pp); + MSG (" Run types : "); - while (pp) - { - MSG5 ("%d:l%d(%s)[%d] ", - pp->pos, pp->len, fribidi_type_name (pp->type), pp->level); - pp = pp->next; - } + for_run_list (pp, pp) + { + MSG5 ("%d:%d(%s)[%d] ", + pp->pos, pp->len, fribidi_bidi_type_name (pp->type), pp->level); + } MSG ("\n"); } static void print_resolved_levels ( - FriBidiRun * pp + FriBidiRun *pp ) { + fribidi_assert (pp); + MSG (" Res. levels: "); - while (pp) - { - FriBidiStrIndex i; - for (i = RL_LEN (pp); i; i--) - MSG2 ("%c", fribidi_char_from_level (RL_LEVEL (pp))); - pp = pp->next; - } + for_run_list (pp, pp) + { + FriBidiStrIndex i; + for (i = RL_LEN (pp); i; i--) + MSG2 ("%c", fribidi_char_from_level (RL_LEVEL (pp))); + } MSG ("\n"); } static void print_resolved_types ( - FriBidiRun * pp + FriBidiRun *pp ) { + fribidi_assert (pp); + MSG (" Res. types : "); - while (pp) - { - FriBidiStrIndex i; - for (i = RL_LEN (pp); i; i--) - MSG2 ("%c", fribidi_char_from_bidi_type (pp->type)); - pp = pp->next; - } + for_run_list (pp, pp) + { + FriBidiStrIndex i; + for (i = RL_LEN (pp); i; i--) + MSG2 ("%c", fribidi_char_from_bidi_type (pp->type)); + } MSG ("\n"); } @@ -344,6 +298,8 @@ print_bidi_string ( FriBidiStrIndex len ) { + fribidi_assert (str); + MSG (" Org. types : "); for (; len; len--) MSG2 ("%c", fribidi_char_from_bidi_type (fribidi_get_bidi_type (*str++))); @@ -351,44 +307,58 @@ print_bidi_string ( } #endif /* DEBUG */ +static fribidi_boolean +fribidi_analyse_string ( + const FriBidiChar *str, + FriBidiStrIndex len, + FriBidiCharType *pbase_dir, + FriBidiRun **pmain_run_list, + FriBidiLevel *pmax_level +) FRIBIDI_GNUC_WARN_UNUSED; + /*====================================================================== * This function should follow the Unicode specification closely! *----------------------------------------------------------------------*/ -static void -fribidi_analyse_string ( + static fribidi_boolean fribidi_analyse_string ( /* input */ const FriBidiChar *str, FriBidiStrIndex len, /* input and output */ FriBidiCharType *pbase_dir, /* output */ - FriBidiRun ** ptype_rl_list, + FriBidiRun **pmain_run_list, FriBidiLevel *pmax_level ) { FriBidiLevel base_level, max_level; FriBidiCharType base_dir; - FriBidiStrIndex i; - FriBidiRun *type_rl_list, *explicits_list, *explicits_list_end, *pp; + FriBidiRun *main_run_list = NULL, *explicits_list = NULL, *pp; + fribidi_boolean status = false; DBG ("Entering fribidi_analyse_string"); + fribidi_assert (str); + fribidi_assert (pbase_dir); + fribidi_assert (pmain_run_list); + fribidi_assert (pmax_level); + /* Determinate character types */ DBG (" Determine character types"); { - FriBidiCharType *char_type = + FriBidiCharType *char_types = (FriBidiCharType *) fribidi_malloc (len * sizeof (FriBidiCharType)); - for (i = 0; i < len; i++) - char_type[i] = fribidi_get_type (str[i]); + if (!char_types) + goto out; + fribidi_get_bidi_types (str, len, char_types); /* Run length encode the character types */ - type_rl_list = run_list_encode_bidi_types (char_type, len); - fribidi_free (char_type); + main_run_list = run_list_encode_bidi_types (char_types, len); + fribidi_free (char_types); + if (!main_run_list) + goto out; } DBG (" Determine character types, Done"); - init_list (&explicits_list, &explicits_list_end); - /* Find base level */ DBG (" Finding the base level"); if (FRIBIDI_IS_STRONG (*pbase_dir)) @@ -401,13 +371,12 @@ fribidi_analyse_string ( that was passed on input. */ base_level = FRIBIDI_DIR_TO_LEVEL (*pbase_dir); base_dir = FRIBIDI_TYPE_ON; - for (pp = type_rl_list; pp; pp = pp->next) - if (FRIBIDI_IS_LETTER (RL_TYPE (pp))) - { - base_level = FRIBIDI_DIR_TO_LEVEL (RL_TYPE (pp)); - base_dir = FRIBIDI_LEVEL_TO_DIR (base_level); - break; - } + for_run_list (pp, main_run_list) if (FRIBIDI_IS_LETTER (RL_TYPE (pp))) + { + base_level = FRIBIDI_DIR_TO_LEVEL (RL_TYPE (pp)); + base_dir = FRIBIDI_LEVEL_TO_DIR (base_level); + break; + } } base_dir = FRIBIDI_LEVEL_TO_DIR (base_level); DBG2 (" Base level : %c", fribidi_char_from_level (base_level)); @@ -415,19 +384,16 @@ fribidi_analyse_string ( DBG (" Finding the base level, Done"); # if DEBUG - if (fribidi_debug_status ()) + if UNLIKELY + (fribidi_debug_status ()) { - print_types_re (type_rl_list); + print_types_re (main_run_list); } # endif /* DEBUG */ /* Explicit Levels and Directions */ DBG ("Explicit Levels and Directions"); { - /* X1. Begin by setting the current embedding level to the paragraph - embedding level. Set the directional override status to neutral. - Process each character iteratively, applying rules X2 through X9. - Only embedding levels from 0 to 61 are valid in this phase. */ FriBidiLevel level, new_level; FriBidiCharType override, new_override; FriBidiStrIndex i; @@ -435,6 +401,19 @@ fribidi_analyse_string ( LevelInfo *status_stack; FriBidiRun temp_link; +/* explicits_list is a list like main_run_list, that holds the explicit + codes that are removed from main_run_list, to reinsert them later by + calling the shadow_run_list. +*/ + explicits_list = new_run_list (); + if UNLIKELY + (!explicits_list) goto out; + + /* X1. Begin by setting the current embedding level to the paragraph + embedding level. Set the directional override status to neutral. + Process each character iteratively, applying rules X2 through X9. + Only embedding levels from 0 to 61 are valid in this phase. */ + level = base_level; override = FRIBIDI_TYPE_ON; /* stack */ @@ -445,61 +424,67 @@ fribidi_analyse_string ( (LevelInfo *) fribidi_malloc (sizeof (LevelInfo) * FRIBIDI_BIDI_MAX_RESOLVED_LEVELS); - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - FriBidiCharType this_type = RL_TYPE (pp); - if (FRIBIDI_IS_EXPLICIT_OR_BN (this_type)) - { - if (FRIBIDI_IS_STRONG (this_type)) - { /* LRE, RLE, LRO, RLO */ - /* 1. Explicit Embeddings */ - /* X2. With each RLE, compute the least greater odd embedding level. */ - /* X3. With each LRE, compute the least greater even embedding level. */ - /* 2. Explicit Overrides */ - /* X4. With each RLO, compute the least greater odd embedding level. */ - /* X5. With each LRO, compute the least greater even embedding level. */ - new_override = FRIBIDI_EXPLICIT_TO_OVERRIDE_DIR (this_type); - for (i = RL_LEN (pp); i; i--) - { - new_level = - ((level + FRIBIDI_DIR_TO_LEVEL (this_type) + 2) & ~1) - - FRIBIDI_DIR_TO_LEVEL (this_type); - PUSH_STATUS; - } - } - else if (this_type == FRIBIDI_TYPE_PDF) - { - /* 3. Terminating Embeddings and overrides */ - /* X7. With each PDF, determine the matching embedding or - override code. */ - for (i = RL_LEN (pp); i; i--) - POP_STATUS; - } - /* X9. Remove all RLE, LRE, RLO, LRO, PDF, and BN codes. */ - /* Remove element and add it to explicits_list */ - temp_link.next = pp->next; - pp->level = FRIBIDI_LEVEL_REMOVED; - move_run_before (pp, explicits_list_end); - pp = &temp_link; - } - else - { - /* X6. For all typed besides RLE, LRE, RLO, LRO, and PDF: - a. Set the level of the current character to the current - embedding level. - b. Whenever the directional override status is not neutral, - reset the current character type to the directional override - status. */ - RL_LEVEL (pp) = level; - if (!FRIBIDI_IS_NEUTRAL (override)) - RL_TYPE (pp) = override; - } - /* X8. All explicit directional embeddings and overrides are - completely terminated at the end of each paragraph. Paragraph - separators are not included in the embedding. */ - /* This function is running on a single paragraph, so we can do - X8 after all the input is processed. */ - } + for_run_list (pp, main_run_list) + { + FriBidiCharType this_type = RL_TYPE (pp); + if (FRIBIDI_IS_EXPLICIT_OR_BN (this_type)) + { + register FriBidiLevel level_before = level; + + if (FRIBIDI_IS_STRONG (this_type)) + { /* LRE, RLE, LRO, RLO */ + /* 1. Explicit Embeddings */ + /* X2. With each RLE, compute the least greater odd + embedding level. */ + /* X3. With each LRE, compute the least greater even + embedding level. */ + /* 2. Explicit Overrides */ + /* X4. With each RLO, compute the least greater odd + embedding level. */ + /* X5. With each LRO, compute the least greater even + embedding level. */ + new_override = FRIBIDI_EXPLICIT_TO_OVERRIDE_DIR (this_type); + for (i = RL_LEN (pp); i; i--) + { + new_level = + ((level + FRIBIDI_DIR_TO_LEVEL (this_type) + 2) & ~1) - + FRIBIDI_DIR_TO_LEVEL (this_type); + PUSH_STATUS; + } + } + else if (this_type == FRIBIDI_TYPE_PDF) + { + /* 3. Terminating Embeddings and overrides */ + /* X7. With each PDF, determine the matching embedding or + override code. */ + for (i = RL_LEN (pp); i; i--) + POP_STATUS; + } + /* X9. Remove all RLE, LRE, RLO, LRO, PDF, and BN codes. */ + /* Remove element and add it to explicits_list */ + temp_link.next = pp->next; + pp->level = FRIBIDI_SENTINEL; + move_node_before (pp, explicits_list); + pp = &temp_link; + } + else + { + /* X6. For all types besides RLE, LRE, RLO, LRO, and PDF: + a. Set the level of the current character to the current + embedding level. + b. Whenever the directional override status is not neutral, + reset the current character type to the directional override + status. */ + RL_LEVEL (pp) = level; + if (!FRIBIDI_IS_NEUTRAL (override)) + RL_TYPE (pp) = override; + } + /* X8. All explicit directional embeddings and overrides are + completely terminated at the end of each paragraph. Paragraph + separators are not included in the embedding. */ + /* This function is running on a single paragraph, so we can do + X8 after all the input is processed. */ + } /* Implementing X8. It has no effect on a single paragraph! */ level = base_level; @@ -519,65 +504,66 @@ fribidi_analyse_string ( /* Resolving Implicit Levels can be done out of X10 loop, so only change of Resolving Weak Types and Resolving Neutral Types is needed. */ - compact_list (type_rl_list); + compact_list (main_run_list); # if DEBUG - if (fribidi_debug_status ()) + if UNLIKELY + (fribidi_debug_status ()) { - print_types_re (type_rl_list); + print_types_re (main_run_list); print_bidi_string (str, len); - print_resolved_levels (type_rl_list); - print_resolved_types (type_rl_list); + print_resolved_levels (main_run_list); + print_resolved_types (main_run_list); } # endif /* DEBUG */ /* 4. Resolving weak types */ DBG ("Resolving weak types"); { - FriBidiCharType last_strong, prev_type_org; + FriBidiCharType last_strong, prev_type_orig; fribidi_boolean w4; last_strong = base_dir; - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - FriBidiCharType prev_type, this_type, next_type; - - prev_type = PREV_TYPE_OR_SOR (pp); - this_type = RL_TYPE (pp); - next_type = NEXT_TYPE_OR_EOR (pp); - - if (FRIBIDI_IS_STRONG (prev_type)) - last_strong = prev_type; - - /* W1. NSM - Examine each non-spacing mark (NSM) in the level run, and change the - type of the NSM to the type of the previous character. If the NSM - is at the start of the level run, it will get the type of sor. */ - /* Implementation note: it is important that if the previous character - is not sor, then we should merge this run with the previous, - because of rules like W5, that we assume all of a sequence of - adjacent ETs are in one FriBidiRun. */ - if (this_type == FRIBIDI_TYPE_NSM) - { - if (RL_LEVEL (pp->prev) == RL_LEVEL (pp)) - pp = merge_with_prev (pp); - else - RL_TYPE (pp) = prev_type; - continue; /* As we know the next condition cannot be true. */ - } + for_run_list (pp, main_run_list) + { + FriBidiCharType prev_type, this_type, next_type; + + prev_type = PREV_TYPE_OR_SOR (pp); + this_type = RL_TYPE (pp); + next_type = NEXT_TYPE_OR_EOR (pp); + + if (FRIBIDI_IS_STRONG (prev_type)) + last_strong = prev_type; + + /* W1. NSM + Examine each non-spacing mark (NSM) in the level run, and change the + type of the NSM to the type of the previous character. If the NSM + is at the start of the level run, it will get the type of sor. */ + /* Implementation note: it is important that if the previous character + is not sor, then we should merge this run with the previous, + because of rules like W5, that we assume all of a sequence of + adjacent ETs are in one FriBidiRun. */ + if (this_type == FRIBIDI_TYPE_NSM) + { + if (RL_LEVEL (pp->prev) == RL_LEVEL (pp)) + pp = merge_with_prev (pp); + else + RL_TYPE (pp) = prev_type; + continue; /* As we know the next condition cannot be true. */ + } - /* W2: European numbers. */ - if (this_type == FRIBIDI_TYPE_EN && last_strong == FRIBIDI_TYPE_AL) - { - RL_TYPE (pp) = FRIBIDI_TYPE_AN; + /* W2: European numbers. */ + if (this_type == FRIBIDI_TYPE_EN && last_strong == FRIBIDI_TYPE_AL) + { + RL_TYPE (pp) = FRIBIDI_TYPE_AN; - /* Resolving dependency of loops for rules W1 and W2, so we - can merge them in one loop. */ - if (next_type == FRIBIDI_TYPE_NSM) - RL_TYPE (pp->next) = FRIBIDI_TYPE_AN; - } - } + /* Resolving dependency of loops for rules W1 and W2, so we + can merge them in one loop. */ + if (next_type == FRIBIDI_TYPE_NSM) + RL_TYPE (pp->next) = FRIBIDI_TYPE_AN; + } + } last_strong = base_dir; @@ -586,78 +572,80 @@ fribidi_analyse_string ( through "w4". */ w4 = true; /* Resolving dependency of loops for rules W4 and W5 with W7, - W7 may change an EN to L but it sets the prev_type_org if needed, + W7 may change an EN to L but it sets the prev_type_orig if needed, so W4 and W5 in next turn can still do their works. */ - prev_type_org = FRIBIDI_TYPE_ON; + prev_type_orig = FRIBIDI_TYPE_ON; - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - FriBidiCharType prev_type, this_type, next_type; + for_run_list (pp, main_run_list) + { + FriBidiCharType prev_type, this_type, next_type; - prev_type = PREV_TYPE_OR_SOR (pp); - this_type = RL_TYPE (pp); - next_type = NEXT_TYPE_OR_EOR (pp); + prev_type = PREV_TYPE_OR_SOR (pp); + this_type = RL_TYPE (pp); + next_type = NEXT_TYPE_OR_EOR (pp); - if (FRIBIDI_IS_STRONG (prev_type)) - last_strong = prev_type; + if (FRIBIDI_IS_STRONG (prev_type)) + last_strong = prev_type; - /* W3: Change ALs to R. */ - if (this_type == FRIBIDI_TYPE_AL) - { - RL_TYPE (pp) = FRIBIDI_TYPE_RTL; - w4 = true; - prev_type_org = FRIBIDI_TYPE_ON; - continue; - } + /* W3: Change ALs to R. */ + if (this_type == FRIBIDI_TYPE_AL) + { + RL_TYPE (pp) = FRIBIDI_TYPE_RTL; + w4 = true; + prev_type_orig = FRIBIDI_TYPE_ON; + continue; + } - /* W4. A single european separator changes to a european number. - A single common separator between two numbers of the same type - changes to that type. */ - if (w4 - && RL_LEN (pp) == 1 && FRIBIDI_IS_ES_OR_CS (this_type) - && FRIBIDI_IS_NUMBER (prev_type_org) && prev_type_org == next_type - && (prev_type_org == FRIBIDI_TYPE_EN - || this_type == FRIBIDI_TYPE_CS)) - { - RL_TYPE (pp) = prev_type; - this_type = RL_TYPE (pp); - } - w4 = true; + /* W4. A single european separator changes to a european number. + A single common separator between two numbers of the same type + changes to that type. */ + if (w4 + && RL_LEN (pp) == 1 && FRIBIDI_IS_ES_OR_CS (this_type) + && FRIBIDI_IS_NUMBER (prev_type_orig) + && prev_type_orig == next_type + && (prev_type_orig == FRIBIDI_TYPE_EN + || this_type == FRIBIDI_TYPE_CS)) + { + RL_TYPE (pp) = prev_type; + this_type = RL_TYPE (pp); + } + w4 = true; - /* W5. A sequence of European terminators adjacent to European - numbers changes to All European numbers. */ - if (this_type == FRIBIDI_TYPE_ET - && (prev_type_org == FRIBIDI_TYPE_EN - || next_type == FRIBIDI_TYPE_EN)) - { - RL_TYPE (pp) = FRIBIDI_TYPE_EN; - w4 = false; - this_type = RL_TYPE (pp); - } + /* W5. A sequence of European terminators adjacent to European + numbers changes to All European numbers. */ + if (this_type == FRIBIDI_TYPE_ET + && (prev_type_orig == FRIBIDI_TYPE_EN + || next_type == FRIBIDI_TYPE_EN)) + { + RL_TYPE (pp) = FRIBIDI_TYPE_EN; + w4 = false; + this_type = RL_TYPE (pp); + } - /* W6. Otherwise change separators and terminators to other neutral. */ - if (FRIBIDI_IS_NUMBER_SEPARATOR_OR_TERMINATOR (this_type)) - RL_TYPE (pp) = FRIBIDI_TYPE_ON; + /* W6. Otherwise change separators and terminators to other neutral. */ + if (FRIBIDI_IS_NUMBER_SEPARATOR_OR_TERMINATOR (this_type)) + RL_TYPE (pp) = FRIBIDI_TYPE_ON; - /* W7. Change european numbers to L. */ - if (this_type == FRIBIDI_TYPE_EN && last_strong == FRIBIDI_TYPE_LTR) - { - RL_TYPE (pp) = FRIBIDI_TYPE_LTR; - prev_type_org = (RL_LEVEL (pp) == RL_LEVEL (pp->next) ? - FRIBIDI_TYPE_EN : FRIBIDI_TYPE_ON); - } - else - prev_type_org = PREV_TYPE_OR_SOR (pp->next); - } + /* W7. Change european numbers to L. */ + if (this_type == FRIBIDI_TYPE_EN && last_strong == FRIBIDI_TYPE_LTR) + { + RL_TYPE (pp) = FRIBIDI_TYPE_LTR; + prev_type_orig = (RL_LEVEL (pp) == RL_LEVEL (pp->next) ? + FRIBIDI_TYPE_EN : FRIBIDI_TYPE_ON); + } + else + prev_type_orig = PREV_TYPE_OR_SOR (pp->next); + } } - compact_neutrals (type_rl_list); + compact_neutrals (main_run_list); # if DEBUG - if (fribidi_debug_status ()) + if UNLIKELY + (fribidi_debug_status ()) { - print_resolved_levels (type_rl_list); - print_resolved_types (type_rl_list); + print_resolved_levels (main_run_list); + print_resolved_types (main_run_list); } # endif /* DEBUG */ @@ -666,30 +654,31 @@ fribidi_analyse_string ( { /* N1. and N2. For each neutral, resolve it. */ - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - FriBidiCharType prev_type, this_type, next_type; - - /* "European and arabic numbers are treated as though they were R" - FRIBIDI_CHANGE_NUMBER_TO_RTL does this. */ - this_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (RL_TYPE (pp)); - prev_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (PREV_TYPE_OR_SOR (pp)); - next_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (NEXT_TYPE_OR_EOR (pp)); - - if (FRIBIDI_IS_NEUTRAL (this_type)) - RL_TYPE (pp) = (prev_type == next_type) ? - /* N1. */ prev_type : - /* N2. */ FRIBIDI_EMBEDDING_DIRECTION (pp); - } + for_run_list (pp, main_run_list) + { + FriBidiCharType prev_type, this_type, next_type; + + /* "European and Arabic numbers are treated as though they were R" + FRIBIDI_CHANGE_NUMBER_TO_RTL does this. */ + this_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (RL_TYPE (pp)); + prev_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (PREV_TYPE_OR_SOR (pp)); + next_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (NEXT_TYPE_OR_EOR (pp)); + + if (FRIBIDI_IS_NEUTRAL (this_type)) + RL_TYPE (pp) = (prev_type == next_type) ? + /* N1. */ prev_type : + /* N2. */ FRIBIDI_EMBEDDING_DIRECTION (pp); + } } - compact_list (type_rl_list); + compact_list (main_run_list); # if DEBUG - if (fribidi_debug_status ()) + if UNLIKELY + (fribidi_debug_status ()) { - print_resolved_levels (type_rl_list); - print_resolved_types (type_rl_list); + print_resolved_levels (main_run_list); + print_resolved_types (main_run_list); } # endif /* DEBUG */ @@ -698,77 +687,83 @@ fribidi_analyse_string ( { max_level = base_level; - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - FriBidiCharType this_type; - int level; - - this_type = RL_TYPE (pp); - level = RL_LEVEL (pp); - - /* I1. Even */ - /* I2. Odd */ - if (FRIBIDI_IS_NUMBER (this_type)) - RL_LEVEL (pp) = (level + 2) & ~1; - else - RL_LEVEL (pp) = (level ^ FRIBIDI_DIR_TO_LEVEL (this_type)) + - (level & 1); - - if (RL_LEVEL (pp) > max_level) - max_level = RL_LEVEL (pp); - } + for_run_list (pp, main_run_list) + { + FriBidiCharType this_type; + int level; + + this_type = RL_TYPE (pp); + level = RL_LEVEL (pp); + + /* I1. Even */ + /* I2. Odd */ + if (FRIBIDI_IS_NUMBER (this_type)) + RL_LEVEL (pp) = (level + 2) & ~1; + else + RL_LEVEL (pp) = (level ^ FRIBIDI_DIR_TO_LEVEL (this_type)) + + (level & 1); + + if (RL_LEVEL (pp) > max_level) + max_level = RL_LEVEL (pp); + } } - compact_list (type_rl_list); + compact_list (main_run_list); # if DEBUG - if (fribidi_debug_status ()) + if UNLIKELY + (fribidi_debug_status ()) { print_bidi_string (str, len); - print_resolved_levels (type_rl_list); - print_resolved_types (type_rl_list); + print_resolved_levels (main_run_list); + print_resolved_types (main_run_list); } # endif /* DEBUG */ -/* Reinsert the explicit codes & bn's that already removed, from the - explicits_list to type_rl_list. */ +/* Reinsert the explicit codes & BN's that are already removed, from the + explicits_list to main_run_list. */ DBG ("Reinserting explicit codes"); { - FriBidiRun *p; - - shadow_run_list (type_rl_list, explicits_list); - p = type_rl_list->next; - if (p->level < 0) + register FriBidiRun *p; + register fribidi_boolean stat = + shadow_run_list (main_run_list, explicits_list, true); + explicits_list = NULL; + if UNLIKELY + (!stat) goto out; + p = main_run_list->next; + if (p != main_run_list && p->level == FRIBIDI_SENTINEL) p->level = base_level; - for (; p->next; p = p->next) - if (p->level < 0) - p->level = p->prev->level; + for_run_list (p, main_run_list) if (p->level == FRIBIDI_SENTINEL) + p->level = p->prev->level; } # if DEBUG - if (fribidi_debug_status ()) + if UNLIKELY + (fribidi_debug_status ()) { - print_types_re (type_rl_list); - print_resolved_levels (type_rl_list); - print_resolved_types (type_rl_list); + print_types_re (main_run_list); + print_resolved_levels (main_run_list); + print_resolved_types (main_run_list); } # endif /* DEBUG */ DBG ("Reset the embedding levels"); { - int j, k, state, pos; - FriBidiRun *p, *q, *list, *list_end; + register int j, k, state, pos; + register FriBidiRun *p, *q, *list; /* L1. Reset the embedding levels of some chars. */ - init_list (&list, &list_end); - q = list_end; + list = new_run_list (); + if UNLIKELY + (!list) goto out; + q = list; state = 1; pos = len - 1; for (j = len - 1; j >= -1; j--) { - /* if state is on at the very first of string, do this too. */ + /* if state is on at the very first of the string, do this too. */ if (j >= 0) - k = fribidi_get_type (str[j]); + k = fribidi_get_bidi_type (str[j]); else k = FRIBIDI_TYPE_ON; if (!state && FRIBIDI_IS_SEPARATOR (k)) @@ -780,85 +775,86 @@ fribidi_analyse_string ( { state = 0; p = new_run (); - p->prev = p->next = NULL; + if UNLIKELY + (!p) + { + free_run_list (list); + goto out; + } p->pos = j + 1; p->len = pos - j; p->type = base_dir; p->level = base_level; - move_run_before (p, q); + move_node_before (p, q); q = p; } } - shadow_run_list (type_rl_list, list); + if UNLIKELY + (!shadow_run_list (main_run_list, list, false)) goto out; } # if DEBUG - if (fribidi_debug_status ()) + if UNLIKELY + (fribidi_debug_status ()) { - print_types_re (type_rl_list); - print_resolved_levels (type_rl_list); - print_resolved_types (type_rl_list); + print_types_re (main_run_list); + print_resolved_levels (main_run_list); + print_resolved_types (main_run_list); } # endif /* DEBUG */ - *ptype_rl_list = type_rl_list; + status = true; + *pmain_run_list = main_run_list; *pmax_level = max_level; *pbase_dir = base_dir; DBG ("Leaving fribidi_analyse_string"); - return; +out: + if UNLIKELY + (explicits_list) free_run_list (explicits_list); + if UNLIKELY + (!status && main_run_list) free_run_list (main_run_list); + + return status; } -/*====================================================================== - * Frees up the rl_list, must be called after each call to - * fribidi_analyse_string(), after the list is not needed anymore. - *----------------------------------------------------------------------*/ static void -free_rl_list ( - FriBidiRun * type_rl_list +bidi_string_reverse ( + FriBidiChar *str, + FriBidiStrIndex len ) { + FriBidiStrIndex i; - FriBidiRun *pp; - - DBG ("Entering free_rl_list"); + fribidi_assert (str); - if (!type_rl_list) + for (i = 0; i < len / 2; i++) { - DBG ("Leaving free_rl_list"); - return; + FriBidiChar tmp = str[i]; + str[i] = str[len - 1 - i]; + str[len - 1 - i] = tmp; } +} -#if USE_SIMPLE_MALLOC - pp = type_rl_list; - while (pp) +static void +index_array_reverse ( + FriBidiStrIndex *arr, + FriBidiStrIndex len +) +{ + FriBidiStrIndex i; + + fribidi_assert (arr); + + for (i = 0; i < len / 2; i++) { - FriBidiRun *p; - - p = pp; - pp = pp->next; - free_run (p); - }; -#else /* !USE_SIMPLE_MALLOC */ - for (pp = type_rl_list->next; pp->next; pp = pp->next) - /* Nothing */ ; - pp->next = free_runs; - free_runs = type_rl_list; - type_rl_list = NULL; -#endif /* !USE_SIMPLE_MALLOC */ - - DBG ("Leaving free_rl_list"); - return; + FriBidiStrIndex tmp = arr[i]; + arr[i] = arr[len - 1 - i]; + arr[len - 1 - i] = tmp; + } } -/*====================================================================== - * Here starts the exposed front end functions. - *----------------------------------------------------------------------*/ -/*====================================================================== - * fribidi_remove_bidi_marks() removes bidirectional marks, and returns - * the new length, updates each of other inputs if not NULL. - *----------------------------------------------------------------------*/ FRIBIDI_ENTRY FriBidiStrIndex fribidi_remove_bidi_marks ( FriBidiChar *str, @@ -885,7 +881,7 @@ fribidi_remove_bidi_marks ( j = 0; for (i = 0; i < length; i++) - if (!FRIBIDI_IS_EXPLICIT (fribidi_get_type (str[i])) + if (!FRIBIDI_IS_EXPLICIT (fribidi_get_bidi_type (str[i])) && str[i] != FRIBIDI_CHAR_LRM && str[i] != FRIBIDI_CHAR_RLM) { str[j] = str[i]; @@ -915,10 +911,6 @@ fribidi_remove_bidi_marks ( } -/*====================================================================== - * fribidi_log2vis() calls the function_analyse_string() and then - * does reordering and fills in the output strings. - *----------------------------------------------------------------------*/ FRIBIDI_ENTRY fribidi_boolean fribidi_log2vis ( /* input */ @@ -933,41 +925,57 @@ fribidi_log2vis ( FriBidiLevel *embedding_level_list ) { - FriBidiRun *type_rl_list, *pp = NULL; + FriBidiRun *main_run_list = NULL, *pp = NULL; FriBidiLevel max_level; fribidi_boolean private_V_to_L = false; + fribidi_boolean status = true; + + DBG ("Entering fribidi_log2vis()"); - DBG ("Entering fribidi_log2vis()\n"); + fribidi_assert (str); + fribidi_assert (pbase_dir); if (len == 0) + goto out; + + if UNLIKELY + (len > FRIBIDI_MAX_STRING_LENGTH && (position_V_to_L_list || + position_L_to_V_list)) + { +# if DEBUG + MSG2 (FRIBIDI ": cannot handle strings > %ld characters\n", + (long) FRIBIDI_MAX_STRING_LENGTH); +# endif /* DEBUG */ + status = false; + goto out; + } + + if UNLIKELY + (!fribidi_analyse_string (str, len, pbase_dir, + /* output */ + &main_run_list, &max_level)) { - DBG ("Leaving fribidi_log2vis()\n"); - return true; + status = false; + goto out; } /* If l2v is to be calculated we must have v2l as well. If it is not given by the caller, we have to make a private instance of it. */ if (position_L_to_V_list && !position_V_to_L_list) { - private_V_to_L = true; position_V_to_L_list = (FriBidiStrIndex *) fribidi_malloc (sizeof (FriBidiStrIndex) * len); + if (!position_V_to_L_list) + { + status = false; + goto out; + } + private_V_to_L = true; } - if (len > FRIBIDI_MAX_STRING_LENGTH && position_V_to_L_list) - { -# if DEBUG - MSG2 (FRIBIDI ": cannot handle strings > %ld characters\n", - (long) FRIBIDI_MAX_STRING_LENGTH); -# endif /* DEBUG */ - return false; - } - fribidi_analyse_string (str, len, pbase_dir, - /* output */ - &type_rl_list, &max_level); /* 7. Reordering resolved levels */ - DBG ("Reordering resolved levels\n"); + DBG ("Reordering resolved levels"); { FriBidiLevel level_idx; FriBidiStrIndex i; @@ -975,37 +983,33 @@ fribidi_log2vis ( /* Set up the ordering array to sorted order */ if (position_V_to_L_list) { - DBG (" Initialize position_V_to_L_list\n"); + DBG (" Initialize position_V_to_L_list"); for (i = 0; i < len; i++) position_V_to_L_list[i] = i; - DBG (" Initialize position_V_to_L_list, Done\n"); + DBG (" Initialize position_V_to_L_list, Done"); } /* Copy the logical string to the visual */ if (visual_str) { - DBG (" Initialize visual_str\n"); + DBG (" Initialize visual_str"); for (i = 0; i < len; i++) visual_str[i] = str[i]; visual_str[len] = 0; - DBG (" Initialize visual_str, Done\n"); + DBG (" Initialize visual_str, Done"); } /* Assign the embedding level array */ if (embedding_level_list) { - DBG (" Fill the embedding levels array\n"); - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - FriBidiStrIndex i, pos, len; - FriBidiLevel level; - - pos = pp->pos; - len = pp->len; - level = pp->level; - for (i = 0; i < len; i++) - embedding_level_list[pos + i] = level; - } - DBG (" Fill the embedding levels array, Done\n"); + DBG (" Fill the embedding levels array"); + for_run_list (pp, main_run_list) + { + register FriBidiStrIndex i, pos = pp->pos, len = pp->len; + register FriBidiLevel level = pp->level; + for (i = 0; i < len; i++) + embedding_level_list[pos + i] = level; + } + DBG (" Fill the embedding levels array, Done"); } /* Reorder both the outstring and the order array */ @@ -1014,125 +1018,121 @@ fribidi_log2vis ( if (fribidi_mirroring_status () && visual_str) { /* L4. Mirror all characters that are in odd levels and have mirrors. */ - DBG (" Mirroring\n"); - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - if (pp->level & 1) - { - FriBidiStrIndex i; - for (i = RL_POS (pp); i < RL_POS (pp) + RL_LEN (pp); i++) - { - FriBidiChar mirrored_ch; - if (fribidi_get_mirror_char - (visual_str[i], &mirrored_ch)) - visual_str[i] = mirrored_ch; - } - } - } - DBG (" Mirroring, Done\n"); + DBG (" Mirroring"); + for_run_list (pp, main_run_list) + { + if (pp->level & 1) + { + FriBidiStrIndex i; + for (i = RL_POS (pp); i < RL_POS (pp) + RL_LEN (pp); i++) + { + FriBidiChar mirrored_ch; + if (fribidi_get_mirror_char + (visual_str[i], &mirrored_ch)) + visual_str[i] = mirrored_ch; + } + } + } + DBG (" Mirroring, Done"); } if (fribidi_reorder_nsm_status ()) { /* L3. Reorder NSMs. */ - DBG (" Reordering NSM sequences\n"); + DBG (" Reordering NSM sequences"); /* We apply this rule before L2, so go backward in odd levels. */ - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - if (pp->level & 1) - { - FriBidiStrIndex i, seq_end = 0; - fribidi_boolean is_nsm_seq; - - is_nsm_seq = false; - for (i = RL_POS (pp) + RL_LEN (pp) - 1; i >= RL_POS (pp); - i--) - { - FriBidiCharType this_type; - - this_type = fribidi_get_type (str[i]); - if (is_nsm_seq && this_type != FRIBIDI_TYPE_NSM) - { - if (visual_str) - { - bidi_string_reverse (visual_str + i, - seq_end - i + 1); - } - if (position_V_to_L_list) - { - index_array_reverse (position_V_to_L_list + i, - seq_end - i + 1); - } - is_nsm_seq = 0; - } - else if (!is_nsm_seq && this_type == FRIBIDI_TYPE_NSM) - { - seq_end = i; - is_nsm_seq = 1; - } - } - if (is_nsm_seq) - { - DBG - ("Warning: NSMs at the beggining of run level.\n"); - } - } - } - DBG (" Reordering NSM sequences, Done\n"); + for_run_list (pp, main_run_list) + { + if (pp->level & 1) + { + FriBidiStrIndex i, seq_end = 0; + fribidi_boolean is_nsm_seq; + + is_nsm_seq = false; + for (i = RL_POS (pp) + RL_LEN (pp) - 1; i >= RL_POS (pp); + i--) + { + FriBidiCharType this_type; + + this_type = fribidi_get_bidi_type (str[i]); + if (is_nsm_seq && this_type != FRIBIDI_TYPE_NSM) + { + if (visual_str) + { + bidi_string_reverse (visual_str + i, + seq_end - i + 1); + } + if (position_V_to_L_list) + { + index_array_reverse (position_V_to_L_list + i, + seq_end - i + 1); + } + is_nsm_seq = 0; + } + else if (!is_nsm_seq && this_type == FRIBIDI_TYPE_NSM) + { + seq_end = i; + is_nsm_seq = 1; + } + } + if (is_nsm_seq) + { + DBG ("Warning: NSMs at the beggining of level run.\n"); + } + } + } + DBG (" Reordering NSM sequences, Done"); } /* L2. Reorder. */ - DBG (" Reordering\n"); + DBG (" Reordering"); for (level_idx = max_level; level_idx > 0; level_idx--) { - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - if (RL_LEVEL (pp) >= level_idx) - { - /* Find all stretches that are >= level_idx */ - FriBidiStrIndex len = RL_LEN (pp), pos = RL_POS (pp); - FriBidiRun *pp1 = pp->next; - while (pp1->next && RL_LEVEL (pp1) >= level_idx) - { - len += RL_LEN (pp1); - pp1 = pp1->next; - } - pp = pp1->prev; - if (visual_str) - bidi_string_reverse (visual_str + pos, len); - if (position_V_to_L_list) - index_array_reverse (position_V_to_L_list + pos, len); - } - } + for_run_list (pp, main_run_list) + { + if (RL_LEVEL (pp) >= level_idx) + { + /* Find all stretches that are >= level_idx */ + register FriBidiStrIndex len = pp->len, pos = pp->pos; + register FriBidiRun *pp1 = pp->next; + while (pp1->next && pp1->level >= level_idx) + { + len += pp1->len; + pp1 = pp1->next; + } + pp = pp1->prev; + if (visual_str) + bidi_string_reverse (visual_str + pos, len); + if (position_V_to_L_list) + index_array_reverse (position_V_to_L_list + pos, len); + } + } } - DBG (" Reordering, Done\n"); + DBG (" Reordering, Done"); } /* Convert the v2l list to l2v */ if (position_L_to_V_list) { - DBG (" Converting v2l list to l2v\n"); + DBG (" Converting v2l list to l2v"); for (i = 0; i < len; i++) position_L_to_V_list[position_V_to_L_list[i]] = i; - DBG (" Converting v2l list to l2v, Done\n"); + DBG (" Converting v2l list to l2v, Done"); } } - DBG ("Reordering resolved levels, Done\n"); + DBG ("Reordering resolved levels, Done"); + DBG ("Leaving fribidi_log2vis()"); +out: if (private_V_to_L) fribidi_free (position_V_to_L_list); - free_rl_list (type_rl_list); + free_run_list (main_run_list); - DBG ("Leaving fribidi_log2vis()\n"); - return true; + return status; } -/*====================================================================== - * fribidi_log2vis_get_embedding_levels() is used in order to just get - * the embedding levels. - *----------------------------------------------------------------------*/ FRIBIDI_ENTRY fribidi_boolean fribidi_log2vis_get_embedding_levels ( /* input */ @@ -1144,33 +1144,40 @@ fribidi_log2vis_get_embedding_levels ( FriBidiLevel *embedding_level_list ) { - FriBidiRun *type_rl_list, *pp; + FriBidiRun *main_run_list, *pp; FriBidiLevel max_level; + fribidi_boolean status = true; - DBG ("Entering fribidi_log2vis_get_embedding_levels()\n"); + DBG ("Entering fribidi_log2vis_get_embedding_levels()"); - if (len == 0) - { - DBG ("Leaving fribidi_log2vis_get_embedding_levels()\n"); - return true; - } + fribidi_assert (str); + fribidi_assert (pbase_dir); - fribidi_analyse_string (str, len, pbase_dir, - /* output */ - &type_rl_list, &max_level); + if UNLIKELY + (len == 0) goto out; - for (pp = type_rl_list->next; pp->next; pp = pp->next) + if UNLIKELY + (!fribidi_analyse_string (str, len, pbase_dir, + /* output */ + &main_run_list, &max_level)) { - FriBidiStrIndex i, pos = RL_POS (pp), len = RL_LEN (pp); - FriBidiLevel level = RL_LEVEL (pp); - for (i = 0; i < len; i++) - embedding_level_list[pos + i] = level; + status = false; + goto out; } - free_rl_list (type_rl_list); + for_run_list (pp, main_run_list) + { + register FriBidiStrIndex i, pos = pp->pos, len = pp->len; + register FriBidiLevel level = pp->level; + for (i = 0; i < len; i++) + embedding_level_list[pos++] = level; + } + + DBG ("Leaving fribidi_log2vis_get_embedding_levels()"); +out: + free_run_list (main_run_list); - DBG ("Leaving fribidi_log2vis_get_embedding_levels()\n"); - return true; + return status; } /* Editor directions: diff --git a/lib/fribidi-bidi.h b/lib/fribidi-bidi.h index abbc59e..4763526 100644 --- a/lib/fribidi-bidi.h +++ b/lib/fribidi-bidi.h @@ -1,10 +1,10 @@ /* FriBidi * fribidi-bidi.h - bidirectional algorithm * - * $Id: fribidi-bidi.h,v 1.1 2004-04-25 18:47:57 behdad Exp $ + * $Id: fribidi-bidi.h,v 1.2 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-25 18:47:57 $ - * $Revision: 1.1 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.2 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi-bidi.h,v $ * * Authors: @@ -53,7 +53,8 @@ * * Returns: Non-zero if it was successful, or zero if any error occured. */ -FRIBIDI_ENTRY fribidi_boolean fribidi_log2vis ( +FRIBIDI_ENTRY fribidi_boolean +fribidi_log2vis ( const FriBidiChar *str, /* input logical string */ FriBidiStrIndex len, /* input string length */ FriBidiCharType *pbase_dir, /* requested and resolved paragraph @@ -65,7 +66,7 @@ FRIBIDI_ENTRY fribidi_boolean fribidi_log2vis ( * back to the logical string * positions */ FriBidiLevel *embedding_level_list /* output list of embedding levels */ -); +) FRIBIDI_GNUC_WARN_UNUSED; #define fribidi_log2vis_get_embedding_levels FRIBIDI_NAMESPACE(log2vis_get_embedding_levels) /* fribidi_log2vis_get_embedding_levels - get bidi embedding levels @@ -75,13 +76,13 @@ FRIBIDI_ENTRY fribidi_boolean fribidi_log2vis ( * * Returns: Non-zero if it was successful, or zero if any error occured. */ -FRIBIDI_ENTRY fribidi_boolean fribidi_log2vis_get_embedding_levels ( + FRIBIDI_ENTRY fribidi_boolean fribidi_log2vis_get_embedding_levels ( const FriBidiChar *str, /* input logical string */ FriBidiStrIndex len, /* input string length */ FriBidiCharType *pbase_dir, /* requested and resolved paragraph * base direction */ FriBidiLevel *embedding_level_list /* output list of embedding levels */ -); +) FRIBIDI_GNUC_WARN_UNUSED; #define fribidi_remove_bidi_marks FRIBIDI_NAMESPACE(remove_bidi_marks) /* fribidi_remove_bidi_marks - remove bidi marks out an string @@ -96,13 +97,13 @@ FRIBIDI_ENTRY fribidi_boolean fribidi_log2vis_get_embedding_levels ( * * Returns: New length of the string. */ -FRIBIDI_ENTRY FriBidiStrIndex fribidi_remove_bidi_marks ( + FRIBIDI_ENTRY FriBidiStrIndex fribidi_remove_bidi_marks ( FriBidiChar *str, FriBidiStrIndex length, FriBidiStrIndex *position_to_this_list, FriBidiStrIndex *position_from_this_list, FriBidiLevel *embedding_level_list -); +) FRIBIDI_GNUC_WARN_UNUSED; #include "fribidi-enddecls.h" diff --git a/lib/fribidi-common.h b/lib/fribidi-common.h index 06933bc..111d3cd 100644 --- a/lib/fribidi-common.h +++ b/lib/fribidi-common.h @@ -1,10 +1,10 @@ /* FriBidi * fribidi-common.h - common include for library headers * - * $Id: fribidi-common.h,v 1.2 2004-04-28 03:20:22 behdad Exp $ + * $Id: fribidi-common.h,v 1.3 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-28 03:20:22 $ - * $Revision: 1.2 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.3 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi-common.h,v $ * * Author: @@ -72,6 +72,29 @@ # endif /* !__cplusplus */ #endif /* !FRIBIDI_BEGIN_DECLS */ +#ifdef FRIBIDI_USE_GLIB +# ifndef __C2MAN__ +# include <glib/gmacros.h> +# define FRIBIDI_GNUC_CONST G_GNUC_CONST +# define FRIBIDI_GNUC_DEPRECATED G_GNUC_DEPRECATED +# endif /* !__C2MAN__ */ +#else /* !FRIBIDI_USE_GLIB */ +# define FRIBIDI_GNUC_CONST +# define FRIBIDI_GNUC_DEPRECATED +#endif /* !FRIBIDI_USE_GLIB */ +#if __GNUC__ > 2 +# define FRIBIDI_GNUC_WARN_UNUSED \ + __attribute__((__warn_unused_result__)) +# define FRIBIDI_GNUC_MALLOC \ + __attribute__((__malloc__)) +# define FRIBIDI_GNUC_HIDDEN \ + __attribute__((__visibility__ ("hidden"))) +#else /* __GNUC__ <= 2 */ +# define FRIBIDI_GNUC_WARN_UNUSED +# define FRIBIDI_GNUC_MALLOC +# define FRIBIDI_GNUC_HIDDEN +#endif /* __GNUC__ <= 2 */ + #define fribidi_version_info FRIBIDI_NAMESPACE(version_info) /* An string containing the version information of the library. */ diff --git a/lib/fribidi-env.c b/lib/fribidi-env.c index 8c5bc21..44eb056 100644 --- a/lib/fribidi-env.c +++ b/lib/fribidi-env.c @@ -1,10 +1,10 @@ /* FriBidi * fribidi-mirroring.c - get mirrored character * - * $Id: fribidi-env.c,v 1.2 2004-04-28 02:37:56 behdad Exp $ + * $Id: fribidi-env.c,v 1.3 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-28 02:37:56 $ - * $Revision: 1.2 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.3 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/Attic/fribidi-env.c,v $ * * Authors: @@ -33,12 +33,12 @@ * For licensing issues, contact <license@farsiweb.info>. */ +#include "common.h" + #include <fribidi-env.h> #include "env.h" -#include "common.h" - /* Library state variables */ #if DEBUG @@ -49,8 +49,8 @@ static fribidi_boolean flag_reorder_nsm = false; #if !USE_SIMPLE_MALLOC -FriBidiRun *free_runs = NULL; -FriBidiMemChunk *run_mem_chunk = NULL; +FriBidiRun *free_runs FRIBIDI_GNUC_HIDDEN = NULL; +FriBidiMemChunk *run_mem_chunk FRIBIDI_GNUC_HIDDEN = NULL; #endif /* !USE_SIMPLE_MALLOC */ @@ -70,6 +70,7 @@ fribidi_debug_status ( FRIBIDI_ENTRY fribidi_boolean fribidi_set_debug ( + /* input */ fribidi_boolean state ) { @@ -82,6 +83,7 @@ fribidi_set_debug ( FRIBIDI_ENTRY fribidi_boolean fribidi_set_mirroring ( + /* input */ fribidi_boolean state ) { @@ -98,6 +100,7 @@ fribidi_mirroring_status ( FRIBIDI_ENTRY fribidi_boolean fribidi_set_reorder_nsm ( + /* input */ fribidi_boolean state ) { diff --git a/lib/fribidi-env.h b/lib/fribidi-env.h index 95722e3..f174898 100644 --- a/lib/fribidi-env.h +++ b/lib/fribidi-env.h @@ -1,10 +1,10 @@ /* FriBidi * fribidi-env.h - state manipulation routines * - * $Id: fribidi-env.h,v 1.1 2004-04-25 18:47:57 behdad Exp $ + * $Id: fribidi-env.h,v 1.2 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-25 18:47:57 $ - * $Revision: 1.1 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.2 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/Attic/fribidi-env.h,v $ * * Author: @@ -60,16 +60,17 @@ FRIBIDI_ENTRY fribidi_boolean fribidi_debug_status ( * * Returns: the new debugging output status. */ -FRIBIDI_ENTRY fribidi_boolean fribidi_set_debug ( +FRIBIDI_ENTRY fribidi_boolean +fribidi_set_debug ( fribidi_boolean state /* new state to set */ -); +) FRIBIDI_GNUC_DEPRECATED; #define fribidi_mirroring_status FRIBIDI_NAMESPACE(mirroring_status) /* fribidi_mirroring_status - get current mirroring status */ -FRIBIDI_ENTRY fribidi_boolean fribidi_mirroring_status ( + FRIBIDI_ENTRY fribidi_boolean fribidi_mirroring_status ( void -); +) FRIBIDI_GNUC_DEPRECATED; #define fribidi_set_mirroring FRIBIDI_NAMESPACE(set_mirroring) /* fribidi_set_mirroring - set mirroring on or off @@ -85,16 +86,16 @@ FRIBIDI_ENTRY fribidi_boolean fribidi_mirroring_status ( * * Returns: the new mirroring status. */ -FRIBIDI_ENTRY fribidi_boolean fribidi_set_mirroring ( + FRIBIDI_ENTRY fribidi_boolean fribidi_set_mirroring ( fribidi_boolean state /* new state to set */ -); +) FRIBIDI_GNUC_DEPRECATED; #define fribidi_reorder_nsm_status FRIBIDI_NAMESPACE(reorder_nsm_status) /* fribidi_reorder_nsm_status - get current marks reordering status */ -FRIBIDI_ENTRY fribidi_boolean fribidi_reorder_nsm_status ( + FRIBIDI_ENTRY fribidi_boolean fribidi_reorder_nsm_status ( void -); +) FRIBIDI_GNUC_DEPRECATED; #define fribidi_set_reorder_nsm FRIBIDI_NAMESPACE(set_reorder_nsm) /* fribidi_set_reorder_nsm - set marks reordering on or off @@ -112,9 +113,9 @@ FRIBIDI_ENTRY fribidi_boolean fribidi_reorder_nsm_status ( * * Returns: the new marks reordering status. */ -FRIBIDI_ENTRY fribidi_boolean fribidi_set_reorder_nsm ( + FRIBIDI_ENTRY fribidi_boolean fribidi_set_reorder_nsm ( fribidi_boolean state /* new state to set */ -); +) FRIBIDI_GNUC_DEPRECATED; #include "fribidi-enddecls.h" diff --git a/lib/fribidi-mem.c b/lib/fribidi-mem.c index 0fe5fcb..b54d234 100644 --- a/lib/fribidi-mem.c +++ b/lib/fribidi-mem.c @@ -1,10 +1,10 @@ /* FriBidi * fribidi-mem.c - memory manipulation routines * - * $Id: fribidi-mem.c,v 1.3 2004-04-28 02:37:56 behdad Exp $ + * $Id: fribidi-mem.c,v 1.4 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-28 02:37:56 $ - * $Revision: 1.3 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.4 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi-mem.c,v $ * * Authors: @@ -31,10 +31,10 @@ * For licensing issues, contact <license@farsiweb.info>. */ -#include "mem.h" - #include "common.h" +#include "mem.h" + #if !FRIBIDI_USE_GLIB struct _FriBidiMemChunk @@ -54,10 +54,13 @@ fribidi_mem_chunk_new ( int alloc_type ) { - register FriBidiMemChunk *m = - (FriBidiMemChunk *) fribidi_malloc (sizeof (FriBidiMemChunk)); + register FriBidiMemChunk *m; - if (m) + fribidi_assert (area_size >= atom_size * 8); + + m = (FriBidiMemChunk *) fribidi_malloc (sizeof (FriBidiMemChunk)); + if LIKELY + (m) { m->atom_size = atom_size; m->area_size = area_size; @@ -74,10 +77,14 @@ fribidi_mem_chunk_alloc ( FriBidiMemChunk *mem_chunk ) { - if (mem_chunk->empty_size < mem_chunk->atom_size) + fribidi_assert (mem_chunk); + + if UNLIKELY + (mem_chunk->empty_size < mem_chunk->atom_size) { register void *chunk = fribidi_malloc (mem_chunk->area_size); - if (chunk) + if LIKELY + (chunk) { (void *) chunk = (void *) mem_chunk->chunk + emptysize - area_size; (char *) chunk += sizeof (void *); @@ -89,8 +96,7 @@ fribidi_mem_chunk_alloc ( } { - register void *m; - m = mem_chunk->chunk; + register void *m = mem_chunk->chunk; mem_chunk->chunk = (void *) ((char *) mem_chunk->chunk + mem_chunk->atom_size); mem_chunk->empty_size -= mem_chunk->atom_size; @@ -105,8 +111,13 @@ fribidi_mem_chunk_destroy ( FriBidiMemChunk *mem_chunk ) { - register void *chunk = mem_chunk->chunk + emptysize - areasize; - while (chunk) + register void *chunk; + + fribidi_assert (mem_chunk); + + chunk = mem_chunk->chunk + emptysize - areasize; + while LIKELY + (chunk) { register void *tofree = chunk; chunk = *(void *) chunk; diff --git a/lib/fribidi-mirroring.c b/lib/fribidi-mirroring.c index 18b77c5..4a8e371 100644 --- a/lib/fribidi-mirroring.c +++ b/lib/fribidi-mirroring.c @@ -22,10 +22,10 @@ * * For licensing issues, contact <license@farsiweb.info>. */ -/* $Id: fribidi-mirroring.c,v 1.3 2004-04-27 23:53:43 behdad Exp $ +/* $Id: fribidi-mirroring.c,v 1.4 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-27 23:53:43 $ - * $Revision: 1.3 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.4 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi-mirroring.c,v $ * * Authors: @@ -33,12 +33,12 @@ * Dov Grobgeld, 1999, 2000 */ +#include "common.h" + #include <fribidi-mirroring.h> #include "mirroring-table.i" -#include "common.h" - FRIBIDI_ENTRY fribidi_boolean fribidi_get_mirror_char ( /* input */ @@ -53,7 +53,8 @@ fribidi_get_mirror_char ( pos = step = (nFriBidiMirroredChars / 2) + 1; - while (step > 1) + while LIKELY + (step > 1) { FriBidiChar cmp_ch = FriBidiMirroredChars[pos].ch; step = (step + 1) / 2; @@ -61,14 +62,15 @@ fribidi_get_mirror_char ( if (cmp_ch < ch) { pos += step; - if (pos > nFriBidiMirroredChars - 1) - pos = nFriBidiMirroredChars - 1; + if UNLIKELY + (pos >= nFriBidiMirroredChars) pos = nFriBidiMirroredChars - 1; } - else if (cmp_ch > ch) + else if LIKELY + (cmp_ch > ch) { pos -= step; - if (pos < 0) - pos = 0; + if UNLIKELY + (pos < 0) pos = 0; } else break; diff --git a/lib/fribidi-run.c b/lib/fribidi-run.c index c00318c..83e1eb4 100644 --- a/lib/fribidi-run.c +++ b/lib/fribidi-run.c @@ -1,10 +1,10 @@ /* FriBidi * fribidi-run.c - text run data type * - * $Id: fribidi-run.c,v 1.1 2004-04-28 02:37:56 behdad Exp $ + * $Id: fribidi-run.c,v 1.2 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-28 02:37:56 $ - * $Revision: 1.1 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.2 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi-run.c,v $ * * Authors: @@ -33,18 +33,18 @@ * For licensing issues, contact <license@farsiweb.info>. */ +#include "common.h" + #include "run.h" #include "env.h" #include "bidi-types.h" -#include "common.h" - FriBidiRun * new_run ( void ) { - FriBidiRun *run; + register FriBidiRun *run; #if USE_SIMPLE_MALLOC run = fribidi_malloc (sizeof (FriBidiRun)); @@ -52,30 +52,42 @@ new_run ( if (free_runs) { run = free_runs; - free_runs = free_runs->next; + free_runs = run->next; } else { - if (!run_mem_chunk) - run_mem_chunk = fribidi_chunk_new_for_type (FriBidiRun); + if UNLIKELY + (!run_mem_chunk) run_mem_chunk = fribidi_chunk_new_for_type (FriBidiRun + ); - run = fribidi_chunk_new (FriBidiRun, run_mem_chunk); + if LIKELY + (run_mem_chunk) + { + run = fribidi_chunk_new (FriBidiRun, + run_mem_chunk + ); + } + else + run = NULL; } #endif /* !USE_SIMPLE_MALLOC */ - run->len = 0; - run->pos = 0; - run->level = 0; - run->next = NULL; - run->prev = NULL; + if LIKELY + (run) + { + run->len = run->pos = run->level = 0; + run->next = run->prev = NULL; + } return run; } void free_run ( - FriBidiRun * run + /* input */ + FriBidiRun *run ) { + fribidi_assert (run); #if USE_SIMPLE_MALLOC fribidi_free (run); #else /* !USE_SIMPLE_MALLOC */ @@ -84,70 +96,111 @@ free_run ( #endif /* !USE_SIMPLE_MALLOC */ } -#define FRIBIDI_ADD_TYPE_LINK(p,q) \ - FRIBIDI_BEGIN_STMT \ - (p)->len = (q)->pos - (p)->pos; \ - (p)->next = (q); \ - (q)->prev = (p); \ - (p) = (q); \ - FRIBIDI_END_STMT +FriBidiRun * +new_run_list ( + void +) +{ + register FriBidiRun *run; + + run = new_run (); + + if LIKELY + (run) + { + run->type = FRIBIDI_TYPE_SENTINEL; + run->level = FRIBIDI_SENTINEL; + run->pos = FRIBIDI_SENTINEL; + run->len = FRIBIDI_SENTINEL; + run->next = run->prev = run; + } + + return run; +} + +void +free_run_list ( + FriBidiRun *run_list +) +{ + if (!run_list) + return; + + fribidi_validate_run_list (run_list); + +#if USE_SIMPLE_MALLOC + { + register FriBidiRun *pp; + + pp = run_list; + pp->prev->next = NULL; + while LIKELY + (pp) + { + register FriBidiRun *p; + + p = pp; + pp = pp->next; + free_run (p); + }; + } +#else /* !USE_SIMPLE_MALLOC */ + run_list->prev->next = free_runs; + free_runs = run_list; +#endif /* !USE_SIMPLE_MALLOC */ +} + FriBidiRun * run_list_encode_bidi_types ( + /* input */ FriBidiCharType *char_type, FriBidiStrIndex len ) { - FriBidiRun *list, *last, *run; - + FriBidiRun *list, *last; + register FriBidiRun *run = NULL; FriBidiStrIndex i; - /* Add the starting run */ - list = new_run (); - list->type = FRIBIDI_TYPE_SOT; - list->level = FRIBIDI_LEVEL_START; + fribidi_assert (char_type); + + /* Create the list sentinel */ + list = new_run_list (); + if UNLIKELY + (!list) return NULL; last = list; - /* Sweep over the string_type s */ + /* Scan over the character types */ for (i = 0; i < len; i++) if (char_type[i] != last->type) { run = new_run (); + if UNLIKELY + (!run) break; run->type = char_type[i]; run->pos = i; - FRIBIDI_ADD_TYPE_LINK (last, run); + last->len = run->pos - last->pos; + last->next = run; + run->prev = last; + last = run; } - /* Add the ending run */ - run = new_run (); - run->type = FRIBIDI_TYPE_EOT; - run->level = FRIBIDI_LEVEL_END; - run->pos = len; - FRIBIDI_ADD_TYPE_LINK (last, run); - - return list; -} + /* Close the circle */ + last->len = len - last->pos; + last->next = list; + list->prev = last; -/* move a run before another element in a list, the list must have a - previous element, used to update explicits_list. - assuming that p have both prev and next or none of them, also update - the list that p is currently in, if any. -*/ -void -move_run_before ( - FriBidiRun * p, - FriBidiRun * list -) -{ - if (p->prev) + if UNLIKELY + (!run) { - p->prev->next = p->next; - p->next->prev = p->prev; + /* Memory allocation failed */ + free_run_list (list); + return NULL; } - p->prev = list->prev; - list->prev->next = p; - p->next = list; - list->prev = p; + + fribidi_validate_run_list (list); + + return list; } /* override the run list 'base', with the runs in the list 'over', to @@ -162,106 +215,154 @@ move_run_before ( of the last element of the 'over' list. these two conditions are always satisfied for the two usages mentioned above. + Note: + frees the over list. + Todo: use some explanatory names instead of p, q, ... rewrite comment above to remove references to special usage. */ -void +fribidi_boolean shadow_run_list ( - FriBidiRun * base, - FriBidiRun * over + /* input */ + FriBidiRun *base, + FriBidiRun *over, + fribidi_boolean preserve_length ) { - FriBidiRun *p = base, *q, *r, *s, *t; - FriBidiStrIndex pos = 0, pos2; + register FriBidiRun *p = base, *q, *r, *s, *t; + register FriBidiStrIndex pos = 0, pos2; + fribidi_boolean status = false; - if (!over) - return; - q = over; - while (q) - { - if (!q->len || q->pos < pos) - { - t = q; - q = q->next; - free_run (t); - continue; - } - pos = q->pos; - while (p->next && p->next->pos <= pos) - p = p->next; - /* now p is the element that q must be inserted 'in'. */ - pos2 = pos + q->len; - r = p; - while (r->next && r->next->pos < pos2) - r = r->next; - /* now r is the last element that q affects. */ - if (p == r) - { - /* split p into at most 3 interval, and insert q in the place of - the second interval, set r to be the third part. */ - /* third part needed? */ - if (p->next && p->next->pos == pos2) - r = r->next; - else - { - r = new_run (); - *r = *p; - if (r->next) - { - r->next->prev = r; - r->len = r->next->pos - pos2; - } - else - r->len -= pos - p->pos; - r->pos = pos2; - } - /* first part needed? */ - if (p->prev && p->pos == pos) - { - t = p; + fribidi_validate_run_list (base); + fribidi_validate_run_list (over); + + for_run_list (q, over) + { + if UNLIKELY + (!q->len || q->pos < pos) continue; + pos = q->pos; + while (p->next->type != FRIBIDI_TYPE_SENTINEL && p->next->pos <= pos) + p = p->next; + /* now p is the element that q must be inserted 'in'. */ + pos2 = pos + q->len; + r = p; + while (r->next->type != FRIBIDI_TYPE_SENTINEL && r->next->pos < pos2) + r = r->next; + if (preserve_length) + r->len += q->len; + /* now r is the last element that q affects. */ + if LIKELY + (p == r) + { + /* split p into at most 3 intervals, and insert q in the place of + the second interval, set r to be the third part. */ + /* third part needed? */ + if (p->pos + p->len > pos2) + { + r = new_run (); + if UNLIKELY + (!r) goto out; + p->next->prev = r; + r->next = p->next; + r->level = p->level; + r->type = p->type; + r->len = p->pos + p->len - pos2; + r->pos = pos2; + } + else + r = r->next; + + if LIKELY + (p->pos + p->len >= pos) + { + /* first part needed? */ + if (p->pos < pos) + /* cut the end of p. */ + p->len = pos - p->pos; + else + { + t = p; + p = p->prev; + free_run (t); + } + } + } + else + { + if LIKELY + (p->pos + p->len >= pos) + { + /* p needed? */ + if (p->pos < pos) + /* cut the end of p. */ + p->len = pos - p->pos; + else p = p->prev; - free_run (t); - } - else - p->len = pos - p->pos; - } - else - { - /* cut the end of p. */ - p->len = pos - p->pos; - /* if all of p is cut, remove it. */ - if (!p->len && p->prev) - p = p->prev; - - /* cut the begining of r. */ - r->pos = pos2; - if (r->next) - r->len = r->next->pos - pos2; - /* if all of r is cut, remove it. */ - if (!r->len && r->next) - r = r->next; - - /* remove the elements between p and r. */ - for (s = p->next; s != r;) - { - t = s; - s = s->next; - free_run (t); - } - } - /* before updating the next and prev runs to point to the inserted q, - we must remember the next element of q in the 'over' list. - */ - t = q; - q = q->next; - p->next = t; - t->prev = p; - t->next = r; - r->prev = t; - } + } + + /* r needed? */ + if (r->pos + r->len > pos2) + { + /* cut the begining of r. */ + r->len = r->pos + r->len - pos2; + r->pos = pos2; + } + else + r = r->next; + + /* remove the elements between p and r. */ + for (s = p->next; s != r;) + { + t = s; + s = s->next; + free_run (t); + } + } + /* before updating the next and prev runs to point to the inserted q, + we must remember the next element of q in the 'over' list. + */ + t = q; + q = q->prev; + delete_node (t); + p->next = t; + t->prev = p; + t->next = r; + r->prev = t; + } + status = true; + + fribidi_validate_run_list (base); + +out: + free_run_list (over); + + return status; +} + +#if DEBUG + +void +fribidi_validate_run_list ( + FriBidiRun *run_list /* input run list */ +) +{ + register FriBidiRun *q; + + fribidi_assert (run_list); + fribidi_assert (run_list->next); + fribidi_assert (run_list->next->prev == run_list); + fribidi_assert (run_list->type == FRIBIDI_TYPE_SENTINEL); + for_run_list (q, run_list) + { + fribidi_assert (q->next); + fribidi_assert (q->next->prev == q); + } + fribidi_assert (q == run_list); } +#endif /* !DEBUG */ + /* Editor directions: * vim:textwidth=78:tabstop=8:shiftwidth=2:autoindent:cindent */ diff --git a/lib/fribidi-types.h b/lib/fribidi-types.h index e938a13..c4856ba 100644 --- a/lib/fribidi-types.h +++ b/lib/fribidi-types.h @@ -1,10 +1,10 @@ /* FriBidi * fribidi-types.h - define data types for the rest of the library * - * $Id: fribidi-types.h,v 1.2 2004-04-27 16:47:22 behdad Exp $ + * $Id: fribidi-types.h,v 1.3 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-27 16:47:22 $ - * $Revision: 1.2 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.3 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi-types.h,v $ * * Author: @@ -56,12 +56,12 @@ # define FRIBIDI_UINT32_LOCAL uint32_t # else /* !HAVE_STDINT_H */ # define FRIBIDI_UINT8_LOCAL unsigned char -# if SIZEOF_SHORT >= 2 +# if !defined(SIZEOF_SHORT) || SIZEOF_SHORT >= 2 # define FRIBIDI_UINT16_LOCAL unsigned short # else /* SIZEOF_SHORT < 2 */ # define FRIBIDI_UINT16_LOCAL unsigned int # endif /* SIZEOF_SHORT < 2 */ -# if SIZEOF_INT >= 4 +# if !defined(SIZEOF_INT) || SIZEOF_INT >= 4 # define FRIBIDI_UINT32_LOCAL unsigned int # else /* SIZEOF_INT < 4 */ # define FRIBIDI_UINT32_LOCAL unsigned long diff --git a/lib/fribidi.c b/lib/fribidi.c index 3c6d0cf..707f115 100644 --- a/lib/fribidi.c +++ b/lib/fribidi.c @@ -1,10 +1,10 @@ /* FriBidi * fribidi.c - Unicode bidirectional and Arabic joining algorithms * - * $Id: fribidi.c,v 1.2 2004-04-25 19:12:42 behdad Exp $ + * $Id: fribidi.c,v 1.3 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-25 19:12:42 $ - * $Revision: 1.2 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.3 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi.c,v $ * * Authors: @@ -33,10 +33,10 @@ * For licensing issues, contact <license@farsiweb.info>. */ -#include <fribidi.h> - #include "common.h" +#include <fribidi.h> + const char *fribidi_version_info = "(" FRIBIDI_NAME ") " FRIBIDI_VERSION "\n" "Interface version " FRIBIDI_INTERFACE_VERSION_STRING ",\n" diff --git a/lib/fribidi.def b/lib/fribidi.def new file mode 100644 index 0000000..dcd72c0 --- /dev/null +++ b/lib/fribidi.def @@ -0,0 +1,13 @@ +libfribidi_la_symbols = \ + fribidi_get_bidi_type \ + fribidi_get_bidi_types \ + fribidi_log2vis \ + fribidi_log2vis_get_embedding_levels \ + fribidi_remove_bidi_marks \ + fribidi_get_mirror_char \ + fribidi_debug_status \ + fribidi_set_debug \ + fribidi_mirroring_status \ + fribidi_set_mirroring \ + fribidi_reorder_nsm_status \ + fribidi_set_reorder_nsm @@ -1,10 +1,10 @@ /* FriBidi * mem.h - memory manipulation routines * - * $Id: mem.h,v 1.3 2004-04-28 02:37:56 behdad Exp $ + * $Id: mem.h,v 1.4 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-28 02:37:56 $ - * $Revision: 1.3 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.4 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/mem.h,v $ * * Author: @@ -33,12 +33,10 @@ #ifndef _MEM_H #define _MEM_H -#include <fribidi-common.h> +#include "common.h" #include <fribidi-types.h> -#include "common.h" - #include <fribidi-begindecls.h> #if !FRIBIDI_USE_GLIB @@ -48,22 +46,25 @@ typedef struct _FriBidiMemChunk FriBidiMemChunk; #define FRIBIDI_ALLOC_ONLY 1 #define fribidi_mem_chunk_new FRIBIDI_PRIVATESPACE(mem_chunk_new) -FriBidiMemChunk *fribidi_mem_chunk_new ( +FriBidiMemChunk * +fribidi_mem_chunk_new ( const char *name, int atom_size, unsigned long area_size, int alloc_type -); +) + FRIBIDI_GNUC_HIDDEN FRIBIDI_GNUC_MALLOC FRIBIDI_GNUC_WARN_UNUSED; #define fribidi_mem_chunk_alloc FRIBIDI_PRIVATESPACE(mem_chunk_alloc) -void *fribidi_mem_chunk_alloc ( + void *fribidi_mem_chunk_alloc ( FriBidiMemChunk *mem_chunk -); +) + FRIBIDI_GNUC_HIDDEN FRIBIDI_GNUC_MALLOC FRIBIDI_GNUC_WARN_UNUSED; #define fribidi_mem_chunk_destroy FRIBIDI_PRIVATESPACE(mem_chunk_destroy) -void *fribidi_mem_chunk_destroy ( + void *fribidi_mem_chunk_destroy ( FriBidiMemChunk *mem_chunk -); +) FRIBIDI_GNUC_HIDDEN; #else /* FRIBIDI_USE_GLIB */ diff --git a/lib/mirroring-table.i b/lib/mirroring-table.i index 6e47900..bf31db6 100644 --- a/lib/mirroring-table.i +++ b/lib/mirroring-table.i @@ -3,8 +3,8 @@ by fribidi_create_mirroring */ -#ifndef FRIBIDI_TAB_MIRRORING_I -#define FRIBIDI_TAB_MIRRORING_I +#ifndef MIRRORING_TABLE_I +#define MIRRORING_TABLE_I #include <fribidi-types.h> @@ -348,6 +348,8 @@ FriBidiMirroredChars[] = {0xFF60, 0xFF5F}, {0xFF62, 0xFF63}, {0xFF63, 0xFF62}, + /* add an extra entry, doesn't harm ;-), but helps in binary search */ + {0x0000, 0x0000} } ; /* *INDENT-ON* */ @@ -355,4 +357,4 @@ FriBidiMirroredChars[] = static const int nFriBidiMirroredChars = 318; -#endif /* FRIBIDI_TAB_MIRRORING_I */ +#endif /* MIRRORING_TABLE_I */ @@ -1,10 +1,10 @@ /* FriBidi * run.h - text run data type * - * $Id: run.h,v 1.1 2004-04-28 02:37:56 behdad Exp $ + * $Id: run.h,v 1.2 2004-05-03 22:05:19 behdad Exp $ * $Author: behdad $ - * $Date: 2004-04-28 02:37:56 $ - * $Revision: 1.1 $ + * $Date: 2004-05-03 22:05:19 $ + * $Revision: 1.2 $ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/run.h,v $ * * Authors: @@ -35,13 +35,13 @@ #ifndef _RUN_H #define _RUN_H +#include "common.h" + #include <fribidi-common.h> #include <fribidi-types.h> #include <fribidi-bidi-types.h> -#include "common.h" - #include <fribidi-begindecls.h> struct _FriBidiRun @@ -55,32 +55,100 @@ struct _FriBidiRun }; -FriBidiRun *new_run ( +#define new_run FRIBIDI_PRIVATESPACE(new_run) +FriBidiRun * +new_run ( + void +) + FRIBIDI_GNUC_HIDDEN FRIBIDI_GNUC_MALLOC FRIBIDI_GNUC_WARN_UNUSED; + +#define free_run FRIBIDI_PRIVATESPACE(free_run) + void free_run ( + FriBidiRun *run +) FRIBIDI_GNUC_HIDDEN; + +#define new_run_list FRIBIDI_PRIVATESPACE(new_run_list) + FriBidiRun *new_run_list ( void -); +) + FRIBIDI_GNUC_HIDDEN FRIBIDI_GNUC_MALLOC FRIBIDI_GNUC_WARN_UNUSED; -void free_run ( - FriBidiRun * run -); +#define free_run_list FRIBIDI_PRIVATESPACE(free_run_list) + void free_run_list ( + FriBidiRun *run_list +) FRIBIDI_GNUC_HIDDEN; -FriBidiRun *run_list_encode_bidi_types ( +#define run_list_encode_bidi_types FRIBIDI_PRIVATESPACE(run_list_encode_bidi_types) + FriBidiRun *run_list_encode_bidi_types ( FriBidiCharType *char_type, FriBidiStrIndex len -); +) + FRIBIDI_GNUC_HIDDEN FRIBIDI_GNUC_WARN_UNUSED; + +#define shadow_run_list FRIBIDI_PRIVATESPACE(shadow_run_list) + fribidi_boolean shadow_run_list ( + FriBidiRun *base, + FriBidiRun *over, + fribidi_boolean preserve_length +) + FRIBIDI_GNUC_HIDDEN FRIBIDI_GNUC_WARN_UNUSED; + + +#define swap(a,b) \ + FRIBIDI_BEGIN_STMT \ + void *t; \ + (t) = (a); \ + (a) = (b); \ + (b) = (t); \ + FRIBIDI_END_STMT + +#define merge_lists(a,b) \ + FRIBIDI_BEGIN_STMT \ + swap((a)->prev->next, (b)->prev->next); \ + swap((a)->prev, (b)->prev); \ + FRIBIDI_END_STMT + +#define delete_node(x) \ + FRIBIDI_BEGIN_STMT \ + (x)->prev->next = (x)->next; \ + (x)->next->prev = (x)->prev; \ + FRIBIDI_END_STMT + +#define insert_node_before(x, list) \ + FRIBIDI_BEGIN_STMT \ + (x)->prev = (list)->prev; \ + (list)->prev->next = (x); \ + (x)->next = (list); \ + (list)->prev = (x); \ + FRIBIDI_END_STMT + +#define move_node_before(x, list) \ + FRIBIDI_BEGIN_STMT \ + if ((x)->prev) \ + delete_node(x); \ + insert_node_before((x), (list)); \ + FRIBIDI_END_STMT + +#define for_run_list(x, list) \ + for ((x) = (list)->next; (x)->type != FRIBIDI_TYPE_SENTINEL; (x) = (x)->next) + + +#if DEBUG + +#define fribidi_validate_run_list FRIBIDI_NAMESPACE(validate_run_list) + void fribidi_validate_run_list ( + FriBidiRun *run_list /* input run list */ +) FRIBIDI_GNUC_HIDDEN; + +#else /* !DEBUG */ -void move_run_before ( - FriBidiRun * p, - FriBidiRun * list -); +#define fribidi_validate_run_list(run_list) fribidi_assert(run_list) -void shadow_run_list ( - FriBidiRun * base, - FriBidiRun * over -); +#endif /* !DEBUG */ #include <fribidi-enddecls.h> -#endif /* !_MEM_H */ +#endif /* !_RUN_H */ /* Editor directions: * vim:textwidth=78:tabstop=8:shiftwidth=2:autoindent:cindent */ diff --git a/test/run.tests b/test/run.tests index c8bd759..cee4cdd 100755 --- a/test/run.tests +++ b/test/run.tests @@ -1,4 +1,4 @@ -#!/bin/bash +#! /bin/sh # run.tests - Check that the algorithm does what it is supposed to # Copyright (C) 1999,2000 Dov Grobgeld, and # Copyright (C) 2001,2002 Behdad Esfahbod. @@ -26,7 +26,7 @@ if test -z "$top_builddir"; then fi if test -z "$srcdir"; then - srcdir=. + srcdir=`echo "$0" | sed 's,/[^/]*$,,'` fi test "${VERBOSE+set}" != "set" && VERBOSE=yes |