/****************************************************************** ** ** QUEUE.C: ** ** ADT Queue Implementation ** ** This file is part of Apt Abstrct Data Types (ADT) ** Copyright (c) 1991 -- Apt Technologies ** All rights reserved ** ******************************************************************/ /* ---------- C Headers */ //#include "cheaders.h" /* ---------- Headers */ #include "apt.h" #include "allocate.h" #include "pqueue.h" #include #include #include /* ---------- Private Function Prototypes */ #ifdef __ANSI_C__ PRIVATE void QueueDisposeItem(QueueItem, DisposeFunction); PRIVATE QueueItem QueueGetItem(Queue); PRIVATE QueueItem QueueNewItem(void*, int); PRIVATE void QueuePutItem(Queue, QueueItem); PRIVATE QueueItem QueueRemoveItem(Queue, QueueItem); PRIVATE int QueueCompareEqual(void *, void *); #else PRIVATE void QueueDisposeItem(); PRIVATE QueueItem QueueGetItem(); PRIVATE QueueItem QueueNewItem(); PRIVATE void QueuePutItem(); PRIVATE QueueItem QueueRemoveItem(); PRIVATE int QueueCompareEqual(); #endif /* ---------- Functions */ /* ** ** QueueApply ** */ PUBLIC #ifdef __ANSI_C__ void QueueApply(Queue q, ApplyFunction f) #else void QueueApply(q,f) Queue q; ApplyFunction f; #endif { QueueItem item; for (item = q->head; item != NULL; item = item->next) { (*f)(item->element); } } /* ** ** QueueApply1 ** */ PUBLIC #ifdef __ANSI_C__ void QueueApply1(Queue q, void *p1, ApplyFunction1 f) #else void QueueApply1(q,p1,f) Queue q; void *p1; ApplyFunction1 f; #endif { QueueItem item; for (item = q->head; item != NULL; item = item->next) { (*f)(item->element,p1); } } /* ** ** QueueApply2 ** */ PUBLIC #ifdef __ANSI_C__ void QueueApply2(Queue q, void *p1, void *p2, ApplyFunction2 f) #else void QueueApply2(q,p1,p2,f) Queue q; void *p1; void *p2; ApplyFunction2 f; #endif { QueueItem item; for (item = q->head; item != NULL; item = item->next) { (*f)(item->element,p1,p2); } } /* ** ** QueueApply3 ** */ PUBLIC #ifdef __ANSI_C__ void QueueApply3(Queue q, void *p1, void* p2, void *p3, ApplyFunction3 f) #else void QueueApply3(q,p1,p2,p3,f) Queue q; void *p1; void *p2; void *p3; ApplyFunction3 f; #endif { QueueItem item; for (item = q->head; item != NULL; item = item->next) { (*f)(item->element,p1,p2,p3); } } /* ** ** QueueCAR ** */ PUBLIC #ifdef __ANSI_C__ void *QueueCAR(Queue q) #else void *QueueCAR(q) Queue q; #endif { if (q != NULL && q->head != NULL) return QueueItemElement(q->head); return NULL; } /* ** ** QueueCDR ** */ PUBLIC #ifdef __ANSI_C__ Queue QueueCDR(Queue q) #else Queue QueueCDR(q) Queue q; #endif { if (q != NULL && q->head != NULL) { Queue new = QueueNew(); new->head = q->head->next; new->tail = new->head != NULL ? q->tail : NULL; new->size = q->size-1; return new; } else return NULL; } /* ** ** QueueDispose ** */ PUBLIC #ifdef __ANSI_C__ void QueueDispose(Queue q, DisposeFunction f) #else void QueueDispose(q,f) Queue q; DisposeFunction f; #endif { QueueItem item; QueueItem next = NULL; for (item = q->head; item != NULL; item = next) { next = item->next; QueueDisposeItem(item,f); } free(q); } /* ** ** QueueDisposeItem ** */ PRIVATE #ifdef __ANSI_C__ void QueueDisposeItem(QueueItem item, DisposeFunction f) #else void QueueDisposeItem(item,f) QueueItem item; DisposeFunction f; #endif { if (f) (*f)(item->element); free(item); } /* ** ** QueueFind ** */ PUBLIC #ifdef __ANSI_C__ void *QueueFind(Queue q, void *element, ComparisonFunction f) #else void *QueueFind(q,element,f) Queue q; void *element; ComparisonFunction f; #endif { QueueItem item; for (item = q->head; item != NULL; item = item->next) { if ((*f)(element,item->element) == 0) break; } return (item != NULL ? item->element : NULL); } /* ** ** QueueFindAndRemove ** */ PUBLIC #ifdef __ANSI_C__ void *QueueFindAndRemove(Queue q, void *element, ComparisonFunction f) #else void *QueueFindAndRemove(q, element, f) Queue q; void *element; ComparisonFunction f; #endif { QueueItem item; for (item = q->head; item != NULL; item = item->next) { if ((*f)(element,item->element) == 0) break; } item = QueueRemoveItem(q,item); return (item != NULL ? item->element : NULL); } /* ** ** QueueFindAndRemoveType ** */ PUBLIC #ifdef __ANSI_C__ void *QueueFindAndRemoveType(Queue q, void *element, ComparisonFunction f, int type) #else void *QueueFindAndRemoveType(q, element, f, type) Queue q; void *element; ComparisonFunction f; int type; #endif { QueueItem item; for (item = q->head; item != NULL; item = item->next) { if ((*f)(element,item->element) == 0 && item->type == type) break; } item = QueueRemoveItem(q,item); return (item != NULL ? item->element : NULL); } /* ** ** QueueFindType ** */ PUBLIC #ifdef __ANSI_C__ void *QueueFindType(Queue q, int type) #else void *QueueFindType(q,type) Queue q; int type; #endif { QueueItem item; for (item = q->head; item != NULL; item = item->next) { if (item->type == type) break; } return (item != NULL ? item->element : NULL); } /* ** ** QueueFindTypeAndRemove ** */ PUBLIC #ifdef __ANSI_C__ void *QueueFindTypeAndRemove(Queue q, int type) #else void *QueueFindTypeAndRemove(q,type) Queue q; int type; #endif { QueueItem item; for (item = q->head; item != NULL; item = item->next) { if (item->type == type) break; } return (QueueRemoveItem(q,item)); } /* ** ** QueueGet ** */ PUBLIC #ifdef __ANSI_C__ void *QueueGet(Queue q) #else void *QueueGet(q) Queue q; #endif { void *element; QueueItem item; item = QueueGetItem(q); if (item) { element = item->element; QueueDisposeItem(item,NULL); } else element = NULL; return (element); } /* ** ** QueueGetItem ** */ PRIVATE #ifdef __ANSI_C__ QueueItem QueueGetItem(Queue q) #else QueueItem QueueGetItem(q) Queue q; #endif { QueueItem item; if (q->head) { item = q->head; q->head = q->head->next; q->size--; } else item = NULL; return (item); } /* ** ** QueueHead ** */ PUBLIC #ifdef __ANSI_C__ QueueItem QueueHead(Queue q) #else QueueItem QueueHead(q) Queue q; #endif { return q != NULL ? q->head : NULL; } /* ** ** QueueItemElement ** */ PUBLIC #ifdef __ANSI_C__ void *QueueItemElement(QueueItem item) #else void *QueueItemElement(item) QueueItem item; #endif { return (item->element); } /* ** ** QueueItemType ** */ PUBLIC #ifdef __ANSI_C__ int QueueItemType(QueueItem item) #else int QueueItemType(item) QueueItem item; #endif { return (item->type); } /* ** ** QueueLook ** */ PUBLIC #ifdef __ANSI_C__ void *QueueLook(Queue q) #else void *QueueLook(q) Queue q; #endif { QueueItem item; item = q->head; return (item != NULL ? item->element : NULL); } /* ** ** QueueNew ** */ PUBLIC #ifdef __ANSI_C__ Queue QueueNew(void) #else Queue QueueNew() #endif { Queue q; q = ((Queue)Allocate(sizeof(_Queue))); if (q) { q->head = q->tail = NULL; q->size = 0; } return (q); } /* ** ** QueueNewItem ** */ PRIVATE #ifdef __ANSI_C__ QueueItem QueueNewItem(void *element, int type) #else QueueItem QueueNewItem(element,type) void *element; int type; #endif { QueueItem item; item = ((QueueItem)Allocate(sizeof(_QueueItem))); if (item) { item->element = element; item->type = type; item->next = NULL; } return (item); } /* ** ** QueueNext ** */ PUBLIC #ifdef __ANSI_C__ QueueItem QueueNext(QueueItem item) #else QueueItem QueueNext(item) QueueItem item; #endif { return item != NULL ? item->next : NULL; } /* ** ** QueuePut ** */ PUBLIC #ifdef __ANSI_C__ void QueuePut(Queue q, void *element, int type) #else void QueuePut(q,element,type) Queue q; void *element; int type; #endif { QueueItem item; item = QueueNewItem(element,type); QueuePutItem(q,item); } /* ** ** QueuePutItem ** */ PRIVATE #ifdef __ANSI_C__ void QueuePutItem(Queue q, QueueItem item) #else void QueuePutItem(q,item) Queue q; QueueItem item; #endif { if (q->head == NULL) { q->head = q->tail = item; } else { q->tail->next = item; q->tail = q->tail->next; } q->size++; } /* ** ** QueuePutOnPriority ** */ PUBLIC #ifdef __ANSI_C__ void QueuePutOnPriority(Queue q, void *element, int type, ComparisonFunction f) #else void QueuePutOnPriority(q,element,type,f) Queue q; void *element; int type; ComparisonFunction f; #endif { QueueItem item; item = QueueNewItem(element,type); //fprintf(stderr,"searching for location using %p.\n",f); if (f == NULL){ //fprintf(stderr,"comparing function is null %f \n",f); exit(1); QueuePutItem(q,item); }else { if (q->head == NULL) QueuePutItem(q,item); else { QueueItem p, lastp = NULL; for (p = q->head; p != NULL; p = p->next) { int cval =(*f)(element,p->element); if (cval<0){ // fprintf(stderr,"%i <=> %i == %i\n",*((int *) element),*((int *)(p->element)), // cval); break; } lastp = p; } if (p == q->head) { item->next = q->head; q->head = item; } else if (p == NULL) { q->tail->next = item; q->tail = q->tail->next; } else { item->next = p; lastp->next = item; } q->size++; } } } /* ** ** QueueRemoveItem ** */ PRIVATE #ifdef __ANSI_C__ QueueItem QueueRemoveItem(Queue q, QueueItem item) #else QueueItem QueueRemoveItem(q,item) Queue q; QueueItem item; #endif { QueueItem this, prev = NULL; if (q == NULL) return (NULL); if (item == NULL) return (NULL); this = q->head; while (this && this != item) { prev = this; this = this->next; } if (this == NULL) return (NULL); if (this == q->head) q->head = item->next; if (this == q->tail) q->tail = prev; if (prev) prev->next = this->next; q->size--; return (item); } /* ** ** QueueSeek ** */ PUBLIC #ifdef __ANSI_C__ QueueItem QueueSeek(Queue q, int position) #else QueueItem QueueSeek(q,position) Queue q; int position; #endif { QueueItem item; #if 0 /* Allow single-level negative addressing of queue items */ if (position <= 0) position += QueueSize(q); #endif /* Seeks which fail will result in NULL, not error conditions */ if (position <= 0 || position > QueueSize(q)) return NULL; item = QueueHead(q); while (--position > 0) item = QueueNext(item); return item; } /* ** ** QueueSize ** */ PUBLIC #ifdef __ANSI_C__ int QueueSize(Queue q) #else int QueueSize(q) Queue q; #endif { return q != NULL ? q->size : 0; } /* ** ** QueueTail ** */ PUBLIC #ifdef __ANSI_C__ QueueItem QueueTail(Queue q) #else QueueItem QueueTail(q) Queue q; #endif { return q != NULL ? q->tail : NULL; } PRIVATE #ifdef __ANSI_C__ int QueueCompareEqual(void *x, void *y) #else int QueueCompareEqual(x,y) void *x, *y; #endif { return 0; }