henesyinit from lsubb0c8bdb6 years agoHistory
238 lines · 3.8 KB · C
RawDownload
/* * Constraints and expressions. */ #include <u.h>#include <libc.h>#include <fcall.h>#include <thread.h>#include <ip.h>#include "names.h"#include "vols.h"  static char**	atoms;static int	natoms;Cnstr	netokcnstr;Cnstr	netbadcnstr; static intatom(char* a){	int	i; 	if(a == nil){		fprint(2, "%s: atom: nil atom\n", argv0);		return atom("");	}	for (i = 0; i < natoms; i++)		if (!strcmp(atoms[i], a))			return i;	if (!(natoms%Incr))		atoms = erealloc(atoms, (natoms+Incr)*sizeof(char*));	atoms[natoms] = estrdup(a);	natoms++;	return natoms - 1;}  voidexprfree(Expr* e){	int	i; 	if (e != nil){		for (i = 0; i < e->ncnstrs; i++)			free(e->cnstrs[i]);		free(e);	}} Cnstr*parsecnstr(char* ln, Cnstr* c){	char*	toks[Nattrs];	int	ntoks;	char*	p;	int	na;	int	i;	char*	nln; 	nln = estrdup(ln);	ntoks = gettokens(nln, toks, nelem(toks), " \t");	if (ntoks == 0){		free(nln);		return nil;	}	if (ntoks == Nattrs)		fprint(2, "%s: too many attrs in constraint: %s.\n", argv0, ln);	if (c == nil)		c = emalloc(sizeof(Cnstr));	c->nattrs = 0;	for (i = 0; i < ntoks; i++){		p = strchr(toks[i], '=');		if (p == nil){			fprint(2, "%s: bad attribute: %s: %s\n", argv0, ln, toks[i]);			continue;		}		*p++ = 0;		if (*toks[i] == 0 || *p == 0){			*--p = '=';			fprint(2, "%s: bad attribute: %s: %s\n", argv0, ln, toks[i]);			continue;		}		na = c->nattrs++;		c->attrs[na].var = atom(toks[i]);		c->attrs[na].val = atom(p);	}	free(nln);	return c;} Expr*parseexpr(char* ln, Expr* e){	char*	buf;	char*	p;	char*	np;	Cnstr*	c; 	e->ncnstrs = 0; 	if (ln == nil)		ln = "";	buf = estrdup(ln);	for (p = buf; p && *p; p = np){		if (e->ncnstrs >= Ncnstrs){			fprint(2, "%s: too many constraints in spec\n", argv0);			break;		}		np = strchr(p, '|');		if (np)			*np++ = 0;		c = parsecnstr(p, nil);		if (c && c->nattrs > 0)			e->cnstrs[e->ncnstrs++] = c;		else			free(c);	}	free(buf);	return e;} intcnstrmatch(Cnstr* env, Cnstr* c){	int	i, j;	Prop*	a; 	if (c == nil)		return 1;	for (i = 0; i < c->nattrs; i++){		if (env == nil)			return 0;		a = &c->attrs[i];		for (j = 0; j < env->nattrs; j++){			if (a->var == Any || a->var == env->attrs[j].var)			if (a->val == Any || a->val == env->attrs[j].val)				break;		}		if (j == env->nattrs)			return 0;	}	return i == c->nattrs;} voidcnstrcat(Cnstr* c1, Cnstr* c2){	int i, j; 	if (c1 == nil || c2 == nil)		return;	for (j = 0; j < c2->nattrs; j++){		for (i = 0; i < c1->nattrs; i++){			if (c1->attrs[i].var == c2->attrs[j].var){				c1->attrs[i].val = c2->attrs[j].val;				break;			}		}		if (i == c1->nattrs && c1->nattrs < Nattrs){			c1->attrs[i] = c2->attrs[j];			c1->nattrs++;		}	}}  /* Returns -1 for no match. * Returns the index for the cnstr when matches */intexprmatch(Cnstr* env, Expr* exp){	int	i;	Cnstr*	c; 	if (exp->ncnstrs == 0)		return 0;	for (i = 0; i < exp->ncnstrs; i++){		c = exp->cnstrs[i];		if (cnstrmatch(env, c))			return i;	}	return -1;} intkfmt(Fmt* fmt){	Cnstr*	c;	Prop*	a;	char	buf[128];	char*	s;	int	j; 	c = va_arg(fmt->args, Cnstr*);	if (c == nil)		return fmtstrcpy(fmt , "-");	s = buf;	*buf = 0;	s = seprint(s, buf+sizeof(buf), "'");	for (j = 0; j < c->nattrs; j++){		a = &c->attrs[j];		s = seprint(s, buf+sizeof(buf), "%s=%s ",			atoms[a->var], atoms[a->val]);	}	seprint(s, buf+sizeof(buf), "'");	return fmtstrcpy(fmt, buf);} intKfmt(Fmt* fmt){	Expr*	e;	char	buf[250];	char*	s;	int	i; 	e = va_arg(fmt->args, Expr*);	if (e == nil || e->ncnstrs == 0)		return fmtstrcpy(fmt , "-");	s = buf;	*buf = 0;	for (i = 0; i < e->ncnstrs; i++){		s = seprint(s, buf+sizeof(buf), "%k", e->cnstrs[i]);		if (i < e->ncnstrs - 1)			s = seprint(s, buf+sizeof(buf), "| ");	}	return fmtstrcpy(fmt, buf);} voidexprinit(void){	atom("*");	parsecnstr("net=ok",  &netokcnstr);	parsecnstr("net=bad", &netbadcnstr);}