#include <u.h>
#include <libc.h>
#include <auth.h>
int
_attrfmt(Fmt *fmt)
{
char *b, buf[1024], *ebuf;
Attr *a;
ebuf = buf+sizeof buf;
b = buf;
strcpy(buf, " ");
for(a=va_arg(fmt->args, Attr*); a; a=a->next){
if(a->name == nil)
continue;
switch(a->type){
case AttrQuery:
b = seprint(b, ebuf, " %q?", a->name);
break;
case AttrNameval:
b = seprint(b, ebuf, " %q=%q", a->name, a->val);
break;
case AttrDefault:
b = seprint(b, ebuf, " %q:=%q", a->name, a->val);
break;
}
}
return fmtstrcpy(fmt, buf+1);
}
Attr*
_copyattr(Attr *a)
{
Attr **la, *na;
na = nil;
la = &na;
for(; a; a=a->next){
*la = _mkattr(a->type, a->name, a->val, nil);
setmalloctag(*la, getcallerpc(&a));
la = &(*la)->next;
}
*la = nil;
return na;
}
Attr*
_delattr(Attr *a, char *name)
{
Attr *fa;
Attr **la;
for(la=&a; *la; ){
if(strcmp((*la)->name, name) == 0){
fa = *la;
*la = (*la)->next;
fa->next = nil;
_freeattr(fa);
}else
la=&(*la)->next;
}
return a;
}
Attr*
_findattr(Attr *a, char *n)
{
for(; a; a=a->next)
if(strcmp(a->name, n) == 0 && a->type != AttrQuery)
return a;
return nil;
}
void
_freeattr(Attr *a)
{
Attr *anext;
for(; a; a=anext){
anext = a->next;
free(a->name);
free(a->val);
a->name = (void*)~0;
a->val = (void*)~0;
a->next = (void*)~0;
free(a);
}
}
Attr*
_mkattr(int type, char *name, char *val, Attr *next)
{
Attr *a;
a = malloc(sizeof(*a));
if(a==nil)
sysfatal("_mkattr malloc: %r");
a->type = type;
a->name = strdup(name);
a->val = strdup(val);
if(a->name==nil || a->val==nil)
sysfatal("_mkattr malloc: %r");
a->next = next;
setmalloctag(a, getcallerpc(&type));
return a;
}
static Attr*
cleanattr(Attr *a)
{
Attr *fa;
Attr **la;
for(la=&a; *la; ){
if((*la)->type==AttrQuery && _findattr(a, (*la)->name)){
fa = *la;
*la = (*la)->next;
fa->next = nil;
_freeattr(fa);
}else
la=&(*la)->next;
}
return a;
}
Attr*
_parseattr(char *s)
{
char *p, *t, *tok[256];
int i, ntok, type;
Attr *a;
s = strdup(s);
if(s == nil)
sysfatal("_parseattr strdup: %r");
ntok = tokenize(s, tok, nelem(tok));
a = nil;
for(i=ntok-1; i>=0; i--){
t = tok[i];
if((p = strchr(t, '='))){
*p++ = '\0';
// if(p-2 >= t && p[-2] == ':'){
// p[-2] = '\0';
// type = AttrDefault;
// }else
type = AttrNameval;
a = _mkattr(type, t, p, a);
setmalloctag(a, getcallerpc(&s));
}
else if(t[strlen(t)-1] == '?'){
t[strlen(t)-1] = '\0';
a = _mkattr(AttrQuery, t, "", a);
setmalloctag(a, getcallerpc(&s));
}else{
/* really a syntax error, but better to provide some indication */
a = _mkattr(AttrNameval, t, "", a);
setmalloctag(a, getcallerpc(&s));
}
}
free(s);
return cleanattr(a);
}
char*
_strfindattr(Attr *a, char *n)
{
a = _findattr(a, n);
if(a == nil)
return nil;
return a->val;
}
|