Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
emacs
emacs
Commits
45d82bdc
Commit
45d82bdc
authored
Feb 04, 1994
by
Karl Heuer
Browse files
Add comments describing the rules used by the merge algorithm.
parent
ee095968
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
102 additions
and
46 deletions
+102
-46
src/intervals.c
src/intervals.c
+102
-46
No files found.
src/intervals.c
View file @
45d82bdc
...
...
@@ -47,6 +47,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* The rest of the file is within this conditional. */
#ifdef USE_TEXT_PROPERTIES
/* Test for membership, allowing for t (actually any non-cons) to mean the
universal set. */
#define TMEM(sym, set) (CONSP (set) ? ! NILP (Fmemq (sym, set)) : ! NILP (set))
/* Factor for weight-balancing interval trees. */
Lisp_Object interval_balance_threshold;
...
...
@@ -846,61 +851,105 @@ adjust_intervals_for_insertion (tree, position, length)
return tree;
}
/* Any property might be front-sticky on the left, rear-sticky on the left,
front-sticky on the right, or rear-sticky on the right; the 16 combinations
can be arranged in a matrix with rows denoting the left conditions and
columns denoting the right conditions:
_ __ _
_ FR FR FR FR
FR__ 0 1 2 3
_FR 4 5 6 7
FR 8 9 A B
FR C D E F
left-props = '(front-sticky (p8 p9 pa pb pc pd pe pf)
rear-nonsticky (p4 p5 p6 p7 p8 p9 pa pb)
p0 L p1 L p2 L p3 L p4 L p5 L p6 L p7 L
p8 L p9 L pa L pb L pc L pd L pe L pf L)
right-props = '(front-sticky (p2 p3 p6 p7 pa pb pe pf)
rear-nonsticky (p1 p2 p5 p6 p9 pa pd pe)
p0 R p1 R p2 R p3 R p4 R p5 R p6 R p7 R
p8 R p9 R pa R pb R pc R pd R pe R pf R)
We inherit from whoever has a sticky side facing us. If both sides
do (cases 2, 3, E, and F), then we inherit from whichever side has a
non-nil value for the current property. If both sides do, then we take
from the left.
When we inherit a property, we get its stickiness as well as its value.
So, when we merge the above two lists, we expect to get this:
result = '(front-sticky (p6 p7 pa pb pc pd pe pf)
rear-nonsticky (p6 pa)
p0 L p1 L p2 L p3 L p6 R p7 R
pa R pb R pc L pd L pe L pf L)
The optimizable special cases are:
left rear-nonsticky = nil, right front-sticky = nil (inherit left)
left rear-nonsticky = t, right front-sticky = t (inherit right)
left rear-nonsticky = t, right front-sticky = nil (inherit none)
*/
Lisp_Object
merge_properties_sticky (pleft, pright)
Lisp_Object pleft, pright;
{
register Lisp_Object props = Qnil, front = Qnil, rear = Qnil;
Lisp_Object lfront = textget (pleft, Qfront_sticky);
Lisp_Object lrear = textget (pleft, Qrear_nonsticky);
Lisp_Object rfront = textget (pright, Qfront_sticky);
Lisp_Object rrear = textget (pright, Qrear_nonsticky);
register Lisp_Object tail1, tail2, sym;
register Lisp_Object tail1, tail2, sym, lval, rval;
int use_left, use_right;
/* Go through each element of P
LEF
T. */
for (tail1 = p
lef
t; ! NILP (tail1); tail1 = Fcdr (Fcdr (tail1)))
/* Go through each element of P
RIGH
T. */
for (tail1 = p
righ
t; ! NILP (tail1); tail1 = Fcdr (Fcdr (tail1)))
{
sym = Fcar (tail1);
/* Sticky properties get special treatment. */
if (EQ (sym, Qrear_nonsticky) || EQ (sym, Qfront_sticky))
continue;
if (CONSP (lrear) ? NILP (Fmemq (sym, lrear)) : NILP (lrear))
rval = Fcar (Fcdr (tail1));
for (tail2 = pleft; ! NILP (tail2); tail2 = Fcdr (Fcdr (tail2)))
if (EQ (sym, Fcar (tail2)))
break;
lval = (NILP (tail2) ? Qnil : Fcar( Fcdr (tail2)));
use_left = ! TMEM (sym, lrear);
use_right = TMEM (sym, rfront);
if (use_left && use_right)
{
use_left = ! NILP (lval);
use_right = ! NILP (rval);
}
if (use_left)
{
/*
rear-sticky is dominant, we needn't search in PRIGHT. */
props = Fcons (sym, Fcons (Fcar (Fcdr (tail1)), props));
if ((CONSP (lfront) || NILP (lfront))
&& ! NILP (Fmemq
(sym, lfront))
)
/*
We build props as (value sym ...) rather than (sym value ...)
because we plan to nreverse it when we're done. */
if (! NILP (lval))
props = Fcons (lval, Fcons (sym, props));
if (TMEM
(sym, lfront))
front = Fcons (sym, front);
if (TMEM (sym, lrear))
rear = Fcons (sym, rear);
}
else
else
if (use_right)
{
/* Go through PRIGHT, looking for sym. */
for (tail2 = pright; ! NILP (tail2); tail2 = Fcdr (Fcdr (tail2)))
if (EQ (sym, Fcar (tail2)))
{
if (CONSP (rfront)
? ! NILP (Fmemq (sym, rfront)) : ! NILP (rfront))
{
/* Nonsticky at the left and sticky at the right,
so take the right one. */
props = Fcons (sym, Fcons (Fcar (Fcdr (tail2)), props));
front = Fcons (sym, front);
if ((CONSP (rrear) || NILP (rrear))
&& ! NILP (Fmemq (sym, rrear)))
rear = Fcons (sym, rear);
}
break;
}
if (! NILP (rval))
props = Fcons (rval, Fcons (sym, props));
if (TMEM (sym, rfront))
front = Fcons (sym, front);
if (TMEM (sym, rrear))
rear = Fcons (sym, rear);
}
}
/* Now let's see what to keep from PRIGHT. */
for (tail2 = pright; ! NILP (tail2); tail2 = Fcdr (Fcdr (tail2)))
/* Now go through each element of PLEFT. */
for (tail2 = pleft; ! NILP (tail2); tail2 = Fcdr (Fcdr (tail2)))
{
sym = Fcar (tail2);
...
...
@@ -908,30 +957,37 @@ merge_properties_sticky (pleft, pright)
if (EQ (sym, Qrear_nonsticky) || EQ (sym, Qfront_sticky))
continue;
/* If it ain't sticky, we don't take it. */
if (CONSP (rfront)
? NILP (Fmemq (sym, rfront)) : NILP (rfront))
continue;
/* If sym is in PLEFT we already got it. */
for (tail1 = pleft; ! NILP (tail1); tail1 = Fcdr (Fcdr (tail1)))
/* If sym is in PRIGHT, we've already considered it. */
for (tail1 = pright; ! NILP (tail1); tail1 = Fcdr (Fcdr (tail1)))
if (EQ (sym, Fcar (tail1)))
break;
if (NILP (tail1))
if (! NILP (tail1))
continue;
lval = Fcar (Fcdr (tail2));
/* Since rval is known to be nil in this loop, the test simplifies. */
if (! TMEM (sym, lrear))
{
props = Fcons (sym, Fcons (Fcar (Fcdr (tail2)), props));
if (! NILP (lval))
props = Fcons (lval, Fcons (sym, props));
if (TMEM (sym, lfront))
front = Fcons (sym, front);
}
else if (TMEM (sym, rfront))
{
/* The value is nil, but we still inherit the stickiness
from the right. */
front = Fcons (sym, front);
if ((CONSP (rrear) || NILP (rrear))
&& ! NILP (Fmemq (sym, rrear)))
if (TMEM (sym, rrear))
rear = Fcons (sym, rear);
}
}
props = Fnreverse (props);
if (! NILP (front))
props = Fcons (Qfront_sticky, Fcons (Fnreverse (front), props));
if (! NILP (rear))
props = Fcons (Qrear_nonsticky, Fcons (Fnreverse (rear), props));
if (! NILP (front))
props = Fcons (Qfront_sticky, Fcons (Fnreverse (front), props));
return props;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment