Implemented attrlistInsertCharactersUnattributed().
This commit is contained in:
parent
fee06b9553
commit
78f5ca5eb5
|
@ -202,6 +202,29 @@ static void attrGrow(struct attrlist *alist, struct attr *a, size_t start, size_
|
||||||
attrInsertBefore(alist, a, before);
|
attrInsertBefore(alist, a, before);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns the right side of the split, which is unlinked, or NULL if no split was done
|
||||||
|
static struct attr *attrSplitAt(struct attrlist *alist, struct attr *a, size_t at)
|
||||||
|
{
|
||||||
|
struct attr *b;
|
||||||
|
|
||||||
|
// no splittng needed?
|
||||||
|
// note the equality: we don't need to split at start or end
|
||||||
|
// in the end case, the last split point is at - 1; at itself is outside the range, and at - 1 results in the right hand side having length 1
|
||||||
|
if (at <= a->start)
|
||||||
|
return NULL;
|
||||||
|
if (at >= a->end)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
b = uiNew(struct attr);
|
||||||
|
b->type = a->type;
|
||||||
|
b->val = a->val;
|
||||||
|
b->start = at;
|
||||||
|
b->end = a->end;
|
||||||
|
|
||||||
|
a->end = at;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
void attrlistInsertAt(struct attrlist *alist, uiAttribute type, uintptr_t val, size_t start, size_t end)
|
void attrlistInsertAt(struct attrlist *alist, uiAttribute type, uintptr_t val, size_t start, size_t end)
|
||||||
{
|
{
|
||||||
struct attr *a;
|
struct attr *a;
|
||||||
|
@ -266,13 +289,58 @@ void attrlistInsertAt(struct attrlist *alist, uiAttribute type, uintptr_t val, s
|
||||||
attrInsertBefore(alist, tail, before);
|
attrInsertBefore(alist, tail, before);
|
||||||
}
|
}
|
||||||
|
|
||||||
void attrlistInsertCharacters(struct attrlist *alist, size_t start, size_t end)
|
void attrlistInsertCharactersUnattributed(struct attrlist *alist, size_t start, size_t count)
|
||||||
{
|
{
|
||||||
|
struct attr *a;
|
||||||
|
struct attr *tails = NULL;
|
||||||
|
|
||||||
|
// every attribute before the insertion point can either cross into the insertion point or not
|
||||||
|
// if it does, we need to split that attribute apart at the insertion point, keeping only the old attribute in place, adjusting the new tail, and preparing it for being re-added later
|
||||||
|
for (a = alist->first; a != NULL; a = a->next) {
|
||||||
|
struct attr *tail;
|
||||||
|
|
||||||
|
// stop once we get to the insertion point
|
||||||
|
if (a->start >= start)
|
||||||
|
break;
|
||||||
|
// only do something if overlapping
|
||||||
|
if (!attrHasPos(a, start))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
tail = attrSplitAt(alist, a, start);
|
||||||
|
// adjust the new tail for the insertion
|
||||||
|
tail->start += count;
|
||||||
|
tail->end += count;
|
||||||
|
// and queue it for re-adding later
|
||||||
|
// we can safely use tails as if it was singly-linked since it's just a temporary list; we properly merge them back in below and they'll be doubly-linked again then
|
||||||
|
// TODO actually we could probably save some time by making then doubly-linked now and adding them in one fell swoop, but that would make things a bit more complicated...
|
||||||
|
tail->next = tails;
|
||||||
|
tails = tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
// at this point in the attribute list, we are at or after the insertion point
|
||||||
|
// all the split-apart attributes will be at the insertion point
|
||||||
|
// therefore, we can just add them all back now, and the list will still be sorted correctly
|
||||||
|
while (tails != NULL) {
|
||||||
|
struct attr *next;
|
||||||
|
|
||||||
|
// make all the links NULL before insertion, just to be safe
|
||||||
|
next = tails->next;
|
||||||
|
tails->next = NULL;
|
||||||
|
attrInsertBefore(alist, tails, a);
|
||||||
|
tails = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// every remaining attribute will be either at or after the insertion point
|
||||||
|
// we just need to move them ahead
|
||||||
|
for (; a != NULL; a = a->next) {
|
||||||
|
a->start += count;
|
||||||
|
a->end += count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The attributes are those of character start - 1.
|
// The attributes are those of character start - 1.
|
||||||
// If start == 0, the attributes are those of character 0.
|
// If start == 0, the attributes are those of character 0.
|
||||||
void attrlistInsertCharactersExtendingAttributes(struct attrlist *alist, size_t start, size_t end)
|
void attrlistInsertCharactersExtendingAttributes(struct attrlist *alist, size_t start, size_t count)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue