plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }