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 (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 }