Finished filling in exp_attrdll.c. I think this will stay.
This commit is contained in:
parent
0078615662
commit
ab8aa9266e
|
@ -156,19 +156,23 @@ static struct attr *attrDropRange(struct attrlist *alist, struct attr *a, size_t
|
|||
return a->next;
|
||||
|
||||
// just outright delete the attribute?
|
||||
if (a->start == start && a->end == end)
|
||||
// the inequalities handle attributes entirely inside the range
|
||||
// if both are equal, the attribute's range is equal to the range
|
||||
if (a->start >= start && a->end <= end)
|
||||
return attrDelete(alist, a);
|
||||
|
||||
// only chop off the start or end?
|
||||
if (a->start == start) { // chop off the end
|
||||
a->end = end;
|
||||
return a->next;
|
||||
}
|
||||
if (a->end == end) { // chop off the start
|
||||
a->start = start;
|
||||
if (a->start == start) { // chop off the start
|
||||
// we are dropping the left half, so set a->start and unlink
|
||||
a->start = end;
|
||||
*tail = a;
|
||||
return attrUnlink(attr, a);
|
||||
}
|
||||
if (a->end == end) { // chop off the end
|
||||
// we are dropping the right half, so just set a->end
|
||||
a->end = start;
|
||||
return a->next;
|
||||
}
|
||||
|
||||
// we'll need to split the attribute into two
|
||||
b = uiNew(struct attr);
|
||||
|
@ -226,6 +230,61 @@ static struct attr *attrSplitAt(struct attrlist *alist, struct attr *a, size_t a
|
|||
return b;
|
||||
}
|
||||
|
||||
// attrDeleteRange() removes attributes while deleting characters.
|
||||
//
|
||||
// If the attribute does not include the deleted range, then nothing is done (though the start and end are adjusted as necessary).
|
||||
//
|
||||
// If the attribute needs to be deleted, it is deleted.
|
||||
//
|
||||
// Otherwise, the attribute only needs the start or end deleted, and it is adjusted.
|
||||
//
|
||||
// In all cases, the return value is the next attribute to look at in a forward sequential loop.
|
||||
// TODO rewrite this comment
|
||||
static struct attr *attrDeleteRange(struct attrlist *alist, struct attr *a, size_t start, size_t end)
|
||||
{
|
||||
size_t ostart, oend;
|
||||
size_t count;
|
||||
|
||||
ostart = start;
|
||||
oend = end;
|
||||
count = oend - ostart;
|
||||
|
||||
if (!attrRangeIntersect(a, &start, &end)) {
|
||||
// out of range
|
||||
// adjust if necessary
|
||||
if (a->start >= ostart)
|
||||
a->start -= count;
|
||||
if (a->end >= oend)
|
||||
a->end -= count;
|
||||
return a->next;
|
||||
}
|
||||
|
||||
// just outright delete the attribute?
|
||||
// the inequalities handle attributes entirely inside the range
|
||||
// if both are equal, the attribute's range is equal to the range
|
||||
if (a->start >= start && a->end <= end)
|
||||
return attrDelete(alist, a);
|
||||
|
||||
// only chop off the start or end?
|
||||
if (a->start == start) { // chop off the start
|
||||
// if we weren't adjusting positions this would just be setting a->start to end
|
||||
// but since this is deleting from the start, we need to adjust both by count
|
||||
a->start = end - count;
|
||||
a->end -= count;
|
||||
return a->next;
|
||||
}
|
||||
if (a->end == end) { // chop off the end
|
||||
// a->start is already good
|
||||
a->end = start;
|
||||
return a->next;
|
||||
}
|
||||
|
||||
// in this case, the deleted range is inside the attribute
|
||||
// we can clear it by just removing count from a->end
|
||||
a->end -= count;
|
||||
return a->next;
|
||||
}
|
||||
|
||||
void attrlistInsertAt(struct attrlist *alist, uiAttribute type, uintptr_t val, size_t start, size_t end)
|
||||
{
|
||||
struct attr *a;
|
||||
|
@ -464,10 +523,55 @@ void attrlistRemoveAttribute(struct attrlist *alist, uiAttribute type, size_t st
|
|||
}
|
||||
}
|
||||
|
||||
// TODO merge this with the above
|
||||
void attrlistRemoveAttributes(struct attrlist *alist, size_t start, size_t end)
|
||||
{
|
||||
struct attr *a;
|
||||
struct attr *tails = NULL; // see attrlistInsertCharactersUnattributed() above
|
||||
struct attr *tailsAt = NULL;
|
||||
|
||||
a = alist->start;
|
||||
while (a != NULL) {
|
||||
size_t lstart, lend;
|
||||
|
||||
// this defines where to re-attach the tails
|
||||
// (all the tails will have their start at end, so we can just insert them all before tailsAt)
|
||||
if (a->start >= end) {
|
||||
tailsAt = a;
|
||||
// and at this point we're done, so
|
||||
break;
|
||||
}
|
||||
lstart = start;
|
||||
lend = end;
|
||||
if (!attrRangeIntersect(a, &lstart, &lend))
|
||||
goto next;
|
||||
a = attrDropRange(alist, a, start, end, &tail);
|
||||
if (tail != NULL) {
|
||||
tail->next = tails;
|
||||
tails = tail;
|
||||
}
|
||||
continue;
|
||||
|
||||
next:
|
||||
a = a->next;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void attrlistRemoveCharacters(struct attrlist *alist, size_t start, size_t end)
|
||||
{
|
||||
struct attr *a;
|
||||
|
||||
a = alist->first;
|
||||
while (a != NULL)
|
||||
a = attrDeleteRange(alist, a, start, end);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue