package rosa

import (
	"slices"
	"strconv"
	"strings"

	"hakurei.app/internal/pkg"
)

// skipGNUTests generates a string for skipping specific tests by number in a
// GNU test suite. This is nontrivial because the test suite does not support
// excluding tests in any way, so ranges for all but the skipped tests have to
// be specified instead.
//
// For example, to skip test 764, ranges around the skipped test must be
// specified:
//
//	1-763 765-
//
// Tests are numbered starting from 1. The resulting string is unquoted.
func skipGNUTests(tests ...int) string {
	tests = slices.Clone(tests)
	slices.Sort(tests)

	var buf strings.Builder

	if tests[0] != 1 {
		buf.WriteString("1-")
	}

	for i, n := range tests {
		if n != 1 && (i == 0 || tests[i-1] != n-1) {
			buf.WriteString(strconv.Itoa(n - 1))
			buf.WriteString(" ")
		}
		if i == len(tests)-1 || tests[i+1] != n+1 {
			buf.WriteString(strconv.Itoa(n + 1))
			buf.WriteString("-")
		}
	}
	return buf.String()
}

func (t Toolchain) newM4() (pkg.Artifact, string) {
	const (
		version  = "1.4.21"
		checksum = "pPa6YOo722Jw80l1OsH1tnUaklnPFjFT-bxGw5iAVrZTm1P8FQaWao_NXop46-pm"
	)
	return t.NewPackage("m4", version, newTar(
		"https://ftpmirror.gnu.org/gnu/m4/m4-"+version+".tar.bz2",
		checksum,
		pkg.TarBzip2,
	), &PackageAttr{
		Writable: true,
		ScriptEarly: `
chmod +w tests/test-c32ispunct.sh && echo '#!/bin/sh' > tests/test-c32ispunct.sh
`,
	}, (*MakeHelper)(nil),
		Diffutils,

		KernelHeaders,
	), version
}
func init() {
	artifactsM[M4] = Metadata{
		f: Toolchain.newM4,

		Name:        "m4",
		Description: "a macro processor with GNU extensions",
		Website:     "https://www.gnu.org/software/m4/",

		ID: 1871,
	}
}

func (t Toolchain) newBison() (pkg.Artifact, string) {
	const (
		version  = "3.8.2"
		checksum = "BhRM6K7URj1LNOkIDCFDctSErLS-Xo5d9ba9seg10o6ACrgC1uNhED7CQPgIY29Y"
	)
	return t.NewPackage("bison", version, newTar(
		"https://ftpmirror.gnu.org/gnu/bison/bison-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), nil, &MakeHelper{
		Check: []string{
			"TESTSUITEFLAGS=" + jobsFlagE + "' " + skipGNUTests(
				// clang miscompiles (SIGILL)
				764,
			) + "'",
			"check",
		},
	},
		M4,
		Diffutils,
		Sed,
	), version
}
func init() {
	artifactsM[Bison] = Metadata{
		f: Toolchain.newBison,

		Name:        "bison",
		Description: "a general-purpose parser generator",
		Website:     "https://www.gnu.org/software/bison/",

		ID: 193,
	}
}

func (t Toolchain) newSed() (pkg.Artifact, string) {
	const (
		version  = "4.10"
		checksum = "TXTRFQJCyflb-bpBRI2S5Y1DpplwvT7-KfXtpqN4AdZgZ5OtI6yStn1-bkhDKx51"
	)
	return t.NewPackage("sed", version, newTar(
		"https://ftpmirror.gnu.org/gnu/sed/sed-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), nil, (*MakeHelper)(nil),
		Diffutils,

		KernelHeaders,
	), version
}
func init() {
	artifactsM[Sed] = Metadata{
		f: Toolchain.newSed,

		Name:        "sed",
		Description: "a non-interactive command-line text editor",
		Website:     "https://www.gnu.org/software/sed/",

		ID: 4789,
	}
}

func (t Toolchain) newAutoconf() (pkg.Artifact, string) {
	const (
		version  = "2.73"
		checksum = "yGabDTeOfaCUB0JX-h3REYLYzMzvpDwFmFFzHNR7QilChCUNE4hR6q7nma4viDYg"
	)
	return t.NewPackage("autoconf", version, newTar(
		"https://ftpmirror.gnu.org/gnu/autoconf/autoconf-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), &PackageAttr{
		Flag: TExclusive,
	}, &MakeHelper{
		Check: []string{
			"TESTSUITEFLAGS=" + jobsFlagE,
			"check",
		},
	},
		M4,
		Perl,
		Bash,
		Diffutils,
	), version
}
func init() {
	artifactsM[Autoconf] = Metadata{
		f: Toolchain.newAutoconf,

		Name:        "autoconf",
		Description: "M4 macros to produce self-contained configure script",
		Website:     "https://www.gnu.org/software/autoconf/",

		Dependencies: P{
			M4,
			Perl,
		},

		ID: 141,
	}
}

func (t Toolchain) newAutomake() (pkg.Artifact, string) {
	const (
		version  = "1.18.1"
		checksum = "FjvLG_GdQP7cThTZJLDMxYpRcKdpAVG-YDs1Fj1yaHlSdh_Kx6nRGN14E0r_BjcG"
	)
	return t.NewPackage("automake", version, newTar(
		"https://ftpmirror.gnu.org/gnu/automake/automake-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), &PackageAttr{
		Writable: true,
		ScriptEarly: `
test_disable() { chmod +w "$2" && echo "$1" > "$2"; }

test_disable '#!/bin/sh' t/objcxx-minidemo.sh
test_disable '#!/bin/sh' t/objcxx-deps.sh

test_disable '#!/bin/sh' t/dist-no-built-sources.sh
test_disable '#!/bin/sh' t/distname.sh
test_disable '#!/bin/sh' t/pr9.sh
`,
	}, (*MakeHelper)(nil),
		Grep,
		Gzip,
		Autoconf,
		Diffutils,
	), version
}
func init() {
	artifactsM[Automake] = Metadata{
		f: Toolchain.newAutomake,

		Name:        "automake",
		Description: "a tool for automatically generating Makefile.in files",
		Website:     "https://www.gnu.org/software/automake/",

		Dependencies: P{
			Autoconf,
		},

		ID: 144,
	}
}

func (t Toolchain) newLibtool() (pkg.Artifact, string) {
	const (
		version  = "2.5.4"
		checksum = "pa6LSrQggh8mSJHQfwGjysAApmZlGJt8wif2cCLzqAAa2jpsTY0jZ-6stS3BWZ2Q"
	)
	return t.NewPackage("libtool", version, newTar(
		"https://ftpmirror.gnu.org/gnu/libtool/libtool-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), nil, &MakeHelper{
		// _Z2a2c: symbol not found
		SkipCheck: t.isStage0(),

		Check: []string{
			"TESTSUITEFLAGS=" + jobsFlagE,
			"check",
		},
	},
		M4,
		Diffutils,
	), version
}
func init() {
	artifactsM[Libtool] = Metadata{
		f: Toolchain.newLibtool,

		Name:        "libtool",
		Description: "a generic library support script",
		Website:     "https://www.gnu.org/software/libtool/",

		ID: 1741,
	}
}

func (t Toolchain) newGzip() (pkg.Artifact, string) {
	const (
		version  = "1.14"
		checksum = "NWhjUavnNfTDFkZJyAUonL9aCOak8GVajWX2OMlzpFnuI0ErpBFyj88mz2xSjz0q"
	)
	return t.NewPackage("gzip", version, newTar(
		"https://ftpmirror.gnu.org/gnu/gzip/gzip-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), nil, &MakeHelper{
		// dependency loop
		SkipCheck: true,
	}), version
}
func init() {
	artifactsM[Gzip] = Metadata{
		f: Toolchain.newGzip,

		Name:        "gzip",
		Description: "a popular data compression program",
		Website:     "https://www.gnu.org/software/gzip/",

		ID: 1290,
	}
}

func (t Toolchain) newGettext() (pkg.Artifact, string) {
	const (
		version  = "1.0"
		checksum = "3MasKeEdPeFEgWgzsBKk7JqWqql1wEMbgPmzAfs-mluyokoW0N8oQVxPQoOnSdgC"
	)
	return t.NewPackage("gettext", version, newTar(
		"https://ftpmirror.gnu.org/gnu/gettext/gettext-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), &PackageAttr{
		Writable: true,
		ScriptEarly: `
test_disable() { chmod +w "$2" && echo "$1" > "$2"; }

test_disable '#!/bin/sh' gettext-tools/tests/msgcat-22
test_disable '#!/bin/sh' gettext-tools/tests/msgconv-2
test_disable '#!/bin/sh' gettext-tools/tests/msgconv-8
test_disable '#!/bin/sh' gettext-tools/tests/xgettext-python-3
test_disable '#!/bin/sh' gettext-tools/tests/msgmerge-compendium-6
test_disable '#!/bin/sh' gettext-tools/tests/gettextpo-1
test_disable '#!/bin/sh' gettext-tools/tests/format-c-5
test_disable '#!/bin/sh' gettext-tools/gnulib-tests/test-c32ispunct.sh
test_disable 'int main(){return 0;}' gettext-tools/gnulib-tests/test-stdcountof-h.c

touch gettext-tools/autotools/archive.dir.tar
`,
	}, (*MakeHelper)(nil),
		Diffutils,
		Gzip,
		Sed,

		KernelHeaders,
	), version
}
func init() {
	artifactsM[Gettext] = Metadata{
		f: Toolchain.newGettext,

		Name:        "gettext",
		Description: "tools for producing multi-lingual messages",
		Website:     "https://www.gnu.org/software/gettext/",

		ID: 898,
	}
}

func (t Toolchain) newDiffutils() (pkg.Artifact, string) {
	const (
		version  = "3.12"
		checksum = "9J5VAq5oA7eqwzS1Yvw-l3G5o-TccUrNQR3PvyB_lgdryOFAfxtvQfKfhdpquE44"
	)
	return t.NewPackage("diffutils", version, newTar(
		"https://ftpmirror.gnu.org/gnu/diffutils/diffutils-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), &PackageAttr{
		Writable: true,
		ScriptEarly: `
test_disable() { chmod +w "$2" && echo "$1" > "$2"; }

test_disable '#!/bin/sh' gnulib-tests/test-c32ispunct.sh
test_disable 'int main(){return 0;}' gnulib-tests/test-c32ispunct.c
test_disable '#!/bin/sh' tests/cmp
`,
		Flag: TEarly,
	}, (*MakeHelper)(nil)), version
}
func init() {
	artifactsM[Diffutils] = Metadata{
		f: Toolchain.newDiffutils,

		Name:        "diffutils",
		Description: "several programs related to finding differences between files",
		Website:     "https://www.gnu.org/software/diffutils/",

		ID: 436,
	}
}

func (t Toolchain) newPatch() (pkg.Artifact, string) {
	const (
		version  = "2.8"
		checksum = "MA0BQc662i8QYBD-DdGgyyfTwaeALZ1K0yusV9rAmNiIsQdX-69YC4t9JEGXZkeR"
	)
	return t.NewPackage("patch", version, newTar(
		"https://ftpmirror.gnu.org/gnu/patch/patch-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), &PackageAttr{
		Writable: true,
		ScriptEarly: `
test_disable() { chmod +w "$2" && echo "$1" > "$2"; }

test_disable '#!/bin/sh' tests/ed-style
test_disable '#!/bin/sh' tests/need-filename
`,
		Flag: TEarly,
	}, (*MakeHelper)(nil)), version
}
func init() {
	artifactsM[Patch] = Metadata{
		f: Toolchain.newPatch,

		Name:        "patch",
		Description: "a program to apply diff output to files",
		Website:     "https://savannah.gnu.org/projects/patch/",

		ID: 2597,
	}
}

func (t Toolchain) newBash() (pkg.Artifact, string) {
	const (
		version  = "5.3"
		checksum = "4LQ_GRoB_ko-Ih8QPf_xRKA02xAm_TOxQgcJLmFDT6udUPxTAWrsj-ZNeuTusyDq"
	)
	return t.NewPackage("bash", version, newTar(
		"https://ftpmirror.gnu.org/gnu/bash/bash-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), &PackageAttr{
		Flag: TEarly,
	}, &MakeHelper{
		Script: "ln -s bash /work/system/bin/sh\n",
		Configure: []KV{
			{"without-bash-malloc"},
		},
	}), version
}
func init() {
	artifactsM[Bash] = Metadata{
		f: Toolchain.newBash,

		Name:        "bash",
		Description: "the Bourne Again SHell",
		Website:     "https://www.gnu.org/software/bash/",

		ID: 166,
	}
}

func (t Toolchain) newCoreutils() (pkg.Artifact, string) {
	const (
		version  = "9.11"
		checksum = "t8UMed5wpFEoC56aa42_yidfOAaRGzOfj7MRtQkkqgGbpXiskNA8bd-EmVSQkZie"
	)
	return t.NewPackage("coreutils", version, newTar(
		"https://ftpmirror.gnu.org/gnu/coreutils/coreutils-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), &PackageAttr{
		Writable: true,
		ScriptEarly: `
test_disable() { chmod +w "$2" && echo "$1" > "$2"; }

test_disable '#!/bin/sh' gnulib-tests/test-c32ispunct.sh
test_disable '#!/bin/sh' tests/ls/hyperlink.sh
test_disable '#!/bin/sh' tests/misc/user.sh
test_disable 'int main(){return 0;}' gnulib-tests/test-chown.c
test_disable 'int main(){return 0;}' gnulib-tests/test-fchownat.c
test_disable 'int main(){return 0;}' gnulib-tests/test-lchown.c
`,

		Flag: TEarly,
	}, &MakeHelper{
		Configure: []KV{
			{"enable-single-binary", "symlinks"},
		},
	},
		Perl,
		Bash,

		KernelHeaders,
	), version
}
func init() {
	artifactsM[Coreutils] = Metadata{
		f: Toolchain.newCoreutils,

		Name:        "coreutils",
		Description: "the basic file, shell and text manipulation utilities",
		Website:     "https://www.gnu.org/software/coreutils/",

		ID: 343,
	}
}

func (t Toolchain) newTexinfo() (pkg.Artifact, string) {
	const (
		version  = "7.3"
		checksum = "RRmC8Xwdof7JuZJeWGAQ_GeASIHAuJFQMbNONXBz5InooKIQGmqmWRjGNGEr5n4-"
	)
	return t.NewPackage("texinfo", version, newTar(
		"https://ftpmirror.gnu.org/gnu/texinfo/texinfo-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), nil, &MakeHelper{
		// nonstandard glibc extension
		SkipCheck: true,
	},
		Perl,
	), version
}
func init() {
	artifactsM[Texinfo] = Metadata{
		f: Toolchain.newTexinfo,

		Name:        "texinfo",
		Description: "the GNU square-wheel-reinvension of man pages",
		Website:     "https://www.gnu.org/software/texinfo/",

		Dependencies: P{
			Perl,
			Gawk,
		},

		ID: 4958,
	}
}

func (t Toolchain) newGperf() (pkg.Artifact, string) {
	const (
		version  = "3.3"
		checksum = "RtIy9pPb_Bb8-31J2Nw-rRGso2JlS-lDlVhuNYhqR7Nt4xM_nObznxAlBMnarJv7"
	)
	return t.NewPackage("gperf", version, newTar(
		"https://ftpmirror.gnu.org/gperf/gperf-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), nil, (*MakeHelper)(nil),
		Diffutils,
	), version
}
func init() {
	artifactsM[Gperf] = Metadata{
		f: Toolchain.newGperf,

		Name:        "gperf",
		Description: "a perfect hash function generator",
		Website:     "https://www.gnu.org/software/gperf/",

		ID: 1237,
	}
}

func (t Toolchain) newGawk() (pkg.Artifact, string) {
	const (
		version  = "5.4.0"
		checksum = "m0RkIolC-PI7EY5q8pcx5Y-0twlIW0Yp3wXXmV-QaHorSdf8BhZ7kW9F8iWomz0C"
	)
	return t.NewPackage("gawk", version, newTar(
		"https://ftpmirror.gnu.org/gnu/gawk/gawk-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), &PackageAttr{
		Flag: TEarly,
	}, &MakeHelper{
		// dependency loop
		SkipCheck: true,
	}), version
}
func init() {
	artifactsM[Gawk] = Metadata{
		f: Toolchain.newGawk,

		Name:        "gawk",
		Description: "an implementation of awk with GNU extensions",
		Website:     "https://www.gnu.org/software/gawk/",

		ID: 868,
	}
}

func (t Toolchain) newGrep() (pkg.Artifact, string) {
	const (
		version  = "3.12"
		checksum = "qMB4RjaPNRRYsxix6YOrjE8gyAT1zVSTy4nW4wKW9fqa0CHYAuWgPwDTirENzm_1"
	)
	return t.NewPackage("grep", version, newTar(
		"https://ftpmirror.gnu.org/gnu/grep/grep-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), &PackageAttr{
		Writable: true,
		ScriptEarly: `
test_disable() { chmod +w "$2" && echo "$1" > "$2"; }

test_disable '#!/bin/sh' gnulib-tests/test-c32ispunct.sh
test_disable 'int main(){return 0;}' gnulib-tests/test-c32ispunct.c
`,
	}, (*MakeHelper)(nil),
		Diffutils,
	), version
}
func init() {
	artifactsM[Grep] = Metadata{
		f: Toolchain.newGrep,

		Name:        "grep",
		Description: "searches input for lines containing a match to a pattern",
		Website:     "https://www.gnu.org/software/grep/",

		ID: 1251,
	}
}

func (t Toolchain) newFindutils() (pkg.Artifact, string) {
	const (
		version  = "4.10.0"
		checksum = "ZXABdNBQXL7QjTygynRRTdXYWxQKZ0Wn5eMd3NUnxR0xaS0u0VfcKoTlbo50zxv6"
	)
	return t.NewPackage("findutils", version, pkg.NewHTTPGet(
		nil, "https://ftpmirror.gnu.org/gnu/findutils/findutils-"+version+".tar.xz",
		mustDecode(checksum),
	), &PackageAttr{
		ScriptEarly: `
echo '#!/bin/sh' > gnulib-tests/test-c32ispunct.sh
echo 'int main(){return 0;}' > tests/xargs/test-sigusr.c
`,
	}, (*MakeHelper)(nil),
		Diffutils,
		XZ,
		Sed,
	), version
}
func init() {
	artifactsM[Findutils] = Metadata{
		f: Toolchain.newFindutils,

		Name:        "findutils",
		Description: "the basic directory searching utilities",
		Website:     "https://www.gnu.org/software/findutils/",

		ID: 812,
	}
}

func (t Toolchain) newBC() (pkg.Artifact, string) {
	const (
		version  = "1.08.2"
		checksum = "8h6f3hjV80XiFs6v9HOPF2KEyg1kuOgn5eeFdVspV05ODBVQss-ey5glc8AmneLy"
	)
	return t.NewPackage("bc", version, newTar(
		"https://ftpmirror.gnu.org/gnu/bc/bc-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), &PackageAttr{
		// source expected to be writable
		Writable: true,
		Chmod:    true,
	}, (*MakeHelper)(nil),
		Texinfo,
	), version
}
func init() {
	artifactsM[BC] = Metadata{
		f: Toolchain.newBC,

		Name:        "bc",
		Description: "an arbitrary precision numeric processing language",
		Website:     "https://www.gnu.org/software/bc/",

		ID: 170,
	}
}

func (t Toolchain) newLibiconv() (pkg.Artifact, string) {
	const (
		version  = "1.19"
		checksum = "UibB6E23y4MksNqYmCCrA3zTFO6vJugD1DEDqqWYFZNuBsUWMVMcncb_5pPAr88x"
	)
	return t.NewPackage("libiconv", version, newTar(
		"https://ftpmirror.gnu.org/gnu/libiconv/libiconv-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), nil, (*MakeHelper)(nil)), version
}
func init() {
	artifactsM[Libiconv] = Metadata{
		f: Toolchain.newLibiconv,

		Name:        "libiconv",
		Description: "iconv implementation independent of glibc",
		Website:     "https://www.gnu.org/software/libiconv/",

		ID: 10656,
	}
}

func (t Toolchain) newTar() (pkg.Artifact, string) {
	const (
		version  = "1.35"
		checksum = "zSaoSlVUDW0dSfm4sbL4FrXLFR8U40Fh3zY5DWhR5NCIJ6GjU6Kc4VZo2-ZqpBRA"
	)
	return t.NewPackage("tar", version, newTar(
		"https://ftpmirror.gnu.org/gnu/tar/tar-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), nil, &MakeHelper{
		Configure: []KV{
			{"disable-acl"},
			{"without-posix-acls"},
			{"without-xattrs"},
		},
		Check: []string{
			// very expensive
			"TARTEST_SKIP_LARGE_FILES=1",

			"TESTSUITEFLAGS=" + jobsFlagE,
			"check",
		},
	},
		Diffutils,

		Gzip,
		Bzip2,
		Zstd,
	), version
}
func init() {
	artifactsM[Tar] = Metadata{
		f: Toolchain.newTar,

		Name:        "tar",
		Description: "provides the ability to create tar archives",
		Website:     "https://www.gnu.org/software/tar/",

		ID: 4939,
	}
}

func (t Toolchain) newParallel() (pkg.Artifact, string) {
	const (
		version  = "20260422"
		checksum = "eTsepxgqhXpMEhPd55qh-W5y4vjKn0x9TD2mzbJCNZYtFf4lT4Wzoqr74HGJYBEH"
	)
	return t.NewPackage("parallel", version, newTar(
		"https://ftpmirror.gnu.org/gnu/parallel/parallel-"+version+".tar.bz2",
		checksum,
		pkg.TarBzip2,
	), &PackageAttr{
		ScriptEarly: `
ln -s ../system/bin/bash /bin/
`,
	}, (*MakeHelper)(nil),
		Perl,
		Bash,
	), version
}
func init() {
	artifactsM[Parallel] = Metadata{
		f: Toolchain.newParallel,

		Name:        "parallel",
		Description: "a shell tool for executing jobs in parallel using one or more computers",
		Website:     "https://www.gnu.org/software/parallel/",

		Dependencies: P{
			Perl,
		},

		ID: 5448,
	}
}

func (t Toolchain) newLibunistring() (pkg.Artifact, string) {
	const (
		version  = "1.4.2"
		checksum = "iW9BbfLoVlXjWoLTZ4AekQSu4cFBnLcZ4W8OHWbv0AhJNgD3j65_zqaLMzFKylg2"
	)
	return t.NewPackage("libunistring", version, newTar(
		"https://ftpmirror.gnu.org/gnu/libunistring/libunistring-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), &PackageAttr{
		Writable: true,
		ScriptEarly: `
test_disable() { chmod +w "$2" && echo "$1" > "$2"; }

test_disable '#!/bin/sh' tests/test-c32ispunct.sh
test_disable 'int main(){return 0;}' tests/test-c32ispunct.c
`,
	}, (*MakeHelper)(nil),
		Diffutils,
	), version
}
func init() {
	artifactsM[Libunistring] = Metadata{
		f: Toolchain.newLibunistring,

		Name:        "libunistring",
		Description: "provides functions for manipulating Unicode strings",
		Website:     "https://www.gnu.org/software/libunistring/",

		ID: 1747,
	}
}

func (t Toolchain) newLibtasn1() (pkg.Artifact, string) {
	const (
		version  = "4.21.0"
		checksum = "9DYI3UYbfYLy8JsKUcY6f0irskbfL0fHZA91Q-JEOA3kiUwpodyjemRsYRjUpjuq"
	)
	return t.NewPackage("libtasn1", version, newTar(
		"https://ftpmirror.gnu.org/gnu/libtasn1/libtasn1-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), nil, (*MakeHelper)(nil)), version
}
func init() {
	artifactsM[Libtasn1] = Metadata{
		f: Toolchain.newLibtasn1,

		Name:        "libtasn1",
		Description: "the ASN.1 library used by GnuTLS, p11-kit and some other packages",
		Website:     "https://www.gnu.org/software/libtasn1/",

		ID: 1734,
	}
}

func (t Toolchain) newReadline() (pkg.Artifact, string) {
	const (
		version  = "8.3"
		checksum = "r-lcGRJq_MvvBpOq47Z2Y1OI2iqrmtcqhTLVXR0xWo37ZpC2uT_md7gKq5o_qTMV"
	)
	return t.NewPackage("readline", version, newTar(
		"https://ftpmirror.gnu.org/gnu/readline/readline-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), nil, &MakeHelper{
		Configure: []KV{
			{"with-curses"},
			{"with-shared-termcap-library"},
		},
	},
		Ncurses,
	), version
}
func init() {
	artifactsM[Readline] = Metadata{
		f: Toolchain.newReadline,

		Name:        "readline",
		Description: "provides a set of functions for use by applications that allow users to edit command lines as they are typed in",
		Website:     "https://tiswww.cwru.edu/php/chet/readline/rltop.html",

		Dependencies: P{
			Ncurses,
		},

		ID: 4173,
	}
}

func (t Toolchain) newGnuTLS() (pkg.Artifact, string) {
	const (
		version  = "3.8.12"
		checksum = "VPdP-nRydQQRJcnma-YA7CJYA_kzTJ2rb3QFeP6D27emSyInJ8sQ-Wzn518I38dl"
	)

	var configureExtra []KV
	switch arch {
	case "arm64":
		configureExtra = []KV{
			{"disable-hardware-acceleration"},
		}
	}

	return t.NewPackage("gnutls", version, t.newTagRemote(
		"https://gitlab.com/gnutls/gnutls.git",
		version, checksum,
	), &PackageAttr{
		Patches: []KV{
			{"bootstrap-remove-gtk-doc", `diff --git a/bootstrap.conf b/bootstrap.conf
index 1c3cc61e6..32bae9387 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -50,7 +50,6 @@ bison      2.4
 gettext    0.17
 git        1.4.4
 gperf      -
-gtkdocize  -
 perl       5.5
 wget       -
 "
diff --git a/configure.ac b/configure.ac
index 5057536e5..731558a15 100644
--- a/configure.ac
+++ b/configure.ac
@@ -403,11 +403,6 @@ if test "$enable_fuzzer_target" != "no";then
 	AC_DEFINE([FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION], 1, [Enable fuzzer target -not for production])
 fi
 
-dnl
-dnl check for gtk-doc
-dnl
-GTK_DOC_CHECK([1.14],[--flavour no-tmpl])
-
 AM_GNU_GETTEXT([external])
 AM_GNU_GETTEXT_VERSION([0.19])
 m4_ifdef([AM_GNU_GET][TEXT_REQUIRE_VERSION],[
diff --git a/doc/Makefile.am b/doc/Makefile.am
index fb1390d70..52f0ad9af 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -33,9 +33,6 @@ IMAGES = \
 	pkcs11-vision.png
 
 SUBDIRS = examples scripts credentials latex
-if ENABLE_GTK_DOC
-SUBDIRS += reference
-endif
 
 -include $(top_srcdir)/doc/doc.mk
 
diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am
index f10c8ed3c..b711b58ec 100644
--- a/doc/reference/Makefile.am
+++ b/doc/reference/Makefile.am
@@ -82,13 +82,4 @@ include $(top_srcdir)/gtk-doc.make
 # e.g. EXTRA_DIST += version.xml.in
 EXTRA_DIST += version.xml.in
 
-# Comment this out if you want 'make check' to test you doc status
-# and run some sanity checks
-if ENABLE_GTK_DOC
-TESTS_ENVIRONMENT = \
-  DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \
-  SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir)
-#TESTS = $(GTKDOC_CHECK)
-endif
-
 -include $(top_srcdir)/git.mk
`},

			{"alpine-tests-certtool", `I think this tests is simply wrong.
When a PIN is given, the program should run in batch mode.
So the question for "Enter password" should _not_ be present.

DO NOT REMOVE UNLESS VERIFIED IT'S NOT ACTUALLY NECESSARY ANYMORE.

--- a/tests/cert-tests/certtool.sh	2019-02-07 07:33:45.960887338 +0000
+++ b/tests/cert-tests/certtool.sh	2019-02-07 07:36:14.550955051 +0000
@@ -49,7 +49,7 @@
 
 	#check whether password is being honoured
 	#some CI runners need GNUTLS_PIN (GNUTLS_PIN=${PASS})
-	${SETSID} "${CERTTOOL}" --generate-self-signed --load-privkey ${TMPFILE1} --template ${srcdir}/templates/template-test.tmpl --ask-pass >${TMPFILE2} 2>&1 <<EOF
+	GNUTLS_PIN=${PASS} ${SETSID} "${CERTTOOL}" --generate-self-signed --load-privkey ${TMPFILE1} --template ${srcdir}/templates/template-test.tmpl --ask-pass >${TMPFILE2} 2>&1 <<EOF
 $PASS
 EOF
 	if test $? != 0;then
@@ -59,7 +59,7 @@
 	fi
 
 	grep "Enter password" ${TMPFILE2} >/dev/null 2>&1
-	if test $? != 0;then
+	if test $? != 1; then
 		cat ${TMPFILE2}
 		echo "No password was asked"
 		exit 1
`},

			{"test-kernel-version-ksh", `diff --git a/tests/scripts/common.sh b/tests/scripts/common.sh
index 1b78b8cf1..350156a86 100644
--- a/tests/scripts/common.sh
+++ b/tests/scripts/common.sh
@@ -279,10 +279,6 @@ kernel_version_check() {
 	kernel_major=$(echo $kernel_version | cut -d. -f1 2>/dev/null)
 	kernel_minor=$(echo $kernel_version | cut -d. -f2 2>/dev/null)
 
-	if ! [[ "$kernel_major" =~ ^[0-9]+$ ]] || ! [[ "$kernel_minor" =~ ^[0-9]+$ ]]; then
-		return 1
-	fi
-
 	if [ "$kernel_major" -lt "$required_major" ]; then
 		return 1
 	fi
`},
		},
	}, &MakeHelper{
		Generate: "./bootstrap --skip-po --no-git --gnulib-srcdir=gnulib",

		Configure: append([]KV{
			{"disable-doc"},
			{"disable-openssl-compatibility"},

			{"with-default-trust-store-file", "/system/etc/ssl/certs/ca-bundle.crt"},
			{"with-default-trust-store-pkcs11", "pkcs11:"},

			{"with-zlib", "link"},
			{"with-zstd", "link"},
		}, configureExtra...),
	},
		Gzip,
		Automake,
		Libtool,
		Bison,
		Gettext,
		Gperf,
		PkgConfig,

		Python,
		Texinfo,
		Diffutils,
		NSSCACert,

		Libev,
		Zlib,
		Zstd,
		P11Kit,
		nettle3,
		Libunistring,
	), version
}
func init() {
	artifactsM[GnuTLS] = Metadata{
		f: Toolchain.newGnuTLS,

		Name:        "gnutls",
		Description: "a secure communications library implementing the SSL, TLS and DTLS protocols",
		Website:     "https://gnutls.org",

		Dependencies: P{
			Zlib,
			Zstd,
			P11Kit,
			nettle3,
			Libunistring,
		},

		ID: 1221,
	}
}

func (t Toolchain) newBinutils() (pkg.Artifact, string) {
	const (
		version  = "2.46.0"
		checksum = "4kK1_EXQipxSqqyvwD4LbiMLFKCUApjq6PeG4XJP4dzxYGqDeqXfh8zLuTyOuOVR"
	)
	return t.NewPackage("binutils", version, newTar(
		"https://ftpmirror.gnu.org/gnu/binutils/binutils-"+version+".tar.bz2",
		checksum,
		pkg.TarBzip2,
	), nil, (*MakeHelper)(nil),
		Bash,
	), version
}
func init() {
	artifactsM[Binutils] = Metadata{
		f: Toolchain.newBinutils,

		Name:        "binutils",
		Description: "a collection of binary tools",
		Website:     "https://www.gnu.org/software/binutils/",

		ID: 7981,
	}
}

func (t Toolchain) newGMP() (pkg.Artifact, string) {
	const (
		version  = "6.3.0"
		checksum = "yrgbgEDWKDdMWVHh7gPbVl56-sRtVVhfvv0M_LX7xMUUk_mvZ1QOJEAnt7g4i3k5"
	)
	return t.NewPackage("gmp", version, newTar(
		"https://gcc.gnu.org/pub/gcc/infrastructure/"+
			"gmp-"+version+".tar.bz2",
		checksum,
		pkg.TarBzip2,
	), &PackageAttr{
		Env: []string{
			"CC=cc",
		},
	}, (*MakeHelper)(nil),
		M4,
	), version
}
func init() {
	artifactsM[GMP] = Metadata{
		f: Toolchain.newGMP,

		Name:        "gmp",
		Description: "a free library for arbitrary precision arithmetic",
		Website:     "https://gmplib.org/",

		ID: 1186,
	}
}

func (t Toolchain) newMPFR() (pkg.Artifact, string) {
	const (
		version  = "4.2.2"
		checksum = "wN3gx0zfIuCn9r3VAn_9bmfvAYILwrRfgBjYSD1IjLqyLrLojNN5vKyQuTE9kA-B"
	)
	return t.NewPackage("mpfr", version, newTar(
		"https://gcc.gnu.org/pub/gcc/infrastructure/"+
			"mpfr-"+version+".tar.bz2",
		checksum,
		pkg.TarBzip2,
	), nil, (*MakeHelper)(nil),
		GMP,
	), version
}
func init() {
	artifactsM[MPFR] = Metadata{
		f: Toolchain.newMPFR,

		Name:        "mpfr",
		Description: "a C library for multiple-precision floating-point computations",
		Website:     "https://www.mpfr.org/",

		Dependencies: P{
			GMP,
		},

		ID: 2019,
	}
}

func (t Toolchain) newMPC() (pkg.Artifact, string) {
	const (
		version  = "1.4.1"
		checksum = "ZffaZyWkvIw0iPvRe5EJ7O-VvHtSkbbb3K_7SgPtK810NvGan7nbF0T5-6tozjQN"
	)
	return t.NewPackage("mpc", version, newFromGitLab(
		"gitlab.inria.fr",
		"mpc/mpc",
		version, checksum,
	), &PackageAttr{
		// does not find mpc-impl.h otherwise
		EnterSource: true,
	}, &MakeHelper{
		InPlace:  true,
		Generate: "autoreconf -vfi",
	},
		Automake,
		Libtool,
		Texinfo,

		MPFR,
	), version
}
func init() {
	artifactsM[MPC] = Metadata{
		f: Toolchain.newMPC,

		Name:        "mpc",
		Description: "a C library for the arithmetic of complex numbers",
		Website:     "https://www.multiprecision.org/",

		Dependencies: P{
			MPFR,
		},

		ID: 1667,
	}
}

func (t Toolchain) newGCC() (pkg.Artifact, string) {
	const (
		version  = "16.1.0"
		checksum = "4ASoWbxaA2FW7PAB0zzHDPC5XnNhyaAyjtDPpGzceSLeYnEIXsNYZR3PA_Zu5P0K"
	)

	var configureExtra []KV
	switch arch {
	case "amd64", "arm64":
		configureExtra = append(configureExtra, KV{"with-multilib-list", "''"})
	}

	return t.NewPackage("gcc", version, newTar(
		"https://ftp.tsukuba.wide.ad.jp/software/gcc/releases/"+
			"gcc-"+version+"/gcc-"+version+".tar.gz",
		checksum,
		pkg.TarGzip,
	), &PackageAttr{
		Patches: []KV{
			{"musl-off64_t-loff_t", `diff --git a/libgo/sysinfo.c b/libgo/sysinfo.c
index 180f5c31d74..44d7ea73f7d 100644
--- a/libgo/sysinfo.c
+++ b/libgo/sysinfo.c
@@ -365,11 +365,7 @@ enum {
 typedef loff_t libgo_loff_t_type;
 #endif

-#if defined(HAVE_OFF64_T)
-typedef off64_t libgo_off_t_type;
-#else
 typedef off_t libgo_off_t_type;
-#endif

 // The following section introduces explicit references to types and
 // constants of interest to support bootstrapping libgo using a
`},

			{"musl-legacy-lfs", `diff --git a/libgo/go/internal/syscall/unix/at_largefile.go b/libgo/go/internal/syscall/unix/at_largefile.go
index 82e0dcfd074..16151ecad1b 100644
--- a/libgo/go/internal/syscall/unix/at_largefile.go
+++ b/libgo/go/internal/syscall/unix/at_largefile.go
@@ -10,5 +10,5 @@ import (
 	"syscall"
 )

-//extern fstatat64
+//extern fstatat
 func fstatat(int32, *byte, *syscall.Stat_t, int32) int32
diff --git a/libgo/go/os/dir_largefile.go b/libgo/go/os/dir_largefile.go
index 1fc5ee0771f..0c6dffe1a75 100644
--- a/libgo/go/os/dir_largefile.go
+++ b/libgo/go/os/dir_largefile.go
@@ -11,5 +11,5 @@ package os

 import "syscall"

-//extern readdir64
+//extern readdir
 func libc_readdir(*syscall.DIR) *syscall.Dirent
diff --git a/libgo/go/syscall/libcall_glibc.go b/libgo/go/syscall/libcall_glibc.go
index 5c1ec483c75..5a1245ed44b 100644
--- a/libgo/go/syscall/libcall_glibc.go
+++ b/libgo/go/syscall/libcall_glibc.go
@@ -114,7 +114,7 @@ func Pipe2(p []int, flags int) (err error) {
 }

 //sys	sendfile(outfd int, infd int, offset *Offset_t, count int) (written int, err error)
-//sendfile64(outfd _C_int, infd _C_int, offset *Offset_t, count Size_t) Ssize_t
+//sendfile(outfd _C_int, infd _C_int, offset *Offset_t, count Size_t) Ssize_t

 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
 	if race.Enabled {
diff --git a/libgo/go/syscall/libcall_linux.go b/libgo/go/syscall/libcall_linux.go
index 03ca7261b59..ad21fd0b3ac 100644
--- a/libgo/go/syscall/libcall_linux.go
+++ b/libgo/go/syscall/libcall_linux.go
@@ -158,7 +158,7 @@ func Reboot(cmd int) (err error) {
 //adjtimex(buf *Timex) _C_int

 //sys	Fstatfs(fd int, buf *Statfs_t) (err error)
-//fstatfs64(fd _C_int, buf *Statfs_t) _C_int
+//fstatfs(fd _C_int, buf *Statfs_t) _C_int

 func Gettid() (tid int) {
 	r1, _, _ := Syscall(SYS_GETTID, 0, 0, 0)
@@ -245,7 +245,7 @@ func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n i
 }

 //sys	Statfs(path string, buf *Statfs_t) (err error)
-//statfs64(path *byte, buf *Statfs_t) _C_int
+//statfs(path *byte, buf *Statfs_t) _C_int

 //sysnb	Sysinfo(info *Sysinfo_t) (err error)
 //sysinfo(info *Sysinfo_t) _C_int
diff --git a/libgo/go/syscall/libcall_posix_largefile.go b/libgo/go/syscall/libcall_posix_largefile.go
index f90055bb29a..334212f0af1 100644
--- a/libgo/go/syscall/libcall_posix_largefile.go
+++ b/libgo/go/syscall/libcall_posix_largefile.go
@@ -10,40 +10,40 @@
 package syscall

 //sys	Creat(path string, mode uint32) (fd int, err error)
-//creat64(path *byte, mode Mode_t) _C_int
+//creat(path *byte, mode Mode_t) _C_int

 //sys	Fstat(fd int, stat *Stat_t) (err error)
-//fstat64(fd _C_int, stat *Stat_t) _C_int
+//fstat(fd _C_int, stat *Stat_t) _C_int

 //sys	Ftruncate(fd int, length int64) (err error)
-//ftruncate64(fd _C_int, length Offset_t) _C_int
+//ftruncate(fd _C_int, length Offset_t) _C_int

 //sysnb	Getrlimit(resource int, rlim *Rlimit) (err error)
-//getrlimit64(resource _C_int, rlim *Rlimit) _C_int
+//getrlimit(resource _C_int, rlim *Rlimit) _C_int

 //sys	Lstat(path string, stat *Stat_t) (err error)
-//lstat64(path *byte, stat *Stat_t) _C_int
+//lstat(path *byte, stat *Stat_t) _C_int

 //sys	mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
-//mmap64(addr *byte, length Size_t, prot _C_int, flags _C_int, fd _C_int, offset Offset_t) *byte
+//mmap(addr *byte, length Size_t, prot _C_int, flags _C_int, fd _C_int, offset Offset_t) *byte

 //sys	Open(path string, mode int, perm uint32) (fd int, err error)
-//__go_open64(path *byte, mode _C_int, perm Mode_t) _C_int
+//__go_open(path *byte, mode _C_int, perm Mode_t) _C_int

 //sys	Pread(fd int, p []byte, offset int64) (n int, err error)
-//pread64(fd _C_int, buf *byte, count Size_t, offset Offset_t) Ssize_t
+//pread(fd _C_int, buf *byte, count Size_t, offset Offset_t) Ssize_t

 //sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
-//pwrite64(fd _C_int, buf *byte, count Size_t, offset Offset_t) Ssize_t
+//pwrite(fd _C_int, buf *byte, count Size_t, offset Offset_t) Ssize_t

 //sys	Seek(fd int, offset int64, whence int) (off int64, err error)
-//lseek64(fd _C_int, offset Offset_t, whence _C_int) Offset_t
+//lseek(fd _C_int, offset Offset_t, whence _C_int) Offset_t

 //sysnb	Setrlimit(resource int, rlim *Rlimit) (err error)
-//setrlimit64(resource int, rlim *Rlimit) _C_int
+//setrlimit(resource int, rlim *Rlimit) _C_int

 //sys	Stat(path string, stat *Stat_t) (err error)
-//stat64(path *byte, stat *Stat_t) _C_int
+//stat(path *byte, stat *Stat_t) _C_int

 //sys	Truncate(path string, length int64) (err error)
-//truncate64(path *byte, length Offset_t) _C_int
+//truncate(path *byte, length Offset_t) _C_int
diff --git a/libgo/runtime/go-varargs.c b/libgo/runtime/go-varargs.c
index f84860891e6..7efc9615985 100644
--- a/libgo/runtime/go-varargs.c
+++ b/libgo/runtime/go-varargs.c
@@ -84,7 +84,7 @@ __go_ioctl_ptr (int d, int request, void *arg)
 int
 __go_open64 (char *path, int mode, mode_t perm)
 {
-  return open64 (path, mode, perm);
+  return open (path, mode, perm);
 }

 #endif
`},
		},

		ScriptEarly: `
ln -s system/lib /
ln -s system/lib /work/
`,

		// GCC spends most of its time in its many configure scripts, however
		// it also saturates the CPU for a consequential amount of time.
		Flag: TExclusive,
	}, &MakeHelper{
		Configure: append([]KV{
			{"disable-multilib"},
			{"enable-default-pie"},
			{"disable-nls"},
			{"with-gnu-as"},
			{"with-gnu-ld"},
			{"with-system-zlib"},
			{"enable-languages", "c,c++,go"},
			{"with-native-system-header-dir", "/system/include"},
		}, configureExtra...),
		Make: []string{
			"BOOT_CFLAGS='-O2 -g'",
			"bootstrap",
		},

		// This toolchain is hacked to pieces, it is not expected to ever work
		// well in its current state. That does not matter as long as the
		// toolchain it produces passes its own test suite.
		SkipCheck: true,
	},
		Binutils,

		MPC,
		Zlib,
		Libucontext,
		KernelHeaders,
	), version
}
func init() {
	artifactsM[gcc] = Metadata{
		f: Toolchain.newGCC,

		Name:        "gcc",
		Description: "The GNU Compiler Collection",
		Website:     "https://www.gnu.org/software/gcc/",

		Dependencies: P{
			Binutils,

			MPC,
			Zlib,
			Libucontext,
		},

		ID: 6502,
	}
}
