//   cmd/cc/godefs.cc
//
//   derived from pickle.cc which itself was derived from acid.cc.
//
//	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-2011 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"

static int upper;

static char *kwd[] =
{
	"_bool",
	"_break",
	"_byte",
	"_case",
	"_chan",
	"_complex128",
	"_complex64",
	"_const",
	"_continue",
	"_default",
	"_defer",
	"_else",
	"_fallthrough",
	"_false",
	"_float32",
	"_float64",
	"_for",
	"_func",
	"_go",
	"_goto",
	"_if",
	"_import",
	"_int",
	"_int16",
	"_int32",
	"_int64",
	"_int8",
	"_interface",
	"_intptr",
	"_map",
	"_package",
	"_panic",
	"_range",
	"_return",
	"_select",
	"_string",
	"_struct",
	"_switch",
	"_true",
	"_type",
	"_uint",
	"_uint16",
	"_uint32",
	"_uint64",
	"_uint8",
	"_uintptr",
	"_var",
};

static char*
pmap(char *s)
{
	int i, bot, top, mid;

	bot = -1;
	top = nelem(kwd);
	while(top - bot > 1){
		mid = (bot + top) / 2;
		i = strcmp(kwd[mid]+1, s);
		if(i == 0)
			return kwd[mid];
		if(i < 0)
			bot = mid;
		else
			top = mid;
	}

	return s;
}


int
Uconv(Fmt *fp)
{
	char str[STRINGSZ+1];
	char *s, *n;
	int i;

	str[0] = 0;
	s = va_arg(fp->args, char*);

	// strip package name
	n = strrchr(s, '.');
	if(n != nil)
		s = n + 1;

	if(s && *s) {
		if(upper)
			str[0] = toupper(*s);
		else
			str[0] = tolower(*s);
		for(i = 1; i < STRINGSZ && s[i] != 0; i++)
			str[i] = tolower(s[i]);
		str[i] = 0;
	}

	return fmtstrcpy(fp, pmap(str));
}


static Sym*
findsue(Type *t)
{
	int h;
	Sym *s;

	if(t != T)
	for(h=0; h<nelem(hash); h++)
		for(s = hash[h]; s != S; s = s->link)
			if(s->suetag && s->suetag->link == t)
				return s;
	return 0;
}

static void
printtypename(Type *t)
{
	Sym *s;
	Type *t1;
	int w;
	char *n;

	for( ; t != nil; t = t->link) {
		switch(t->etype) {
		case TIND:
			// Special handling of *void.
			if(t->link != nil && t->link->etype==TVOID) {
				Bprint(&outbuf, "unsafe.Pointer");
				return;
			}
			// *func == func
			if(t->link != nil && t->link->etype==TFUNC)
				continue;
			Bprint(&outbuf, "*");
			continue;
		case TARRAY:
			w = t->width;
			if(t->link && t->link->width)
				w /= t->link->width;
			Bprint(&outbuf, "[%d]", w);
			continue;
		}
		break;
	}

	if(t == nil) {
		Bprint(&outbuf, "bad // should not happen");
		return;
	}

	switch(t->etype) {
	case TINT:
		Bprint(&outbuf, "int");
		break;
	case TUINT:
		Bprint(&outbuf, "uint");
		break;
	case TCHAR:
		Bprint(&outbuf, "int8");
		break;
	case TUCHAR:
		Bprint(&outbuf, "uint8");
		break;
	case TSHORT:
		Bprint(&outbuf, "int16");
		break;
	case TUSHORT:
		Bprint(&outbuf, "uint16");
		break;
	case TLONG:
		Bprint(&outbuf, "int32");
		break;
	case TULONG:
		Bprint(&outbuf, "uint32");
		break;
	case TVLONG:
		Bprint(&outbuf, "int64");
		break;
	case TUVLONG:
		Bprint(&outbuf, "uint64");
		break;
	case TFLOAT:
		Bprint(&outbuf, "float32");
		break;
	case TDOUBLE:
		Bprint(&outbuf, "float64");
		break;
	case TUNION:
	case TSTRUCT:
		s = findsue(t->link);
		n = "bad";
		if(s != S)
			n = s->name;
		else if(t->tag)
			n = t->tag->name;
		if(strcmp(n, "String") == 0){
			Bprint(&outbuf, "string");
		} else if(strcmp(n, "Slice") == 0){
			Bprint(&outbuf, "[]byte");
		} else
			Bprint(&outbuf, "%U", n);
		break;
	case TFUNC:
		Bprint(&outbuf, "func(");
		for(t1 = t->down; t1 != T; t1 = t1->down) {
			if(t1->etype == TVOID)
				break;
			if(t1 != t->down)
				Bprint(&outbuf, ", ");
			printtypename(t1);
		}
		Bprint(&outbuf, ")");
		if(t->link && t->link->etype != TVOID) {
			Bprint(&outbuf, " ");
			printtypename(t->link);
		}
		break;
	case TDOT:
		Bprint(&outbuf, "...interface{}");
		break;
	default:
		Bprint(&outbuf, " weird<%T>", t);
	}
}

static int
dontrun(void)
{
	Io *i;
	int n;

	if(!debug['q'] && !debug['Q'])
		return 1;
	if(debug['q'] + debug['Q'] > 1) {
		n = 0;
		for(i=iostack; i; i=i->link)
			n++;
		if(n > 1)
			return 1;
	}

	upper = debug['Q'];
	return 0;
}

void
godeftype(Type *t)
{
	Sym *s;
	Type *l;
	int gotone;

	if(dontrun())
		return;

	switch(t->etype) {
	case TUNION:
	case TSTRUCT:
		s = findsue(t->link);
		if(s == S) {
			Bprint(&outbuf, "/* can't find %T */\n\n", t);
			return;
		}

		gotone = 0; // for unions, take first member of size equal to union
		Bprint(&outbuf, "type %U struct {\n", s->name);
		for(l = t->link; l != T; l = l->down) {
			Bprint(&outbuf, "\t");
			if(t->etype == TUNION) {
				if(!gotone && l->width == t->width)
					gotone = 1;
				else
					Bprint(&outbuf, "// (union)\t");
			}
			if(l->sym != nil)  // not anonymous field
				Bprint(&outbuf, "%U\t", l->sym->name);
			printtypename(l);
			Bprint(&outbuf, "\n");
		}
		Bprint(&outbuf, "}\n\n");
		break;

	default:
		Bprint(&outbuf, "/* %T */\n\n", t);
		break;
	}
}

void
godefvar(Sym *s)
{
	Type *t, *t1;
	char n;

	if(dontrun())
		return;

	t = s->type;
	if(t == nil)
		return;

	switch(t->etype) {
	case TENUM:
		if(!typefd[t->etype])
			Bprint(&outbuf, "const %U = %lld\n", s->name, s->vconst);
		else
			Bprint(&outbuf, "const %U = %f\n;", s->name, s->fconst);
		break;

	case TFUNC:
		Bprint(&outbuf, "func %U(", s->name);
		n = 'a';
		for(t1 = t->down; t1 != T; t1 = t1->down) {
			if(t1->etype == TVOID)
				break;
			if(t1 != t->down)
				Bprint(&outbuf, ", ");
			Bprint(&outbuf, "%c ", n++);
			printtypename(t1);
		}
		Bprint(&outbuf, ")");
		if(t->link && t->link->etype != TVOID) {
			Bprint(&outbuf, " ");
			printtypename(t->link);
		}
		Bprint(&outbuf, "\n");
		break;

	default:
		switch(s->class) {
		case CTYPEDEF:
			if(!typesu[t->etype]) {
				Bprint(&outbuf, "// type %U\t", s->name);
				printtypename(t);
				Bprint(&outbuf, "\n");
			}
			break;
		case CSTATIC:
		case CEXTERN:
		case CGLOBL:
			if(strchr(s->name, '$') != nil)	 // TODO(lvd)
			    break;
			Bprint(&outbuf, "var %U\t", s->name);
			printtypename(t);
			Bprint(&outbuf, "\n");
			break;
		}
		break;
	}
}
