Bug Summary

File:Frameworks/FriBidi Framework/fribidi-0.10.7/fribidi.c
Location:line 739, column 5
Description:dead store

Annotated Source Code

1/* FriBidi - Library of BiDi algorithm
2 * Copyright (C) 1999,2000 Dov Grobgeld, and
3 * Copyright (C) 2001,2002 Behdad Esfahbod.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library, in a file named COPYING; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA
19 *
20 * For licensing issues, contact <dov@imagic.weizmann.ac.il> and
21 * <fwpg@sharif.edu>.
22 */
23
24#include <stdlib.h>
25
26#ifdef HAVE_CONFIG_H
27#include <config.h>
28#endif
29#include "fribidi.h"
30#include "fribidi_mem.h"
31#ifdef DEBUG
32#include <stdio.h>
33#endif
34
35/* Redefine FRIBIDI_CHUNK_SIZE in config.h to override this. */
36#ifndef FRIBIDI_CHUNK_SIZE
37#ifdef MEM_OPTIMIZED
38#define FRIBIDI_CHUNK_SIZE 16
39#else
40#define FRIBIDI_CHUNK_SIZE 128
41#endif
42#endif
43
44#ifdef DEBUG
45#define DBG(s) do { if (fribidi_debug) { fprintf(stderr, s); } } while (0)
46#define DBG2(s, t) do { if (fribidi_debug) { fprintf(stderr, s, t); } } while (0)
47#else
48#define DBG(s)
49#define DBG2(s, t)
50#endif
51
52#ifdef DEBUG
53char fribidi_char_from_type (FriBidiCharType c);
54#endif
55
56#define MAX(a,b) ((a) > (b) ? (a) : (b))
57
58/*======================================================================
59 * Typedef for the run-length list.
60 *----------------------------------------------------------------------*/
61typedef struct _TypeLink TypeLink;
62
63struct _TypeLink
64{
65 TypeLink *prev;
66 TypeLink *next;
67
68 FriBidiCharType type;
69 FriBidiStrIndex pos, len;
70 FriBidiLevel level;
71};
72
73#define FRIBIDI_LEVEL_START -1
74#define FRIBIDI_LEVEL_END -1
75#define FRIBIDI_LEVEL_REMOVED -2
76
77typedef struct
78{
79 FriBidiCharType override; /* only L, R and N are valid */
80 FriBidiLevel level;
81}
82LevelInfo;
83
84#ifdef DEBUG
85static fribidi_boolean fribidi_debug = FRIBIDI_FALSE;
86#endif
87
88fribidi_boolean
89fribidi_set_debug (fribidi_boolean debug)
90{
91#ifdef DEBUG
92 fribidi_debug = debug;
93#else
94 debug = 0;
95#endif
96 return debug;
97}
98
99static void
100bidi_string_reverse (FriBidiChar *str,
101 FriBidiStrIndex len)
102{
103 FriBidiStrIndex i;
104 for (i = 0; i < len / 2; i++)
105 {
106 FriBidiChar tmp = str[i];
107 str[i] = str[len - 1 - i];
108 str[len - 1 - i] = tmp;
109 }
110}
111
112static void
113index_array_reverse (FriBidiStrIndex *arr,
114 FriBidiStrIndex len)
115{
116 FriBidiStrIndex i;
117 for (i = 0; i < len / 2; i++)
118 {
119 FriBidiStrIndex tmp = arr[i];
120 arr[i] = arr[len - 1 - i];
121 arr[len - 1 - i] = tmp;
122 }
123}
124
125#ifndef USE_SIMPLE_MALLOC
126static TypeLink *free_type_links = NULL( ( void * ) 0 );
127#endif
128
129static TypeLink *
130new_type_link (void)
131{
132 TypeLink *link;
133
134#ifdef USE_SIMPLE_MALLOC
135 link = malloc (sizeof (TypeLink));
136#else /* !USE_SIMPLE_MALLOC */
137 if (free_type_links)
138 {
139 link = free_type_links;
140 free_type_links = free_type_links->next;
141 }
142 else
143 {
144 static FriBidiMemChunk *mem_chunk = NULL( ( void * ) 0 );
145
146 if (!mem_chunk)
147 mem_chunk = fribidi_mem_chunk_create( fribidi_mem_chunk_new ( "TypeLink" " mem chunks (" "FRIBIDI_CHUNK_SIZE"
")" , sizeof ( TypeLink ) , sizeof ( TypeLink ) * ( 128 ) , (
1 ) ) )
(TypeLink,
148 FRIBIDI_CHUNK_SIZE,
149 FRIBIDI_ALLOC_ONLY);
150
151 link = fribidi_chunk_new( ( TypeLink * ) fribidi_mem_chunk_alloc ( mem_chunk ) ) (TypeLink,
152 mem_chunk);
153 }
154#endif /* !USE_SIMPLE_MALLOC */
155
156 link->len = 0;
157 link->pos = 0;
158 link->level = 0;
159 link->next = NULL( ( void * ) 0 );
160 link->prev = NULL( ( void * ) 0 );
161 return link;
162}
163
164static void
165free_type_link (TypeLink *link)
166{
167#ifdef USE_SIMPLE_MALLOC
168 free (link);
169#else
170 link->next = free_type_links;
171 free_type_links = link;
172#endif
173}
174
175#define FRIBIDI_ADD_TYPE_LINK(p,q) \
176 do { \
177 (p)->len = (q)->pos - (p)->pos; \
178 (p)->next = (q); \
179 (q)->prev = (p); \
180 (p) = (q); \
181 } while (0)
182
183static TypeLink *
184run_length_encode_types (FriBidiCharType *char_type,
185 FriBidiStrIndex type_len)
186{
187 TypeLink *list, *last, *link;
188
189 FriBidiStrIndex i;
190
191 /* Add the starting link */
192 list = new_type_link ();
193 list->type = FRIBIDI_TYPE_SOT( 0x00000080L );
194 list->level = FRIBIDI_LEVEL_START- 1;
195 last = list;
196
197 /* Sweep over the string_type s */
198 for (i = 0; i < type_len; i++)
199 if (char_type[i] != last->type)
200 {
201 link = new_type_link ();
202 link->type = char_type[i];
203 link->pos = i;
204 FRIBIDI_ADD_TYPE_LINKdo { ( last ) -> len = ( link ) -> pos - ( last ) ->
pos ; ( last ) -> next = ( link ) ; ( link ) -> prev =
( last ) ; ( last ) = ( link ) ; } while ( 0 )
(last, link);
205 }
206
207 /* Add the ending link */
208 link = new_type_link ();
209 link->type = FRIBIDI_TYPE_EOT( 0x00000080L + 0x00000001L );
210 link->level = FRIBIDI_LEVEL_END- 1;
211 link->pos = type_len;
212 FRIBIDI_ADD_TYPE_LINKdo { ( last ) -> len = ( link ) -> pos - ( last ) ->
pos ; ( last ) -> next = ( link ) ; ( link ) -> prev =
( last ) ; ( last ) = ( link ) ; } while ( 0 )
(last, link);
213
214 return list;
215}
216
217/* explicits_list is a list like type_rl_list, that holds the explicit
218 codes that are removed from rl_list, to reinsert them later by calling
219 the override_list.
220*/
221static void
222init_list (TypeLink **start,
223 TypeLink **end)
224{
225 TypeLink *list;
226 TypeLink *link;
227
228 /* Add the starting link */
229 list = new_type_link ();
230 list->type = FRIBIDI_TYPE_SOT( 0x00000080L );
231 list->level = FRIBIDI_LEVEL_START- 1;
232 list->len = 0;
233 list->pos = 0;
234
235 /* Add the ending link */
236 link = new_type_link ();
237 link->type = FRIBIDI_TYPE_EOT( 0x00000080L + 0x00000001L );
238 link->level = FRIBIDI_LEVEL_END- 1;
239 link->len = 0;
240 link->pos = 0;
241 list->next = link;
242 link->prev = list;
243
244 *start = list;
245 *end = link;
246}
247
248/* move an element before another element in a list, the list must have a
249 previous element, used to update explicits_list.
250 assuming that p have both prev and next or none of them, also update
251 the list that p is currently in, if any.
252*/
253static void
254move_element_before (TypeLink *p,
255 TypeLink *list)
256{
257 if (p->prev)
258 {
259 p->prev->next = p->next;
260 p->next->prev = p->prev;
261 }
262 p->prev = list->prev;
263 list->prev->next = p;
264 p->next = list;
265 list->prev = p;
266}
267
268/* override the rl_list 'base', with the elements in the list 'over', to
269 reinsert the previously-removed explicit codes (at X9) from
270 'explicits_list' back into 'type_rl_list'. This is used at the end of I2
271 to restore the explicit marks, and also to reset the character types of
272 characters at L1.
273
274 it is assumed that the 'pos' of the first element in 'base' list is not
275 more than the 'pos' of the first element of the 'over' list, and the
276 'pos' of the last element of the 'base' list is not less than the 'pos'
277 of the last element of the 'over' list. these two conditions are always
278 satisfied for the two usages mentioned above.
279
280 TBD: use some explanatory names instead of p, q, ...
281*/
282static void
283override_list (TypeLink *base,
284 TypeLink *over)
285{
286 TypeLink *p = base, *q, *r, *s, *t;
287 FriBidiStrIndex pos = 0, pos2;
288
289 if (!over)
290 return;
291 q = over;
292 while (q)
293 {
294 if (!q->len || q->pos < pos)
295 {
296 t = q;
297 q = q->next;
298 free_type_link (t);
299 continue;
300 }
301 pos = q->pos;
302 while (p->next && p->next->pos <= pos)
303 p = p->next;
304 /* now p is the element that q must be inserted 'in'. */
305 pos2 = pos + q->len;
306 r = p;
307 while (r->next && r->next->pos < pos2)
308 r = r->next;
309 /* now r is the last element that q affects. */
310 if (p == r)
311 {
312 /* split p into at most 3 interval, and insert q in the place of
313 the second interval, set r to be the third part. */
314 /* third part needed? */
315 if (p->next && p->next->pos == pos2)
316 r = r->next;
317 else
318 {
319 r = new_type_link ();
320 *r = *p;
321 if (r->next)
322 {
323 r->next->prev = r;
324 r->len = r->next->pos - pos2;
325 }
326 else
327 r->len -= pos - p->pos;
328 r->pos = pos2;
329 }
330 /* first part needed? */
331 if (p->prev && p->pos == pos)
332 {
333 t = p;
334 p = p->prev;
335 free_type_link (t);
336 }
337 else
338 p->len = pos - p->pos;
339 }
340 else
341 {
342 /* cut the end of p. */
343 p->len = pos - p->pos;
344 /* if all of p is cut, remove it. */
345 if (!p->len && p->prev)
346 p = p->prev;
347
348 /* cut the begining of r. */
349 r->pos = pos2;
350 if (r->next)
351 r->len = r->next->pos - pos2;
352 /* if all of r is cut, remove it. */
353 if (!r->len && r->next)
354 r = r->next;
355
356 /* remove the elements between p and r. */
357 for (s = p->next; s != r;)
358 {
359 t = s;
360 s = s->next;
361 free_type_link (t);
362 }
363 }
364 /* before updating the next and prev links to point to the inserted q,
365 we must remember the next element of q in the 'over' list.
366 */
367 t = q;
368 q = q->next;
369 p->next = t;
370 t->prev = p;
371 t->next = r;
372 r->prev = t;
373 }
374}
375
376/* Some convenience macros */
377#define RL_TYPE(list) ((list)->type)
378#define RL_LEN(list) ((list)->len)
379#define RL_POS(list) ((list)->pos)
380#define RL_LEVEL(list) ((list)->level)
381
382static TypeLink *
383merge_with_prev (TypeLink *second)
384{
385 TypeLink *first = second->prev;
386 first->next = second->next;
387 first->next->prev = first;
388 RL_LEN( ( first ) -> len ) (first) += RL_LEN( ( second ) -> len ) (second);
389 free_type_link (second);
390 return first;
391}
392
393static void
394compact_list (TypeLink *list)
395{
396 if (list->next)
397 for (list = list->next; list; list = list->next)
398 if (RL_TYPE( ( list -> prev ) -> type ) (list->prev) == RL_TYPE( ( list ) -> type ) (list)
399 && RL_LEVEL( ( list -> prev ) -> level ) (list->prev) == RL_LEVEL( ( list ) -> level ) (list))
400 list = merge_with_prev (list);
401}
402
403static void
404compact_neutrals (TypeLink *list)
405{
406 if (list->next)
407 {
408 for (list = list->next; list; list = list->next)
409 {
410 if (RL_LEVEL( ( list -> prev ) -> level ) (list->prev) == RL_LEVEL( ( list ) -> level ) (list)
411 &&
412 ((RL_TYPE( ( list -> prev ) -> type )
413 (list->prev) == RL_TYPE( ( list ) -> type ) (list)
414 || (FRIBIDI_IS_NEUTRAL( ( ( ( list -> prev ) -> type ) ) & 0x00000040L ) (RL_TYPE (list->prev))
415 && FRIBIDI_IS_NEUTRAL( ( ( ( list ) -> type ) ) & 0x00000040L ) (RL_TYPE (list))))))
416 list = merge_with_prev (list);
417 }
418 }
419}
420
421/*=========================================================================
422 * define macros for push and pop the status in to / out of the stack
423 *-------------------------------------------------------------------------*/
424
425/* There's some little points in pushing and poping into the status stack:
426 1. when the embedding level is not valid (more than UNI_MAX_BIDI_LEVEL=61),
427 you must reject it, and not to push into the stack, but when you see a
428 PDF, you must find the matching code, and if it was pushed in the stack,
429 pop it, it means you must pop if and only if you have pushed the
430 matching code, the over_pushed var counts the number of rejected codes yet.
431 2. there's a more confusing point too, when the embedding level is exactly
432 UNI_MAX_BIDI_LEVEL-1=60, an LRO or LRE must be rejected because the new
433 level would be UNI_MAX_BIDI_LEVEL+1=62, that is invalid, but an RLO or RLE
434 must be accepted because the new level is UNI_MAX_BIDI_LEVEL=61, that is
435 valid, so the rejected codes may be not continuous in the logical order,
436 in fact there is at most two continuous intervals of codes, with a RLO or
437 RLE between them. To support this case, the first_interval var counts the
438 number of rejected codes in the first interval, when it is 0, means that
439 there is only one interval yet.
440*/
441
442/* a. If this new level would be valid, then this embedding code is valid.
443 Remember (push) the current embedding level and override status.
444 Reset current level to this new level, and reset the override status to
445 new_override.
446 b. If the new level would not be valid, then this code is invalid. Don't
447 change the current level or override status.
448*/
449#define PUSH_STATUS \
450 do { \
451 if (new_level <= UNI_MAX_BIDI_LEVEL) \
452 { \
453 if (level == UNI_MAX_BIDI_LEVEL - 1) \
454 first_interval = over_pushed; \
455 status_stack[stack_size].level = level; \
456 status_stack[stack_size].override = override; \
457 stack_size++; \
458 level = new_level; \
459 override = new_override; \
460 } else \
461 over_pushed++; \
462 } while (0)
463
464/* If there was a valid matching code, restore (pop) the last remembered
465 (pushed) embedding level and directional override.
466*/
467#define POP_STATUS \
468 do { \
469 if (over_pushed || stack_size) \
470 { \
471 if (over_pushed > first_interval) \
472 over_pushed--; \
473 else \
474 { \
475 if (over_pushed == first_interval) \
476 first_interval = 0; \
477 stack_size--; \
478 level = status_stack[stack_size].level; \
479 override = status_stack[stack_size].override; \
480 } \
481 } \
482 } while (0)
483
484/*==========================================================================
485 * There was no support for sor and eor in the absence of Explicit Embedding
486 * Levels, so define macros, to support them, with as less change as needed.
487 *--------------------------------------------------------------------------*/
488
489/* Return the type of previous char or the sor, if already at the start of
490 a run level. */
491#define PREV_TYPE_OR_SOR(pp) \
492 ( \
493 RL_LEVEL(pp->prev) == RL_LEVEL(pp) ? \
494 RL_TYPE(pp->prev) : \
495 FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(pp->prev), RL_LEVEL(pp))) \
496 )
497
498/* Return the type of next char or the eor, if already at the end of
499 a run level. */
500#define NEXT_TYPE_OR_EOR(pp) \
501 ( \
502 !pp->next ? \
503 FRIBIDI_LEVEL_TO_DIR(RL_LEVEL(pp)) : \
504 (RL_LEVEL(pp->next) == RL_LEVEL(pp) ? \
505 RL_TYPE(pp->next) : \
506 FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(pp->next), RL_LEVEL(pp))) \
507 ) \
508 )
509
510
511/* Return the embedding direction of a link. */
512#define FRIBIDI_EMBEDDING_DIRECTION(list) \
513 FRIBIDI_LEVEL_TO_DIR(RL_LEVEL(list))
514
515#ifdef DEBUG
516/*======================================================================
517 * For debugging, define some functions for printing the types and the
518 * levels.
519 *----------------------------------------------------------------------*/
520
521static char char_from_level_array[] = {
522 'e', /* FRIBIDI_LEVEL_REMOVED, internal error, this level shouldn't be viewed. */
523 '_', /* FRIBIDI_LEVEL_START or _END, indicating start of string and end of string. */
524 /* 0-9,A-F are the only valid levels in debug mode and before resolving
525 implicits. after that the levels X, Y, Z may be appear too. */
526 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
527 'A', 'B', 'C', 'D', 'E', 'F',
528 'X', 'Y', 'Z', /* only must appear after resolving implicits. */
529 'o', 'o', 'o' /* overflows, this levels and higher levels show a bug!. */
530};
531
532#define fribidi_char_from_level(level) char_from_level_array[(level) + 2]
533
534static void
535print_types_re (TypeLink *pp)
536{
537 fprintf (stderr, " Run types : ");
538 while (pp)
539 {
540 fprintf (stderr, "%d:l%d(%s)[%d] ",
541 pp->pos, pp->len, fribidi_type_name (pp->type), pp->level);
542 pp = pp->next;
543 }
544 fprintf (stderr, "\n");
545}
546
547static void
548print_resolved_levels (TypeLink *pp)
549{
550 fprintf (stderr, " Res. levels: ");
551 while (pp)
552 {
553 FriBidiStrIndex i;
554 for (i = 0; i < RL_LEN (pp); i++)
555 fprintf (stderr, "%c", fribidi_char_from_level (RL_LEVEL (pp)));
556 pp = pp->next;
557 }
558 fprintf (stderr, "\n");
559}
560
561static void
562print_resolved_types (TypeLink *pp)
563{
564 fprintf (stderr, " Res. types : ");
565 while (pp)
566 {
567 FriBidiStrIndex i;
568 for (i = 0; i < RL_LEN (pp); i++)
569 fprintf (stderr, "%c", fribidi_char_from_type (pp->type));
570 pp = pp->next;
571 }
572 fprintf (stderr, "\n");
573}
574
575/* Here, only for test porpuses, we have assumed that a fribidi_string
576 ends with a 0 character */
577static void
578print_bidi_string (FriBidiChar *str)
579{
580 FriBidiStrIndex i;
581 fprintf (stderr, " Org. types : ");
582 for (i = 0; str[i]; i++)
583 fprintf (stderr, "%c",
584 fribidi_char_from_type (fribidi_get_type (str[i])));
585 fprintf (stderr, "\n");
586}
587#endif
588
589/*======================================================================
590 * This function should follow the Unicode specification closely!
591 *----------------------------------------------------------------------*/
592static void
593fribidi_analyse_string ( /* input */
594 FriBidiChar *str,
595 FriBidiStrIndex len,
596 FriBidiCharType *pbase_dir,
597 /* output */
598 TypeLink **ptype_rl_list,
599 FriBidiLevel *pmax_level)
600{
601 FriBidiLevel base_level, max_level;
602 FriBidiCharType base_dir;
603 FriBidiStrIndex i;
604 TypeLink *type_rl_list, *explicits_list, *explicits_list_end, *pp;
605
606 DBG ("Entering fribidi_analyse_string()\n");
607
608 /* Determinate character types */
609 DBG (" Determine character types\n");
610 {
611 FriBidiCharType *char_type =
612 (FriBidiCharType *) malloc (len * sizeof (FriBidiCharType));
613 for (i = 0; i < len; i++)
614 char_type[i] = fribidi_get_type (str[i]);
615
616 /* Run length encode the character types */
617 type_rl_list = run_length_encode_types (char_type, len);
618 free (char_type);
619 }
620 DBG (" Determine character types, Done\n");
621
622 init_list (&explicits_list, &explicits_list_end);
623
624 /* Find base level */
625 DBG (" Finding the base level\n");
626 if (FRIBIDI_IS_STRONG( ( * pbase_dir ) & 0x00000010L ) (*pbase_dir))
627 base_level = FRIBIDI_DIR_TO_LEVEL( ( FriBidiLevel ) ( * pbase_dir & 1 ) ) (*pbase_dir);
628 /* P2. P3. Search for first strong character and use its direction as
629 base direction */
630 else
631 {
632 /* If no strong base_dir was found, resort to the weak direction
633 that was passed on input. */
634 base_level = FRIBIDI_DIR_TO_LEVEL( ( FriBidiLevel ) ( * pbase_dir & 1 ) ) (*pbase_dir);
635 base_dir = FRIBIDI_TYPE_ON( 0x00000040L );
636 for (pp = type_rl_list; pp; pp = pp->next)
637 if (FRIBIDI_IS_LETTER( ( ( ( pp ) -> type ) ) & 0x00000100L ) (RL_TYPE (pp)))
638 {
639 base_level = FRIBIDI_DIR_TO_LEVEL( ( FriBidiLevel ) ( ( ( pp ) -> type ) & 1 ) ) (RL_TYPE (pp));
640 base_dir = FRIBIDI_LEVEL_TO_DIR( ( 0x00000010L + 0x00000100L ) | ( base_level & 1 ) ) (base_level);
641 break;
642 }
643 }
644 base_dir = FRIBIDI_LEVEL_TO_DIR( ( 0x00000010L + 0x00000100L ) | ( base_level & 1 ) ) (base_level);
645 DBG2 (" Base level : %c\n", fribidi_char_from_level (base_level));
646 DBG2 (" Base dir : %c\n", fribidi_char_from_type (base_dir));
647 DBG (" Finding the base level, Done\n");
648
649#ifdef DEBUG
650 if (fribidi_debug)
651 {
652 print_types_re (type_rl_list);
653 }
654#endif
655
656 /* Explicit Levels and Directions */
657 DBG ("Explicit Levels and Directions\n");
658 {
659 /* X1. Begin by setting the current embedding level to the paragraph
660 embedding level. Set the directional override status to neutral.
661 Process each character iteratively, applying rules X2 through X9.
662 Only embedding levels from 0 to 61 are valid in this phase. */
663 FriBidiLevel level, new_level;
664 FriBidiCharType override, new_override;
665 FriBidiStrIndex i;
666 int stack_size, over_pushed, first_interval;
667 LevelInfo *status_stack;
668 TypeLink temp_link;
669
670 level = base_level;
671 override = FRIBIDI_TYPE_ON( 0x00000040L );
672 /* stack */
673 stack_size = 0;
674 over_pushed = 0;
675 first_interval = 0;
676 status_stack =
677 (LevelInfo *) malloc (sizeof (LevelInfo) * (UNI_MAX_BIDI_LEVEL61 + 2));
678
679 for (pp = type_rl_list->next; pp->next; pp = pp->next)
680 {
681 FriBidiCharType this_type = RL_TYPE( ( pp ) -> type ) (pp);
682 if (FRIBIDI_IS_EXPLICIT_OR_BN( ( this_type ) & ( 0x00001000L | 0x00100000L ) ) (this_type))
683 {
684 if (FRIBIDI_IS_STRONG( ( this_type ) & 0x00000010L ) (this_type))
685 { /* LRE, RLE, LRO, RLO */
686 /* 1. Explicit Embeddings */
687 /* X2. With each RLE, compute the least greater odd embedding level. */
688 /* X3. With each LRE, compute the least greater even embedding level. */
689 /* 2. Explicit Overrides */
690 /* X4. With each RLO, compute the least greater odd embedding level. */
691 /* X5. With each LRO, compute the least greater even embedding level. */
692 new_override = FRIBIDI_EXPLICIT_TO_OVERRIDE_DIR( ( ( this_type ) & 0x00004000L ) ? ( ( 0x00000010L + 0x00000100L
) | ( ( ( FriBidiLevel ) ( this_type & 1 ) ) & 1 ) )
: ( 0x00000040L ) )
(this_type);
693 for (i = 0; i < RL_LEN( ( pp ) -> len ) (pp); i++)
694 {
695 new_level =
696 ((level + FRIBIDI_DIR_TO_LEVEL( ( FriBidiLevel ) ( this_type & 1 ) ) (this_type) + 2) & ~1) -
697 FRIBIDI_DIR_TO_LEVEL( ( FriBidiLevel ) ( this_type & 1 ) ) (this_type);
698 PUSH_STATUSdo { if ( new_level <= 61 ) { if ( level == 61 - 1 ) first_interval
= over_pushed ; status_stack [ stack_size ] . level = level ;
status_stack [ stack_size ] . override = override ; stack_size
++ ; level = new_level ; override = new_override ; } else over_pushed
++ ; } while ( 0 )
;
699 }
700 }
701 else if (this_type == FRIBIDI_TYPE_PDF( 0x00000020L + 0x00001000L ))
702 {
703 /* 3. Terminating Embeddings and overrides */
704 /* X7. With each PDF, determine the matching embedding or
705 override code. */
706 for (i = 0; i < RL_LEN( ( pp ) -> len ) (pp); i++)
707 POP_STATUSdo { if ( over_pushed || stack_size ) { if ( over_pushed >
first_interval ) over_pushed -- ; else { if ( over_pushed ==
first_interval ) first_interval = 0 ; stack_size -- ; level =
status_stack [ stack_size ] . level ; override = status_stack
[ stack_size ] . override ; } } } while ( 0 )
;
708 }
709 /* X9. Remove all RLE, LRE, RLO, LRO, PDF, and BN codes. */
710 /* Remove element and add it to explicits_list */
711 temp_link.next = pp->next;
712 pp->level = FRIBIDI_LEVEL_REMOVED- 2;
713 move_element_before (pp, explicits_list_end);
714 pp = &temp_link;
715 }
716 else
717 {
718 /* X6. For all typed besides RLE, LRE, RLO, LRO, and PDF:
719 a. Set the level of the current character to the current
720 embedding level.
721 b. Whenever the directional override status is not neutral,
722 reset the current character type to the directional override
723 status. */
724 RL_LEVEL( ( pp ) -> level ) (pp) = level;
725 if (!FRIBIDI_IS_NEUTRAL( ( override ) & 0x00000040L ) (override))
726 RL_TYPE( ( pp ) -> type ) (pp) = override;
727 }
728 /* X8. All explicit directional embeddings and overrides are
729 completely terminated at the end of each paragraph. Paragraph
730 separators are not included in the embedding. */
731 /* This function is running on a single paragraph, so we can do
732 X8 after all the input is processed. */
733 }
734
735 /* Implementing X8. It has no effect on a single paragraph! */
736 level = base_level;
737 override = FRIBIDI_TYPE_ON( 0x00000040L );
738 stack_size = 0;
Value stored to 'over_pushed' is never read
739 over_pushed = 0;
740
741 free (status_stack);
742 }
743 /* X10. The remaining rules are applied to each run of characters at the
744 same level. For each run, determine the start-of-level-run (sor) and
745 end-of-level-run (eor) type, either L or R. This depends on the
746 higher of the two levels on either side of the boundary (at the start
747 or end of the paragraph, the level of the 'other' run is the base
748 embedding level). If the higher level is odd, the type is R, otherwise
749 it is L. */
750 /* Resolving Implicit Levels can be done out of X10 loop, so only change
751 of Resolving Weak Types and Resolving Neutral Types is needed. */
752
753 compact_list (type_rl_list);
754
755#ifdef DEBUG
756 if (fribidi_debug)
757 {
758 print_types_re (type_rl_list);
759 print_bidi_string (str);
760 print_resolved_levels (type_rl_list);
761 print_resolved_types (type_rl_list);
762 }
763#endif
764
765 /* 4. Resolving weak types */
766 DBG ("Resolving weak types\n");
767 {
768 FriBidiCharType last_strong, prev_type_org;
769 fribidi_boolean w4;
770
771 last_strong = base_dir;
772
773 for (pp = type_rl_list->next; pp->next; pp = pp->next)
774 {
775 FriBidiCharType prev_type, this_type, next_type;
776
777 prev_type = PREV_TYPE_OR_SOR( ( ( pp -> prev ) -> level ) == ( ( pp ) -> level )
? ( ( pp -> prev ) -> type ) : ( ( 0x00000010L + 0x00000100L
) | ( ( ( ( ( pp -> prev ) -> level ) ) > ( ( ( pp )
-> level ) ) ? ( ( ( pp -> prev ) -> level ) ) : ( (
( pp ) -> level ) ) ) & 1 ) ) )
(pp);
778 this_type = RL_TYPE( ( pp ) -> type ) (pp);
779 next_type = NEXT_TYPE_OR_EOR( ! pp -> next ? ( ( 0x00000010L + 0x00000100L ) | ( ( ( pp
) -> level ) & 1 ) ) : ( ( ( pp -> next ) -> level
) == ( ( pp ) -> level ) ? ( ( pp -> next ) -> type
) : ( ( 0x00000010L + 0x00000100L ) | ( ( ( ( ( pp -> next
) -> level ) ) > ( ( ( pp ) -> level ) ) ? ( ( ( pp
-> next ) -> level ) ) : ( ( ( pp ) -> level ) ) ) &
1 ) ) ) )
(pp);
780
781 if (FRIBIDI_IS_STRONG( ( prev_type ) & 0x00000010L ) (prev_type))
782 last_strong = prev_type;
783
784 /* W1. NSM
785 Examine each non-spacing mark (NSM) in the level run, and change the
786 type of the NSM to the type of the previous character. If the NSM
787 is at the start of the level run, it will get the type of sor. */
788 /* Implementation note: it is important that if the previous character
789 is not sor, then we should merge this run with the previous,
790 because of rules like W5, that we assume all of a sequence of
791 adjacent ETs are in one TypeLink. */
792 if (this_type == FRIBIDI_TYPE_NSM( 0x00000020L + 0x00080000L ))
793 {
794 if (RL_LEVEL( ( pp -> prev ) -> level ) (pp->prev) == RL_LEVEL( ( pp ) -> level ) (pp))
795 pp = merge_with_prev (pp);
796 else
797 RL_TYPE( ( pp ) -> type ) (pp) = prev_type;
798 continue; /* As we know the next condition cannot be true. */
799 }
800
801 /* W2: European numbers. */
802 if (this_type == FRIBIDI_TYPE_EN( 0x00000020L + 0x00000200L ) && last_strong == FRIBIDI_TYPE_AL( 0x00000010L + 0x00000100L + 0x00000001L + 0x00000002L ))
803 {
804 RL_TYPE( ( pp ) -> type ) (pp) = FRIBIDI_TYPE_AN( 0x00000020L + 0x00000200L + 0x00000002L );
805
806 /* Resolving dependency of loops for rules W1 and W2, so we
807 can merge them in one loop. */
808 if (next_type == FRIBIDI_TYPE_NSM( 0x00000020L + 0x00080000L ))
809 RL_TYPE( ( pp -> next ) -> type ) (pp->next) = FRIBIDI_TYPE_AN( 0x00000020L + 0x00000200L + 0x00000002L );
810 }
811 }
812
813
814 last_strong = base_dir;
815 /* Resolving dependency of loops for rules W4 and W5, W5 may
816 want to prevent W4 to take effect in the next turn, do this
817 through "w4". */
818 w4 = FRIBIDI_TRUE1;
819 /* Resolving dependency of loops for rules W4 and W5 with W7,
820 W7 may change an EN to L but it sets the prev_type_org if needed,
821 so W4 and W5 in next turn can still do their works. */
822 prev_type_org = FRIBIDI_TYPE_ON( 0x00000040L );
823
824 for (pp = type_rl_list->next; pp->next; pp = pp->next)
825 {
826 FriBidiCharType prev_type, this_type, next_type;
827
828 prev_type = PREV_TYPE_OR_SOR( ( ( pp -> prev ) -> level ) == ( ( pp ) -> level )
? ( ( pp -> prev ) -> type ) : ( ( 0x00000010L + 0x00000100L
) | ( ( ( ( ( pp -> prev ) -> level ) ) > ( ( ( pp )
-> level ) ) ? ( ( ( pp -> prev ) -> level ) ) : ( (
( pp ) -> level ) ) ) & 1 ) ) )
(pp);
829 this_type = RL_TYPE( ( pp ) -> type ) (pp);
830 next_type = NEXT_TYPE_OR_EOR( ! pp -> next ? ( ( 0x00000010L + 0x00000100L ) | ( ( ( pp
) -> level ) & 1 ) ) : ( ( ( pp -> next ) -> level
) == ( ( pp ) -> level ) ? ( ( pp -> next ) -> type
) : ( ( 0x00000010L + 0x00000100L ) | ( ( ( ( ( pp -> next
) -> level ) ) > ( ( ( pp ) -> level ) ) ? ( ( ( pp
-> next ) -> level ) ) : ( ( ( pp ) -> level ) ) ) &
1 ) ) ) )
(pp);
831
832 if (FRIBIDI_IS_STRONG( ( prev_type ) & 0x00000010L ) (prev_type))
833 last_strong = prev_type;
834
835 /* W3: Change ALs to R. */
836 if (this_type == FRIBIDI_TYPE_AL( 0x00000010L + 0x00000100L + 0x00000001L + 0x00000002L ))
837 {
838 RL_TYPE( ( pp ) -> type ) (pp) = FRIBIDI_TYPE_RTL( 0x00000010L + 0x00000100L + 0x00000001L );
839 w4 = FRIBIDI_TRUE1;
840 prev_type_org = FRIBIDI_TYPE_ON( 0x00000040L );
841 continue;
842 }
843
844 /* W4. A single european separator changes to a european number.
845 A single common separator between two numbers of the same type
846 changes to that type. */
847 if (w4
848 && RL_LEN( ( pp ) -> len ) (pp) == 1 && FRIBIDI_IS_ES_OR_CS( ( this_type ) & ( 0x00010000L | 0x00040000L ) ) (this_type)
849 && FRIBIDI_IS_NUMBER( ( prev_type_org ) & 0x00000200L ) (prev_type_org) && prev_type_org == next_type
850 && (prev_type_org == FRIBIDI_TYPE_EN( 0x00000020L + 0x00000200L )
851 || this_type == FRIBIDI_TYPE_CS( 0x00000020L + 0x00000400L + 0x00040000L )))
852 {
853 RL_TYPE( ( pp ) -> type ) (pp) = prev_type;
854 this_type = RL_TYPE( ( pp ) -> type ) (pp);
855 }
856 w4 = FRIBIDI_TRUE1;
857
858 /* W5. A sequence of European terminators adjacent to European
859 numbers changes to All European numbers. */
860 if (this_type == FRIBIDI_TYPE_ET( 0x00000020L + 0x00000400L + 0x00020000L )
861 && (prev_type_org == FRIBIDI_TYPE_EN( 0x00000020L + 0x00000200L )
862 || next_type == FRIBIDI_TYPE_EN( 0x00000020L + 0x00000200L )))
863 {
864 RL_TYPE( ( pp ) -> type ) (pp) = FRIBIDI_TYPE_EN( 0x00000020L + 0x00000200L );
865 w4 = FRIBIDI_FALSE0;
866 this_type = RL_TYPE( ( pp ) -> type ) (pp);
867 }
868
869 /* W6. Otherwise change separators and terminators to other neutral. */
870 if (FRIBIDI_IS_NUMBER_SEPARATOR_OR_TERMINATOR( ( this_type ) & 0x00000400L ) (this_type))
871 RL_TYPE( ( pp ) -> type ) (pp) = FRIBIDI_TYPE_ON( 0x00000040L );
872
873 /* W7. Change european numbers to L. */
874 if (this_type == FRIBIDI_TYPE_EN( 0x00000020L + 0x00000200L ) && last_strong == FRIBIDI_TYPE_LTR( 0x00000010L + 0x00000100L ))
875 {
876 RL_TYPE( ( pp ) -> type ) (pp) = FRIBIDI_TYPE_LTR( 0x00000010L + 0x00000100L );
877 prev_type_org = (RL_LEVEL( ( pp ) -> level ) (pp) == RL_LEVEL( ( pp -> next ) -> level ) (pp->next) ?
878 FRIBIDI_TYPE_EN( 0x00000020L + 0x00000200L ) : FRIBIDI_TYPE_ON( 0x00000040L ));
879 }
880 else
881 prev_type_org = PREV_TYPE_OR_SOR( ( ( pp -> next -> prev ) -> level ) == ( ( pp ->
next ) -> level ) ? ( ( pp -> next -> prev ) -> type
) : ( ( 0x00000010L + 0x00000100L ) | ( ( ( ( ( pp -> next
-> prev ) -> level ) ) > ( ( ( pp -> next ) ->
level ) ) ? ( ( ( pp -> next -> prev ) -> level ) )
: ( ( ( pp -> next ) -> level ) ) ) & 1 ) ) )
(pp->next);
882 }
883 }
884
885 compact_neutrals (type_rl_list);
886
887#ifdef DEBUG
888 if (fribidi_debug)
889 {
890 print_resolved_levels (type_rl_list);
891 print_resolved_types (type_rl_list);
892 }
893#endif
894
895 /* 5. Resolving Neutral Types */
896 DBG ("Resolving neutral types\n");
897 {
898 /* N1. and N2.
899 For each neutral, resolve it. */
900 for (pp = type_rl_list->next; pp->next; pp = pp->next)
901 {
902 FriBidiCharType prev_type, this_type, next_type;
903
904 /* "European and arabic numbers are treated as though they were R"
905 FRIBIDI_CHANGE_NUMBER_TO_RTL does this. */
906 this_type = FRIBIDI_CHANGE_NUMBER_TO_RTL( ( ( ( ( pp ) -> type ) ) & 0x00000200L ) ? ( 0x00000010L
+ 0x00000100L + 0x00000001L ) : ( ( ( pp ) -> type ) ) )
(RL_TYPE (pp));
907 prev_type = FRIBIDI_CHANGE_NUMBER_TO_RTL( ( ( ( ( ( pp -> prev ) -> level ) == ( ( pp ) -> level
) ? ( ( pp -> prev ) -> type ) : ( ( 0x00000010L + 0x00000100L
) | ( ( ( ( ( pp -> prev ) -> level ) ) > ( ( ( pp )
-> level ) ) ? ( ( ( pp -> prev ) -> level ) ) : ( (
( pp ) -> level ) ) ) & 1 ) ) ) ) & 0x00000200L )
? ( 0x00000010L + 0x00000100L + 0x00000001L ) : ( ( ( ( pp ->
prev ) -> level ) == ( ( pp ) -> level ) ? ( ( pp ->
prev ) -> type ) : ( ( 0x00000010L + 0x00000100L ) | ( ( (
( ( pp -> prev ) -> level ) ) > ( ( ( pp ) -> level
) ) ? ( ( ( pp -> prev ) -> level ) ) : ( ( ( pp ) ->
level ) ) ) & 1 ) ) ) ) )
(PREV_TYPE_OR_SOR (pp));
908 next_type = FRIBIDI_CHANGE_NUMBER_TO_RTL( ( ( ( ! pp -> next ? ( ( 0x00000010L + 0x00000100L ) | (
( ( pp ) -> level ) & 1 ) ) : ( ( ( pp -> next ) ->
level ) == ( ( pp ) -> level ) ? ( ( pp -> next ) ->
type ) : ( ( 0x00000010L + 0x00000100L ) | ( ( ( ( ( pp ->
next ) -> level ) ) > ( ( ( pp ) -> level ) ) ? ( (
( pp -> next ) -> level ) ) : ( ( ( pp ) -> level )
) ) & 1 ) ) ) ) ) & 0x00000200L ) ? ( 0x00000010L + 0x00000100L
+ 0x00000001L ) : ( ( ! pp -> next ? ( ( 0x00000010L + 0x00000100L
) | ( ( ( pp ) -> level ) & 1 ) ) : ( ( ( pp -> next
) -> level ) == ( ( pp ) -> level ) ? ( ( pp -> next
) -> type ) : ( ( 0x00000010L + 0x00000100L ) | ( ( ( ( (
pp -> next ) -> level ) ) > ( ( ( pp ) -> level )
) ? ( ( ( pp -> next ) -> level ) ) : ( ( ( pp ) ->
level ) ) ) & 1 ) ) ) ) ) )
(NEXT_TYPE_OR_EOR (pp));
909
910 if (FRIBIDI_IS_NEUTRAL( ( this_type ) & 0x00000040L ) (this_type))
911 RL_TYPE( ( pp ) -> type ) (pp) = (prev_type == next_type) ?
912 /* N1. */ prev_type :
913 /* N2. */ FRIBIDI_EMBEDDING_DIRECTION( ( 0x00000010L + 0x00000100L ) | ( ( ( pp ) -> level ) &
1 ) )
(pp);
914 }
915 }
916
917 compact_list (type_rl_list);
918
919#ifdef DEBUG
920 if (fribidi_debug)
921 {
922 print_resolved_levels (type_rl_list);
923 print_resolved_types (type_rl_list);
924 }
925#endif
926
927 /* 6. Resolving implicit levels */
928 DBG ("Resolving implicit levels\n");
929 {
930 max_level = base_level;
931
932 for (pp = type_rl_list->next; pp->next; pp = pp->next)
933 {
934 FriBidiCharType this_type;
935 int level;
936
937 this_type = RL_TYPE( ( pp ) -> type ) (pp);
938 level = RL_LEVEL( ( pp ) -> level ) (pp);
939
940 /* I1. Even */
941 /* I2. Odd */
942 if (FRIBIDI_IS_NUMBER( ( this_type ) & 0x00000200L ) (this_type))
943 RL_LEVEL( ( pp ) -> level ) (pp) = (level + 2) & ~1;
944 else
945 RL_LEVEL( ( pp ) -> level ) (pp) = (level ^ FRIBIDI_DIR_TO_LEVEL( ( FriBidiLevel ) ( this_type & 1 ) ) (this_type)) +
946 (level & 1);
947
948 if (RL_LEVEL( ( pp ) -> level ) (pp) > max_level)
949 max_level = RL_LEVEL( ( pp ) -> level ) (pp);
950 }
951 }
952
953 compact_list (type_rl_list);
954
955#ifdef DEBUG
956 if (fribidi_debug)
957 {
958 print_bidi_string (str);
959 print_resolved_levels (type_rl_list);
960 print_resolved_types (type_rl_list);
961 }
962#endif
963
964/* Reinsert the explicit codes & bn's that already removed, from the
965 explicits_list to type_rl_list. */
966 DBG ("Reinserting explicit codes\n");
967 {
968 TypeLink *p;
969
970 override_list (type_rl_list, explicits_list);
971 p = type_rl_list->next;
972 if (p->level < 0)
973 p->level = base_level;
974 for (; p->next; p = p->next)
975 if (p->level < 0)
976 p->level = p->prev->level;
977 }
978
979#ifdef DEBUG
980 if (fribidi_debug)
981 {
982 print_types_re (type_rl_list);
983 print_resolved_levels (type_rl_list);
984 print_resolved_types (type_rl_list);
985 }
986#endif
987
988 DBG ("Reset the embedding levels\n");
989 {
990 int j, k, state, pos;
991 TypeLink *p, *q, *list, *list_end;
992
993 /* L1. Reset the embedding levels of some chars. */
994 init_list (&list, &list_end);
995 q = list_end;
996 state = 1;
997 pos = len - 1;
998 for (j = len - 1; j >= -1; j--)
999 {
1000 /* if state is on at the very first of string, do this too. */
1001 if (j >= 0)
1002 k = fribidi_get_type (str[j]);
1003 else
1004 k = FRIBIDI_TYPE_ON( 0x00000040L );
1005 if (!state && FRIBIDI_IS_SEPARATOR( ( k ) & 0x00002000L ) (k))
1006 {
1007 state = 1;
1008 pos = j;
1009 }
1010 else if (state && !FRIBIDI_IS_EXPLICIT_OR_SEPARATOR_OR_BN_OR_WS( ( k ) & ( 0x00001000L | 0x00002000L | 0x00100000L | 0x00800000L
) )
(k))
1011 {
1012 state = 0;
1013 p = new_type_link ();
1014 p->prev = p->next = NULL( ( void * ) 0 );
1015 p->pos = j + 1;
1016 p->len = pos - j;
1017 p->type = base_dir;
1018 p->level = base_level;
1019 move_element_before (p, q);
1020 q = p;
1021 }
1022 }
1023 override_list (type_rl_list, list);