8 char *b, buf[1024], *ebuf;
11 ebuf = buf+sizeof buf;
14 for(a=va_arg(fmt->args, Attr*); a; a=a->next){
19 b = seprint(b, ebuf, " %q?", a->name);
22 b = seprint(b, ebuf, " %q=%q", a->name, a->val);
25 b = seprint(b, ebuf, " %q:=%q", a->name, a->val);
29 return fmtstrcpy(fmt, buf+1);
40 *la = _mkattr(a->type, a->name, a->val, nil);
41 setmalloctag(*la, getcallerpc(&a));
49 _delattr(Attr *a, char *name)
55 if(strcmp((*la)->name, name) == 0){
67 _findattr(Attr *a, char *n)
70 if(strcmp(a->name, n) == 0 && a->type != AttrQuery)
92 _mkattr(int type, char *name, char *val, Attr *next)
96 a = malloc(sizeof(*a));
98 sysfatal("_mkattr malloc: %r");
100 a->name = strdup(name);
101 a->val = strdup(val);
102 if(a->name==nil || a->val==nil)
103 sysfatal("_mkattr malloc: %r");
105 setmalloctag(a, getcallerpc(&type));
116 if((*la)->type==AttrQuery && _findattr(a, (*la)->name)){
130 char *p, *t, *tok[256];
136 sysfatal("_parseattr strdup: %r");
138 ntok = tokenize(s, tok, nelem(tok));
140 for(i=ntok-1; i>=0; i--){
142 if((p = strchr(t, '=')) != nil){
144 a = _mkattr(AttrNameval, t, p, a);
145 }else if((p = strchr(t, '\0')-1) >= t && *p == '?'){
147 a = _mkattr(AttrQuery, t, "", a);
149 /* really a syntax error, but better to provide some indication */
150 a = _mkattr(AttrNameval, t, "", a);
152 setmalloctag(a, getcallerpc(&s));
159 _strfindattr(Attr *a, char *n)