// 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	<ctype.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')
		;
}
