1 #include <u.h> 2 #include <libc.h> 3 #include <auth.h> 4 5 int 6 _attrfmt(Fmt *fmt) 7 { 8 char *b, buf[1024], *ebuf; 9 Attr *a; 10 11 ebuf = buf+sizeof buf; 12 b = buf; 13 strcpy(buf, " "); 14 for(a=va_arg(fmt->args, Attr*); a; a=a->next){ 15 if(a->name == nil) 16 continue; 17 switch(a->type){ 18 case AttrQuery: 19 b = seprint(b, ebuf, " %q?", a->name); 20 break; 21 case AttrNameval: 22 b = seprint(b, ebuf, " %q=%q", a->name, a->val); 23 break; 24 case AttrDefault: 25 b = seprint(b, ebuf, " %q:=%q", a->name, a->val); 26 break; 27 } 28 } 29 return fmtstrcpy(fmt, buf+1); 30 } 31 32 Attr* 33 _copyattr(Attr *a) 34 { 35 Attr **la, *na; 36 37 na = nil; 38 la = &na; 39 for(; a; a=a->next){ 40 *la = _mkattr(a->type, a->name, a->val, nil); 41 setmalloctag(*la, getcallerpc(&a)); 42 la = &(*la)->next; 43 } 44 *la = nil; 45 return na; 46 } 47 48 Attr* 49 _delattr(Attr *a, char *name) 50 { 51 Attr *fa; 52 Attr **la; 53 54 for(la=&a; *la; ){ 55 if(strcmp((*la)->name, name) == 0){ 56 fa = *la; 57 *la = (*la)->next; 58 fa->next = nil; 59 _freeattr(fa); 60 }else 61 la=&(*la)->next; 62 } 63 return a; 64 } 65 66 Attr* 67 _findattr(Attr *a, char *n) 68 { 69 for(; a; a=a->next) 70 if(strcmp(a->name, n) == 0 && a->type != AttrQuery) 71 return a; 72 return nil; 73 } 74 75 void 76 _freeattr(Attr *a) 77 { 78 Attr *anext; 79 80 for(; a; a=anext){ 81 anext = a->next; 82 free(a->name); 83 free(a->val); 84 a->name = (void*)~0; 85 a->val = (void*)~0; 86 a->next = (void*)~0; 87 free(a); 88 } 89 } 90 91 Attr* 92 _mkattr(int type, char *name, char *val, Attr *next) 93 { 94 Attr *a; 95 96 a = malloc(sizeof(*a)); 97 if(a==nil) 98 sysfatal("_mkattr malloc: %r"); 99 a->type = type; 100 a->name = strdup(name); 101 a->val = strdup(val); 102 if(a->name==nil || a->val==nil) 103 sysfatal("_mkattr malloc: %r"); 104 a->next = next; 105 setmalloctag(a, getcallerpc(&type)); 106 return a; 107 } 108 109 static Attr* 110 cleanattr(Attr *a) 111 { 112 Attr *fa; 113 Attr **la; 114 115 for(la=&a; *la; ){ 116 if((*la)->type==AttrQuery && _findattr(a, (*la)->name)){ 117 fa = *la; 118 *la = (*la)->next; 119 fa->next = nil; 120 _freeattr(fa); 121 }else 122 la=&(*la)->next; 123 } 124 return a; 125 } 126 127 Attr* 128 _parseattr(char *s) 129 { 130 char *p, *t, *tok[256]; 131 int i, ntok, type; 132 Attr *a; 133 134 s = strdup(s); 135 if(s == nil) 136 sysfatal("_parseattr strdup: %r"); 137 138 ntok = tokenize(s, tok, nelem(tok)); 139 a = nil; 140 for(i=ntok-1; i>=0; i--){ 141 t = tok[i]; 142 if((p = strchr(t, '='))){ 143 *p++ = '\0'; 144 // if(p-2 >= t && p[-2] == ':'){ 145 // p[-2] = '\0'; 146 // type = AttrDefault; 147 // }else 148 type = AttrNameval; 149 a = _mkattr(type, t, p, a); 150 setmalloctag(a, getcallerpc(&s)); 151 } 152 else if(t[strlen(t)-1] == '?'){ 153 t[strlen(t)-1] = '\0'; 154 a = _mkattr(AttrQuery, t, "", a); 155 setmalloctag(a, getcallerpc(&s)); 156 }else{ 157 /* really a syntax error, but better to provide some indication */ 158 a = _mkattr(AttrNameval, t, "", a); 159 setmalloctag(a, getcallerpc(&s)); 160 } 161 } 162 free(s); 163 return cleanattr(a); 164 } 165 166 char* 167 _strfindattr(Attr *a, char *n) 168 { 169 a = _findattr(a, n); 170 if(a == nil) 171 return nil; 172 return a->val; 173 } 174 175