And finished implementing attrlistInsertAt(). Woo!

This commit is contained in:
Pietro Gagliardi 2016-12-18 14:06:37 -05:00
parent 75525196b1
commit 5c96266c7c
1 changed files with 28 additions and 4 deletions

View File

@ -15,7 +15,7 @@ struct attrlist {
}; };
// if before is NULL, add to the end of the list // if before is NULL, add to the end of the list
static void linkInsertBefore(struct attrlist *alist, struct attr *a, struct attr *before) static void attrInsertBefore(struct attrlist *alist, struct attr *a, struct attr *before)
{ {
// if the list is empty, this is the first item // if the list is empty, this is the first item
if (alist->first == NULL) { if (alist->first == NULL) {
@ -180,6 +180,29 @@ static int attrDropRange(struct attrlist *alist, struct attr *a, size_t start, s
return 2; return 2;
} }
static void attrGrow(struct attrlist *alist, struct attr *a, size_t start, size_t end)
{
struct attr *before;
struct attr *unused;
// adjusting the end is simple: if it ends before our new end, just set the new end
if (a->end < end)
a->end = end;
// adjusting the start is harder
// if the start is before our new start, we are done
// otherwise, we have to move the start back AND reposition the attribute to keep the sorted order
if (a->start <= start)
return;
a->start = start;
// TODO could we just return next?
attrUnlink(alist, a, &unused);
for (before = alist->first; before != NULL; before = before->next)
if (before->start > a->start)
break;
attrInsertBefore(alist, a, before);
}
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;
@ -211,8 +234,9 @@ void attrlistInsertAt(struct attrlist *alist, uiAttribute type, uintptr_t val, s
// okay so this might conflict; if the val is the same as the one we want, we need to expand the existing attribute, not fragment anything // okay so this might conflict; if the val is the same as the one we want, we need to expand the existing attribute, not fragment anything
// TODO this might cause problems with system specific attributes, if we support those; maybe also user-specific? // TODO this might cause problems with system specific attributes, if we support those; maybe also user-specific?
// TODO will this cause problems with fonts?
if (before->val == val) { if (before->val == val) {
// TODO attrGrow(alist, a, start, end);
return; return;
} }
// okay the values are different; we need to split apart // okay the values are different; we need to split apart
@ -230,7 +254,7 @@ void attrlistInsertAt(struct attrlist *alist, uiAttribute type, uintptr_t val, s
a->val = val; a->val = val;
a->start = start; a->start = start;
a->end = end; a->end = end;
linkInsertBefore(alist, a, before); attrInsertBefore(alist, a, before);
// and finally, if we split, insert the remainder // and finally, if we split, insert the remainder
if (tail == NULL) if (tail == NULL)
@ -239,5 +263,5 @@ void attrlistInsertAt(struct attrlist *alist, uiAttribute type, uintptr_t val, s
for (; before != NULL; before = before->next) for (; before != NULL; before = before->next)
if (before->start > tail->start) if (before->start > tail->start)
break; break;
linkInsertBefore(alist, tail, before); attrInsertBefore(alist, tail, before);
} }