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, '=')){
144 // if(p-2 >= t && p[-2] == ':'){
146 // type = AttrDefault;
149 a = _mkattr(type, t, p, a);
150 setmalloctag(a, getcallerpc(&s));
152 else if(t[strlen(t)-1] == '?'){
153 t[strlen(t)-1] = '\0';
154 a = _mkattr(AttrQuery, t, "", a);
155 setmalloctag(a, getcallerpc(&s));
157 /* really a syntax error, but better to provide some indication */
158 a = _mkattr(AttrNameval, t, "", a);
159 setmalloctag(a, getcallerpc(&s));
167 _strfindattr(Attr *a, char *n)