April 25, 2024, 05:58:44 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Linked lists

Started by Parker, November 16, 2005, 06:13:04 PM

Previous topic - Next topic

0 Members and 5 Guests are viewing this topic.

Parker

Yay, now we have linked lists :)

It's similar to the implementation in IB for anyone who came from there, but there are also ListGetPrev and ListGetLast functions.

Here are the functions: (LinkedListFunctions.inc) // declarations for the _new, _renew, and _delete functions
declare import, GlobalAlloc(flags as unsigned int, size as unsigned int),unsigned int;
declare import, GlobalReAlloc(hMem as unsigned int, nBytes as unsigned int, uFlags as unsigned int),unsigned int;
declare import, GlobalFree(memory as unsigned int),unsigned int;

// helper, since there's no NEW and DELETE

sub _new(size as unsigned int),unsigned int
{
return GlobalAlloc(0x40, size);
}

sub _renew(mem as unsigned int, size as unsigned int, zeromem=0 as int),unsigned int
{
return GlobalReAlloc(mem, size, (zeromem * 0x40));
}

sub _delete(ptr as unsigned int),unsigned int
{
return GlobalFree(ptr);
}

// the size of various types
#define SIZE_BYTE 1
#define SIZE_WORD 2
#define SIZE_SHORT 2
#define SIZE_INT 4
#define SIZE_INT64 8
#define SIZE_FLOAT 4
#define SIZE_DOUBLE 8

struct listnode {
pointer pData;
listnode *pNext;
listnode *pPrev;
}

// Linked List implementation, like the one in IB

// CREATE
sub ListCreate(),pointer
{
listnode *pTemp;
pTemp = _new(len(listnode));
// _new automatically zeroes memory.

return pTemp;
}

// ADD, ADDHEAD

sub ListAdd(listnode *list, pointer item),pointer
{
listnode *pTemp;

if (list = 0) return item;

pTemp = ListGetLast(list);

*pTemp.pNext = _new(len(listnode));
*pTemp.*pNext.pPrev = pTemp;
*pTemp.*pNext.pData = item;

return item;
}

sub ListAddHead(listnode *list, pointer item),pointer
{
listnode *pTemp;

if (list = 0) return item;

pTemp = *list.pNext;
*list.pNext = _new(len(listnode));

*list.*pNext.pPrev = list;
*list.*pNext.pData = item;
*list.*pNext.pNext = pTemp;

if (pTemp <> 0)
{
*pTemp.pPrev = *list.pNext;
}

return item;
}

// GETFIRST, GETLAST

sub ListGetFirst(listnode *list),pointer
{
if (list = 0) return 0;

return *list.pNext;
}

sub ListGetLast(listnode *list),pointer
{
listnode *pTemp;

if (list = 0) return 0;

pTemp = list;
while (*pTemp.pNext <> 0)
{
pTemp = *pTemp.pNext;
}

return pTemp;
}

// GETNEXT, GETPREV

sub ListGetNext(listnode *list),pointer
{
if (list = 0) return 0;

return *list.pNext;
}

sub ListGetPrev(listnode *list),pointer
{
// can't do anything to a null list
if (list = 0) return 0;
// this is needed for below
if (*list.pPrev = 0) return 0;
// since the list starts with a null node (pPrev and pData = 0),
// the first should be the one right after the real first.
if (*list.*pPrev.pPrev = 0) return 0;

return *list.pPrev;
}

// GETDATA

sub ListGetData(listnode *list),pointer
{
if (list = 0) return 0;

return *list.pData;
}

// REMOVE, REMOVEALL

sub ListRemove(listnode *list, opt int bDelete = 0),pointer
{
listnode *pPrev;
listnode *pNext;

if (list = 0) return 0;

pPrev = *list.pPrev;
pNext = *list.pNext;

if ((*list.pData <> 0) and (bDelete <> 0)) _delete(*list.pData);

_delete(list);

if (pPrev <> 0)
{
*pPrev.pNext = pNext;
}
if (pNext <> 0)
{
*pNext.pPrev = pPrev;
}

return pNext;
}

sub ListRemoveAll(listnode *list, opt int bDelete = 0)
{
listnode *node;

if (list = 0) return 0;

for (node = ListGetFirst(list); node <> 0; node = ListRemove(node))
{
if (bDelete) _delete(*node.pData);
}

return;
}


And here's an example that also shows how you can do a FOR EACH loop using the C-style FOR.

#include "LinkedListFunctions.inc"

global sub main()
{
pointer ll;
int *item;
ll = ListCreate();
item = ListAddHead(ll, _new(SIZE_INT));
*item = 1;
item = ListAddHead(ll, _new(SIZE_INT));
*item = 2;
item = ListAddHead(ll, _new(SIZE_INT));
*item = 3;

pointer node;
for (node = ListGetFirst(ll); node <> 0; node = ListGetNext(node))
{
item = ListGetData(node);
writeln(str$(*item,0)+"\n");
}
ListRemoveAll(ll,1);

while (GetKey() = "");
return 0;
}

Brian

Worked for me once I put the include file in the right folder!

Brian

Parker

I put the include in my 'includes' folder. Are there problems with storing it in the folder where the source code is?

Brian

Well, I actually put it at first in the aurora\bin folder, because that's where the others were

Works fine if you put it in the aurora\include folder. Didn't try the source folder

Brian

Parker

I believe the 'bin' directory is strictly for Paul's includes that are required to build, but there will be no extra command paks, etc.

Ionic Wind Support Team

For include files it either has to be in the 'include' directory, your source files directory, or you need to specify a path.

#include "c:\myincludes\blah.inc"

Paths can be relative to your source directory as well

#include "..\inc\blah.inc"

Paul.
Ionic Wind Support Team