Plan 9 from Bell Labs’s /usr/web/sources/contrib/nemo/sys/src/cmd/bns/expr.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


/*
 * 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 int
atom(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;
}


void
exprfree(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;
}

int
cnstrmatch(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;
}

void
cnstrcat(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
 */
int
exprmatch(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;
}

int
kfmt(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);
}

int
Kfmt(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);
}

void
exprinit(void)
{
	atom("*");
	parsecnstr("net=ok",  &netokcnstr);
	parsecnstr("net=bad", &netbadcnstr);
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.