#include <u.h>
#include <libc.h>
#include <ctype.h>
#include <fcall.h>
#include <thread.h>
#include <9p.h>

#include "dat.h"
#include "fns.h"

char *whitespace = " \t\r\n";

void*
emalloc(int n)
{
	void *v;
	v = emalloc9p(n);
	setmalloctag(v, getcallerpc(&n));
	memset(v, 0, n);
	return v;
}

char*
estrdup(char *s)
{
	s = estrdup9p(s);
	setmalloctag(s, getcallerpc(&s));
	return s;
}

void
nstrcpy(char *to, char *from, int n)
{
	strncpy(to, from, n);
	to[n-1] = 0;
}

Key*
addkey(Key *h, char *key, char *val)
{
	Key *k;
	int n;

	if(val == nil)
		val = "";
	n = strlen(key)+1;
	k = emalloc(sizeof(*k) + n + strlen(val)+1);
	k->next = h;
	k->val = k->key + n;
	strcpy(k->key, key);
	strcpy(k->val, val);
	return k;
}

Key*
delkey(Key *h, char *key)
{
	Key *k, *p;

	for(p = nil, k = h; k; p = k, k = k->next){
		if(!cistrcmp(k->key, key)){
			if(p)
				p->next = k->next;
			else
				h = k->next;
			memset(k->val, 0, strlen(k->val));
			free(k);
			break;
		}
	}
	return h;
}

Key*
getkey(Key *k, char *key)
{
	while(k){
		if(!cistrcmp(k->key, key))
			break;
		k = k->next;
	}
	return k;
}

char*
lookkey(Key *k, char *key)
{
	if(k = getkey(k, key))
		return k->val;
	return nil;
}

Key*
parsehdr(char *s)
{
	char *v;

	if(*s == 0)
		return nil;
	v = strchr(s, 0)-1;
	while(v >= s && strchr(whitespace, *v))
		*v-- = 0;
	if(v = strchr(s, ':')){
		*v++ = 0;
		while(*v == ' ' || *v == '\t')
			v++;
		if(*s && *v)
			return addkey(0, s, v);
	}
	return nil;
}

char*
unquote(char *s, char **ps)
{
	char *p;

	if(*s != '"'){
		p = s;
		while(*p){
			if(strchr(" \t\r\n", *p) != nil){
				*p++ = 0;
				break;
			}
			p++;
		}
		*ps = p;
		return s;
	}
	for(p=s+1; *p; p++){
		if(*p == '\"'){
			*p++ = 0;
			break;
		}
		if(*p == '\\' && *(p+1)){
			p++;
			continue;
		}
	}
	memmove(s, s+1, p-(s+1));
	s[p-(s+1)] = 0;
	*ps = p;
	return s;
}
