attr.c (2895B)
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 if(s == nil) 135 return nil; 136 137 s = strdup(s); 138 if(s == nil) 139 sysfatal("_parseattr strdup: %r"); 140 141 ntok = tokenize(s, tok, nelem(tok)); 142 a = nil; 143 for(i=ntok-1; i>=0; i--){ 144 t = tok[i]; 145 if(p = strchr(t, '=')){ 146 *p++ = '\0'; 147 /* if(p-2 >= t && p[-2] == ':'){ */ 148 /* p[-2] = '\0'; */ 149 /* type = AttrDefault; */ 150 /* }else */ 151 type = AttrNameval; 152 a = _mkattr(type, t, p, a); 153 setmalloctag(a, getcallerpc(&s)); 154 } 155 else if(t[strlen(t)-1] == '?'){ 156 t[strlen(t)-1] = '\0'; 157 a = _mkattr(AttrQuery, t, "", a); 158 setmalloctag(a, getcallerpc(&s)); 159 }else{ 160 /* really a syntax error, but better to provide some indication */ 161 a = _mkattr(AttrNameval, t, "", a); 162 setmalloctag(a, getcallerpc(&s)); 163 } 164 } 165 free(s); 166 return cleanattr(a); 167 } 168 169 char* 170 _strfindattr(Attr *a, char *n) 171 { 172 a = _findattr(a, n); 173 if(a == nil) 174 return nil; 175 return a->val; 176 }