6 static struct rset
*dir_rslr
; /* pattern of marks for left-to-right strings */
7 static struct rset
*dir_rsrl
; /* pattern of marks for right-to-left strings */
8 static struct rset
*dir_rsctx
; /* direction context patterns */
10 static int dir_match(char **chrs
, int beg
, int end
, int ctx
, int *rec
,
11 int *r_beg
, int *r_end
, int *c_beg
, int *c_end
, int *dir
)
14 struct rset
*rs
= ctx
< 0 ? dir_rsrl
: dir_rslr
;
15 struct sbuf
*str
= sbuf_make();
17 int flg
= (beg
? RE_NOTBOL
: 0) | (chrs
[end
][0] ? RE_NOTEOL
: 0);
19 sbuf_mem(str
, chrs
[beg
], chrs
[end
] - chrs
[beg
]);
20 found
= rset_find(rs
, sbuf_buf(str
), LEN(subs
) / 2, subs
, flg
);
21 if (found
>= 0 && r_beg
&& r_end
&& c_beg
&& c_end
) {
22 char *s
= sbuf_buf(str
);
23 conf_dirmark(found
, NULL
, NULL
, dir
, &grp
);
24 *r_beg
= beg
+ uc_off(s
, subs
[0]);
25 *r_end
= beg
+ uc_off(s
, subs
[1]);
26 *c_beg
= subs
[grp
* 2 + 0] >= 0 ?
27 beg
+ uc_off(s
, subs
[grp
* 2 + 0]) : *r_beg
;
28 *c_end
= subs
[grp
* 2 + 1] >= 0 ?
29 beg
+ uc_off(s
, subs
[grp
* 2 + 1]) : *r_end
;
36 static void dir_reverse(int *ord
, int beg
, int end
)
48 /* reorder the characters based on direction marks and characters */
49 static void dir_fix(char **chrs
, int *ord
, int dir
, int beg
, int end
)
51 int r_beg
, r_end
, c_beg
, c_end
;
53 while (beg
< end
&& !dir_match(chrs
, beg
, end
, dir
, &c_rec
,
54 &r_beg
, &r_end
, &c_beg
, &c_end
, &c_dir
)) {
56 dir_reverse(ord
, r_beg
, r_end
);
58 dir_reverse(ord
, c_beg
, c_end
);
62 dir_fix(chrs
, ord
, c_dir
, c_beg
, c_end
);
67 int dir_context(char *s
)
75 found
= rset_find(dir_rsctx
, s
? s
: "", 0, NULL
, 0);
76 if (!conf_dircontext(found
, NULL
, &dir
))
78 return xdir
< 0 ? -1 : +1;
81 /* reorder the characters in s */
82 void dir_reorder(char *s
, int *ord
)
85 char **chrs
= uc_chop(s
, &n
);
86 int dir
= dir_context(s
);
87 if (n
&& chrs
[n
- 1][0] == '\n') {
91 dir_fix(chrs
, ord
, dir
, 0, n
);
102 for (i
= 0; !conf_dirmark(i
, &pat
, &curctx
, NULL
, NULL
); i
++) {
103 relr
[i
] = curctx
>= 0 ? pat
: NULL
;
104 rerl
[i
] = curctx
<= 0 ? pat
: NULL
;
106 dir_rslr
= rset_make(i
, relr
, 0);
107 dir_rsrl
= rset_make(i
, rerl
, 0);
108 for (i
= 0; !conf_dircontext(i
, &pat
, NULL
); i
++)
110 dir_rsctx
= rset_make(i
, ctx
, 0);
117 rset_free(dir_rsctx
);