blob: d8ad9ab337bce12e836026fb63264e5022ca74a2 [file] [log] [blame]
rscbe8b3152004-06-17 03:27:35 +00001#include <u.h>
2#include <libc.h>
3#include <auth.h>
4
5int
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
32Attr*
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
48Attr*
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
66Attr*
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
75void
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
91Attr*
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
109static Attr*
110cleanattr(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
127Attr*
128_parseattr(char *s)
129{
130 char *p, *t, *tok[256];
131 int i, ntok, type;
132 Attr *a;
133
rsc52e5e852005-02-13 18:34:38 +0000134 if(s == nil)
135 return nil;
136
rscbe8b3152004-06-17 03:27:35 +0000137 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
169char*
170_strfindattr(Attr *a, char *n)
171{
172 a = _findattr(a, n);
173 if(a == nil)
174 return nil;
175 return a->val;
176}
177