Object Sdr_list_insert_last(char *file, int line, Sdr sdrv, Object list, Address data) { SdrList listBuffer; Object elt; SdrListElt eltBuffer; if (!(sdr_in_xn(sdrv))) { oK(_iEnd(file, line, _notInXnMsg())); return 0; } joinTrace(sdrv, file, line); if (list == 0) { oK(_xniEnd(file, line, "list", sdrv)); return 0; } /* create new element */ elt = _sdrzalloc(sdrv, sizeof(SdrListElt)); if (elt == 0) { oK(_iEnd(file, line, "elt")); return 0; } sdr_list__elt_clear(&eltBuffer); eltBuffer.list = list; eltBuffer.data = data; /* insert new element at the end of the list */ sdrFetch(listBuffer, (Address) list); eltBuffer.prev = listBuffer.last; eltBuffer.next = 0; sdrPut((Address) elt, eltBuffer); if (listBuffer.last != 0) { sdrFetch(eltBuffer, (Address) listBuffer.last); eltBuffer.next = elt; sdrPut((Address) listBuffer.last, eltBuffer); } else { listBuffer.first = elt; } listBuffer.last = elt; listBuffer.length += 1; sdrPut((Address) list, listBuffer); return elt; }
Object Sdr_list_insert(char *file, int line, Sdr sdrv, Object list, Address data, SdrListCompareFn compare, void *argData) { SdrList listBuffer; SdrListElt eltBuffer; Object elt; if (!(sdr_in_xn(sdrv))) { oK(_iEnd(file, line, _notInXnMsg())); return 0; } if (list == 0) { oK(_xniEnd(file, line, "list", sdrv)); return 0; } /* If not sorted list, just append to the end of the list. */ if (compare == (SdrListCompareFn) NULL) { return Sdr_list_insert_last(file, line, sdrv, list, data); } /* Application claims that this list is sorted. Find * position to insert new data into list. Start from end * of list to keep sort stable; sort sequence is implicitly * FIFO within key, i.e., we insert element AFTER the last * element in the table with the same key value. */ sdrFetch(listBuffer, (Address) list); for (elt = listBuffer.last; elt != 0; elt = eltBuffer.prev) { sdrFetch(eltBuffer, (Address) elt); if (compare(sdrv, eltBuffer.data, argData) <= 0) break; } /* Insert into list at this point. */ if (elt == 0) { return Sdr_list_insert_first(file, line, sdrv, list, data); } return Sdr_list_insert_after(file, line, sdrv, elt, data); }
Address sdr_list_data(Sdr sdrv, Object elt) { SdrListElt eltBuffer; CHKZERO(elt); sdrFetch(eltBuffer, (Address) elt); return eltBuffer.data; }
Object sdr_list_list(Sdr sdrv, Object elt) { SdrListElt eltBuffer; CHKZERO(elt); sdrFetch(eltBuffer, (Address) elt); return eltBuffer.list; }
long sdr_list_length(Sdr sdrv, Object list) { SdrList listBuffer; CHKERR(list); sdrFetch(listBuffer, list); return listBuffer.length; }
Address sdr_list_user_data(Sdr sdrv, Object list) { SdrList listBuffer; CHKZERO(list); sdrFetch(listBuffer, list); return listBuffer.userData; }
Object sdr_list_prev(Sdr sdrv, Object elt) { SdrListElt eltBuffer; CHKZERO(sdrFetchSafe(sdrv)); CHKZERO(elt); sdrFetch(eltBuffer, (Address) elt); return eltBuffer.prev; }
Object sdr_list_last(Sdr sdrv, Object list) { SdrList listBuffer; CHKZERO(sdrFetchSafe(sdrv)); CHKZERO(list); sdrFetch(listBuffer, (Address) list); return listBuffer.last; }
void Sdr_list_destroy(char *file, int line, Sdr sdrv, Object list, SdrListDeleteFn deleteFn, void *arg) { SdrList listBuffer; Object elt; Object next; SdrListElt eltBuffer; if (!(sdr_in_xn(sdrv))) { oK(_iEnd(file, line, _notInXnMsg())); return; } joinTrace(sdrv, file, line); if (list == 0) { oK(_xniEnd(file, line, "list", sdrv)); return; } sdrFetch(listBuffer, (Address) list); for (elt = listBuffer.first; elt != 0; elt = next) { sdrFetch(eltBuffer, (Address) elt); next = eltBuffer.next; if (deleteFn) { deleteFn(sdrv, eltBuffer.data, arg); } /* just in case user mistakenly accesses later... */ sdr_list__elt_clear(&eltBuffer); sdrPut((Address) elt, eltBuffer); sdrFree(elt); } /* just in case user mistakenly accesses later... */ sdr_list__clear(&listBuffer); sdrPut((Address) list, listBuffer); sdrFree(list); }
long sdr_list_length(Sdr sdrv, Object list) { SdrState *sdr; SdrList listBuffer; CHKERR(sdrv); CHKERR(list); sdr = sdrv->sdr; CHKERR(takeSdr(sdr) == 0); sdrFetch(listBuffer, list); releaseSdr(sdr); return listBuffer.length; }
Object sdr_list_last(Sdr sdrv, Object list) { SdrState *sdr; SdrList listBuffer; CHKZERO(sdrv); CHKZERO(list); sdr = sdrv->sdr; CHKZERO(takeSdr(sdr) == 0); sdrFetch(listBuffer, (Address) list); releaseSdr(sdr); return listBuffer.last; }
Address sdr_list_data(Sdr sdrv, Object elt) { SdrState *sdr; SdrListElt eltBuffer; CHKZERO(sdrv); CHKZERO(elt); sdr = sdrv->sdr; CHKZERO(takeSdr(sdr) == 0); sdrFetch(eltBuffer, (Address) elt); releaseSdr(sdr); return eltBuffer.data; }
Address sdr_list_user_data(Sdr sdrv, Object list) { SdrState *sdr; SdrList listBuffer; CHKZERO(sdrv); CHKZERO(list); sdr = sdrv->sdr; CHKZERO(takeSdr(sdr) == 0); sdrFetch(listBuffer, list); releaseSdr(sdr); return listBuffer.userData; }
void Sdr_list_user_data_set(char *file, int line, Sdr sdrv, Object list, Address data) { SdrList listBuffer; if (!(sdr_in_xn(sdrv))) { oK(_iEnd(file, line, _notInXnMsg())); return; } joinTrace(sdrv, file, line); if (list == 0) { oK(_xniEnd(file, line, "list", sdrv)); return; } sdrFetch(listBuffer, list); listBuffer.userData = data; sdrPut((Address) list, listBuffer); }
Object sdr_list_search(Sdr sdrv, Object fromElt, int reverse, SdrListCompareFn compare, void *arg) { Object eltAddr; SdrListElt elt; int result; CHKZERO(sdrv); CHKZERO(fromElt); if (compare) /* list assumed sorted; bail early if possible */ { if (reverse) { for (eltAddr = fromElt; eltAddr != 0; eltAddr = elt.prev) { sdrFetch(elt, (Address) eltAddr); result = compare(sdrv, elt.data, arg); if (result < 0) { /* past any possible match */ return 0; } if (result == 0) { return eltAddr; } } } else { for (eltAddr = fromElt; eltAddr != 0; eltAddr = elt.next) { sdrFetch(elt, (Address) eltAddr); result = compare(sdrv, elt.data, arg); if (result > 0) { /* past any possible match */ return 0; } if (result == 0) { return eltAddr; } } } return 0; /* end of list reached */ } /* Use "==" since no comparison function was provided. */ if (reverse) { for (eltAddr = fromElt; eltAddr != 0; eltAddr = elt.prev) { sdrFetch(elt, (Address) eltAddr); if (elt.data == (Address) arg) break; } } else { for (eltAddr = fromElt; eltAddr != 0; eltAddr = elt.next) { sdrFetch(elt, (Address) eltAddr); if (elt.data == (Address) arg) break; } } return eltAddr; }
void Sdr_list_delete(char *file, int line, Sdr sdrv, Object elt, SdrListDeleteFn deleteFn, void *arg) { SdrListElt eltBuffer; Object list; SdrList listBuffer; Object next; Object prev; if (!(sdr_in_xn(sdrv))) { oK(_iEnd(file, line, _notInXnMsg())); return; } joinTrace(sdrv, file, line); if (elt == 0) { oK(_xniEnd(file, line, "elt", sdrv)); return; } sdrFetch(eltBuffer, (Address) elt); if ((list = eltBuffer.list) == 0) { oK(_xniEnd(file, line, "list", sdrv)); return; } sdrFetch(listBuffer, (Address) list); if (listBuffer.length < 1) { oK(_xniEnd(file, line, "list non-empty", sdrv)); return; } next = eltBuffer.next; prev = eltBuffer.prev; if (deleteFn) { deleteFn(sdrv, eltBuffer.data, arg); } /* just in case user accesses later... */ sdr_list__elt_clear(&eltBuffer); sdrPut((Address) elt, eltBuffer); sdrFree(elt); if (prev) { sdrFetch(eltBuffer, (Address) prev); eltBuffer.next = next; sdrPut((Address) prev, eltBuffer); } else { listBuffer.first = next; } if (next) { sdrFetch(eltBuffer, (Address) next); eltBuffer.prev = prev; sdrPut((Address) next, eltBuffer); } else { listBuffer.last = prev; } listBuffer.length -= 1; sdrPut((Address) list, listBuffer); }
Object Sdr_list_insert_before(char *file, int line, Sdr sdrv, Object oldElt, Address data) { SdrListElt oldEltBuffer; Object list; SdrList listBuffer; Object elt; SdrListElt eltBuffer; if (!(sdr_in_xn(sdrv))) { oK(_iEnd(file, line, _notInXnMsg())); return 0; } joinTrace(sdrv, file, line); if (oldElt == 0) { oK(_xniEnd(file, line, "oldElt", sdrv)); return 0; } sdrFetch(oldEltBuffer, (Address) oldElt); if ((list = oldEltBuffer.list) == 0) { oK(_xniEnd(file, line, "list", sdrv)); return 0; } /* create new element */ elt = _sdrzalloc(sdrv, sizeof(SdrListElt)); if (elt == 0) { oK(_iEnd(file, line, "elt")); return 0; } sdr_list__elt_clear(&eltBuffer); eltBuffer.list = list; eltBuffer.data = data; /* insert new element before the specified element */ sdrFetch(listBuffer, (Address) list); eltBuffer.prev = oldEltBuffer.prev; eltBuffer.next = oldElt; sdrPut((Address) elt, eltBuffer); if (oldEltBuffer.prev != 0) { sdrFetch(eltBuffer, (Address) oldEltBuffer.prev); eltBuffer.next = elt; sdrPut((Address) oldEltBuffer.prev, eltBuffer); } else { listBuffer.first = elt; } oldEltBuffer.prev = elt; sdrPut((Address) oldElt, oldEltBuffer); listBuffer.length += 1; sdrPut((Address) list, listBuffer); return elt; }