// Inferno utils/cc/dpchk.c
// http://code.google.com/p/inferno-os/source/browse/utils/cc/dpchk.c
//
//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
//	Portions Copyright © 1997-1999 Vita Nuova Limited
//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
//	Portions Copyright © 2004,2006 Bruce Ellis
//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
//	Portions Copyright © 2009 The Go Authors.  All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include	<u.h>
#include	"cc.h"
#include	"y.tab.h"

enum
{
	Fnone	= 0,
	Fl,
	Fvl,
	Fignor,
	Fstar,
	Fadj,

	Fverb	= 10,
};

typedef	struct	Tprot	Tprot;
struct	Tprot
{
	Type*	type;
	Bits	flag;
	Tprot*	link;
};

typedef	struct	Tname	Tname;
struct	Tname
{
	char*	name;
	int	param;
	int	count;
	Tname*	link;
	Tprot*	prot;
};

static	Type*	indchar;
static	uchar	flagbits[512];
static	char*	lastfmt;
static	int	lastadj;
static	int	lastverb;
static	int	nstar;
static	Tprot*	tprot;
static	Tname*	tname;

void
argflag(int c, int v)
{

	switch(v) {
	case Fignor:
	case Fstar:
	case Fl:
	case Fvl:
		flagbits[c] = v;
		break;
	case Fverb:
		flagbits[c] = lastverb;
/*print("flag-v %c %d\n", c, lastadj);*/
		lastverb++;
		break;
	case Fadj:
		flagbits[c] = lastadj;
/*print("flag-l %c %d\n", c, lastadj);*/
		lastadj++;
		break;
	}
}

Bits
getflag(char *s)
{
	Bits flag;
	int f;
	Fmt fmt;
	Rune c;

	flag = zbits;
	nstar = 0;
	fmtstrinit(&fmt);
	for(;;) {
		s += chartorune(&c, s);
		if(c == 0 || c >= nelem(flagbits))
			break;
		fmtrune(&fmt, c);
		f = flagbits[c];
		switch(f) {
		case Fnone:
			argflag(c, Fverb);
			f = flagbits[c];
			break;
		case Fstar:
			nstar++;
		case Fignor:
			continue;
		case Fl:
			if(bset(flag, Fl))
				flag = bor(flag, blsh(Fvl));
		}
		flag = bor(flag, blsh(f));
		if(f >= Fverb)
			break;
	}
	free(lastfmt);
	lastfmt = fmtstrflush(&fmt);
	return flag;
}

static void
newprot(Sym *m, Type *t, char *s, Tprot **prot)
{
	Bits flag;
	Tprot *l;

	if(t == T) {
		warn(Z, "%s: newprot: type not defined", m->name);
		return;
	}
	flag = getflag(s);
	for(l=*prot; l; l=l->link)
		if(beq(flag, l->flag) && sametype(t, l->type))
			return;
	l = alloc(sizeof(*l));
	l->type = t;
	l->flag = flag;
	l->link = *prot;
	*prot = l;
}

static Tname*
newname(char *s, int p, int count)
{
	Tname *l;

	for(l=tname; l; l=l->link)
		if(strcmp(l->name, s) == 0) {
			if(p >= 0 && l->param != p)
				yyerror("vargck %s already defined\n", s);
			return l;
		}
	if(p < 0)
		return nil;

	l = alloc(sizeof(*l));
	l->name = s;
	l->param = p;
	l->link = tname;
	l->count = count;
	tname = l;
	return l;
}

void
arginit(void)
{
	int i;

/* debug['F'] = 1;*/
/* debug['w'] = 1;*/

	lastadj = Fadj;
	lastverb = Fverb;
	indchar = typ(TIND, types[TCHAR]);

	memset(flagbits, Fnone, sizeof(flagbits));

	for(i='0'; i<='9'; i++)
		argflag(i, Fignor);
	argflag('.', Fignor);
	argflag('#', Fignor);
	argflag('u', Fignor);
	argflag('h', Fignor);
	argflag('+', Fignor);
	argflag('-', Fignor);

	argflag('*', Fstar);
	argflag('l', Fl);

	argflag('o', Fverb);
	flagbits['x'] = flagbits['o'];
	flagbits['X'] = flagbits['o'];
}

static char*
getquoted(void)
{
	int c;
	Rune r;
	Fmt fmt;

	c = getnsc();
	if(c != '"')
		return nil;
	fmtstrinit(&fmt);
	for(;;) {
		r = getr();
		if(r == '\n') {
			free(fmtstrflush(&fmt));
			return nil;
		}
		if(r == '"')
			break;
		fmtrune(&fmt, r);
	}
	free(lastfmt);
	lastfmt = fmtstrflush(&fmt);
	return strdup(lastfmt);
}

void
pragvararg(void)
{
	Sym *s;
	int n, c;
	char *t;
	Type *ty;
	Tname *l;

	if(!debug['F'])
		goto out;
	s = getsym();
	if(s && strcmp(s->name, "argpos") == 0)
		goto ckpos;
	if(s && strcmp(s->name, "type") == 0)
		goto cktype;
	if(s && strcmp(s->name, "flag") == 0)
		goto ckflag;
	if(s && strcmp(s->name, "countpos") == 0)
		goto ckcount;
	yyerror("syntax in #pragma varargck");
	goto out;

ckpos:
/*#pragma	varargck	argpos	warn	2*/
	s = getsym();
	if(s == S)
		goto bad;
	n = getnsn();
	if(n < 0)
		goto bad;
	newname(s->name, n, 0);
	goto out;

ckcount:
/*#pragma	varargck	countpos	name 2*/
	s = getsym();
	if(s == S)
		goto bad;
	n = getnsn();
	if(n < 0)
		goto bad;
	newname(s->name, 0, n);
	goto out;

ckflag:
/*#pragma	varargck	flag	'c'*/
	c = getnsc();
	if(c != '\'')
		goto bad;
	c = getr();
	if(c == '\\')
		c = getr();
	else if(c == '\'')
		goto bad;
	if(c == '\n')
		goto bad;
	if(getc() != '\'')
		goto bad;
	argflag(c, Fignor);
	goto out;

cktype:
	c = getnsc();
	unget(c);
	if(c != '"') {
/*#pragma	varargck	type	name	int*/
		s = getsym();
		if(s == S)
			goto bad;
		l = newname(s->name, -1, -1);
		s = getsym();
		if(s == S)
			goto bad;
		ty = s->type;
		while((c = getnsc()) == '*')
			ty = typ(TIND, ty);
		unget(c);
		newprot(s, ty, "a", &l->prot);
		goto out;
	}

/*#pragma	varargck	type	O	int*/
	t = getquoted();
	if(t == nil)
		goto bad;
	s = getsym();
	if(s == S)
		goto bad;
	ty = s->type;
	while((c = getnsc()) == '*')
		ty = typ(TIND, ty);
	unget(c);
	newprot(s, ty, t, &tprot);
	goto out;

bad:
	yyerror("syntax in #pragma varargck");

out:
	while(getnsc() != '\n')
		;
}

Node*
nextarg(Node *n, Node **a)
{
	if(n == Z) {
		*a = Z;
		return Z;
	}
	if(n->op == OLIST) {
		*a = n->left;
		return n->right;
	}
	*a = n;
	return Z;
}

void
checkargs(Node *nn, char *s, int pos)
{
	Node *a, *n;
	Bits flag;
	Tprot *l;

	if(!debug['F'])
		return;
	n = nn;
	for(;;) {
		s = strchr(s, '%');
		if(s == 0) {
			nextarg(n, &a);
			if(a != Z)
				warn(nn, "more arguments than format %T",
					a->type);
			return;
		}
		s++;
		flag = getflag(s);
		while(nstar > 0) {
			n = nextarg(n, &a);
			pos++;
			nstar--;
			if(a == Z) {
				warn(nn, "more format than arguments %s",
					lastfmt);
				return;
			}
			if(a->type == T)
				continue;
			if(!sametype(types[TINT], a->type) &&
			   !sametype(types[TUINT], a->type))
				warn(nn, "format mismatch '*' in %s %T, arg %d",
					lastfmt, a->type, pos);
		}
		for(l=tprot; l; l=l->link)
			if(sametype(types[TVOID], l->type)) {
				if(beq(flag, l->flag)) {
					s++;
					goto loop;
				}
			}

		n = nextarg(n, &a);
		pos++;
		if(a == Z) {
			warn(nn, "more format than arguments %s",
				lastfmt);
			return;
		}
		if(a->type == 0)
			continue;
		for(l=tprot; l; l=l->link)
			if(sametype(a->type, l->type)) {
/*print("checking %T/%ux %T/%ux\n", a->type, flag.b[0], l->type, l->flag.b[0]);*/
				if(beq(flag, l->flag))
					goto loop;
			}
		warn(nn, "format mismatch %s %T, arg %d", lastfmt, a->type, pos);
	loop:;
	}
}

void
dpcheck(Node *n)
{
	char *s;
	Node *a, *b;
	Tname *l;
	Tprot *tl;
	int i, j;

	if(n == Z)
		return;
	b = n->left;
	if(b == Z || b->op != ONAME)
		return;
	s = b->sym->name;
	for(l=tname; l; l=l->link)
		if(strcmp(s, l->name) == 0)
			break;
	if(l == 0)
		return;

	if(l->count > 0) {
		// fetch count, then check remaining length
		i = l->count;
		a = nil;
		b = n->right;
		while(i > 0) {
			b = nextarg(b, &a);
			i--;
		}
		if(a == Z) {
			diag(n, "can't find count arg");
			return;
		}
		if(a->op != OCONST || !typechl[a->type->etype]) {
			diag(n, "count is invalid constant");
			return;
		}
		j = a->vconst;
		i = 0;
		while(b != Z) {
			b = nextarg(b, &a);
			i++;
		}
		if(i != j)
			diag(n, "found %d argument%s after count %d", i, i == 1 ? "" : "s", j);
	}

	if(l->prot != nil) {
		// check that all arguments after param or count
		// are listed in type list.
		i = l->count;
		if(i == 0)
			i = l->param;
		if(i == 0)
			return;
		a = nil;
		b = n->right;
		while(i > 0) {
			b = nextarg(b, &a);
			i--;
		}
		if(a == Z) {
			diag(n, "can't find count/param arg");
			return;
		}
		while(b != Z) {
			b = nextarg(b, &a);
			for(tl=l->prot; tl; tl=tl->link)
				if(sametype(a->type, tl->type))
					break;
			if(tl == nil)
				diag(a, "invalid type %T in call to %s", a->type, s);
		}
	}

	if(l->param <= 0)
		return;
	i = l->param;
	a = nil;
	b = n->right;
	while(i > 0) {
		b = nextarg(b, &a);
		i--;
	}
	if(a == Z) {
		diag(n, "can't find format arg");
		return;
	}
	if(!sametype(indchar, a->type)) {
		diag(n, "format arg type %T", a->type);
		return;
	}
	if(a->op != OADDR || a->left->op != ONAME || a->left->sym != symstring) {
/*		warn(n, "format arg not constant string");*/
		return;
	}
	s = a->left->cstring;
	checkargs(b, s, l->param);
}

void
pragpack(void)
{
	Sym *s;

	packflg = 0;
	s = getsym();
	if(s) {
		packflg = atoi(s->name+1);
		if(strcmp(s->name, "on") == 0 ||
		   strcmp(s->name, "yes") == 0)
			packflg = 1;
	}
	while(getnsc() != '\n')
		;
	if(debug['f'])
		if(packflg)
			print("%4d: pack %d\n", lineno, packflg);
		else
			print("%4d: pack off\n", lineno);
}

void
pragfpround(void)
{
	Sym *s;

	fproundflg = 0;
	s = getsym();
	if(s) {
		fproundflg = atoi(s->name+1);
		if(strcmp(s->name, "on") == 0 ||
		   strcmp(s->name, "yes") == 0)
			fproundflg = 1;
	}
	while(getnsc() != '\n')
		;
	if(debug['f'])
		if(fproundflg)
			print("%4d: fproundflg %d\n", lineno, fproundflg);
		else
			print("%4d: fproundflg off\n", lineno);
}

void
pragtextflag(void)
{
	Sym *s;

	textflag = 0;
	s = getsym();
	textflag = 7;
	if(s)
		textflag = atoi(s->name+1);
	while(getnsc() != '\n')
		;
	if(debug['f'])
		print("%4d: textflag %d\n", lineno, textflag);
}

void
pragincomplete(void)
{
	Sym *s;
	Type *t;
	int istag, w, et;

	istag = 0;
	s = getsym();
	if(s == nil)
		goto out;
	et = 0;
	w = s->lexical;
	if(w == LSTRUCT)
		et = TSTRUCT;
	else if(w == LUNION)
		et = TUNION;
	if(et != 0){
		s = getsym();
		if(s == nil){
			yyerror("missing struct/union tag in pragma incomplete");
			goto out;
		}
		if(s->lexical != LNAME && s->lexical != LTYPE){
			yyerror("invalid struct/union tag: %s", s->name);
			goto out;
		}
		dotag(s, et, 0);
		istag = 1;
	}else if(strcmp(s->name, "_off_") == 0){
		debug['T'] = 0;
		goto out;
	}else if(strcmp(s->name, "_on_") == 0){
		debug['T'] = 1;
		goto out;
	}
	t = s->type;
	if(istag)
		t = s->suetag;
	if(t == T)
		yyerror("unknown type %s in pragma incomplete", s->name);
	else if(!typesu[t->etype])
		yyerror("not struct/union type in pragma incomplete: %s", s->name);
	else
		t->garb |= GINCOMPLETE;
out:
	while(getnsc() != '\n')
		;
	if(debug['f'])
		print("%s incomplete\n", s->name);
}

Sym*
getimpsym(void)
{
	int c;
	char *cp;

	c = getnsc();
	if(isspace(c) || c == '"') {
		unget(c);
		return S;
	}
	for(cp = symb;;) {
		if(cp <= symb+NSYMB-4)
			*cp++ = c;
		c = getc();
		if(c > 0 && !isspace(c) && c != '"')
			continue;
		unget(c);
		break;
	}
	*cp = 0;
	if(cp > symb+NSYMB-4)
		yyerror("symbol too large: %s", symb);
	return lookup();
}

void
pragdynimport(void)
{
	Sym *local, *remote;
	char *path;
	Dynimp *f;

	local = getimpsym();
	if(local == nil)
		goto err;

	remote = getimpsym();
	if(remote == nil)
		goto err;

	path = getquoted();
	if(path == nil)
		goto err;

	if(ndynimp%32 == 0)
		dynimp = realloc(dynimp, (ndynimp+32)*sizeof dynimp[0]);
	f = &dynimp[ndynimp++];
	f->local = local->name;
	f->remote = remote->name;
	f->path = path;
	goto out;

err:
	yyerror("usage: #pragma dynimport local remote \"path\"");

out:
	while(getnsc() != '\n')
		;
}

void
pragdynexport(void)
{
	Sym *local, *remote;
	Dynexp *f;

	local = getsym();
	if(local == nil)
		goto err;

	remote = getsym();
	if(remote == nil)
		goto err;

	if(ndynexp%32 == 0)
		dynexp = realloc(dynexp, (ndynexp+32)*sizeof dynexp[0]);
	f = &dynexp[ndynexp++];
	f->local = local->name;
	f->remote = remote->name;
	goto out;

err:
	yyerror("usage: #pragma dynexport local remote");

out:
	while(getnsc() != '\n')
		;
}
