// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include <u.h>
#include <libc.h>
#include <bio.h>
#include <link.h>

enum
{
	HISTSZ = 10,
	NSYM = 50,
};

int
linklinefmt(Link *ctxt, Fmt *fp)
{
	struct
	{
		Hist*	incl;	/* start of this include file */
		int32	idel;	/* delta line number to apply to include */
		Hist*	line;	/* start of this #line directive */
		int32	ldel;	/* delta line number to apply to #line */
	} a[HISTSZ];
	int32 lno, d;
	int i, n;
	Hist *h;

	lno = va_arg(fp->args, int32);

	n = 0;
	for(h=ctxt->hist; h!=nil; h=h->link) {
		if(h->offset < 0)
			continue;
		if(lno < h->line)
			break;
		if(h->name) {
			if(h->offset > 0) {
				// #line directive
				if(n > 0 && n < HISTSZ) {
					a[n-1].line = h;
					a[n-1].ldel = h->line - h->offset + 1;
				}
			} else {
				// beginning of file
				if(n < HISTSZ) {
					a[n].incl = h;
					a[n].idel = h->line;
					a[n].line = 0;
				}
				n++;
			}
			continue;
		}
		n--;
		if(n > 0 && n < HISTSZ) {
			d = h->line - a[n].incl->line;
			a[n-1].ldel += d;
			a[n-1].idel += d;
		}
	}

	if(n > HISTSZ)
		n = HISTSZ;

	for(i=n-1; i>=0; i--) {
		if(i != n-1) {
			if(fp->flags & ~(FmtWidth|FmtPrec))
				break;
			fmtprint(fp, " ");
		}
		if(ctxt->debugline || (fp->flags&FmtLong))
			fmtprint(fp, "%s/", ctxt->pathname);
		if(a[i].line)
			fmtprint(fp, "%s:%d[%s:%d]",
				a[i].line->name, lno-a[i].ldel+1,
				a[i].incl->name, lno-a[i].idel+1);
		else
			fmtprint(fp, "%s:%d",
				a[i].incl->name, lno-a[i].idel+1);
		lno = a[i].incl->line - 1;	// now print out start of this file
	}
	if(n == 0)
		fmtprint(fp, "<unknown line number>");

	return 0;
}

// Does s have t as a path prefix?
// That is, does s == t or does s begin with t followed by a slash?
// For portability, we allow ASCII case folding, so that haspathprefix("a/b/c", "A/B") is true.
// Similarly, we allow slash folding, so that haspathprefix("a/b/c", "a\\b") is true.
static int
haspathprefix(char *s, char *t)
{
	int i, cs, ct;

	if(t == nil)
		return 0;
	for(i=0; t[i]; i++) {
		cs = s[i];
		ct = t[i];
		if('A' <= cs && cs <= 'Z')
			cs += 'a' - 'A';
		if('A' <= ct && ct <= 'Z')
			ct += 'a' - 'A';
		if(cs == '\\')
			cs = '/';
		if(ct == '\\')
			ct = '/';
		if(cs != ct)
			return 0;
	}
	return s[i] == '\0' || s[i] == '/' || s[i] == '\\';
}

// This is a simplified copy of linklinefmt above.
// It doesn't allow printing the full stack, and it returns the file name and line number separately.
// TODO: Unify with linklinefmt somehow.
void
linkgetline(Link *ctxt, int32 line, LSym **f, int32 *l)
{
	struct
	{
		Hist*	incl;	/* start of this include file */
		int32	idel;	/* delta line number to apply to include */
		Hist*	line;	/* start of this #line directive */
		int32	ldel;	/* delta line number to apply to #line */
	} a[HISTSZ];
	int32 lno, d, dlno;
	int n;
	Hist *h;
	char buf[1024], buf1[1024], *file;

	lno = line;
	n = 0;
	for(h=ctxt->hist; h!=nil; h=h->link) {
		if(h->offset < 0)
			continue;
		if(lno < h->line)
			break;
		if(h->name) {
			if(h->offset > 0) {
				// #line directive
				if(n > 0 && n < HISTSZ) {
					a[n-1].line = h;
					a[n-1].ldel = h->line - h->offset + 1;
				}
			} else {
				// beginning of file
				if(n < HISTSZ) {
					a[n].incl = h;
					a[n].idel = h->line;
					a[n].line = 0;
				}
				n++;
			}
			continue;
		}
		n--;
		if(n > 0 && n < HISTSZ) {
			d = h->line - a[n].incl->line;
			a[n-1].ldel += d;
			a[n-1].idel += d;
		}
	}

	if(n > HISTSZ)
		n = HISTSZ;

	if(n <= 0) {
		*f = linklookup(ctxt, "??", HistVersion);
		*l = 0;
		return;
	}
	
	n--;
	if(a[n].line) {
		file = a[n].line->name;
		dlno = a[n].ldel-1;
	} else {
		file = a[n].incl->name;
		dlno = a[n].idel-1;
	}
	if((!ctxt->windows && file[0] == '/') || (ctxt->windows && file[1] == ':'))
		snprint(buf, sizeof buf, "%s", file);
	else
		snprint(buf, sizeof buf, "%s/%s", ctxt->pathname, file);

	// Remove leading ctxt->trimpath, or else rewrite $GOROOT to $GOROOT_FINAL.
	if(haspathprefix(buf, ctxt->trimpath)) {
		if(strlen(buf) == strlen(ctxt->trimpath))
			strcpy(buf, "??");
		else {
			snprint(buf1, sizeof buf1, "%s", buf+strlen(ctxt->trimpath)+1);
			if(buf1[0] == '\0')
				strcpy(buf1, "??");
			strcpy(buf, buf1);
		}
	} else if(ctxt->goroot_final != nil && haspathprefix(buf, ctxt->goroot)) {
		snprint(buf1, sizeof buf1, "%s%s", ctxt->goroot_final, buf+strlen(ctxt->goroot));
		strcpy(buf, buf1);
	}

	lno -= dlno;
	*f = linklookup(ctxt, buf, HistVersion);
	*l = lno;
}

void
linklinehist(Link *ctxt, int lineno, char *f, int offset)
{
	Hist *h;

	if(0) // debug['f']
		if(f) {
			if(offset)
				print("%4d: %s (#line %d)\n", lineno, f, offset);
			else
				print("%4d: %s\n", lineno, f);
		} else
			print("%4d: <pop>\n", lineno);

	h = malloc(sizeof(Hist));
	memset(h, 0, sizeof *h);
	h->name = f;
	h->line = lineno;
	h->offset = offset;
	h->link = nil;
	if(ctxt->ehist == nil) {
		ctxt->hist = h;
		ctxt->ehist = h;
		return;
	}
	ctxt->ehist->link = h;
	ctxt->ehist = h;
}

void
linkprfile(Link *ctxt, int32 l)
{
	int i, n;
	Hist a[HISTSZ], *h;
	int32 d;

	n = 0;
	for(h = ctxt->hist; h != nil; h = h->link) {
		if(l < h->line)
			break;
		if(h->name) {
			if(h->offset == 0) {
				if(n >= 0 && n < HISTSZ)
					a[n] = *h;
				n++;
				continue;
			}
			if(n > 0 && n < HISTSZ)
				if(a[n-1].offset == 0) {
					a[n] = *h;
					n++;
				} else
					a[n-1] = *h;
			continue;
		}
		n--;
		if(n >= 0 && n < HISTSZ) {
			d = h->line - a[n].line;
			for(i=0; i<n; i++)
				a[i].line += d;
		}
	}
	if(n > HISTSZ)
		n = HISTSZ;
	for(i=0; i<n; i++)
		print("%s:%ld ", a[i].name, (long)(l-a[i].line+a[i].offset+1));
}

/*
 * start a new Prog list.
 */
Plist*
linknewplist(Link *ctxt)
{
	Plist *pl;

	pl = malloc(sizeof(*pl));
	memset(pl, 0, sizeof *pl);
	if(ctxt->plist == nil)
		ctxt->plist = pl;
	else
		ctxt->plast->link = pl;
	ctxt->plast = pl;

	return pl;
}
