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.
/*************************************************************************/ /* 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); }