URI:
       tattr.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tattr.c (3685B)
       ---
            1 #include "std.h"
            2 #include "dat.h"
            3 
            4 Attr*
            5 addattr(Attr *a, char *fmt, ...)
            6 {
            7         char buf[8192];
            8         va_list arg;
            9         Attr *b;
           10 
           11         va_start(arg, fmt);
           12         vseprint(buf, buf+sizeof buf, fmt, arg);
           13         va_end(arg);
           14         b = _parseattr(buf);
           15         a = addattrs(a, b);
           16         setmalloctag(a, getcallerpc(&a));
           17         _freeattr(b);
           18         return a;
           19 }
           20 
           21 /*
           22  *  add attributes in list b to list a.  If any attributes are in
           23  *  both lists, replace those in a by those in b.
           24  */
           25 Attr*
           26 addattrs(Attr *a, Attr *b)
           27 {
           28         int found;
           29         Attr **l, *aa;
           30 
           31         for(; b; b=b->next){
           32                 switch(b->type){
           33                 case AttrNameval:
           34                         for(l=&a; *l; ){
           35                                 if(strcmp((*l)->name, b->name) != 0){
           36                                         l=&(*l)->next;
           37                                         continue;
           38                                 }
           39                                 aa = *l;
           40                                 *l = aa->next;
           41                                 aa->next = nil;
           42                                 freeattr(aa);
           43                         }
           44                         *l = mkattr(AttrNameval, b->name, b->val, nil);
           45                         break;
           46                 case AttrQuery:
           47                         found = 0;
           48                         for(l=&a; *l; l=&(*l)->next)
           49                                 if((*l)->type==AttrNameval && strcmp((*l)->name, b->name) == 0)
           50                                         found++;
           51                         if(!found)
           52                                 *l = mkattr(AttrQuery, b->name, b->val, nil);
           53                         break;
           54                 }
           55         }
           56         return a;
           57 }
           58 
           59 void
           60 setmalloctaghere(void *v)
           61 {
           62         setmalloctag(v, getcallerpc(&v));
           63 }
           64 
           65 Attr*
           66 sortattr(Attr *a)
           67 {
           68         int i;
           69         Attr *anext, *a0, *a1, **l;
           70 
           71         if(a == nil || a->next == nil)
           72                 return a;
           73 
           74         /* cut list in halves */
           75         a0 = nil;
           76         a1 = nil;
           77         i = 0;
           78         for(; a; a=anext){
           79                 anext = a->next;
           80                 if(i++%2){
           81                         a->next = a0;
           82                         a0 = a;
           83                 }else{
           84                         a->next = a1;
           85                         a1 = a;
           86                 }
           87         }
           88 
           89         /* sort */
           90         a0 = sortattr(a0);
           91         a1 = sortattr(a1);
           92 
           93         /* merge */
           94         l = &a;
           95         while(a0 || a1){
           96                 if(a1==nil){
           97                         anext = a0;
           98                         a0 = a0->next;
           99                 }else if(a0==nil){
          100                         anext = a1;
          101                         a1 = a1->next;
          102                 }else if(strcmp(a0->name, a1->name) < 0){
          103                         anext = a0;
          104                         a0 = a0->next;
          105                 }else{
          106                         anext = a1;
          107                         a1 = a1->next;
          108                 }
          109                 *l = anext;
          110                 l = &(*l)->next;
          111         }
          112         *l = nil;
          113         return a;
          114 }
          115 
          116 int
          117 attrnamefmt(Fmt *fmt)
          118 {
          119         char *b, buf[8192], *ebuf;
          120         Attr *a;
          121 
          122         ebuf = buf+sizeof buf;
          123         b = buf;
          124         strcpy(buf, " ");
          125         for(a=va_arg(fmt->args, Attr*); a; a=a->next){
          126                 if(a->name == nil)
          127                         continue;
          128                 b = seprint(b, ebuf, " %q?", a->name);
          129         }
          130         return fmtstrcpy(fmt, buf+1);
          131 }
          132 
          133 /*
          134 static int
          135 hasqueries(Attr *a)
          136 {
          137         for(; a; a=a->next)
          138                 if(a->type == AttrQuery)
          139                         return 1;
          140         return 0;
          141 }
          142 */
          143 
          144 char *ignored[] = {
          145         "role",
          146         "disabled"
          147 };
          148 
          149 static int
          150 ignoreattr(char *s)
          151 {
          152         int i;
          153 
          154         for(i=0; i<nelem(ignored); i++)
          155                 if(strcmp(ignored[i], s)==0)
          156                         return 1;
          157         return 0;
          158 }
          159 
          160 static int
          161 hasname(Attr *a0, Attr *a1, char *name)
          162 {
          163         return _findattr(a0, name) || _findattr(a1, name);
          164 }
          165 
          166 static int
          167 hasnameval(Attr *a0, Attr *a1, char *name, char *val)
          168 {
          169         Attr *a;
          170 
          171         for(a=_findattr(a0, name); a; a=_findattr(a->next, name))
          172                 if(strcmp(a->val, val) == 0)
          173                         return 1;
          174         for(a=_findattr(a1, name); a; a=_findattr(a->next, name))
          175                 if(strcmp(a->val, val) == 0)
          176                         return 1;
          177         return 0;
          178 }
          179 
          180 int
          181 matchattr(Attr *pat, Attr *a0, Attr *a1)
          182 {
          183         int type;
          184 
          185         for(; pat; pat=pat->next){
          186                 type = pat->type;
          187                 if(ignoreattr(pat->name))
          188                         type = AttrDefault;
          189                 switch(type){
          190                 case AttrQuery:                /* name=something be present */
          191                         if(!hasname(a0, a1, pat->name))
          192                                 return 0;
          193                         break;
          194                 case AttrNameval:        /* name=val must be present */
          195                         if(!hasnameval(a0, a1, pat->name, pat->val))
          196                                 return 0;
          197                         break;
          198                 case AttrDefault:        /* name=val must be present if name=anything is present */
          199                         if(hasname(a0, a1, pat->name) && !hasnameval(a0, a1, pat->name, pat->val))
          200                                 return 0;
          201                         break;
          202                 }
          203         }
          204         return 1;
          205 }
          206 
          207 Attr*
          208 parseattrfmtv(char *fmt, va_list arg)
          209 {
          210         char *s;
          211         Attr *a;
          212 
          213         s = vsmprint(fmt, arg);
          214         if(s == nil)
          215                 sysfatal("vsmprint: out of memory");
          216         a = parseattr(s);
          217         free(s);
          218         return a;
          219 }
          220 
          221 Attr*
          222 parseattrfmt(char *fmt, ...)
          223 {
          224         va_list arg;
          225         Attr *a;
          226 
          227         va_start(arg, fmt);
          228         a = parseattrfmtv(fmt, arg);
          229         va_end(arg);
          230         return a;
          231 }