Welcome! Log In Create A New Profile

Advanced

ADT problems

Posted by WillemL 
Announcements Last Post
Announcement SoC Curricula 09/30/2017 01:08PM
Announcement Demarcation or scoping of examinations and assessment 02/13/2017 07:59AM
Announcement School of Computing Short Learning Programmes 11/24/2014 08:37AM
Announcement Unisa contact information 07/28/2011 01:28PM
ADT problems
March 06, 2006 08:11AM
Hi.

I've done chapter 5 in header files but get the following errors:
[Linker error] undefined reference to `linkedListType<int>::linkedListType()'

[Linker error] undefined reference to `linkedListType<int>::~linkedListType()'

[Linker error] undefined reference to `linkedListType<int>::~linkedListType()'

anyone else getting the same problems.

My files:
//linkedListType
//Header file: linkedListType

#ifndef LINKEDLISTTYPE_H
#define LINKEDLISTTYPE_H

#include <iostream>
#include <cassert>
#include <ostream>

using namespace std;

template<class Type>
struct nodeType
{
Type info;
nodeType<Type> *link;
};


template<class Type>
class linkedListType
{
friend ostream& operator<<(ostream&, const linkedListType<Type>&winking smiley;

public:
const linkedListType<Type>& operator=(const linkedListType<Type>&winking smiley;

void initializeList();

bool isEmptyList();

int length();

void destroyList();

Type front();

Type back();

bool search(const Type& searchItem);

void insertFirst(const Type& newItem);

void insertLast(const Type& newItem);

void deleteNode(const Type& deleteItem);

linkedListType();

linkedListType(const linkedListType<Type>& otherList);

~linkedListType();

protected:
int count; //Variable to store the number of elements
//in the list
nodeType<Type> *first; //Pointer to the first node of the list
nodeType<Type> *last; //Pointer to the last node of the list

private:
void copyList(const linkedListType<Type>& otherList);

};
#endif


#include "LinkedListType.h"

template<class Type>
const linkedListType<Type>& linkedListType<Type>eye popping smileyperator=
(const linkedListType<Type>& otherList)
{
if(this != &otherList) //Avoid self-copy
copyList(otherList);
return *this;
}

template<class Type>
linkedListType<Type>::linkedListType(const linkedListType<Type>& otherList)
{
first = NULL;
copyList(otherList);
} //end copy constructor

template<class Type>
linkedListType<Type>::~linkedListType() //dstructor
{
destroyList();
} //end destructor

template<class Type>
void linkedListType<Type>::copyList(const linkedListType<Type>& otherList)
{
nodeType<Type> *newNode; //Pointer to create a node
nodeType<Type> *current; //Pointer to traversed the list

if(first != NULL) //If the list is not empty, make it empty
destroyList();

if(otherList.first == NULL) //otherList is empty
{
first = NULL;
last = NULL;
count = 0;
}
else
{
current = otherList.first; //current points to the list to be copied
count = otherList.count;

//copy the first node
first = new nodeType<Type>; //Create the node

assert(first != NULL);

first->info = current->info; //copy the info
first->link = NULL; //Set the link field of the node to NULL
last = first; //Make last point to the first node
current = current->link; //Make current point to the mext node

//Copy the remaining list
while(current != NULL)
{
newNode = new nodeType<Type>; //Create a node

assert(newNode != NULL);

newNode->info = current->info; //Copy the info
newNode-link = NULL; //Set the link of newNode to NULL
last->link = newNode; //Attach newNode after last
last = newNode; //Make last point to the actual last node
current = current->link; //Make current point to the next node
} //end while
} //end else
} //end copyList

template<class Type>
void linkedListType<Type>::deleteNode(const Type& deleteItem)
{
nodeType<Type> *current; //Pointer to traverse the list
nodeType<Type> *trailCurrent; //Pointer just before current
bool found;

if(first == NULL) //Case 1; list is empty
cerr<<"Cannot delete from an empty list.\n";
else
{
if(first->info == deleteItem) //Case 2
{
current = first;
first = first->link;
count--;
if(first == NULL) //List has only one node
last = NULL;
delete current;
}
else //Search the list for the node with the given info
{
found = false;
trailCurrent = first; //Set trailCurrent to point to the first node
current = first->link; //Set current to point to the second node

while(current != NULL && !found)
{
if(current->info != deleteItem)
{
trailCurrent = current;
current = current->link;
}
else
found = true;
} //End while

if(found) //Case 3; if found, delete the node
{
trailCurrent->link = current->link;
count--;

if(last == current) //node to be deleted was the last node
last = trailCurrent; //Update the value of last

delete current; //Delete the node from the list
}
else
cout<<"Item to be deleted is not in the list.\n"<<endl;
} //End if
} //End else
} //End deleteNode

template<class Type>
void linkedListType<Type>::insertLast(const Type& newItem)
{
nodeType<Type> *newNode; //Pointer to create the new node
newNode = new nodeType<Type>; //Create new node
assert(newNode != NULL); //If unable to allocate memory,
//terminate the program
newNode->info = newItem; //Store the new item in the node
newNode->link = NULL; //Set the link field of newNode
//to NULL
if(first == NULL) //If the list is empty, newNode is both
//the first and last node
{
first = newNode;
last = newNode;
count++; //Increment count
}
else //The list is not empty, insert newNode after last
{
last->link = newNode; //Insert newNode after last
last = newNode; //Make last point to the actual last node
count++;
}
} //end insertLast

template<class Type>
void linkedListType<Type>::insertFirst(const Type& newItem)
{
nodeType<Type> *newNode; //Pointer to create the new node
newNode = new nodeType<Type>; //Create the new node
assert(newNode != NULL); //If unable to allocate memory, terminate
//the program
newNode->info = newItem; //Store newItem in the node
newNode->link = first; //Insert newNode before fisrt
first = newNode; //Make first point to the actual first node
count++; //Increment count

if(last == NULL) //If the last was empty, newNode is also
//the last node in the list
last = newNode;
}


template<class Type>
bool linkedListType<Type>::search(const Type& searchItem)
{
nodeType<Type> *current; //Pointer to traverse(step through) the list
bool found;
current = first; //Set the current to point to the first
//node in the list
found = false; //Set found to false

while(current != NULL && !found) //Search the list
{
if(current->info == searchItem) //The item is found
found = true;
else
current = current->link; //Make current point to the next node
}
return found;
} //end search

template<class Type>
Type linkedListType<Type>::back()
{
assert(last != NULL);
return last->info; //Return the info of the last node
}

template<class Type>
Type linkedListType<Type>::front()
{
assert(last != NULL);
return first->info; //Return the info of the first node
}


template<class Type>
linkedListType<Type>::linkedListType()
{
first = NULL;
last = NULL;
count = 0;
}

template<class Type>
void linkedListType<Type>::destroyList()
{
nodeType<Type> *temp; //pointer to deallocate the memory occuped
//by the node
while(first != NULL) //While there are nodes in the list
{
temp = first; //Set temp to the current node
first = first->link; //Advance first to the next node
delete temp; //deallocate the memory occupied by temp
}
last = NULL; //Initialize last to NULL; first has already been set
//to NULL by the while loop
count = 0;
}

template<class Type>
void linkedListType<Type>::initializeList()
{
destroyList(); //If the list has any nodes, delete them

}

template<class Type>
int linkedListType<Type>::length()
{
return count;
} //End length

template<class Type>
ostream& operator<<(ostream& osObject, const linkedListType<Type>& list)
{
nodeType<Type> *current; //Pointer to traverse the list
current = list.first; //Set current so that it points to the first node
while(current != NULL)
{
osObject<<current->info<<" ";
current = current->link;
}
return osObject;
}



template<class Type>
bool linkedListType<Type>::isEmptyList()
{
return(first == NULL);
}


#include <iostream>
#include "linkedListType.h"
#include "OrderedLinkedListType.h"

using namespace std;

int main()
{
//orderedLinkedListType<int> list;
//orderedLinkedListType<int> list1, list2;
linkedListType<int> list1;
int num;

cout<<"Enter integers ending with -999"<<endl;
cin>>num;

while(num != -999)
{
//list1.insertNode(num);
cin>>num;
}

cout<<endl;

//cout<<"List 1: "<<list1<<endl;

//list2 = list1;

//cout<<"List2: "<<list2<<endl;

cout<<"Enter the number to be deleted: ";
cin>>num;
cout<<endl;

//list2.deleteNode(num);
//cout<<"After deletetin the node, List 2: "<<endl<<list2<<endl;

cin>>num;
return 0;
}

Any help please.
avatar Re: ADT problems
March 06, 2006 07:35PM
Hi WillemL

Your error messages make no sense. Usually, you only get the "Undefined reference" when you've declared something but not defined it but I see you've defined both your default constructor and your destructor so this is a bit strange.

I see you've uncommented all other lines using list1 (bad naming by the way). I suspect you were getting the same error for the other methods. I don't think your linker is linking the implementation of your class.

Try this:

Copy and paste the code into your main source file (rememeber to comment out the include reference). If it compiles properly then there's a problem with your linking settings.

Cheers
Rob
Re: ADT problems
March 09, 2006 08:56AM
I've copied all the code to my main source file and are still having problems. The errors is now:

[Linker error] undefined reference to `operator<<(stdeye popping smileystream&, linkedListType<int> const&winking smiley'

[Linker error] undefined reference to `operator<<(stdeye popping smileystream&, linkedListType<int> const&winking smiley'

[Linker error] undefined reference to `operator<<(stdeye popping smileystream&, linkedListType<int> const&winking smiley'



Here is my code:

#include <iostream>
#include <ostream>
//#include "LinkedList.h"
//#include "OrderedLinkedList.h"

using namespace std;


template<class Type>
struct nodeType
{
Type info;
nodeType<Type> *link;
};

template<class Type>
class linkedListType
{
//friend ostream& operator<<(ostream& osObject, const linkedListType<Type>& list);
friend ostream& operator<<(ostream&, const linkedListType<Type>&winking smiley;
//Overload the stream insertion operator.

public:
//ostream& operator<<(ostream&, const linkedListType<Type>&winking smiley;
const linkedListType<Type>& operator=(const linkedListType<Type>&winking smiley;
//Overload the assignment operator.

void initializeList();
//Function to initialize the list to an empty state.
//Postcondition: first = NULL; last = NULL;
// count = 0

bool isEmptyList();
//Function to determine whether the list is empty.
//Postcondition: Returns true if the list is empty;
// otherwise, returns false.

int length();
//Function to return the number of nodes in the list.
//Postcondition: The value of count is returned.

void destroyList();
//Function to delete all the nodes from the list.
//Postcondition: first = NULL; last = NULL;
// count = 0

Type front();
//Function to return the first element of the list.
//Precondition: The list must exist and must not be empty.
//Postcondition: If the list is empty, then the program
// terminates; otherwise, the first element
// of the list is returned.

Type back();
//Function to return the last element of the list.
//Precondition: The list must exist and must not be empty.
//Postcondition: If the list is empty, then the program
// terminates; otherwise, the last element
// of the list is returned.

bool search(const Type& searchItem);
//Function to determine whether searchItem is in the list.
//Postcondition: Returns true if searchItem is found
// in the list; otherwise, returns false.

void insertFirst(const Type& newItem);
//Function to insert newItem in the list.
//Postcondition: first points to the new list,
// newItem is inserted at the beginning of
// the list, last points to the last node,
// and count is incremented by 1.

void insertLast(const Type& newItem);
//Function to insert newItem at the end of the list.
//Postcondition: first points to the new list,
// newItem is inserted at the end of the list,
// last points to the last node in the list, and
// count is incremented by 1.

void deleteNode(const Type& deleteItem);
//Function to delete deleteItem from the list.
//Postcondition: If found, the node containing deleteItem
// is deleted from the list, first points to the
// first node, last points to the last node of
// the updated list, and count is decremented by 1.

linkedListType();
//Default constructor
//Initialize the list to an empty state.
//Postcondition: first = NULL; last = NULL;
// count = 0

linkedListType(const linkedListType<Type>& otherList);
//copy constructor

~linkedListType();
//Destructor
//Deletes all the nodes from the list.
//Postcondition: The list object is destroyed.

protected:
int count; //Variable to store the number of elements
//in the list
nodeType<Type> *first; //Pointer to the first node of the list
nodeType<Type> *last; //Pointer to the last node of the list

private:
void copyList(const linkedListType<Type>& otherList);
//Function to make a copy of otherList.
//Postcondition: A copy of otherList is created
// and assigned to this list.

};

//template<class Type>
//ostream& operator<<(ostream& osObject, const linkedListType<Type>& list);

template<class Type>
const linkedListType<Type>& linkedListType<Type>eye popping smileyperator=
(const linkedListType<Type>& otherList)
{
if(this != &otherList) //Avoid self-copy
copyList(otherList);
return *this;
}

template<class Type>
linkedListType<Type>::linkedListType(const linkedListType<Type>& otherList)
{
first = NULL;
copyList(otherList);
} //end copy constructor

template<class Type>
linkedListType<Type>::~linkedListType() //dstructor
{
destroyList();
} //end destructor

template<class Type>
void linkedListType<Type>::copyList(const linkedListType<Type>& otherList)
{
nodeType<Type> *newNode; //Pointer to create a node
nodeType<Type> *current; //Pointer to traversed the list

if(first != NULL) //If the list is not empty, make it empty
destroyList();

if(otherList.first == NULL) //otherList is empty
{
first = NULL;
last = NULL;
count = 0;
}
else
{
current = otherList.first; //current points to the list to be copied
count = otherList.count;

//copy the first node
first = new nodeType<Type>; //Create the node

assert(first != NULL);

first->info = current->info; //copy the info
first->link = NULL; //Set the link field of the node to NULL
last = first; //Make last point to the first node
current = current->link; //Make current point to the mext node

//Copy the remaining list
while(current != NULL)
{
newNode = new nodeType<Type>; //Create a node

assert(newNode != NULL);

newNode->info = current->info; //Copy the info
newNode->link = NULL; //Set the link of newNode to NULL
last->link = newNode; //Attach newNode after last
last = newNode; //Make last point to the actual last node
current = current->link; //Make current point to the next node
} //end while
} //end else
} //end copyList

template<class Type>
void linkedListType<Type>::deleteNode(const Type& deleteItem)
{
nodeType<Type> *current; //Pointer to traverse the list
nodeType<Type> *trailCurrent; //Pointer just before current
bool found;

if(first == NULL) //Case 1; list is empty
cerr<<"Cannot delete from an empty list.\n";
else
{
if(first->info == deleteItem) //Case 2
{
current = first;
first = first->link;
count--;
if(first == NULL) //List has only one node
last = NULL;
delete current;
}
else //Search the list for the node with the given info
{
found = false;
trailCurrent = first; //Set trailCurrent to point to the first node
current = first->link; //Set current to point to the second node

while(current != NULL && !found)
{
if(current->info != deleteItem)
{
trailCurrent = current;
current = current->link;
}
else
found = true;
} //End while

if(found) //Case 3; if found, delete the node
{
trailCurrent->link = current->link;
count--;

if(last == current) //node to be deleted was the last node
last = trailCurrent; //Update the value of last

delete current; //Delete the node from the list
}
else
cout<<"Item to be deleted is not in the list.\n"<<endl;
} //End if
} //End else
} //End deleteNode

template<class Type>
void linkedListType<Type>::insertLast(const Type& newItem)
{
nodeType<Type> *newNode; //Pointer to create the new node
newNode = new nodeType<Type>; //Create new node
assert(newNode != NULL); //If unable to allocate memory,
//terminate the program
newNode->info = newItem; //Store the new item in the node
newNode->link = NULL; //Set the link field of newNode
//to NULL
if(first == NULL) //If the list is empty, newNode is both
//the first and last node
{
first = newNode;
last = newNode;
count++; //Increment count
}
else //The list is not empty, insert newNode after last
{
last->link = newNode; //Insert newNode after last
last = newNode; //Make last point to the actual last node
count++;
}
} //end insertLast

template<class Type>
void linkedListType<Type>::insertFirst(const Type& newItem)
{
nodeType<Type> *newNode; //Pointer to create the new node
newNode = new nodeType<Type>; //Create the new node
assert(newNode != NULL); //If unable to allocate memory, terminate
//the program
newNode->info = newItem; //Store newItem in the node
newNode->link = first; //Insert newNode before fisrt
first = newNode; //Make first point to the actual first node
count++; //Increment count

if(last == NULL) //If the last was empty, newNode is also
//the last node in the list
last = newNode;
}


template<class Type>
bool linkedListType<Type>::search(const Type& searchItem)
{
nodeType<Type> *current; //Pointer to traverse(step through) the list
bool found;
current = first; //Set the current to point to the first
//node in the list
found = false; //Set found to false

while(current != NULL && !found) //Search the list
{
if(current->info == searchItem) //The item is found
found = true;
else
current = current->link; //Make current point to the next node
}
return found;
} //end search

template<class Type>
Type linkedListType<Type>::back()
{
assert(last != NULL);
return last->info; //Return the info of the last node
}

template<class Type>
Type linkedListType<Type>::front()
{
assert(last != NULL);
return first->info; //Return the info of the first node
}


template<class Type>
linkedListType<Type>::linkedListType()
{
first = NULL;
last = NULL;
count = 0;
}

template<class Type>
void linkedListType<Type>::destroyList()
{
nodeType<Type> *temp; //pointer to deallocate the memory occuped
//by the node
while(first != NULL) //While there are nodes in the list
{
temp = first; //Set temp to the current node
first = first->link; //Advance first to the next node
delete temp; //deallocate the memory occupied by temp
}
last = NULL; //Initialize last to NULL; first has already been set
//to NULL by the while loop
count = 0;
}

template<class Type>
void linkedListType<Type>::initializeList()
{
destroyList(); //If the list has any nodes, delete them

}

template<class Type>
int linkedListType<Type>::length()
{
return count;
} //End length


template<class Type>
ostream& operator<<(ostream& osObject, const linkedListType<Type>& list)
{
nodeType<Type> *current; //Pointer to traverse the list
current = list.first; //Set current so that it points to the first node
while(current != NULL)
{
osObject<<current->info<<" ";
current = current->link;
}
return osObject;
}



template<class Type>
bool linkedListType<Type>::isEmptyList()
{
return(first == NULL);
}



//*****************************
//*** orderedLinkedListType ***
//*****************************

template<class Type>
class orderedLinkedListType : public linkedListType<Type>
{
public:
bool search(const Type& searchItem);
//Function to determine wheter searchItem is in the list
//Postcondition: Returns true if searchItem is found in
// the list; otherwise, it returns false.

void insertNode(const Type& newItem);
//Function to insert newItem in the list.
//Postcondition: fist point to new list and newItem is
// inserted at the proper place in the list, and
// count is incremented by 1

void deleteNode(const Type& deleteItem);
//Function to delete deleteItem from the list.
//Postcondition: If found, the node containing deleteItem is
// deleted from the list; first points the the
// first node of the new list, and count is
// decremented by 1
// If deleteItem is not in the list, an
// appropriate message is printed.
};

template<class Type>
bool orderedLinkedListType<Type>::search(const Type& searchItem)
{
bool found;
nodeType<Type> *current; //Pointer to traverese the list

found = false; //Initialize found to false
current = first; //Start the search at the first node

while(current != NULL && !found)
if(current->info >= searchItem)
found = true;
else
current = current->link;

if(found)
found = (current->info == searchItem); //Test for equality

return found;
} //end search

template<class Type>
void orderedLinkedListType<Type>::insertNode(const Type& newItem)
{
nodeType<Type> *current; //Pointer to traverse the list
nodeType<Type> *trailCurrent; //Pointer just before current
nodeType<Type> *newNode; //Pointer to create a node
bool found;

newNode = new nodeType<Type>; //Create new node
assert(newNode != NULL);

newNode->info = newItem; //Store newmItem in the node
newNode->link = NULL; //Set link field of the node to NULL

if(first == NULL) //Case 1 - The list is empty
{
first = newNode;
count++;
}
else
{
current = first;
found = false;

while(current != NULL && !found) //Search the list
{
if(current->info >= newItem)
found = true;
else
{
trailCurrent = current;
current = current->link;
}
}
if(current == first) //Case 2 - List isn't empty & item is smaller
//than all items in list
{
newNode->link = first;
first = newNode;
count++;
}
else //Case 3 - List isn't empty & item isn't smallest
{
trailCurrent->link = newNode;
newNode->link = current;
count++;
}
} //end else
} //end insertNode

template<class Type>
void orderedLinkedListType<Type>::deleteNode(const Type& deleteItem)
{
nodeType<Type> *current; //Pointer to traverse the list
nodeType<Type> *trailCurrent; //Pointer kust before current
bool found;

if(first != NULL) //Case 1 - The list is initially empty
cerr<<"Cannot delete from an empty list."<<endl;
else
{
current = first;
found = false;

while(current != NULL && !found) //Search the list
if(current->info >= deleteItem)
found = true;
else
{
trailCurrent = current;
current = current->link;
}

if(current == NULL) // Case 4 - The list isn't empty, but item
//isn't in the list
cout<<"The item to be deleted is not in the list."<<endl;
else
if(current->info == deleteItem) //Item to be deleted is in list
{
if(first == current) //Case 2 - The item is found at first node
{
first = first->link;
delete current;
}
else //Case 3 - The item to delete is somewhere in the list
{
trailCurrent->link = current->link;
delete current;
}
count--;
}
else //Case 4 - The list isn't empty, but item isn't in the list
cout<<"The item to be deleted is not in the list."<<endl;
}
} //end deleteNode


//************
//*** MAIN ***
//************

int main()
{
//orderedLinkedListType<int> list;
orderedLinkedListType<int> list1, list2;
//linkedListType<int> list1;
int num;

cout<<"Enter integers ending with -999"<<endl;
cin>>num;

while(num != -999)
{
list1.insertNode(num);
cin>>num;
}

cout<<endl;

cout<<"List 1: "<<list1<<endl;

list2 = list1;

cout<<"List2: "<<list2<<endl;

cout<<"Enter the number to be deleted: ";
cin>>num;
cout<<endl;

list1.deleteNode(num);

cout<<"After deletetin the node, List 2: "<<endl<<list2<<endl;

cin>>num;
return 0;
}

(in connection with the naming List1, I typed it out of the prescribed book, that is why I cannot understand why I'm having problems.)

This is getting realy silly. I mean, you type everything from the prescribed book in order to start playing with what you've learned, but supprice, The code doesn't work.

And how do I turn of these silly faces?
avatar Re: ADT problems
March 09, 2006 03:59PM
Your problem is that your operator<< function has no body - there is only the function header.
Re: ADT problems
March 13, 2006 08:58AM
Hi, please take note of the errata on page 22 of tutorial letter 101.

regards
Lazarus
Re: ADT problems
March 16, 2006 12:42PM
well according to me, tut 101, p22 has no errata? it's the last question off ass3?

willem, i had a similar problem, but downloaded the source files off their website.

i've done all the question except, q8. their source code doesn't compile, "u cannot access protected item in inhertited class" or something along those lines? so? now what? any ideas?
avatar Re: ADT problems
March 17, 2006 04:29PM
Hi Chris

Did you type it in correctly? It compiles fine on my compiler (MSVS)

An error like the one you mentioned shouldn't occur unless you try to access a member from outside the class.

e.g.

class MyClass {

// some code here

protected:

int myInt;

};

void main() {

MyClass instance;

instance.myInt = 5; // access denied error

}

Cheers
Rob
Re: ADT problems
March 18, 2006 03:48PM
well u c , i never typed it out, i downloaded the original code from malik website, "course.com", the problem i'm having is that, the function:

___________________________________________
template<class Type>
ostream& operator<<(ostream& osObject, const linkedListType<Type>& list)
{
nodeType<Type> *current; //pointer to traverse the list


hot smiley current = list.first; //set current so that it points to
//the first node
while(current != NULL) //while more data to print
{
osObject<<current->info<<" ";
current = current->link;
}

return osObject;
}

____________________________________

from the code gives me this error from the burning smiley line:

'first' : cannot access protected member declared in class 'linkedListType<int>'

______________________________________

from the headerfile linkedlist.h

i'm using MSvisual C++6.

avatar Re: ADT problems
March 19, 2006 10:09AM
Ok simple solution

The operator<< is not a member of the class so any time you want to access private or protected members, you'll get that error.

To remedy this, you need to tell the class that this function has special access rights to all members of the class. You must have the following line somewhere in your LinkedListType class declaration:

friend ostream &operator<< (ostream &osObject, LinkedListType<Type> &list);

That should sort the problem out.

Cheers
Rob
Re: ADT problems
March 24, 2006 08:42AM
Hi,

Sorry! the errata is on page 25 of tut letter 101.


You need to replace the following line in your class definition

friend ostream& operator<<(ostream&, const linkedListType<Type>& );

with

friend ostream& operator<< < > (ostream&, const linkedListType<Type>& );

The difference is < > after <<.

regards
Lazarus Aron
Sorry, only registered users may post in this forum.

Click here to login