/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #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;}
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
#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;
}