// Copyright 2012 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 "a.h"

/*
 * Helpers for building cmd/gc.
 */

// gcopnames creates opnames.h from go.h.
// It finds the OXXX enum, pulls out all the constants
// from OXXX to OEND, and writes a table mapping
// op to string.
void
gcopnames(char *dir, char *file)
{
	char *p, *q;
	int i, j, end;
	Buf in, b, out;
	Vec lines, fields;
	
	binit(&in);
	binit(&b);
	binit(&out);
	vinit(&lines);
	vinit(&fields);
	
	bwritestr(&out, bprintf(&b, "// auto generated by go tool dist\n"));
	bwritestr(&out, bprintf(&b, "static char *opnames[] = {\n"));

	readfile(&in, bprintf(&b, "%s/go.h", dir));
	splitlines(&lines, bstr(&in));
	i = 0;
	while(i<lines.len && !contains(lines.p[i], "OXXX"))
		i++;
	end = 0;
	for(; i<lines.len && !end; i++) {
		p = xstrstr(lines.p[i], "//");
		if(p != nil)
			*p = '\0';
		end = contains(lines.p[i], "OEND");
		splitfields(&fields, lines.p[i]);
		for(j=0; j<fields.len; j++) {
			q = fields.p[j];
			if(*q == 'O')
				q++;
			p = q+xstrlen(q)-1;
			if(*p == ',')
				*p = '\0';
			bwritestr(&out, bprintf(&b, "	[O%s] = \"%s\",\n", q, q));
		}
	}
	
	bwritestr(&out, bprintf(&b, "};\n"));

	writefile(&out, file, 0);

	bfree(&in);
	bfree(&b);
	bfree(&out);
	vfree(&lines);
	vfree(&fields);
}

static int
xatoi(char *s, char **end)
{
	int val = 0;
	for(; *s && *s >= '0' && *s <= '9'; ++s)
		val = val * 10 + (*s - '0');
	*end = s;
	return val;
}

// mkanames reads [5689].out.h and writes anames[5689].c
// The format is much the same as the Go opcodes above.
// It also writes out cnames array for C_* constants and the dnames
// array for D_* constants.
void
mkanames(char *dir, char *file)
{
	int i, j, ch, n, unknown;
	Buf in, b, out, out2;
	Vec lines;
	char *p, *p2;
	Vec dnames[128];

	binit(&b);
	binit(&in);
	binit(&out);
	binit(&out2);
	vinit(&lines);
	for(i=0; i<nelem(dnames); i++)
		vinit(&dnames[i]);

	ch = file[xstrlen(file)-3];
	bprintf(&b, "%s/../cmd/%cl/%c.out.h", dir, ch, ch);
	readfile(&in, bstr(&b));
	splitlines(&lines, bstr(&in));
	
	// Include link.h so that the extern declaration there is
	// checked against the non-extern declaration we are generating.
	bwritestr(&out, bprintf(&b, "// auto generated by go tool dist\n"));
	bwritestr(&out, bprintf(&b, "#include <u.h>\n"));
	bwritestr(&out, bprintf(&b, "#include <libc.h>\n"));
	bwritestr(&out, bprintf(&b, "#include <bio.h>\n"));
	bwritestr(&out, bprintf(&b, "#include <link.h>\n"));
	bwritestr(&out, bprintf(&b, "#include \"../cmd/%cl/%c.out.h\"\n", ch, ch));
	bwritestr(&out, bprintf(&b, "\n"));

	bwritestr(&out, bprintf(&b, "char*	anames%c[] = {\n", ch));
	for(i=0; i<lines.len; i++) {
		if(hasprefix(lines.p[i], "\tA")) {
			p = xstrstr(lines.p[i], ",");
			if(p)
				*p = '\0';
			p = xstrstr(lines.p[i], "\n");
			if(p)
				*p = '\0';
			p = lines.p[i] + 2;
			bwritestr(&out, bprintf(&b, "\t\"%s\",\n", p));
		}
	}
	bwritestr(&out, "};\n");

	j=0;
	bprintf(&out2, "char*	cnames%c[] = {\n", ch);
	for(i=0; i<lines.len; i++) {
		if(hasprefix(lines.p[i], "\tC_")) {
			p = xstrstr(lines.p[i], ",");
			if(p)
				*p = '\0';
			p = xstrstr(lines.p[i], "\n");
			if(p)
				*p = '\0';
			p = lines.p[i] + 3;
			bwritestr(&out2, bprintf(&b, "\t\"%s\",\n", p));
			j++;
		}
	}
	bwritestr(&out2, "};\n");
	if(j>0)
		bwriteb(&out, &out2);

	j=unknown=0;
	n=-1;
	for(i=0; i<lines.len; i++) {
		if(hasprefix(lines.p[i], "\tD_")) {
			p = xstrstr(lines.p[i], ",");
			if(p)
				*p = '\0';
			p = xstrstr(lines.p[i], "\n");
			if(p)
				*p = '\0';

			// Parse explicit value, if any
			p = xstrstr(lines.p[i], "=");
			if(p) {
				// Skip space after '='
				p2 = p + 1;
				while(*p2 == ' ' || *p2 == '\t')
					p2++;
				n = xatoi(p2, &p2);
				// We can't do anything about
				// non-numeric values or anything that
				// follows
				while(*p2 == ' ' || *p2 == '\t')
					p2++;
				if(*p2 != 0) {
					unknown = 1;
					continue;
				}
				// Truncate space before '='
				while(*(p-1) == ' ' || *(p-1) == '\t')
					p--;
				*p = '\0';
				unknown = 0;
			} else {
				n++;
			}

			if(unknown || n >= nelem(dnames))
				continue;

			p = lines.p[i] + 3;
			if(xstrcmp(p, "LAST") == 0)
				continue;
			vadd(&dnames[n], p);
			j++;
		}
	}
	if(j>0){
		bwritestr(&out, bprintf(&b, "char*	dnames%c[D_LAST] = {\n", ch));
		for(i=0; i<nelem(dnames); i++) {
			if(dnames[i].len == 0)
				continue;
			bwritestr(&out, bprintf(&b, "\t[D_%s] = \"", dnames[i].p[0]));
			for(j=0; j<dnames[i].len; j++) {
				if(j != 0)
					bwritestr(&out, "/");
				bwritestr(&out, dnames[i].p[j]);
			}
			bwritestr(&out, "\",\n");
		}
		bwritestr(&out, "};\n");
	}

	writefile(&out, file, 0);

	bfree(&b);
	bfree(&in);
	bfree(&out);
	bfree(&out2);
	vfree(&lines);
	for(i=0; i<nelem(dnames); i++)
		vfree(&dnames[i]);
}
