// Inferno utils/cc/macbody
// http://code.Google.Com/p/inferno-os/source/browse/utils/cc/macbody
//
//	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.

package asm

import (
	"bytes"
	"cmd/internal/obj"
	"fmt"
	"os"
	"strings"
)

const (
	VARMAC = 0x80
)

func getnsn() int32 {
	c := getnsc()
	if c < '0' || c > '9' {
		return -1
	}
	n := int32(0)
	for c >= '0' && c <= '9' {
		n = n*10 + int32(c) - '0'
		c = getc()
	}

	unget(c)
	return n
}

func getsym() *Sym {
	c := getnsc()
	if !isalpha(c) && c != '_' && c < 0x80 {
		unget(c)
		return nil
	}

	var buf bytes.Buffer
	for {
		buf.WriteByte(byte(c))
		c = getc()
		if isalnum(c) || c == '_' || c >= 0x80 {
			continue
		}
		unget(c)
		break
	}
	last = buf.String()
	return Lookup(last)
}

func getsymdots(dots *int) *Sym {
	s := getsym()
	if s != nil {
		return s
	}

	c := getnsc()
	if c != '.' {
		unget(c)
		return nil
	}

	if getc() != '.' || getc() != '.' {
		Yyerror("bad dots in macro")
	}
	*dots = 1
	return Lookup("__VA_ARGS__")
}

func getcom() int {
	var c int

	for {
		c = getnsc()
		if c != '/' {
			break
		}
		c = getc()
		if c == '/' {
			for c != '\n' {
				c = getc()
			}
			break
		}

		if c != '*' {
			break
		}
		c = getc()
		for {
			if c == '*' {
				c = getc()
				if c != '/' {
					continue
				}
				c = getc()
				break
			}

			if c == '\n' {
				Yyerror("comment across newline")
				break
			}

			c = getc()
		}

		if c == '\n' {
			break
		}
	}

	return c
}

func dodefine(cp string) {
	var s *Sym

	if i := strings.Index(cp, "="); i >= 0 {
		p := cp[i+1:]
		cp = cp[:i]
		s = Lookup(cp)
		s.Macro = &Macro{Text: p}
	} else {
		s = Lookup(cp)
		s.Macro = &Macro{Text: "1"}
	}

	if debug['m'] != 0 {
		fmt.Printf("#define (-D) %s %s\n", s.Name, s.Macro.Text)
	}
}

var mactab = []struct {
	Macname string
	Macf    func()
}{
	{"ifdef", nil},  /* macif(0) */
	{"ifndef", nil}, /* macif(1) */
	{"else", nil},   /* macif(2) */
	{"line", maclin},
	{"define", macdef},
	{"include", macinc},
	{"undef", macund},
	{"pragma", macprag},
	{"endif", macend},
}

func domacro() {
	s := getsym()
	if s == nil {
		s = Lookup("endif")
	}
	for i := 0; i < len(mactab); i++ {
		if s.Name == mactab[i].Macname {
			if mactab[i].Macf != nil {
				mactab[i].Macf()
			} else {
				macif(i)
			}
			return
		}
	}

	Yyerror("unknown #: %s", s.Name)
	macend()
}

func macund() {
	s := getsym()
	macend()
	if s == nil {
		Yyerror("syntax in #undef")
		return
	}

	s.Macro = nil
}

const (
	NARG = 25
)

func macdef() {
	var args [NARG]string
	var n int
	var i int
	var c int
	var dots int
	var ischr int
	var base bytes.Buffer

	s := getsym()
	if s == nil {
		goto bad
	}
	if s.Macro != nil {
		Yyerror("macro redefined: %s", s.Name)
	}
	c = getc()
	n = -1
	dots = 0
	if c == '(' {
		n++
		c = getnsc()
		if c != ')' {
			unget(c)
			var a *Sym
			var c int
			for {
				a = getsymdots(&dots)
				if a == nil {
					goto bad
				}
				if n >= NARG {
					Yyerror("too many arguments in #define: %s", s.Name)
					goto bad
				}

				args[n] = a.Name
				n++
				c = getnsc()
				if c == ')' {
					break
				}
				if c != ',' || dots != 0 {
					goto bad
				}
			}
		}

		c = getc()
	}

	if isspace(c) {
		if c != '\n' {
			c = getnsc()
		}
	}
	ischr = 0
	for {
		if isalpha(c) || c == '_' {
			var buf bytes.Buffer
			buf.WriteByte(byte(c))
			c = getc()
			for isalnum(c) || c == '_' {
				buf.WriteByte(byte(c))
				c = getc()
			}

			symb := buf.String()
			for i = 0; i < n; i++ {
				if symb == args[i] {
					break
				}
			}
			if i >= n {
				base.WriteString(symb)
				continue
			}

			base.WriteByte('#')
			base.WriteByte(byte('a' + i))
			continue
		}

		if ischr != 0 {
			if c == '\\' {
				base.WriteByte(byte(c))
				c = getc()
			} else if c == ischr {
				ischr = 0
			}
		} else {
			if c == '"' || c == '\'' {
				base.WriteByte(byte(c))
				ischr = c
				c = getc()
				continue
			}

			if c == '/' {
				c = getc()
				if c == '/' {
					c = getc()
					for {
						if c == '\n' {
							break
						}
						c = getc()
					}

					continue
				}

				if c == '*' {
					c = getc()
					for {
						if c == '*' {
							c = getc()
							if c != '/' {
								continue
							}
							c = getc()
							break
						}

						if c == '\n' {
							Yyerror("comment and newline in define: %s", s.Name)
							break
						}

						c = getc()
					}

					continue
				}

				base.WriteByte('/')
				continue
			}
		}

		if c == '\\' {
			c = getc()
			if c == '\n' {
				c = getc()
				continue
			} else if c == '\r' {
				c = getc()
				if c == '\n' {
					c = getc()
					continue
				}
			}

			base.WriteByte('\\')
			continue
		}

		if c == '\n' {
			break
		}
		if c == '#' {
			if n > 0 {
				base.WriteByte(byte(c))
			}
		}

		base.WriteByte(byte(c))
		c = GETC()
		if c == '\n' {
			Lineno++
		}
		if c == -1 {
			Yyerror("eof in a macro: %s", s.Name)
			break
		}
	}

	s.Macro = &Macro{
		Text: base.String(),
		Narg: n + 1,
		Dots: dots != 0,
	}
	if debug['m'] != 0 {
		fmt.Printf("#define %s %s\n", s.Name, s.Macro.Text)
	}
	return

bad:
	if s == nil {
		Yyerror("syntax in #define")
	} else {
		Yyerror("syntax in #define: %s", s.Name)
	}
	macend()
}

func macexpand(s *Sym) []byte {
	if s.Macro.Narg == 0 {
		if debug['m'] != 0 {
			fmt.Printf("#expand %s %s\n", s.Name, s.Macro.Text)
		}
		return []byte(s.Macro.Text)
	}

	nargs := s.Macro.Narg - 1
	dots := s.Macro.Dots

	c := getnsc()
	var arg []string
	var cp string
	var out bytes.Buffer
	if c != '(' {
		goto bad
	}
	c = getc()
	if c != ')' {
		unget(c)
		l := 0
		var buf bytes.Buffer
		var c int
		for {
			c = getc()
			if c == '"' {
				for {
					buf.WriteByte(byte(c))
					c = getc()
					if c == '\\' {
						buf.WriteByte(byte(c))
						c = getc()
						continue
					}

					if c == '\n' {
						goto bad
					}
					if c == '"' {
						break
					}
				}
			}

			if c == '\'' {
				for {
					buf.WriteByte(byte(c))
					c = getc()
					if c == '\\' {
						buf.WriteByte(byte(c))
						c = getc()
						continue
					}

					if c == '\n' {
						goto bad
					}
					if c == '\'' {
						break
					}
				}
			}

			if c == '/' {
				c = getc()
				switch c {
				case '*':
					for {
						c = getc()
						if c == '*' {
							c = getc()
							if c == '/' {
								break
							}
						}
					}

					buf.WriteByte(' ')
					continue

				case '/':
					for {
						c = getc()
						if !(c != '\n') {
							break
						}
					}

				default:
					unget(c)
					c = '/'
				}
			}

			if l == 0 {
				if c == ',' {
					if len(arg) == nargs-1 && dots {
						buf.WriteByte(',')
						continue
					}

					arg = append(arg, buf.String())
					buf.Reset()
					continue
				}

				if c == ')' {
					arg = append(arg, buf.String())
					break
				}
			}

			if c == '\n' {
				c = ' '
			}
			buf.WriteByte(byte(c))
			if c == '(' {
				l++
			}
			if c == ')' {
				l--
			}
		}
	}

	if len(arg) != nargs {
		Yyerror("argument mismatch expanding: %s", s.Name)
		return nil
	}

	cp = s.Macro.Text
	for i := 0; i < len(cp); i++ {
		c = int(cp[i])
		if c == '\n' {
			c = ' '
		}
		if c != '#' {
			out.WriteByte(byte(c))
			continue
		}

		i++
		if i >= len(cp) {
			goto bad
		}
		c = int(cp[i])
		if c == '#' {
			out.WriteByte(byte(c))
			continue
		}

		c -= 'a'
		if c < 0 || c >= len(arg) {
			continue
		}
		out.WriteString(arg[c])
	}

	if debug['m'] != 0 {
		fmt.Printf("#expand %s %s\n", s.Name, out.String())
	}
	return out.Bytes()

bad:
	Yyerror("syntax in macro expansion: %s", s.Name)
	return nil
}

func macinc() {
	var c int
	var buf bytes.Buffer
	var f *os.File
	var hp string
	var str string
	var symb string

	c0 := getnsc()
	if c0 != '"' {
		c = c0
		if c0 != '<' {
			goto bad
		}
		c0 = '>'
	}

	for {
		c = getc()
		if c == c0 {
			break
		}
		if c == '\n' {
			goto bad
		}
		buf.WriteByte(byte(c))
	}
	str = buf.String()

	c = getcom()
	if c != '\n' {
		goto bad
	}

	for i := 0; i < len(include); i++ {
		if i == 0 && c0 == '>' {
			continue
		}
		symb = include[i]
		symb += "/"
		if symb == "./" {
			symb = ""
		}
		symb += str
		var err error
		f, err = os.Open(symb)
		if err == nil {
			break
		}
	}

	if f == nil {
		symb = str
	}
	hp = symb
	newio()
	pushio()
	newfile(hp, f)
	return

bad:
	unget(c)
	Yyerror("syntax in #include")
	macend()
}

func maclin() {
	var buf bytes.Buffer
	var symb string

	n := getnsn()
	c := getc()
	if n < 0 {
		goto bad
	}
	for {
		if c == ' ' || c == '\t' {
			c = getc()
			continue
		}

		if c == '"' {
			break
		}
		if c == '\n' {
			symb = "<noname>"
			goto nn
		}

		goto bad
	}

	for {
		c = getc()
		if c == '"' {
			break
		}
		buf.WriteByte(byte(c))
	}
	symb = buf.String()

	c = getcom()
	if c != '\n' {
		goto bad
	}

nn:
	obj.Linklinehist(Ctxt, int(Lineno), symb, int(n))
	return

bad:
	unget(c)
	Yyerror("syntax in #line")
	macend()
}

func macif(f int) {
	var c int
	var l int
	var bol int
	var s *Sym

	if f == 2 {
		goto skip
	}
	s = getsym()
	if s == nil {
		goto bad
	}
	if getcom() != '\n' {
		goto bad
	}
	if (s.Macro != nil) != (f != 0) {
		return
	}

skip:
	bol = 1
	l = 0
	for {
		c = getc()
		if c != '#' {
			if !isspace(c) {
				bol = 0
			}
			if c == '\n' {
				bol = 1
			}
			continue
		}

		if !(bol != 0) {
			continue
		}
		s = getsym()
		if s == nil {
			continue
		}
		if s.Name == "endif" {
			if l != 0 {
				l--
				continue
			}

			macend()
			return
		}

		if s.Name == "ifdef" || s.Name == "ifndef" {
			l++
			continue
		}

		if l == 0 && f != 2 && s.Name == "else" {
			macend()
			return
		}
	}

bad:
	Yyerror("syntax in #if(n)def")
	macend()
}

func macprag() {
	var c int

	s := getsym()

	if s != nil && s.Name == "lib" {
		c0 := getnsc()
		if c0 != '"' {
			c = c0
			if c0 != '<' {
				goto bad
			}
			c0 = '>'
		}

		var buf bytes.Buffer
		for {
			c = getc()
			if c == c0 {
				break
			}
			if c == '\n' {
				goto bad
			}
			buf.WriteByte(byte(c))
		}
		symb := buf.String()

		c = getcom()
		if c != '\n' {
			goto bad
		}

		/*
		 * put pragma-line in as a funny history
		 */
		obj.Linklinehist(Ctxt, int(Lineno), symb, -1)
		return
	}
	if s != nil && s.Name == "pack" {
		pragpack()
		return
	}

	if s != nil && s.Name == "fpround" {
		pragfpround()
		return
	}

	if s != nil && s.Name == "textflag" {
		pragtextflag()
		return
	}

	if s != nil && s.Name == "dataflag" {
		pragdataflag()
		return
	}

	if s != nil && s.Name == "varargck" {
		pragvararg()
		return
	}

	if s != nil && s.Name == "incomplete" {
		pragincomplete()
		return
	}

	if s != nil && (strings.HasPrefix(s.Name, "cgo_") || strings.HasPrefix(s.Name, "dyn")) {
		pragcgo(s.Name)
		return
	}

	for getnsc() != '\n' {
	}
	return

bad:
	unget(c)
	Yyerror("syntax in #pragma lib")
	macend()
}

func macend() {
	var c int

	for {
		c = getnsc()
		if c < 0 || c == '\n' {
			return
		}
	}
}
