Table of Contents

About

This implementation uses Amiga OS types and memory-allocation semantics in order to be used for other programs that rely on a stack implementation.

The program can be compiled on the Amiga using SAS/C by issuing:

sc link stacks.c

When the program is run, it will perform a series of operations using the implemented queue functions and display the output in the calling shell:

stack size: 1
Elements in the stack: ! Day Good 
stack size: 3
number of elements in the stack: 3
Pop: !
Pop: Day
Elements in the stack: Good 
Pop: Good
Stack is empty.

Uses

Code

queues.c
/*************************************************************************/
/*    Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3    */
/*************************************************************************/
/*                                                                       */
/*  stringStack                                                          */
/*                                                                       */
/*  An implementation of a stack of strings for Amiga OS.                */
/*                                                                       */
/*  Implemented functions:                                               */
/*      - push                                                           */
/*      - pop                                                            */
/*      - is empty                                                       */
/*      - size                                                           */
/*      - count                                                          */
/*      - print                                                          */
/*                                                                       */
/*  Compile on Amiga OS using SAS/C and issuing: sc link stacks.c        */
/*                                                                       */
/*************************************************************************/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#include <proto/exec.h>
#include <proto/dos.h>
 
/* The stringStack structure with top being the index of the next element 
 * to be inserted in stack (the top-most element to be found at top - 1).
 */
typedef struct {
   ULONG size;
   UBYTE **store;
   ULONG top;
} stringStack;
 
/*
 * Creates a new stringStack with a given size.
 */
stringStack* stringStackCreate(ULONG size) {
   stringStack *s = (stringStack*)AllocMem(
       sizeof(stringStack), 
       MEMF_ANY|MEMF_CLEAR
   );
   if ((s->store = (UBYTE**)AllocMem(
       size * sizeof(UBYTE **), 
       MEMF_ANY|MEMF_CLEAR
       )) == NULL) return NULL;
   s->size = size;
   s->top = 0;
   return s;
}
 
/*
 * Clears a stringStack and returns a pointer to a new empty stack.
 */
stringStack* stringStackClear(stringStack *s) {
    if (s != NULL)
        FreeMem(s, sizeof(s));
    return stringStackCreate(1);
}
 
/*
 * Takes as parameter a stringStack and returns 1 if the stack is empty
 * or 0 if the stack is not empty.
 */
BOOL stringStackIsEmpty(stringStack *s) {
    return (BOOL)(s->top == 0);
}
 
/*
 * Returns allocated stack size (not the number of elements).
 */
ULONG stringStackSize(stringStack *s) {
    return s->size;
}
 
/*
 * Returns the number of elements in a stringStack.
 */
ULONG stringStackCount(stringStack *s) {
    return s->top;
}
 
/*
 * Pushes an element onto the stringStack.
 */
void stringStackPush(stringStack *s, UBYTE *e) {
    UBYTE **sStore;
    if (s->top > s->size - 1) { // realloc for AmigaOS
        sStore = (UBYTE **)AllocMem(
            (s->size + 1) * sizeof(UBYTE **), 
            MEMF_ANY|MEMF_CLEAR
        );
        CopyMem(s->store, sStore, s->size * sizeof(UBYTE **));
        FreeMem(s->store, sizeof(s->store));
        s->store = sStore;
        ++s->size;
    }
    s->store[s->top] = (UBYTE *)AllocMem(
            strlen(e) * sizeof(UBYTE *) + 1, 
            MEMF_ANY|MEMF_CLEAR
    );
    CopyMem(e, s->store[s->top], strlen(e) * sizeof(UBYTE *) + 1);
    ++s->top;
}
 
/*
 * Pops an element off the stringStack or returns NULL in case the
 * stack is empty.
 */
UBYTE *stringStackPop(stringStack *s) {
   UBYTE *e;
   if (stringStackIsEmpty(s))
       return NULL;
   --s->top;
   e = (UBYTE *)AllocMem(
       strlen(s->store[s->top]) * sizeof(UBYTE *) + 1, 
       MEMF_ANY|MEMF_CLEAR
   );
   CopyMem(
       s->store[s->top], 
       e, 
       strlen(s->store[s->top]) * sizeof(UBYTE *) + 1
   );
   return e;
}
 
/*
 * Prints out the elements of the stringStack.
 */
void stringStackPrint(stringStack *s) {
    LONG i;
    if (stringStackIsEmpty(s)) {
        Printf("Stack is empty.\n");
        return;
    }
    Printf("Elements in the stack: ");
    i = s->top - 1;
    do {
        Printf("%s ", s->store[i]);
    } while (--i > -1);
    Printf("\n");
}
 
int main(void) {
    stringStack *q = stringStackCreate(1);
    Printf("stack size: %ld\n", stringStackSize(q));
    stringStackPush(q, "Good");
    stringStackPush(q, "Day");
    stringStackPush(q, "!");
    stringStackPrint(q);
    Printf("stack size: %ld\n", stringStackSize(q));
    Printf("number of elements in the stack: %ld\n", stringStackCount(q));
    Printf("Pop: %s\n", stringStackPop(q));
    Printf("Pop: %s\n", stringStackPop(q));
    stringStackPrint(q);
    Printf("Pop: %s\n", stringStackPop(q));
    stringStackPrint(q);
}