home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / unix / unixtools / util / c / queue < prev    next >
Encoding:
Text File  |  1992-07-21  |  5.9 KB  |  288 lines

  1. /*      > C.Queue - Queue data type */
  2.  
  3. #include <stddef.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "queue.h"
  7.  
  8. #ifdef test
  9. #include <stdio.h>
  10. #endif
  11.  
  12. struct link
  13. {
  14.         struct link *next;
  15.         char data[1];
  16. };
  17.  
  18. typedef struct link *link;
  19.  
  20. /* Return values from functions */
  21.  
  22. #define OK      1
  23. #define ERR     0
  24.  
  25. /* General component routines */
  26.  
  27. queue Q_new (int obj_len)
  28. {
  29.         register queue q;
  30.  
  31.         q = malloc(sizeof(struct queue));
  32.  
  33.         if ( q == NULL )
  34.                 return NULL;
  35.  
  36.         q->head     = NULL;
  37.         q->tail     = NULL;
  38.         q->obj_size = obj_len;
  39.  
  40.         return q;
  41. }
  42.  
  43. void Q_free (queue q)
  44. {
  45.         Q_clear(q);
  46.         free(q);
  47. }
  48.  
  49. void Q_clear (queue q)
  50. {
  51.         link this_entry = q->head;
  52.         link next_entry;
  53.         
  54.         while ( this_entry != NULL )
  55.         {
  56.                 next_entry = this_entry->next;
  57.                 free(this_entry);
  58.                 this_entry = next_entry;
  59.         }
  60.  
  61.         q->head = q->tail = NULL;
  62. }
  63.  
  64. int Q_copy (queue q1, const queue q2)
  65. {
  66.         link p;
  67.         link new;
  68.         link last;
  69.         int size;
  70.  
  71.         if ( q1->obj_size != q2->obj_size )
  72.                 return ERR;
  73.  
  74.         Q_clear(q1);
  75.  
  76.         last = (link)q1;
  77.         size = q2->obj_size;
  78.  
  79.         for ( p = q2->head; p != NULL; p = p->next )
  80.         {
  81.                 new = malloc(sizeof(struct link) - 1 + size);
  82.                 if ( new == NULL )
  83.                 {
  84.                         Q_clear(q1);
  85.                         return ERR;
  86.                 }
  87.                 last->next = new;
  88.                 memcpy(new->data,p->data,size);
  89.                 last = new;
  90.         }
  91.  
  92.         last->next = NULL;
  93.         q1->tail = last;
  94.  
  95.         return OK;
  96. }
  97.  
  98. int Q_equal (const queue q1, const queue q2)
  99. {
  100.         int size;
  101.         link p1;
  102.         link p2;
  103.  
  104.         if ( q1->obj_size != q2->obj_size )
  105.                 return 0;
  106.  
  107.         size = q1->obj_size;
  108.  
  109.         for
  110.         (
  111.                 p1 = q1->head, p2 = q2->head;
  112.                 p1 != NULL && p2 != NULL;
  113.                 p1 = p1->next, p2 = p2->next
  114.         )
  115.         {
  116.                 if ( memcmp(p1->data,p2->data,size) != 0 )
  117.                         return 0;
  118.         }
  119.  
  120.         return ( p1 == p2 );
  121. }
  122.  
  123. int Q_empty (const queue q)
  124. {
  125.         return ( q->head == NULL );
  126. }
  127.  
  128. int Q_size (const queue q)
  129. {
  130.         int i = 0;
  131.         link p;
  132.  
  133.         for ( p = q->head; p != NULL; p = p->next )
  134.                 ++i;
  135.  
  136.         return i;
  137. }
  138.  
  139. int Q_iterate (const queue q, int (*process)(void *))
  140. {
  141.         int ret = 0;
  142.         link p;
  143.  
  144.         for ( p = q->head; p != NULL; p = p->next )
  145.         {
  146.                 ret = (*process)(p->data);
  147.  
  148.                 /* Non-zero => stop processing here */
  149.  
  150.                 if ( ret != 0 )
  151.                         break;
  152.         }
  153.  
  154.         /* Negative => Abnormal (error) termination */
  155.  
  156.         return ( ret >= 0 );
  157. }
  158.  
  159. /* queue-specific routines */
  160.  
  161. int Q_add (queue q, const void *object)
  162. {
  163.         link new;
  164.  
  165.         new = malloc(sizeof(struct link) - 1 + q->obj_size);
  166.  
  167.         if ( new == NULL )
  168.                 return ERR;
  169.  
  170.         memcpy(new->data,object,q->obj_size);
  171.  
  172.         new->next = NULL;
  173.  
  174.         if ( q->tail != NULL )
  175.                 ((link)q->tail)->next = new;
  176.  
  177.         q->tail = new;
  178.  
  179.         if ( q->head == NULL )
  180.                 q->head = new;
  181.  
  182.         return OK;
  183. }
  184.  
  185. int Q_remove (queue q)
  186. {
  187.         link p;
  188.  
  189.         if ( q->head == NULL )
  190.                 return ERR;
  191.  
  192.         p = q->head;
  193.  
  194.         q->head = p->next;
  195.         free(p);
  196.  
  197.         if ( q->head == NULL )
  198.                 q->tail = NULL;
  199.  
  200.         return OK;
  201. }
  202.  
  203. void *Q_head (const queue q)
  204. {
  205.         if ( q->head == NULL )
  206.                 return NULL;
  207.  
  208.         return ((link)q->head)->data;
  209. }
  210.  
  211. /*---------------------------------------------------------------------------*/
  212.  
  213. #ifdef test
  214. int print (void *ptr)
  215. {
  216.         printf("%d ",*(int *)ptr);
  217.         return STATUS_CONTINUE;
  218. }
  219.  
  220. void Q_dump (queue q)
  221. {
  222.         printf("queue: ");
  223.         Q_iterate(q,print);
  224.         putchar('\n');
  225. }
  226. #endif
  227.  
  228. /*---------------------------------------------------------------------------*/
  229.  
  230. #ifdef test
  231.  
  232. #define BUFLEN 255
  233.  
  234. int main (void)
  235. {
  236.         char buf[BUFLEN];
  237.         int i, j, num;
  238.         queue q[10];
  239.  
  240.         for ( i = 0; i < 10; ++i )
  241.                 q[i] = Q_new(sizeof(int));
  242.  
  243.         for ( ; ; )
  244.         {
  245.                 printf(">");
  246.                 fgets(buf,BUFLEN,stdin);
  247.  
  248.                 if ( buf[0] == '\n' || buf[0] == '\0' )
  249.                         continue;
  250.                 else if ( sscanf(buf,"clear %1d",&i) == 1 )
  251.                         Q_clear(q[i]);
  252.                 else if ( sscanf(buf,"copy %1d %1d",&i,&j) == 2 )
  253.                         Q_copy(q[i],q[j]);
  254.                 else if ( sscanf(buf,"equal %1d %1d",&i,&j) == 2 )
  255.                         printf("%s\n",(Q_equal(q[i],q[j]) ? "yes" : "no"));
  256.                 else if ( sscanf(buf,"empty %1d",&i) == 1 )
  257.                         printf("%s\n",(Q_empty(q[i]) ? "yes" : "no"));
  258.                 else if ( sscanf(buf,"size %1d",&i) == 1 )
  259.                         printf("%d\n",Q_size(q[i]));
  260.                 else if ( sscanf(buf,"dump %1d",&i) == 1 )
  261.                         Q_dump(q[i]);
  262.                 else if ( sscanf(buf,"add %1d %d",&i,&num) == 2 )
  263.                         Q_add(q[i],&num);
  264.                 else if ( sscanf(buf,"remove %1d",&i) == 1 )
  265.                         Q_remove(q[i]);
  266.                 else if ( sscanf(buf,"head %1d",&i) == 1 )
  267.                 {
  268.                         int *p = Q_head(q[i]);
  269.                         if ( p == NULL )
  270.                                 printf("Empty\n");
  271.                         else
  272.                                 printf("%d\n",*p);
  273.                 }
  274.                 else if ( strncmp(buf,"quit",4) == 0 )
  275.                         break;
  276.                 else
  277.                         printf("Mistake\n");
  278.         }
  279.  
  280.         printf("Deleting q[0-9]\n");
  281.         for ( i = 0; i < 10; ++i )
  282.                 Q_free(q[i]);
  283.  
  284.         return 0;
  285. }
  286.  
  287. #endif
  288.