home *** CD-ROM | disk | FTP | other *** search
- /* > C.Queue - Queue data type */
-
- #include <stddef.h>
- #include <stdlib.h>
- #include <string.h>
- #include "queue.h"
-
- #ifdef test
- #include <stdio.h>
- #endif
-
- struct link
- {
- struct link *next;
- char data[1];
- };
-
- typedef struct link *link;
-
- /* Return values from functions */
-
- #define OK 1
- #define ERR 0
-
- /* General component routines */
-
- queue Q_new (int obj_len)
- {
- register queue q;
-
- q = malloc(sizeof(struct queue));
-
- if ( q == NULL )
- return NULL;
-
- q->head = NULL;
- q->tail = NULL;
- q->obj_size = obj_len;
-
- return q;
- }
-
- void Q_free (queue q)
- {
- Q_clear(q);
- free(q);
- }
-
- void Q_clear (queue q)
- {
- link this_entry = q->head;
- link next_entry;
-
- while ( this_entry != NULL )
- {
- next_entry = this_entry->next;
- free(this_entry);
- this_entry = next_entry;
- }
-
- q->head = q->tail = NULL;
- }
-
- int Q_copy (queue q1, const queue q2)
- {
- link p;
- link new;
- link last;
- int size;
-
- if ( q1->obj_size != q2->obj_size )
- return ERR;
-
- Q_clear(q1);
-
- last = (link)q1;
- size = q2->obj_size;
-
- for ( p = q2->head; p != NULL; p = p->next )
- {
- new = malloc(sizeof(struct link) - 1 + size);
- if ( new == NULL )
- {
- Q_clear(q1);
- return ERR;
- }
- last->next = new;
- memcpy(new->data,p->data,size);
- last = new;
- }
-
- last->next = NULL;
- q1->tail = last;
-
- return OK;
- }
-
- int Q_equal (const queue q1, const queue q2)
- {
- int size;
- link p1;
- link p2;
-
- if ( q1->obj_size != q2->obj_size )
- return 0;
-
- size = q1->obj_size;
-
- for
- (
- p1 = q1->head, p2 = q2->head;
- p1 != NULL && p2 != NULL;
- p1 = p1->next, p2 = p2->next
- )
- {
- if ( memcmp(p1->data,p2->data,size) != 0 )
- return 0;
- }
-
- return ( p1 == p2 );
- }
-
- int Q_empty (const queue q)
- {
- return ( q->head == NULL );
- }
-
- int Q_size (const queue q)
- {
- int i = 0;
- link p;
-
- for ( p = q->head; p != NULL; p = p->next )
- ++i;
-
- return i;
- }
-
- int Q_iterate (const queue q, int (*process)(void *))
- {
- int ret = 0;
- link p;
-
- for ( p = q->head; p != NULL; p = p->next )
- {
- ret = (*process)(p->data);
-
- /* Non-zero => stop processing here */
-
- if ( ret != 0 )
- break;
- }
-
- /* Negative => Abnormal (error) termination */
-
- return ( ret >= 0 );
- }
-
- /* queue-specific routines */
-
- int Q_add (queue q, const void *object)
- {
- link new;
-
- new = malloc(sizeof(struct link) - 1 + q->obj_size);
-
- if ( new == NULL )
- return ERR;
-
- memcpy(new->data,object,q->obj_size);
-
- new->next = NULL;
-
- if ( q->tail != NULL )
- ((link)q->tail)->next = new;
-
- q->tail = new;
-
- if ( q->head == NULL )
- q->head = new;
-
- return OK;
- }
-
- int Q_remove (queue q)
- {
- link p;
-
- if ( q->head == NULL )
- return ERR;
-
- p = q->head;
-
- q->head = p->next;
- free(p);
-
- if ( q->head == NULL )
- q->tail = NULL;
-
- return OK;
- }
-
- void *Q_head (const queue q)
- {
- if ( q->head == NULL )
- return NULL;
-
- return ((link)q->head)->data;
- }
-
- /*---------------------------------------------------------------------------*/
-
- #ifdef test
- int print (void *ptr)
- {
- printf("%d ",*(int *)ptr);
- return STATUS_CONTINUE;
- }
-
- void Q_dump (queue q)
- {
- printf("queue: ");
- Q_iterate(q,print);
- putchar('\n');
- }
- #endif
-
- /*---------------------------------------------------------------------------*/
-
- #ifdef test
-
- #define BUFLEN 255
-
- int main (void)
- {
- char buf[BUFLEN];
- int i, j, num;
- queue q[10];
-
- for ( i = 0; i < 10; ++i )
- q[i] = Q_new(sizeof(int));
-
- for ( ; ; )
- {
- printf(">");
- fgets(buf,BUFLEN,stdin);
-
- if ( buf[0] == '\n' || buf[0] == '\0' )
- continue;
- else if ( sscanf(buf,"clear %1d",&i) == 1 )
- Q_clear(q[i]);
- else if ( sscanf(buf,"copy %1d %1d",&i,&j) == 2 )
- Q_copy(q[i],q[j]);
- else if ( sscanf(buf,"equal %1d %1d",&i,&j) == 2 )
- printf("%s\n",(Q_equal(q[i],q[j]) ? "yes" : "no"));
- else if ( sscanf(buf,"empty %1d",&i) == 1 )
- printf("%s\n",(Q_empty(q[i]) ? "yes" : "no"));
- else if ( sscanf(buf,"size %1d",&i) == 1 )
- printf("%d\n",Q_size(q[i]));
- else if ( sscanf(buf,"dump %1d",&i) == 1 )
- Q_dump(q[i]);
- else if ( sscanf(buf,"add %1d %d",&i,&num) == 2 )
- Q_add(q[i],&num);
- else if ( sscanf(buf,"remove %1d",&i) == 1 )
- Q_remove(q[i]);
- else if ( sscanf(buf,"head %1d",&i) == 1 )
- {
- int *p = Q_head(q[i]);
- if ( p == NULL )
- printf("Empty\n");
- else
- printf("%d\n",*p);
- }
- else if ( strncmp(buf,"quit",4) == 0 )
- break;
- else
- printf("Mistake\n");
- }
-
- printf("Deleting q[0-9]\n");
- for ( i = 0; i < 10; ++i )
- Q_free(q[i]);
-
- return 0;
- }
-
- #endif
-