home *** CD-ROM | disk | FTP | other *** search
- /* > C.Stack - Stack data type */
-
- #include <stddef.h>
- #include <stdlib.h>
- #include <string.h>
- #include "stack.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 */
-
- stack stk_new (int obj_len)
- {
- register stack s;
-
- s = malloc(sizeof(struct stack));
-
- if ( s == NULL )
- return NULL;
-
- s->top = NULL;
- s->obj_size = obj_len;
-
- return s;
- }
-
- void stk_free (stack s)
- {
- stk_clear(s);
- free(s);
- }
-
- void stk_clear (stack s)
- {
- link this_entry = s->top;
- link next_entry;
-
- while ( this_entry != NULL )
- {
- next_entry = this_entry->next;
- free(this_entry);
- this_entry = next_entry;
- }
-
- s->top = NULL;
- }
-
- int stk_copy (stack s1, const stack s2)
- {
- link p;
- link new;
- link last;
- int size;
-
- if ( s1->obj_size != s2->obj_size )
- return ERR;
-
- stk_clear(s1);
-
- last = (link)s1;
- size = s2->obj_size;
-
- for ( p = s2->top; p != NULL; p = p->next )
- {
- new = malloc(sizeof(struct link) - 1 + size);
- if ( new == NULL )
- {
- stk_clear(s1);
- return ERR;
- }
- last->next = new;
- memcpy(new->data,p->data,size);
- last = new;
- }
-
- last->next = NULL;
- return OK;
- }
-
- int stk_equal (const stack s1, const stack s2)
- {
- int size;
- link p1;
- link p2;
-
- if ( s1->obj_size != s2->obj_size )
- return 0;
-
- size = s1->obj_size;
-
- for
- (
- p1 = s1->top, p2 = s2->top;
- p1 != NULL && p2 != NULL;
- p1 = p1->next, p2 = p2->next
- )
- {
- if ( memcmp(p1->data,p2->data,size) != 0 )
- return 0;
- }
-
- return ( p1 == p2 );
- }
-
- int stk_empty (const stack s)
- {
- return ( s->top == NULL );
- }
-
- int stk_size (const stack s)
- {
- int i = 0;
- link p;
-
- for ( p = s->top; p != NULL; p = p->next )
- ++i;
-
- return i;
- }
-
- int stk_iterate (const stack s, int (*process)(void *))
- {
- int ret = 0;
- link p;
-
- for ( p = s->top; 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 );
- }
-
- /* stack-specific routines */
-
- int stk_push (stack s, const void *object)
- {
- link new;
-
- new = malloc(sizeof(struct link) - 1 + s->obj_size);
-
- if ( new == NULL )
- return ERR;
-
- memcpy(new->data,object,s->obj_size);
-
- new->next = s->top;
- s->top = new;
-
- return OK;
- }
-
- int stk_pop (stack s)
- {
- link p;
-
- if ( s->top == NULL )
- return ERR;
-
- p = s->top;
-
- s->top = p->next;
- free(p);
-
- return OK;
- }
-
- void *stk_top (const stack s)
- {
- if ( s->top == NULL )
- return NULL;
-
- return ((link)s->top)->data;
- }
-
- /*---------------------------------------------------------------------------*/
-
- #ifdef test
- int print (void *ptr)
- {
- printf("%d ",*(int *)ptr);
- return STATUS_CONTINUE;
- }
-
- void stk_dump (stack s)
- {
- printf("Stack: ");
- stk_iterate(s,print);
- putchar('\n');
- }
- #endif
-
- /*---------------------------------------------------------------------------*/
-
- #ifdef test
-
- #define BUFLEN 255
-
- int main (void)
- {
- char buf[BUFLEN];
- int i, j, num;
- stack s[10];
-
- for ( i = 0; i < 10; ++i )
- s[i] = stk_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 )
- stk_clear(s[i]);
- else if ( sscanf(buf,"copy %1d %1d",&i,&j) == 2 )
- stk_copy(s[i],s[j]);
- else if ( sscanf(buf,"equal %1d %1d",&i,&j) == 2 )
- printf("%s\n",(stk_equal(s[i],s[j]) ? "yes" : "no"));
- else if ( sscanf(buf,"empty %1d",&i) == 1 )
- printf("%s\n",(stk_empty(s[i]) ? "yes" : "no"));
- else if ( sscanf(buf,"size %1d",&i) == 1 )
- printf("%d\n",stk_size(s[i]));
- else if ( sscanf(buf,"dump %1d",&i) == 1 )
- stk_dump(s[i]);
- else if ( sscanf(buf,"push %1d %d",&i,&num) == 2 )
- stk_push(s[i],&num);
- else if ( sscanf(buf,"top %1d",&i) == 1 )
- {
- int *p = stk_top(s[i]);
- if ( p == NULL )
- printf("Empty\n");
- else
- printf("%d\n",*p);
- }
- else if ( sscanf(buf,"pop %1d",&i) == 1 )
- stk_pop(s[i]);
- else if ( strncmp(buf,"quit",4) == 0 )
- break;
- else
- printf("Mistake\n");
- }
-
- printf("Deleting s[0-9]\n");
- for ( i = 0; i < 10; ++i )
- stk_free(s[i]);
-
- return 0;
- }
-
- #endif
-