mirror of https://github.com/0intro/conterm
175 lines
2.8 KiB
C
175 lines
2.8 KiB
C
#include <u.h>
|
|
#include <libc.h>
|
|
#include <auth.h>
|
|
|
|
int
|
|
_attrfmt(Fmt *fmt)
|
|
{
|
|
char *b, buf[1024], *ebuf;
|
|
Attr *a;
|
|
|
|
ebuf = buf+sizeof buf;
|
|
b = buf;
|
|
strcpy(buf, " ");
|
|
for(a=va_arg(fmt->args, Attr*); a; a=a->next){
|
|
if(a->name == nil)
|
|
continue;
|
|
switch(a->type){
|
|
case AttrQuery:
|
|
b = seprint(b, ebuf, " %q?", a->name);
|
|
break;
|
|
case AttrNameval:
|
|
b = seprint(b, ebuf, " %q=%q", a->name, a->val);
|
|
break;
|
|
case AttrDefault:
|
|
b = seprint(b, ebuf, " %q:=%q", a->name, a->val);
|
|
break;
|
|
}
|
|
}
|
|
return fmtstrcpy(fmt, buf+1);
|
|
}
|
|
|
|
Attr*
|
|
_copyattr(Attr *a)
|
|
{
|
|
Attr **la, *na;
|
|
|
|
na = nil;
|
|
la = &na;
|
|
for(; a; a=a->next){
|
|
*la = _mkattr(a->type, a->name, a->val, nil);
|
|
setmalloctag(*la, getcallerpc(&a));
|
|
la = &(*la)->next;
|
|
}
|
|
*la = nil;
|
|
return na;
|
|
}
|
|
|
|
Attr*
|
|
_delattr(Attr *a, char *name)
|
|
{
|
|
Attr *fa;
|
|
Attr **la;
|
|
|
|
for(la=&a; *la; ){
|
|
if(strcmp((*la)->name, name) == 0){
|
|
fa = *la;
|
|
*la = (*la)->next;
|
|
fa->next = nil;
|
|
_freeattr(fa);
|
|
}else
|
|
la=&(*la)->next;
|
|
}
|
|
return a;
|
|
}
|
|
|
|
Attr*
|
|
_findattr(Attr *a, char *n)
|
|
{
|
|
for(; a; a=a->next)
|
|
if(strcmp(a->name, n) == 0 && a->type != AttrQuery)
|
|
return a;
|
|
return nil;
|
|
}
|
|
|
|
void
|
|
_freeattr(Attr *a)
|
|
{
|
|
Attr *anext;
|
|
|
|
for(; a; a=anext){
|
|
anext = a->next;
|
|
free(a->name);
|
|
free(a->val);
|
|
a->name = (void*)~0;
|
|
a->val = (void*)~0;
|
|
a->next = (void*)~0;
|
|
free(a);
|
|
}
|
|
}
|
|
|
|
Attr*
|
|
_mkattr(int type, char *name, char *val, Attr *next)
|
|
{
|
|
Attr *a;
|
|
|
|
a = malloc(sizeof(*a));
|
|
if(a==nil)
|
|
sysfatal("_mkattr malloc: %r");
|
|
a->type = type;
|
|
a->name = strdup(name);
|
|
a->val = strdup(val);
|
|
if(a->name==nil || a->val==nil)
|
|
sysfatal("_mkattr malloc: %r");
|
|
a->next = next;
|
|
setmalloctag(a, getcallerpc(&type));
|
|
return a;
|
|
}
|
|
|
|
static Attr*
|
|
cleanattr(Attr *a)
|
|
{
|
|
Attr *fa;
|
|
Attr **la;
|
|
|
|
for(la=&a; *la; ){
|
|
if((*la)->type==AttrQuery && _findattr(a, (*la)->name)){
|
|
fa = *la;
|
|
*la = (*la)->next;
|
|
fa->next = nil;
|
|
_freeattr(fa);
|
|
}else
|
|
la=&(*la)->next;
|
|
}
|
|
return a;
|
|
}
|
|
|
|
Attr*
|
|
_parseattr(char *s)
|
|
{
|
|
char *p, *t, *tok[256];
|
|
int i, ntok, type;
|
|
Attr *a;
|
|
|
|
s = strdup(s);
|
|
if(s == nil)
|
|
sysfatal("_parseattr strdup: %r");
|
|
|
|
ntok = tokenize(s, tok, nelem(tok));
|
|
a = nil;
|
|
for(i=ntok-1; i>=0; i--){
|
|
t = tok[i];
|
|
if((p = strchr(t, '='))){
|
|
*p++ = '\0';
|
|
// if(p-2 >= t && p[-2] == ':'){
|
|
// p[-2] = '\0';
|
|
// type = AttrDefault;
|
|
// }else
|
|
type = AttrNameval;
|
|
a = _mkattr(type, t, p, a);
|
|
setmalloctag(a, getcallerpc(&s));
|
|
}
|
|
else if(t[strlen(t)-1] == '?'){
|
|
t[strlen(t)-1] = '\0';
|
|
a = _mkattr(AttrQuery, t, "", a);
|
|
setmalloctag(a, getcallerpc(&s));
|
|
}else{
|
|
/* really a syntax error, but better to provide some indication */
|
|
a = _mkattr(AttrNameval, t, "", a);
|
|
setmalloctag(a, getcallerpc(&s));
|
|
}
|
|
}
|
|
free(s);
|
|
return cleanattr(a);
|
|
}
|
|
|
|
char*
|
|
_strfindattr(Attr *a, char *n)
|
|
{
|
|
a = _findattr(a, n);
|
|
if(a == nil)
|
|
return nil;
|
|
return a->val;
|
|
}
|
|
|