#                            COPYRIGHT
#
#  cschem - modular/flexible schematics editor - box symbol generator utility
#  Copyright (C) 2022,2023 Tibor 'Igor2' Palinkas
#
#  (Supported by NLnet NGI0 PET Fund in 2022)
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
#  Contact:
#    Project page: http://repo.hu/projects/sch-rnd
#    contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html
#    mailing list: http://www.repo.hu/projects/sch-rnd/contact.html

BEGIN {
	nslots=0
	SLOT["", "npins"] = 0
}

# return $0 in a string with $1 removed 
function del1(   tmp)
{
	tmp = $0
	sub("^[ \t]*[^ \t]*[ \t]*", "", tmp)
	return tmp
}

# return $0 in a string with $1 and $2 removed 
function del2(   tmp)
{
	tmp = $0
	sub("^[ \t]*[^ \t]*[ \t]*[^ \t]*[ \t]*", "", tmp)
	return tmp
}

function add_pin()
{
	PINS[slot, SLOT[slot, "npins"]] = pin
	SLOT[slot, "npins"]++
	pin = ""
	return 0
}

function add_slot()
{
	SLOTS[nslots] = slot
	nslots++
	slot = ""
	return 0
}

function parse_pin()
{
	pin=slot "::" $3
	dbg("parse_pin(): pin=" pin)
	while(getline == 1) {
		if ((/^[ \t]*#/) || (NF == 0)) continue
		if (($1 == "end") && ($2 == "pin"))
			return add_pin()
		if ($1 == "end") {
			print "Invalid end - expected slot end in line", NR > stderr
			exit 1
		}
		if (($1 == "num") || ($1 == "loc") || ($1 == "dir") || ($1 == "label")) {
			if (PIN[pin, $1] != "") {
				print "ERROR: multiple definitions of " pin "/" $1 " in line " NR > "/dev/stderr"
				exit 1
			}
			PIN[pin, $1] = strip(del1($0))
		}
		else if ($1 == "invcirc") {
			if (PIN[pin, $1] != "") {
				print "ERROR: multiple definitions of " pin "/" $1 " in line " NR > "/dev/stderr"
				exit 1
			}
			PIN[pin, $1] = 1
		}
		else if ($1 == "funcmap") {
			PIN[pin, "funcmap"] = 1
		}
		else {
			print "Invalid pin command in line", NR > stderr
			exit 1
		}
	}
}

# recurse parsing anything (except slots) - expects $0 is the "begin" line
function parse_any()
{
	if ($2 == "pin")
		return parse_pin()

	print "Invalid begin in line", NR > stderr
	exit 1
}


# recurse parsing a slot - expects $0 is the "begin" line
function parse_slot()
{
	slot=$3
	SLOT[slot, "npins"] = 0
	while(getline == 1) {
		if ((/^[ \t]*#/) || (NF == 0)) continue
		if (($1 == "end") && ($2 == "slot"))
			return add_slot()
		if ($1 == "end") {
			print "Invalid end - expected slot end in line", NR > stderr
			exit 1
		}
		if ($1 == "shape")
			SLOT[slot, "shape"] = del1($0)
		else if ($1 == "shape_fill")
			SLOT[slot, "shape_fill"] = tobool($2)
		else if ($1 == "pinalign")
			SLOT[slot, "pinalign", $2] = $3
		else if ($1 == "label")
			SLOT[slot, "label", ++SLOT["", "labels"]] = $2
		else if ($1 == "attr")
			SLOT[slot, "attr",  $2] = del2($0)
		else if ($1 == "attr_both") {
			SLOT[slot, "attr",  $2] = del2($0)
			SLOT[slot, "attr_vis",  $2] = "both"
		}
		else if ($1 == "attr_invis") {
			SLOT[slot, "attr",  $2] = del2($0)
			SLOT[slot, "attr_vis",  $2] = "none"
		}
		else if ($1 == "begin")
			parse_any()
		else {
			print "Invalid slot command in line", NR > stderr
			exit 1
		}
	}
	print "Premature end of file while reading slot in line", NR > stderr
	exit 1
}

(NR == 1) {
	inputname=FILENAME
	basename=inputname
	sub("[.][^.]*$", "", basename)
}
/^[\t ]*#/ { next }
($1 == refdes) { refdes = $2 }
/begin slot/ { parse_slot(); next }
($1 == "begin") { slot=""; parse_any() }
($1 == "pinalign") { SLOT["", "pinalign", $2] = $3 }
($1 == "label") { SLOT["", "label", ++SLOT["", "labels"]] = $2 }
($1 == "attr") { SLOT["", "attr",  $2] = del2($0) }
($1 == "attr_both") { SLOT["", "attr",  $2] = del2($0); SLOT["", "attr_vis",  $2] = "both"; }
($1 == "attr_invis") { SLOT["", "attr",  $2] = del2($0); SLOT["", "attr_vis",  $2] = "none"; }
($1 == "shape") { SLOT["", "shape"] = del1($0) }
($1 == "shape_fill") {SLOT["", "shape_fill"] = tobool($2) }

($1 == "text_size_mult") {
	text_size_mult = $2 + 0;
	if (text_size_mult <= 0) {
		print "text_size_mult must be greater than zero" > "/dev/stderr"
		exit 1
	}
}
