[FriBidi-commit] fribidi/lib fribidi.def, NONE, 1.1 Headers.mk, 1.2, 1.3 Makefile.am, 1.3, 1.4 bidi-type-table.i, 1.1.1.1, 1.2 bidi-types-list.h, 1.2, 1.3 bidi-types.h, 1.2, 1.3 common.h, 1.4, 1.5 debug.h, 1.2, 1.3 env.h, 1.1, 1.2 fribidi-bidi-type.c, 1.2, 1.3 fribidi-bidi-type.h, 1.1.1.1, 1.2 fribidi-bidi-types.c, 1.2, 1.3 fribidi-bidi-types.h, 1.2, 1.3 fribidi-bidi.c, 1.4, 1.5 fribidi-bidi.h, 1.1.1.1, 1.2 fribidi-common.h, 1.2, 1.3 fribidi-env.c, 1.2, 1.3 fribidi-env.h, 1.1.1.1, 1.2 fribidi-mem.c, 1.3, 1.4 fribidi-mirroring.c, 1.3, 1.4 fribidi-run.c, 1.1, 1.2 fribidi-types.h, 1.2, 1.3 fribidi.c, 1.2, 1.3 mem.h, 1.3, 1.4 mirroring-table.i, 1.1.1.1, 1.2 run.h, 1.1, 1.2

Behdad Esfahbod behdad at pdx.freedesktop.org
Tue May 4 08:05:22 EST 2004


Update of /cvs/fribidi/fribidi/lib
In directory pdx:/tmp/cvs-serv16180/lib

Modified Files:
	Headers.mk Makefile.am bidi-type-table.i bidi-types-list.h 
	bidi-types.h common.h debug.h env.h fribidi-bidi-type.c 
	fribidi-bidi-type.h fribidi-bidi-types.c fribidi-bidi-types.h 
	fribidi-bidi.c fribidi-bidi.h fribidi-common.h fribidi-env.c 
	fribidi-env.h fribidi-mem.c fribidi-mirroring.c fribidi-run.c 
	fribidi-types.h fribidi.c mem.h mirroring-table.i run.h 
Added Files:
	fribidi.def 
Log Message:
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.


--- NEW FILE: fribidi.def ---
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

Index: Headers.mk
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/Headers.mk,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/Headers.mk	27 Apr 2004 16:47:22 -0000	1.2
+++ b/Headers.mk	3 May 2004 22:05:19 -0000	1.3
@@ -13,16 +13,4 @@
 		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

Index: Makefile.am
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/Makefile.am,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- a/Makefile.am	28 Apr 2004 03:20:22 -0000	1.3
+++ b/Makefile.am	3 May 2004 22:05:19 -0000	1.4
@@ -10,9 +10,9 @@
 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
 

Index: bidi-type-table.i
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/bidi-type-table.i,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- a/bidi-type-table.i	25 Apr 2004 18:47:57 -0000	1.1.1.1
+++ b/bidi-type-table.i	3 May 2004 22:05:19 -0000	1.2
@@ -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 @@
 #undef RTL
 #undef LTR
 
-static FriBidiCharType
+static inline FriBidiCharType
 get_bidi_type (
   /* input */
   FriBidiChar uch
@@ -5225,4 +5225,4 @@
 }
 
 
-#endif /* FRIBIDI_TAB_CHAR_TYPE_2_I */
+#endif /* BIDI_TYPE_TABLE_I */

Index: bidi-types-list.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/bidi-types-list.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/bidi-types-list.h	27 Apr 2004 16:47:22 -0000	1.2
+++ b/bidi-types-list.h	3 May 2004 22:05:19 -0000	1.3
@@ -57,12 +57,11 @@
 
 /* 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* */

Index: bidi-types.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/bidi-types.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/bidi-types.h	28 Apr 2004 02:37:56 -0000	1.2
+++ b/bidi-types.h	3 May 2004 22:05:19 -0000	1.3
@@ -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 @@
 #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 */
 

Index: common.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/common.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- a/common.h	28 Apr 2004 02:37:56 -0000	1.4
+++ b/common.h	3 May 2004 22:05:19 -0000	1.5
@@ -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 */

Index: debug.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/debug.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/debug.h	27 Apr 2004 16:47:22 -0000	1.2
+++ b/debug.h	3 May 2004 22:05:19 -0000	1.3
@@ -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 */
 

Index: env.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/env.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- a/env.h	28 Apr 2004 02:37:56 -0000	1.1
+++ b/env.h	3 May 2004 22:05:19 -0000	1.2
@@ -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

Index: fribidi-bidi-type.c
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-bidi-type.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/fribidi-bidi-type.c	28 Apr 2004 02:37:56 -0000	1.2
+++ b/fribidi-bidi-type.c	3 May 2004 22:05:19 -0000	1.3
@@ -31,13 +31,13 @@
  * For licensing issues, contact <license at 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 @@
 }
 
 /* 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 @@
   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. */

Index: fribidi-bidi-type.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-bidi-type.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- a/fribidi-bidi-type.h	25 Apr 2004 18:47:57 -0000	1.1.1.1
+++ b/fribidi-bidi-type.h	3 May 2004 22:05:19 -0000	1.2
@@ -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 */

Index: fribidi-bidi-types.c
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-bidi-types.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/fribidi-bidi-types.c	28 Apr 2004 02:37:56 -0000	1.2
+++ b/fribidi-bidi-types.c	3 May 2004 22:05:19 -0000	1.3
@@ -31,15 +31,15 @@
  * For licensing issues, contact <license at 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

Index: fribidi-bidi-types.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-bidi-types.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/fribidi-bidi-types.h	28 Apr 2004 02:37:56 -0000	1.2
+++ b/fribidi-bidi-types.h	3 May 2004 22:05:19 -0000	1.3
@@ -60,7 +60,7 @@
 #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 @@
 /* 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 @@
 #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 @@
 #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 @@
  * 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"
 

Index: fribidi-bidi.c
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-bidi.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- a/fribidi-bidi.c	28 Apr 2004 02:37:56 -0000	1.4
+++ b/fribidi-bidi.c	3 May 2004 22:05:19 -0000	1.5
@@ -33,6 +33,8 @@
  * For licensing issues, contact <license at 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 @@
 }
 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 @@
 
 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 @@
 
 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 @@
  *-------------------------------------------------------------------------*/
 
 /* 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 @@
 */
 #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 @@
 */
 #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 @@
  * 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 @@
  *----------------------------------------------------------------------*/
 
 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 @@
   '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 @@
   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 @@
 }
 #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 @@
          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 @@
   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 @@
     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 @@
       (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 @@
   /* 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;
+    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;
 
-	/* 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. */
-	  }
+      /* 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 @@
        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 @@
   {
     /* 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;
+    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));
+      /* "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);
-      }
+      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 @@
   {
     max_level = base_level;
 
-    for (pp = type_rl_list->next; pp->next; pp = pp->next)
-      {
-	FriBidiCharType this_type;
-	int level;
+    for_run_list (pp, main_run_list)
+    {
+      FriBidiCharType this_type;
+      int level;
 
-	this_type = RL_TYPE (pp);
-	level = RL_LEVEL (pp);
+      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);
+      /* 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);
-      }
+      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 @@
 	  {
 	    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)
-    {
-      FriBidiRun *p;
+static void
+index_array_reverse (
+  FriBidiStrIndex *arr,
+  FriBidiStrIndex len
+)
+{
+  FriBidiStrIndex i;
 
-      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 */
+  fribidi_assert (arr);
 
-  DBG ("Leaving free_rl_list");
-  return;
+  for (i = 0; i < len / 2; i++)
+    {
+      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 @@
 
   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_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 @@
   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()\n");
+  DBG ("Entering fribidi_log2vis()");
+
+  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))
     {
-      DBG ("Leaving fribidi_log2vis()\n");
-      return true;
+#     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))
+    {
+      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 @@
     /* 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 @@
 	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;
+	    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;
+		  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");
+		      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 @@
   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()\n");
-  return true;
+  DBG ("Leaving fribidi_log2vis_get_embedding_levels()");
+out:
+  free_run_list (main_run_list);
+
+  return status;
 }
 
 /* Editor directions:

Index: fribidi-bidi.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-bidi.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- a/fribidi-bidi.h	25 Apr 2004 18:47:57 -0000	1.1.1.1
+++ b/fribidi-bidi.h	3 May 2004 22:05:19 -0000	1.2
@@ -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 @@
 						 * 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 @@
  *
  * 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 @@
  *
  * 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"
 

Index: fribidi-common.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-common.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/fribidi-common.h	28 Apr 2004 03:20:22 -0000	1.2
+++ b/fribidi-common.h	3 May 2004 22:05:19 -0000	1.3
@@ -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. */

Index: fribidi-env.c
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-env.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/fribidi-env.c	28 Apr 2004 02:37:56 -0000	1.2
+++ b/fribidi-env.c	3 May 2004 22:05:19 -0000	1.3
@@ -33,12 +33,12 @@
  * For licensing issues, contact <license at farsiweb.info>.
  */
 
+#include "common.h"
+
 #include <fribidi-env.h>
 
 #include "env.h"
 
-#include "common.h"
-
 /* Library state variables */
 
 #if DEBUG
@@ -49,8 +49,8 @@
 
 
 #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_ENTRY fribidi_boolean
 fribidi_set_debug (
+  /* input */
   fribidi_boolean state
 )
 {
@@ -82,6 +83,7 @@
 
 FRIBIDI_ENTRY fribidi_boolean
 fribidi_set_mirroring (
+  /* input */
   fribidi_boolean state
 )
 {
@@ -98,6 +100,7 @@
 
 FRIBIDI_ENTRY fribidi_boolean
 fribidi_set_reorder_nsm (
+  /* input */
   fribidi_boolean state
 )
 {

Index: fribidi-env.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-env.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- a/fribidi-env.h	25 Apr 2004 18:47:57 -0000	1.1.1.1
+++ b/fribidi-env.h	3 May 2004 22:05:19 -0000	1.2
@@ -60,16 +60,17 @@
  *
  * 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 @@
  *
  * 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 @@
  *
  * 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"

Index: fribidi-mem.c
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-mem.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- a/fribidi-mem.c	28 Apr 2004 02:37:56 -0000	1.3
+++ b/fribidi-mem.c	3 May 2004 22:05:19 -0000	1.4
@@ -31,10 +31,10 @@
  * For licensing issues, contact <license at farsiweb.info>.
  */
 
-#include "mem.h"
-
 #include "common.h"
 
+#include "mem.h"
+
 #if !FRIBIDI_USE_GLIB
 
 struct _FriBidiMemChunk
@@ -54,10 +54,13 @@
   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 @@
   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 @@
     }
 
   {
-    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 @@
   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;

Index: fribidi-mirroring.c
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-mirroring.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- a/fribidi-mirroring.c	27 Apr 2004 23:53:43 -0000	1.3
+++ b/fribidi-mirroring.c	3 May 2004 22:05:19 -0000	1.4
@@ -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 @@
 
   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 @@
       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;

Index: fribidi-run.c
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-run.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- a/fribidi-run.c	28 Apr 2004 02:37:56 -0000	1.1
+++ b/fribidi-run.c	3 May 2004 22:05:19 -0000	1.2
@@ -33,18 +33,18 @@
  * For licensing issues, contact <license at 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 @@
   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 @@
 #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 @@
    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;
+	/* 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->next;
-      p->next = t;
-      t->prev = p;
-      t->next = r;
-      r->prev = t;
-    }
+	/* 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
  */

Index: fribidi-types.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-types.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/fribidi-types.h	27 Apr 2004 16:47:22 -0000	1.2
+++ b/fribidi-types.h	3 May 2004 22:05:19 -0000	1.3
@@ -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

Index: fribidi.c
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/fribidi.c	25 Apr 2004 19:12:42 -0000	1.2
+++ b/fribidi.c	3 May 2004 22:05:19 -0000	1.3
@@ -33,10 +33,10 @@
  * For licensing issues, contact <license at 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"

Index: mem.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/mem.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- a/mem.h	28 Apr 2004 02:37:56 -0000	1.3
+++ b/mem.h	3 May 2004 22:05:19 -0000	1.4
@@ -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 @@
 #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 */
 

Index: mirroring-table.i
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/mirroring-table.i,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- a/mirroring-table.i	25 Apr 2004 18:47:57 -0000	1.1.1.1
+++ b/mirroring-table.i	3 May 2004 22:05:19 -0000	1.2
@@ -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 @@
   {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 @@
 static const int nFriBidiMirroredChars = 318;
 
 
-#endif /* FRIBIDI_TAB_MIRRORING_I */
+#endif /* MIRRORING_TABLE_I */

Index: run.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/run.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- a/run.h	28 Apr 2004 02:37:56 -0000	1.1
+++ b/run.h	3 May 2004 22:05:19 -0000	1.2
@@ -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 @@
 };
 
 
-FriBidiRun *new_run (
+#define new_run FRIBIDI_PRIVATESPACE(new_run)
+FriBidiRun *
+new_run (
   void
-);
+)
+     FRIBIDI_GNUC_HIDDEN FRIBIDI_GNUC_MALLOC FRIBIDI_GNUC_WARN_UNUSED;
 
-void free_run (
-  FriBidiRun * run
-);
+#define free_run FRIBIDI_PRIVATESPACE(free_run)
+     void free_run (
+  FriBidiRun *run
+) FRIBIDI_GNUC_HIDDEN;
 
-FriBidiRun *run_list_encode_bidi_types (
+#define new_run_list FRIBIDI_PRIVATESPACE(new_run_list)
+     FriBidiRun *new_run_list (
+  void
+)
+     FRIBIDI_GNUC_HIDDEN FRIBIDI_GNUC_MALLOC FRIBIDI_GNUC_WARN_UNUSED;
+
+#define free_run_list FRIBIDI_PRIVATESPACE(free_run_list)
+     void free_run_list (
+  FriBidiRun *run_list
+) FRIBIDI_GNUC_HIDDEN;
+
+#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;
 
-void move_run_before (
-  FriBidiRun * p,
-  FriBidiRun * list
-);
+#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;
 
-void shadow_run_list (
-  FriBidiRun * base,
-  FriBidiRun * over
-);
+
+#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 */
+
+#define fribidi_validate_run_list(run_list) fribidi_assert(run_list)
+
+#endif /* !DEBUG */
 
 #include <fribidi-enddecls.h>
 
-#endif /* !_MEM_H */
+#endif /* !_RUN_H */
 /* Editor directions:
  * vim:textwidth=78:tabstop=8:shiftwidth=2:autoindent:cindent
  */




More information about the FriBidi-Commit mailing list