#include <mylib.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "/usr/include/assert.h"

property::property() :attr(0), val(0), comment(0), refc(0), next(0) {}


property::property(struct property *n, const char *a, const char *v, const char *c)
:attr(strdup(a?a:"")), val(v?strdup(v):0), comment(c?strdup(c):0), refc(0), next(n) {}


void property::free()
{
 if(attr)	{
	::free(attr);
	attr = 0;
	}
 if(val)	{
	::free(val);
	val = 0;
	}
 if(comment)	{
	::free(comment);
	comment = 0;
	}
}


property::~property() { free(); }

proplist::proplist() : first(0) {};

void property::incref()	{ refc++;}

int property::decref()	{ if(refc-- <= 0) {free();} return 0;}


proplist::~proplist()
{
 while(pop())
	;
}


BOOL proplist::pop()
{
 assert(this);
 if(!isempty())	{
	struct property *next = first->next;
	if(first->decref())
		delete first;
	first = next;
	}

 return !isempty();
}


proplist::proplist(const proplist& x)
: first(x.first)
{
 struct property *t;
 for(t=first; t; t=t->next)
	t->incref();
}



proplist& proplist::operator=(const proplist& x)
{
 if(this != &x)	{
	while(pop())
		;
	}
 first = x.first;
 struct property *t;
 for(t=first; t; t=t->next)
	t->incref();

 return *this;
}


void proplist::add(const char *a, const char *v, const char *c)
{
 assert(this);
 struct property *t;
 for(t=first; t; t=t->next)
	if(strcmp(t->attr, a) == 0)	{
		if(t->val)
			free(t->val);
		if(t->comment)
			free(t->comment);

		t->val = v ? strdup(v) : 0;
		t->comment = c ? strdup(c) : 0;
		return;
		}

 first = new property(first, a, v, c);
}


property *proplist::get(const char *a)
{
 assert(this);
 struct property *t;
 for(t=first; t; t=t->next)
	if(strcmp(t->attr, a) == 0)
		return t;

 return 0;
}


const char *proplist::getstring(const char *attr, const char *notthere)
{
 assert(this);
 property *tmp = get(attr);
 if(!tmp)
	return notthere;

 return tmp->val;
}
