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

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