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