/* * 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 #include #include 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()); 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()); 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()); } else if(t[strlen(t)-1] == '?'){ t[strlen(t)-1] = '\0'; a = _mkattr(AttrQuery, t, "", a); setmalloctag(a, getcallerpc()); }else{ /* really a syntax error, but better to provide some indication */ a = _mkattr(AttrNameval, t, "", a); setmalloctag(a, getcallerpc()); } } free(s); return cleanattr(a); } char* _strfindattr(Attr *a, char *n) { a = _findattr(a, n); if(a == nil) return nil; return a->val; }