modernc.org/libc@v1.24.1/generate.go (about)

     1  //go:build ignore
     2  // +build ignore
     3  
     4  package main
     5  
     6  import (
     7  	"bufio"
     8  	"bytes"
     9  	"fmt"
    10  	"io/ioutil"
    11  	"os"
    12  	"os/exec"
    13  	"path/filepath"
    14  	"runtime"
    15  	"sort"
    16  	"strings"
    17  
    18  	"modernc.org/cc/v3"
    19  	ccgo "modernc.org/ccgo/v3/lib"
    20  )
    21  
    22  var (
    23  	goos   = runtime.GOOS
    24  	goarch = runtime.GOARCH
    25  )
    26  
    27  func origin(skip int) string {
    28  	pc, fn, fl, _ := runtime.Caller(skip)
    29  	f := runtime.FuncForPC(pc)
    30  	var fns string
    31  	if f != nil {
    32  		fns = f.Name()
    33  		if x := strings.LastIndex(fns, "."); x > 0 {
    34  			fns = fns[x+1:]
    35  		}
    36  	}
    37  	return fmt.Sprintf("%s:%d:%s", filepath.Base(fn), fl, fns)
    38  }
    39  
    40  func trc(s string, args ...interface{}) string { //TODO-
    41  	switch {
    42  	case s == "":
    43  		s = fmt.Sprintf(strings.Repeat("%v ", len(args)), args...)
    44  	default:
    45  		s = fmt.Sprintf(s, args...)
    46  	}
    47  	_, fn, fl, _ := runtime.Caller(1)
    48  	r := fmt.Sprintf("\n%s:%d: TRC %s", fn, fl, s)
    49  	fmt.Fprintf(os.Stdout, "%s\n", r)
    50  	os.Stdout.Sync()
    51  	return r
    52  }
    53  
    54  func main() {
    55  	fmt.Printf("Running on %s/%s.\n", runtime.GOOS, runtime.GOARCH)
    56  	if s := os.Getenv("TARGET_GOOS"); s != "" {
    57  		goos = s
    58  	}
    59  	if s := os.Getenv("TARGET_GOARCH"); s != "" {
    60  		goarch = s
    61  	}
    62  	g := []string{"libc.go", "mem.go"}
    63  	switch goos {
    64  	case "linux":
    65  		g = append(g, "libc_unix.go", "pthread.go", "pthread_all.go")
    66  		makeMuslLinux(goos, goarch)
    67  	case "freebsd":
    68  		g = append(g, "libc_unix.go", "pthread.go", "pthread_all.go")
    69  		makeMuslFreeBSD(goos, goarch)
    70  	case "netbsd":
    71  		g = append(g, "libc_unix.go", "pthread.go", "pthread_all.go")
    72  		makeMuslNetBSD(goos, goarch)
    73  	case "openbsd":
    74  		g = append(g, "libc_unix.go", "pthread.go", "pthread_all.go")
    75  		makeMuslOpenBSD(goos, goarch)
    76  	case "darwin":
    77  		g = append(g, "libc_unix.go", "pthread.go", "pthread_all.go")
    78  		makeMuslDarwin(goos, goarch)
    79  	case "windows":
    80  		g = append(g, "libc_windows.go")
    81  		makeMuslWin(goos, goarch)
    82  	}
    83  	_, _, hostSysIncludes, err := cc.HostConfig(os.Getenv("CCGO_CPP"))
    84  	if err != nil {
    85  		fail(err)
    86  	}
    87  
    88  	x, err := filepath.Glob(fmt.Sprintf("*_%s.go", goos))
    89  	if err != nil {
    90  		fail(err)
    91  	}
    92  
    93  	g = append(g, x...)
    94  	if x, err = filepath.Glob(fmt.Sprintf("*_%s_%s.go", goos, goarch)); err != nil {
    95  		fail(err)
    96  	}
    97  
    98  	g = append(g, x...)
    99  	m := map[string]struct{}{}
   100  	for _, v := range g {
   101  		f, err := os.Open(v)
   102  		if err != nil {
   103  			fail(err)
   104  		}
   105  
   106  		sc := bufio.NewScanner(f)
   107  		for sc.Scan() {
   108  			s := sc.Text()
   109  			s0 := s
   110  			switch {
   111  			case strings.HasPrefix(s, "func X"):
   112  				s = s[len("func X"):]
   113  				x := strings.IndexByte(s, '(')
   114  				s = s[:x]
   115  			case strings.HasPrefix(s, "var X"):
   116  				s = s[len("var X"):]
   117  				x := strings.IndexByte(s, ' ')
   118  				s = s[:x]
   119  			default:
   120  				continue
   121  			}
   122  
   123  			if s == "" {
   124  				panic(fmt.Sprintf("internal error %q", s0))
   125  			}
   126  			m[s] = struct{}{}
   127  		}
   128  		if err := sc.Err(); err != nil {
   129  			fail(err)
   130  		}
   131  
   132  		f.Close()
   133  	}
   134  	var a []string
   135  	for k := range m {
   136  		a = append(a, k)
   137  	}
   138  	sort.Strings(a)
   139  	b := bytes.NewBuffer(nil)
   140  	b.WriteString(`// Code generated by 'go generate' - DO NOT EDIT.
   141  
   142  package libc // import "modernc.org/libc"
   143  
   144  var CAPI = map[string]struct{}{`)
   145  
   146  	for _, v := range a {
   147  		fmt.Fprintf(b, "\n\t%q: {},", v)
   148  	}
   149  	b.WriteString("\n}")
   150  	if err := ioutil.WriteFile(fmt.Sprintf("capi_%s_%s.go", goos, goarch), b.Bytes(), 0660); err != nil {
   151  		fail(err)
   152  	}
   153  
   154  	ccgoHelpers()
   155  
   156  	if err := libcHeaders(hostSysIncludes); err != nil {
   157  		fail(err)
   158  	}
   159  }
   160  
   161  func makeMuslWin(goos, goarch string) {
   162  	if runtime.GOOS != "windows" {
   163  		switch goarch {
   164  		case "386":
   165  			makeMuslWin386(goos, goarch)
   166  			return
   167  		default:
   168  			fail(fmt.Errorf("must be runned on Windows"))
   169  		}
   170  	}
   171  
   172  	wd, err := os.Getwd()
   173  	if err != nil {
   174  		fail(err)
   175  	}
   176  
   177  	if err := os.Chdir("musl"); err != nil {
   178  		fail(err)
   179  	}
   180  
   181  	var arch string
   182  	switch goarch {
   183  	case "amd64":
   184  		arch = "x86_64"
   185  	case "386":
   186  		arch = "i386"
   187  	case "arm":
   188  		arch = "arm"
   189  	case "arm64":
   190  		arch = "aarch64"
   191  	default:
   192  		fail(fmt.Errorf("unknown/unsupported GOARCH: %q", goarch))
   193  	}
   194  	defer func() {
   195  		if err := os.Chdir(wd); err != nil {
   196  			fail(err)
   197  		}
   198  	}()
   199  
   200  	//TODO- run("mkdir", "-p", "obj/include/bits")
   201  	//TODO- run("sh", "-c", fmt.Sprintf("sed -f ./tools/mkalltypes.sed ./arch/%s/bits/alltypes.h.in ./include/alltypes.h.in > obj/include/bits/alltypes.h", arch))
   202  	//TODO- run("sh", "-c", fmt.Sprintf("cp arch/%s/bits/syscall.h.in obj/include/bits/syscall.h", arch))
   203  	//TODO- run("sh", "-c", fmt.Sprintf("sed -n -e s/__NR_/SYS_/p < arch/%s/bits/syscall.h.in >> obj/include/bits/syscall.h", arch))
   204  	if err := os.MkdirAll("obj\\include\\bits", 0770); err != nil {
   205  		fail(err)
   206  	}
   207  
   208  	run("cmd", "/c", fmt.Sprintf("sed -f ./tools/mkalltypes.sed ./arch/%s/bits/alltypes.h.in ./include/alltypes.h.in > obj/include/bits/alltypes.h", arch))
   209  	run("cmd", "/c", fmt.Sprintf("cp arch/%s/bits/syscall.h.in obj/include/bits/syscall.h", arch))
   210  	run("cmd", "/c", fmt.Sprintf("sed -n -e s/__NR_/SYS_/p < arch/%s/bits/syscall.h.in >> obj/include/bits/syscall.h", arch))
   211  
   212  	if out, err := runcc(
   213  		"-D__environ=environ",
   214  		"-export-externs", "X",
   215  		"-export-fields", "F",
   216  		"-hide", "__syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6",
   217  		"-nostdinc",
   218  		"-nostdlib",
   219  		"-o", fmt.Sprintf("../musl_%s_%s.go", goos, goarch),
   220  		"-pkgname", "libc",
   221  		"-static-locals-prefix", "_s",
   222  
   223  		// Keep the order below, don't sort!
   224  		fmt.Sprintf("-I%s", filepath.Join("arch", arch)),
   225  		fmt.Sprintf("-I%s", "arch/generic"),
   226  		fmt.Sprintf("-I%s", "obj/src/internal"),
   227  		fmt.Sprintf("-I%s", "src/include"),
   228  		fmt.Sprintf("-I%s", "src/internal"),
   229  		fmt.Sprintf("-I%s", "obj/include"),
   230  		fmt.Sprintf("-I%s", "include"),
   231  		// Keep the order above, don't sort!
   232  
   233  		"copyright.c", // Inject legalese first
   234  
   235  		// Keep the below lines sorted.
   236  		"src/ctype/isalnum.c",
   237  		"src/ctype/isalpha.c",
   238  		"src/ctype/isdigit.c",
   239  		"src/ctype/islower.c",
   240  		"src/ctype/isprint.c",
   241  		"src/ctype/isspace.c",
   242  		"src/ctype/isxdigit.c",
   243  		"src/env/putenv.c",
   244  		"src/env/setenv.c",
   245  		"src/env/unsetenv.c",
   246  		"src/multibyte/wcrtomb.c",
   247  		"src/multibyte/wcsrtombs.c",
   248  		"src/multibyte/wcstombs.c",
   249  		"src/stdlib/bsearch.c",
   250  		"src/string/strchrnul.c",
   251  		"src/string/strdup.c",
   252  	); err != nil {
   253  		fail(fmt.Errorf("%s\nFAIL: %v", out, err))
   254  	}
   255  }
   256  
   257  func makeMuslWin386(goos, goarch string) {
   258  	if runtime.GOOS != "linux" {
   259  		fail(fmt.Errorf("must be runned on Linux"))
   260  	}
   261  
   262  	wd, err := os.Getwd()
   263  	if err != nil {
   264  		fail(err)
   265  	}
   266  
   267  	if err := os.Chdir("musl"); err != nil {
   268  		fail(err)
   269  	}
   270  
   271  	arch := "i386"
   272  	defer func() {
   273  		if err := os.Chdir(wd); err != nil {
   274  			fail(err)
   275  		}
   276  	}()
   277  
   278  	run("mkdir", "-p", "obj/include/bits")
   279  	run("sh", "-c", fmt.Sprintf("sed -f ./tools/mkalltypes.sed ./arch/%s/bits/alltypes.h.in ./include/alltypes.h.in > obj/include/bits/alltypes.h", arch))
   280  	run("sh", "-c", fmt.Sprintf("cp arch/%s/bits/syscall.h.in obj/include/bits/syscall.h", arch))
   281  	run("sh", "-c", fmt.Sprintf("sed -n -e s/__NR_/SYS_/p < arch/%s/bits/syscall.h.in >> obj/include/bits/syscall.h", arch))
   282  
   283  	if _, err := runcc(
   284  		"-D__environ=environ",
   285  		"-export-externs", "X",
   286  		"-hide", "__syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6",
   287  		"-nostdinc",
   288  		"-nostdlib",
   289  		"-o", fmt.Sprintf("../musl_%s_%s.go", goos, goarch),
   290  		"-pkgname", "libc",
   291  		"-static-locals-prefix", "_s",
   292  
   293  		// Keep the order below, don't sort!
   294  		fmt.Sprintf("-I%s", filepath.Join("arch", arch)),
   295  		fmt.Sprintf("-I%s", "arch/generic"),
   296  		fmt.Sprintf("-I%s", "obj/src/internal"),
   297  		fmt.Sprintf("-I%s", "src/include"),
   298  		fmt.Sprintf("-I%s", "src/internal"),
   299  		fmt.Sprintf("-I%s", "obj/include"),
   300  		fmt.Sprintf("-I%s", "include"),
   301  		// Keep the order above, don't sort!
   302  
   303  		"copyright.c", // Inject legalese first
   304  
   305  		// Keep the below lines sorted.
   306  		"src/ctype/isalnum.c",
   307  		"src/ctype/isalpha.c",
   308  		"src/ctype/isdigit.c",
   309  		"src/ctype/islower.c",
   310  		"src/ctype/isprint.c",
   311  		"src/ctype/isspace.c",
   312  		"src/ctype/isxdigit.c",
   313  		"src/env/putenv.c",
   314  		"src/env/setenv.c",
   315  		"src/env/unsetenv.c",
   316  		"src/multibyte/wcrtomb.c",
   317  		"src/multibyte/wcsrtombs.c",
   318  		"src/multibyte/wcstombs.c",
   319  		"src/string/strchrnul.c",
   320  		"src/string/strdup.c",
   321  	); err != nil {
   322  		fail(err)
   323  	}
   324  }
   325  
   326  func makeMuslDarwin(goos, goarch string) {
   327  	wd, err := os.Getwd()
   328  	if err != nil {
   329  		fail(err)
   330  	}
   331  
   332  	if err := os.Chdir("musl"); err != nil {
   333  		fail(err)
   334  	}
   335  
   336  	var arch string
   337  	switch goarch {
   338  	case "amd64":
   339  		arch = "x86_64"
   340  	case "arm64":
   341  		arch = "aarch64"
   342  	default:
   343  		fail(fmt.Errorf("unknown/unsupported GOARCH: %q", goarch))
   344  	}
   345  	defer func() {
   346  		if err := os.Chdir(wd); err != nil {
   347  			fail(err)
   348  		}
   349  	}()
   350  
   351  	run("mkdir", "-p", "obj/include/bits")
   352  	run("sh", "-c", fmt.Sprintf("sed -f ./tools/mkalltypes.sed ./arch/%s/bits/alltypes.h.in ./include/alltypes.h.in > obj/include/bits/alltypes.h", arch))
   353  	run("sh", "-c", fmt.Sprintf("cp arch/%s/bits/syscall.h.in obj/include/bits/syscall.h", arch))
   354  	run("sh", "-c", fmt.Sprintf("sed -n -e s/__NR_/SYS_/p < arch/%s/bits/syscall.h.in >> obj/include/bits/syscall.h", arch))
   355  	if _, err := runcc(
   356  		"-D__environ=environ",
   357  		"-export-externs", "X",
   358  		"-export-fields", "F",
   359  		"-hide", "__syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6",
   360  		"-hide", "isascii,isspace,tolower,toupper",
   361  		"-nostdinc",
   362  		"-nostdlib",
   363  		"-o", fmt.Sprintf("../musl_%s_%s.go", goos, goarch),
   364  		"-pkgname", "libc",
   365  		"-static-locals-prefix", "_s",
   366  
   367  		// Keep the order below, don't sort!
   368  		fmt.Sprintf("-I%s", filepath.Join("arch", arch)),
   369  		fmt.Sprintf("-I%s", "arch/generic"),
   370  		fmt.Sprintf("-I%s", "obj/src/internal"),
   371  		fmt.Sprintf("-I%s", "src/include"),
   372  		fmt.Sprintf("-I%s", "src/internal"),
   373  		fmt.Sprintf("-I%s", "obj/include"),
   374  		fmt.Sprintf("-I%s", "include"),
   375  		// Keep the order above, don't sort!
   376  
   377  		"copyright.c", // Inject legalese first
   378  
   379  		"../darwin/table.c",
   380  
   381  		// Keep the below lines sorted.
   382  		"src/env/putenv.c",
   383  		"src/env/setenv.c",
   384  		"src/env/unsetenv.c",
   385  		"src/internal/floatscan.c",
   386  		"src/internal/intscan.c",
   387  		"src/internal/shgetc.c",
   388  		"src/locale/localeconv.c",
   389  		"src/math/__fpclassify.c",
   390  		"src/math/__fpclassifyf.c",
   391  		"src/math/__fpclassifyl.c",
   392  		"src/math/copysignl.c",
   393  		"src/math/fabsl.c",
   394  		"src/math/fmodl.c",
   395  		"src/math/nanf.c",
   396  		"src/math/rint.c",
   397  		"src/math/scalbn.c",
   398  		"src/math/scalbnl.c",
   399  		"src/network/freeaddrinfo.c",
   400  		"src/network/getaddrinfo.c",
   401  		"src/network/gethostbyaddr.c",
   402  		"src/network/gethostbyaddr_r.c",
   403  		"src/network/gethostbyname.c",
   404  		"src/network/gethostbyname2.c",
   405  		"src/network/gethostbyname2_r.c",
   406  		"src/network/getnameinfo.c",
   407  		"src/network/h_errno.c",
   408  		"src/network/inet_aton.c",
   409  		"src/network/inet_ntop.c",
   410  		"src/network/inet_pton.c",
   411  		"src/network/lookup_ipliteral.c",
   412  		"src/network/lookup_name.c",
   413  		"src/network/lookup_serv.c",
   414  		"src/prng/rand_r.c",
   415  		"src/stdio/__toread.c",
   416  		"src/stdio/__uflow.c",
   417  		"src/stdlib/bsearch.c",
   418  		"src/stdlib/strtod.c",
   419  		"src/stdlib/strtol.c",
   420  		"src/string/strchrnul.c",
   421  		"src/string/strdup.c",
   422  		"src/string/strlcat.c",
   423  		"src/string/strlcpy.c",
   424  		"src/string/strncasecmp.c",
   425  		"src/string/strncat.c",
   426  		"src/string/strnlen.c",
   427  		"src/string/strspn.c",
   428  		"src/string/strtok.c",
   429  	); err != nil {
   430  		fail(err)
   431  	}
   432  }
   433  
   434  func makeMuslLinux(goos, goarch string) {
   435  	wd, err := os.Getwd()
   436  	if err != nil {
   437  		fail(err)
   438  	}
   439  
   440  	if err := os.Chdir("musl"); err != nil {
   441  		fail(err)
   442  	}
   443  
   444  	var arch string
   445  	switch goarch {
   446  	case "amd64":
   447  		arch = "x86_64"
   448  	case "386":
   449  		arch = "i386"
   450  	case "arm":
   451  		arch = "arm"
   452  	case "arm64":
   453  		arch = "aarch64"
   454  	case "s390x":
   455  		arch = "s390x"
   456  	case "ppc64le":
   457  		arch = "powerpc64"
   458  	case "riscv64":
   459  		arch = "riscv64"
   460  	default:
   461  		fail(fmt.Errorf("unknown/unsupported GOARCH: %q", goarch))
   462  	}
   463  	defer func() {
   464  		if err := os.Chdir(wd); err != nil {
   465  			fail(err)
   466  		}
   467  	}()
   468  
   469  	run("mkdir", "-p", "obj/include/bits")
   470  	run("sh", "-c", fmt.Sprintf("sed -f ./tools/mkalltypes.sed ./arch/%s/bits/alltypes.h.in ./include/alltypes.h.in > obj/include/bits/alltypes.h", arch))
   471  	run("sh", "-c", fmt.Sprintf("cp arch/%s/bits/syscall.h.in obj/include/bits/syscall.h", arch))
   472  	run("sh", "-c", fmt.Sprintf("sed -n -e s/__NR_/SYS_/p < arch/%s/bits/syscall.h.in >> obj/include/bits/syscall.h", arch))
   473  	if _, err := runcc(
   474  		"-export-externs", "X",
   475  		"-export-fields", "F",
   476  		"-hide", "__syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6",
   477  		"-nostdinc",
   478  		"-nostdlib",
   479  		"-o", fmt.Sprintf("../musl_%s_%s.go", goos, goarch),
   480  		"-pkgname", "libc",
   481  		"-static-locals-prefix", "_s",
   482  
   483  		// Keep the order below, don't sort!
   484  		fmt.Sprintf("-I%s", filepath.Join("arch", arch)),
   485  		fmt.Sprintf("-I%s", "arch/generic"),
   486  		fmt.Sprintf("-I%s", "obj/src/internal"),
   487  		fmt.Sprintf("-I%s", "src/include"),
   488  		fmt.Sprintf("-I%s", "src/internal"),
   489  		fmt.Sprintf("-I%s", "obj/include"),
   490  		fmt.Sprintf("-I%s", "include"),
   491  		// Keep the order above, don't sort!
   492  
   493  		"copyright.c", // Inject legalese first
   494  
   495  		// Keep the below lines sorted.
   496  		"src/ctype/__ctype_b_loc.c",
   497  		"src/ctype/isalnum.c",
   498  		"src/ctype/isalpha.c",
   499  		"src/ctype/isdigit.c",
   500  		"src/ctype/islower.c",
   501  		"src/ctype/isprint.c",
   502  		"src/ctype/isupper.c",
   503  		"src/ctype/isxdigit.c",
   504  		"src/dirent/closedir.c",
   505  		"src/dirent/opendir.c",
   506  		"src/dirent/readdir.c",
   507  		"src/internal/floatscan.c",
   508  		"src/internal/intscan.c",
   509  		"src/internal/shgetc.c",
   510  		"src/locale/localeconv.c",
   511  		"src/math/__fpclassify.c",
   512  		"src/math/__fpclassifyf.c",
   513  		"src/math/__fpclassifyl.c",
   514  		"src/math/copysignl.c",
   515  		"src/math/fabsl.c",
   516  		"src/math/fmodl.c",
   517  		"src/math/nanf.c",
   518  		"src/math/rint.c",
   519  		"src/math/scalbn.c",
   520  		"src/math/scalbnl.c",
   521  		"src/multibyte/internal.c",
   522  		"src/multibyte/mbrtowc.c",
   523  		"src/multibyte/mbsinit.c",
   524  		"src/network/freeaddrinfo.c",
   525  		"src/network/getaddrinfo.c",
   526  		"src/network/gethostbyaddr.c",
   527  		"src/network/gethostbyaddr_r.c",
   528  		"src/network/gethostbyname.c",
   529  		"src/network/gethostbyname2.c",
   530  		"src/network/gethostbyname2_r.c",
   531  		"src/network/gethostbyname_r.c",
   532  		"src/network/getnameinfo.c",
   533  		"src/network/h_errno.c",
   534  		"src/network/inet_aton.c",
   535  		"src/network/inet_ntop.c",
   536  		"src/network/inet_pton.c",
   537  		"src/network/lookup_ipliteral.c",
   538  		"src/network/lookup_name.c",
   539  		"src/network/lookup_serv.c",
   540  		"src/prng/rand_r.c",
   541  		"src/stdio/__lockfile.c",
   542  		"src/stdio/__toread.c",
   543  		"src/stdio/__uflow.c",
   544  		"src/stdio/sscanf.c",
   545  		"src/stdio/vfscanf.c",
   546  		"src/stdio/vsscanf.c",
   547  		"src/stdlib/bsearch.c",
   548  		"src/stdlib/strtod.c",
   549  		"src/stdlib/strtol.c",
   550  		"src/string/strdup.c",
   551  		"src/string/strlcat.c",
   552  		"src/string/strlcpy.c",
   553  		"src/string/strncasecmp.c",
   554  		"src/string/strncat.c",
   555  		"src/string/strnlen.c",
   556  		"src/string/strspn.c",
   557  		"src/string/strtok.c",
   558  		"src/thread/pthread_attr_get.c",
   559  		"src/thread/pthread_attr_setdetachstate.c",
   560  		"src/thread/pthread_mutex_lock.c",
   561  		"src/thread/pthread_mutexattr_destroy.c",
   562  		"src/thread/pthread_mutexattr_init.c",
   563  		"src/thread/pthread_mutexattr_settype.c",
   564  	); err != nil {
   565  		fail(err)
   566  	}
   567  }
   568  
   569  func makeMuslNetBSD(goos, goarch string) {
   570  	wd, err := os.Getwd()
   571  	if err != nil {
   572  		fail(err)
   573  	}
   574  
   575  	if err := os.Chdir("musl"); err != nil {
   576  		fail(err)
   577  	}
   578  
   579  	var arch string
   580  	switch goarch {
   581  	case "amd64":
   582  		arch = "x86_64"
   583  	case "arm":
   584  		arch = "arm"
   585  	default:
   586  		fail(fmt.Errorf("unknown/unsupported GOARCH: %q", goarch))
   587  	}
   588  	defer func() {
   589  		if err := os.Chdir(wd); err != nil {
   590  			fail(err)
   591  		}
   592  	}()
   593  
   594  	run("mkdir", "-p", "obj/include/bits")
   595  	run("sh", "-c", fmt.Sprintf("sed -f ./tools/mkalltypes.sed ./arch/%s/bits/alltypes.h.in ./include/alltypes.h.in > obj/include/bits/alltypes.h", arch))
   596  	run("sh", "-c", fmt.Sprintf("cp arch/%s/bits/syscall.h.in obj/include/bits/syscall.h", arch))
   597  	run("sh", "-c", fmt.Sprintf("sed -n -e s/__NR_/SYS_/p < arch/%s/bits/syscall.h.in >> obj/include/bits/syscall.h", arch))
   598  	if _, err := runcc(
   599  		"-export-externs", "X",
   600  		"-export-fields", "F",
   601  		"-hide", "__syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6,getnameinfo,gethostbyaddr_r,",
   602  		"-nostdinc",
   603  		"-nostdlib",
   604  		"-o", fmt.Sprintf("../musl_%s_%s.go", goos, goarch),
   605  		"-pkgname", "libc",
   606  		"-static-locals-prefix", "_s",
   607  
   608  		// Keep the order below, don't sort!
   609  		fmt.Sprintf("-I%s", filepath.Join("arch", arch)),
   610  		fmt.Sprintf("-I%s", "arch/generic"),
   611  		fmt.Sprintf("-I%s", "obj/src/internal"),
   612  		fmt.Sprintf("-I%s", "src/include"),
   613  		fmt.Sprintf("-I%s", "src/internal"),
   614  		fmt.Sprintf("-I%s", "obj/include"),
   615  		fmt.Sprintf("-I%s", "include"),
   616  		// Keep the order above, don't sort!
   617  
   618  		"copyright.c", // Inject legalese first
   619  
   620  		"../netbsd/ctype_.cpp.c",
   621  
   622  		// Keep the below lines sorted.
   623  		"src/ctype/isalnum.c",
   624  		"src/ctype/isalpha.c",
   625  		"src/ctype/isdigit.c",
   626  		"src/ctype/isprint.c",
   627  		"src/internal/floatscan.c",
   628  		"src/internal/intscan.c",
   629  		"src/internal/shgetc.c",
   630  		"src/math/copysignl.c",
   631  		"src/math/fabsl.c",
   632  		"src/math/fmodl.c",
   633  		"src/math/rint.c",
   634  		"src/math/scalbn.c",
   635  		"src/math/scalbnl.c",
   636  		"src/network/freeaddrinfo.c",
   637  		"src/network/getaddrinfo.c",
   638  		"src/network/gethostbyaddr.c",
   639  		"src/network/gethostbyaddr_r.c",
   640  		"src/network/gethostbyname.c",
   641  		"src/network/gethostbyname2.c",
   642  		"src/network/gethostbyname2_r.c",
   643  		"src/network/getnameinfo.c",
   644  		"src/network/h_errno.c",
   645  		"src/network/inet_aton.c",
   646  		"src/network/inet_ntop.c",
   647  		"src/network/inet_pton.c",
   648  		"src/network/lookup_ipliteral.c",
   649  		"src/network/lookup_name.c",
   650  		"src/network/lookup_serv.c",
   651  		"src/stdio/__toread.c",
   652  		"src/stdio/__uflow.c",
   653  		"src/stdlib/bsearch.c",
   654  		"src/stdlib/strtod.c",
   655  		"src/stdlib/strtol.c",
   656  		"src/string/strdup.c",
   657  		"src/string/strnlen.c",
   658  		"src/string/strspn.c",
   659  	); err != nil {
   660  		fail(err)
   661  	}
   662  }
   663  
   664  func makeMuslOpenBSD(goos, goarch string) {
   665  	wd, err := os.Getwd()
   666  	if err != nil {
   667  		fail(err)
   668  	}
   669  
   670  	if err := os.Chdir("musl"); err != nil {
   671  		fail(err)
   672  	}
   673  
   674  	var arch string
   675  	switch goarch {
   676  	case "amd64":
   677  		arch = "x86_64"
   678  	case "386":
   679  		arch = "i386"
   680  	case "arm":
   681  		arch = "arm"
   682  	case "arm64":
   683  		arch = "aarch64"
   684  	default:
   685  		fail(fmt.Errorf("unknown/unsupported GOARCH: %q", goarch))
   686  	}
   687  	defer func() {
   688  		if err := os.Chdir(wd); err != nil {
   689  			fail(err)
   690  		}
   691  	}()
   692  
   693  	run("mkdir", "-p", "obj/include/bits")
   694  	run("sh", "-c", fmt.Sprintf("sed -f ./tools/mkalltypes.sed ./arch/%s/bits/alltypes.h.in ./include/alltypes.h.in > obj/include/bits/alltypes.h", arch))
   695  	run("sh", "-c", fmt.Sprintf("cp arch/%s/bits/syscall.h.in obj/include/bits/syscall.h", arch))
   696  	run("sh", "-c", fmt.Sprintf("sed -n -e s/__NR_/SYS_/p < arch/%s/bits/syscall.h.in >> obj/include/bits/syscall.h", arch))
   697  	if _, err := runcc(
   698  		"-export-externs", "X",
   699  		"-export-fields", "F",
   700  		"-hide", "__syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6,getnameinfo,gethostbyaddr_r,",
   701  		"-nostdinc",
   702  		"-nostdlib",
   703  		"-o", fmt.Sprintf("../musl_%s_%s.go", goos, goarch),
   704  		"-pkgname", "libc",
   705  		"-static-locals-prefix", "_s",
   706  
   707  		// Keep the order below, don't sort!
   708  		fmt.Sprintf("-I%s", filepath.Join("arch", arch)),
   709  		fmt.Sprintf("-I%s", "arch/generic"),
   710  		fmt.Sprintf("-I%s", "obj/src/internal"),
   711  		fmt.Sprintf("-I%s", "src/include"),
   712  		fmt.Sprintf("-I%s", "src/internal"),
   713  		fmt.Sprintf("-I%s", "obj/include"),
   714  		fmt.Sprintf("-I%s", "include"),
   715  		// Keep the order above, don't sort!
   716  
   717  		"copyright.c", // Inject legalese first
   718  
   719  		"../openbsd/ctype_.c",
   720  
   721  		// Keep the below lines sorted.
   722  		"src/ctype/isalnum.c",
   723  		"src/ctype/isalpha.c",
   724  		"src/ctype/isdigit.c",
   725  		"src/ctype/islower.c",
   726  		"src/ctype/isprint.c",
   727  		"src/ctype/isspace.c",
   728  		"src/ctype/isupper.c",
   729  		"src/ctype/isxdigit.c",
   730  		"src/internal/floatscan.c",
   731  		"src/internal/intscan.c",
   732  		"src/internal/shgetc.c",
   733  		"src/math/copysignl.c",
   734  		"src/math/fabsl.c",
   735  		"src/math/fmodl.c",
   736  		"src/math/rint.c",
   737  		"src/math/scalbn.c",
   738  		"src/math/scalbnl.c",
   739  		"src/network/freeaddrinfo.c",
   740  		"src/network/getaddrinfo.c",
   741  		"src/network/gethostbyaddr.c",
   742  		"src/network/gethostbyaddr_r.c",
   743  		"src/network/gethostbyname.c",
   744  		"src/network/gethostbyname2.c",
   745  		"src/network/gethostbyname2_r.c",
   746  		"src/network/getnameinfo.c",
   747  		"src/network/h_errno.c",
   748  		"src/network/inet_aton.c",
   749  		"src/network/inet_ntop.c",
   750  		"src/network/inet_pton.c",
   751  		"src/network/lookup_ipliteral.c",
   752  		"src/network/lookup_name.c",
   753  		"src/network/lookup_serv.c",
   754  		"src/stdio/__toread.c",
   755  		"src/stdio/__uflow.c",
   756  		"src/stdlib/bsearch.c",
   757  		"src/stdlib/strtod.c",
   758  		"src/stdlib/strtol.c",
   759  		"src/string/strdup.c",
   760  		"src/string/strnlen.c",
   761  		"src/string/strspn.c",
   762  	); err != nil {
   763  		fail(err)
   764  	}
   765  }
   766  
   767  func makeMuslFreeBSD(goos, goarch string) {
   768  	wd, err := os.Getwd()
   769  	if err != nil {
   770  		fail(err)
   771  	}
   772  
   773  	if err := os.Chdir("musl"); err != nil {
   774  		fail(err)
   775  	}
   776  
   777  	var arch string
   778  	switch goarch {
   779  	case "amd64":
   780  		arch = "x86_64"
   781  	case "386":
   782  		arch = "i386"
   783  	case "arm":
   784  		arch = "arm"
   785  	default:
   786  		fail(fmt.Errorf("unknown/unsupported GOARCH: %q", goarch))
   787  	}
   788  	defer func() {
   789  		if err := os.Chdir(wd); err != nil {
   790  			fail(err)
   791  		}
   792  	}()
   793  
   794  	run("mkdir", "-p", "obj/include/bits")
   795  	run("sh", "-c", fmt.Sprintf("sed -f ./tools/mkalltypes.sed ./arch/%s/bits/alltypes.h.in ./include/alltypes.h.in > obj/include/bits/alltypes.h", arch))
   796  	run("sh", "-c", fmt.Sprintf("cp arch/%s/bits/syscall.h.in obj/include/bits/syscall.h", arch))
   797  	run("sh", "-c", fmt.Sprintf("sed -n -e s/__NR_/SYS_/p < arch/%s/bits/syscall.h.in >> obj/include/bits/syscall.h", arch))
   798  	if _, err := runcc(
   799  		"-export-externs", "X",
   800  		"-export-fields", "F",
   801  		"-hide", "__syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6,getnameinfo,gethostbyaddr_r,",
   802  		"-nostdinc",
   803  		"-nostdlib",
   804  		"-o", fmt.Sprintf("../musl_%s_%s.go", goos, goarch),
   805  		"-pkgname", "libc",
   806  		"-static-locals-prefix", "_s",
   807  
   808  		// Keep the order below, don't sort!
   809  		fmt.Sprintf("-I%s", filepath.Join("arch", arch)),
   810  		fmt.Sprintf("-I%s", "arch/generic"),
   811  		fmt.Sprintf("-I%s", "obj/src/internal"),
   812  		fmt.Sprintf("-I%s", "src/include"),
   813  		fmt.Sprintf("-I%s", "src/internal"),
   814  		fmt.Sprintf("-I%s", "obj/include"),
   815  		fmt.Sprintf("-I%s", "include"),
   816  		// Keep the order above, don't sort!
   817  
   818  		"copyright.c", // Inject legalese first
   819  
   820  		"../freebsd/table.cpp.c",
   821  
   822  		// Keep the below lines sorted.
   823  		"src/ctype/isalnum.c",
   824  		"src/ctype/isalpha.c",
   825  		"src/ctype/isdigit.c",
   826  		"src/ctype/islower.c",
   827  		"src/ctype/isprint.c",
   828  		"src/ctype/isspace.c",
   829  		"src/ctype/isupper.c",
   830  		"src/ctype/isxdigit.c",
   831  		"src/internal/floatscan.c",
   832  		"src/internal/intscan.c",
   833  		"src/internal/shgetc.c",
   834  		"src/math/copysignl.c",
   835  		"src/math/fabsl.c",
   836  		"src/math/fmodl.c",
   837  		"src/math/rint.c",
   838  		"src/math/scalbn.c",
   839  		"src/math/scalbnl.c",
   840  		"src/network/freeaddrinfo.c",
   841  		"src/network/getaddrinfo.c",
   842  		"src/network/gethostbyaddr.c",
   843  		"src/network/gethostbyaddr_r.c",
   844  		"src/network/gethostbyname.c",
   845  		"src/network/gethostbyname2.c",
   846  		"src/network/gethostbyname2_r.c",
   847  		"src/network/getnameinfo.c",
   848  		"src/network/h_errno.c",
   849  		"src/network/inet_aton.c",
   850  		"src/network/inet_ntop.c",
   851  		"src/network/inet_pton.c",
   852  		"src/network/lookup_ipliteral.c",
   853  		"src/network/lookup_name.c",
   854  		"src/network/lookup_serv.c",
   855  		"src/stdio/__toread.c",
   856  		"src/stdio/__uflow.c",
   857  		"src/stdlib/bsearch.c",
   858  		"src/stdlib/strtod.c",
   859  		"src/stdlib/strtol.c",
   860  		"src/string/strdup.c",
   861  		"src/string/strnlen.c",
   862  		"src/string/strspn.c",
   863  	); err != nil {
   864  		fail(err)
   865  	}
   866  }
   867  
   868  func run(arg0 string, args ...string) []byte {
   869  	fmt.Printf("%s %q\n", arg0, args)
   870  	cmd := exec.Command(arg0, args...)
   871  	out, err := cmd.CombinedOutput()
   872  	if err != nil {
   873  		sout := strings.TrimSpace(string(out))
   874  		fmt.Fprintf(os.Stderr, "==== FAIL\n%s\n%s\n", sout, err)
   875  		fail(err)
   876  	}
   877  	return out
   878  }
   879  
   880  type echoWriter struct {
   881  	w bytes.Buffer
   882  }
   883  
   884  func (w *echoWriter) Write(b []byte) (int, error) {
   885  	os.Stdout.Write(b)
   886  	return w.w.Write(b)
   887  }
   888  
   889  func runcc(args ...string) ([]byte, error) {
   890  	args = append([]string{"ccgo"}, args...)
   891  	// fmt.Printf("%q\n", args)
   892  	var out echoWriter
   893  	err := ccgo.NewTask(args, &out, &out).Main()
   894  	return out.w.Bytes(), err
   895  }
   896  
   897  func libcHeaders(paths []string) error {
   898  	const cfile = "gen.c"
   899  	return filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
   900  		if err != nil {
   901  			return err
   902  		}
   903  
   904  		if !info.IsDir() {
   905  			return nil
   906  		}
   907  
   908  		path = filepath.Clean(path)
   909  		if strings.HasPrefix(path, ".") {
   910  			return nil
   911  		}
   912  
   913  		dir := path
   914  		ok := false
   915  		for _, v := range paths {
   916  			full := filepath.Join(v, dir+".h")
   917  			if fi, err := os.Stat(full); err == nil && !fi.IsDir() {
   918  				ok = true
   919  				break
   920  			}
   921  		}
   922  		if !ok {
   923  			return nil
   924  		}
   925  
   926  		var src string
   927  		switch filepath.ToSlash(path) {
   928  		case "fts":
   929  			src = `
   930  #include <sys/types.h>
   931  #include <sys/stat.h>
   932  #include <fts.h>
   933  `
   934  		default:
   935  			src = fmt.Sprintf("#include <%s.h>\n", dir)
   936  		}
   937  		src += "static char _;\n"
   938  		fn := filepath.Join(dir, cfile)
   939  		if err := ioutil.WriteFile(fn, []byte(src), 0660); err != nil {
   940  			return err
   941  		}
   942  
   943  		defer os.Remove(fn)
   944  
   945  		dest := filepath.Join(path, fmt.Sprintf("%s_%s_%s.go", filepath.Base(path), goos, goarch))
   946  		base := filepath.Base(dir)
   947  		argv := []string{
   948  			fn,
   949  
   950  			"-crt-import-path", "",
   951  			"-export-defines", "",
   952  			"-export-enums", "",
   953  			"-export-externs", "X",
   954  			"-export-fields", "F",
   955  			"-export-structs", "",
   956  			"-export-typedefs", "",
   957  			"-header",
   958  			"-hide", "_OSSwapInt16,_OSSwapInt32,_OSSwapInt64",
   959  			"-ignore-unsupported-alignment",
   960  			"-o", dest,
   961  			"-pkgname", base,
   962  		}
   963  		out, err := runcc(argv...)
   964  		if err != nil {
   965  			fmt.Fprintf(os.Stderr, "%s: %s%s\n", path, out, err)
   966  		} else {
   967  			fmt.Fprintf(os.Stdout, "%s\n%s", path, out)
   968  		}
   969  		return nil
   970  	})
   971  }
   972  
   973  func fail(err error) {
   974  	fmt.Fprintf(os.Stderr, "%v (%v: %v:)\n", err, origin(3), origin(2))
   975  	os.Exit(1)
   976  }
   977  
   978  func ccgoHelpers() {
   979  	var (
   980  		signed = []string{
   981  			"int8",
   982  			"int16",
   983  			"int32",
   984  			"int64",
   985  		}
   986  		unsigned = []string{
   987  			"uint8",
   988  			"uint16",
   989  			"uint32",
   990  			"uint64",
   991  		}
   992  		ints   = append(signed[:len(signed):len(signed)], unsigned...)
   993  		intptr = append(ints[:len(ints):len(ints)], "uintptr")
   994  		arith  = append(ints[:len(ints):len(ints)], "float32", "float64", "complex64", "complex128")
   995  		scalar = append(arith[:len(arith):len(arith)], []string{"uintptr"}...)
   996  		sizes  = []string{"8", "16", "32", "64"}
   997  		atomic = []string{
   998  			"int32",
   999  			"int64",
  1000  			"uint32",
  1001  			"uint64",
  1002  			"uintptr",
  1003  		}
  1004  	)
  1005  
  1006  	b := bytes.NewBuffer(nil)
  1007  	b.WriteString(`// Code generated by 'go generate' - DO NOT EDIT.
  1008  
  1009  package libc // import "modernc.org/libc"
  1010  
  1011  import (
  1012  	"sync/atomic"
  1013  	"unsafe"
  1014  )
  1015  
  1016  `)
  1017  	for _, v := range atomic {
  1018  		fmt.Fprintln(b)
  1019  		fmt.Fprintf(b, "func AtomicStoreN%s(ptr uintptr, val %s, memorder int32) { atomic.Store%[1]s((*%[2]s)(unsafe.Pointer(ptr)), val) }\n", capitalize(v), v)
  1020  	}
  1021  
  1022  	fmt.Fprintln(b)
  1023  	for _, v := range atomic {
  1024  		fmt.Fprintln(b)
  1025  		fmt.Fprintf(b, "func AtomicLoadN%s(ptr uintptr, memorder int32) %s { return atomic.Load%[1]s((*%[2]s)(unsafe.Pointer(ptr))) }\n", capitalize(v), v)
  1026  	}
  1027  
  1028  	for _, v := range scalar {
  1029  		fmt.Fprintf(b, "func Assign%s(p *%s, v %[2]s) %[2]s { *p = v; return v }\n", capitalize(v), v)
  1030  	}
  1031  
  1032  	fmt.Fprintln(b)
  1033  	for _, v := range scalar {
  1034  		fmt.Fprintf(b, "func AssignPtr%s(p uintptr, v %s) %[2]s { *(*%[2]s)(unsafe.Pointer(p)) = v; return v }\n", capitalize(v), v)
  1035  	}
  1036  
  1037  	fmt.Fprintln(b)
  1038  	for _, v := range scalar {
  1039  		fmt.Fprintf(b, "func AssignMul%s(p *%s, v %[2]s) %[2]s { *p *= v; return *p }\n", capitalize(v), v)
  1040  	}
  1041  
  1042  	fmt.Fprintln(b)
  1043  	for _, v := range scalar {
  1044  		fmt.Fprintf(b, "func AssignDiv%s(p *%s, v %[2]s) %[2]s { *p /= v; return *p }\n", capitalize(v), v)
  1045  	}
  1046  
  1047  	fmt.Fprintln(b)
  1048  	for _, v := range intptr {
  1049  		fmt.Fprintf(b, "func AssignRem%s(p *%s, v %[2]s) %[2]s { *p %%= v; return *p }\n", capitalize(v), v)
  1050  	}
  1051  
  1052  	fmt.Fprintln(b)
  1053  	for _, v := range scalar {
  1054  		fmt.Fprintf(b, "func AssignAdd%s(p *%s, v %[2]s) %[2]s { *p += v; return *p }\n", capitalize(v), v)
  1055  	}
  1056  
  1057  	fmt.Fprintln(b)
  1058  	for _, v := range scalar {
  1059  		fmt.Fprintf(b, "func AssignSub%s(p *%s, v %[2]s) %[2]s { *p -= v; return *p }\n", capitalize(v), v)
  1060  	}
  1061  
  1062  	fmt.Fprintln(b)
  1063  	for _, v := range intptr {
  1064  		fmt.Fprintf(b, "func AssignAnd%s(p *%s, v %[2]s) %[2]s { *p &= v; return *p }\n", capitalize(v), v)
  1065  	}
  1066  
  1067  	fmt.Fprintln(b)
  1068  	for _, v := range intptr {
  1069  		fmt.Fprintf(b, "func AssignXor%s(p *%s, v %[2]s) %[2]s { *p ^= v; return *p }\n", capitalize(v), v)
  1070  	}
  1071  
  1072  	fmt.Fprintln(b)
  1073  	for _, v := range intptr {
  1074  		fmt.Fprintf(b, "func AssignOr%s(p *%s, v %[2]s) %[2]s { *p |= v; return *p }\n", capitalize(v), v)
  1075  	}
  1076  
  1077  	fmt.Fprintln(b)
  1078  	for _, v := range scalar {
  1079  		fmt.Fprintf(b, "func AssignMulPtr%s(p uintptr, v %s) %[2]s { *(*%[2]s)(unsafe.Pointer(p)) *= v; return *(*%[2]s)(unsafe.Pointer(p)) }\n\n", capitalize(v), v)
  1080  	}
  1081  
  1082  	fmt.Fprintln(b)
  1083  	for _, v := range scalar {
  1084  		fmt.Fprintf(b, "func AssignDivPtr%s(p uintptr, v %s) %[2]s { *(*%[2]s)(unsafe.Pointer(p)) /= v; return *(*%[2]s)(unsafe.Pointer(p)) }\n\n", capitalize(v), v)
  1085  	}
  1086  
  1087  	fmt.Fprintln(b)
  1088  	for _, v := range intptr {
  1089  		fmt.Fprintf(b, "func AssignRemPtr%s(p uintptr, v %s) %[2]s { *(*%[2]s)(unsafe.Pointer(p)) %%= v; return *(*%[2]s)(unsafe.Pointer(p)) }\n\n", capitalize(v), v)
  1090  	}
  1091  
  1092  	fmt.Fprintln(b)
  1093  	for _, v := range scalar {
  1094  		fmt.Fprintf(b, "func AssignAddPtr%s(p uintptr, v %s) %[2]s { *(*%[2]s)(unsafe.Pointer(p)) += v; return *(*%[2]s)(unsafe.Pointer(p)) }\n\n", capitalize(v), v)
  1095  	}
  1096  
  1097  	fmt.Fprintln(b)
  1098  	for _, v := range scalar {
  1099  		fmt.Fprintf(b, "func AssignSubPtr%s(p uintptr, v %s) %[2]s { *(*%[2]s)(unsafe.Pointer(p)) -= v; return *(*%[2]s)(unsafe.Pointer(p)) }\n\n", capitalize(v), v)
  1100  	}
  1101  
  1102  	fmt.Fprintln(b)
  1103  	for _, v := range intptr {
  1104  		fmt.Fprintf(b, "func AssignAndPtr%s(p uintptr, v %s) %[2]s { *(*%[2]s)(unsafe.Pointer(p)) &= v; return *(*%[2]s)(unsafe.Pointer(p)) }\n\n", capitalize(v), v)
  1105  	}
  1106  
  1107  	fmt.Fprintln(b)
  1108  	for _, v := range intptr {
  1109  		fmt.Fprintf(b, "func AssignXorPtr%s(p uintptr, v %s) %[2]s { *(*%[2]s)(unsafe.Pointer(p)) ^= v; return *(*%[2]s)(unsafe.Pointer(p)) }\n\n", capitalize(v), v)
  1110  	}
  1111  
  1112  	fmt.Fprintln(b)
  1113  	for _, v := range intptr {
  1114  		fmt.Fprintf(b, "func AssignOrPtr%s(p uintptr, v %s) %[2]s { *(*%[2]s)(unsafe.Pointer(p)) |= v; return *(*%[2]s)(unsafe.Pointer(p)) }\n\n", capitalize(v), v)
  1115  	}
  1116  
  1117  	fmt.Fprintln(b)
  1118  	for _, v := range intptr {
  1119  		fmt.Fprintf(b, "func AssignShlPtr%s(p uintptr, v int) %s { *(*%[2]s)(unsafe.Pointer(p)) <<= v; return *(*%[2]s)(unsafe.Pointer(p)) }\n\n", capitalize(v), v)
  1120  	}
  1121  
  1122  	fmt.Fprintln(b)
  1123  	for _, v := range intptr {
  1124  		fmt.Fprintf(b, "func AssignShrPtr%s(p uintptr, v int) %s { *(*%[2]s)(unsafe.Pointer(p)) >>= v; return *(*%[2]s)(unsafe.Pointer(p)) }\n\n", capitalize(v), v)
  1125  	}
  1126  
  1127  	fmt.Fprintln(b)
  1128  	for _, v := range intptr {
  1129  		fmt.Fprintf(b, "func AssignShl%s(p *%s, v int) %[2]s { *p <<= v; return *p }\n\n", capitalize(v), v)
  1130  	}
  1131  
  1132  	fmt.Fprintln(b)
  1133  	for _, v := range intptr {
  1134  		fmt.Fprintf(b, "func AssignShr%s(p *%s, v int) %[2]s { *p >>= v; return *p }\n\n", capitalize(v), v)
  1135  	}
  1136  
  1137  	fmt.Fprintln(b)
  1138  	for _, v := range scalar {
  1139  		fmt.Fprintf(b, "func PreInc%s(p *%s, d %[2]s) %[2]s { *p += d; return *p }\n", capitalize(v), v)
  1140  	}
  1141  
  1142  	fmt.Fprintln(b)
  1143  	for _, v := range atomic {
  1144  		fmt.Fprintf(b, "func PreIncAtomic%s(p *%s, d %[2]s) %[2]s { return atomic.Add%[1]s(p, d) }\n", capitalize(v), v)
  1145  	}
  1146  
  1147  	fmt.Fprintln(b)
  1148  	for _, v := range scalar {
  1149  		fmt.Fprintf(b, "func PreDec%s(p *%s, d %[2]s) %[2]s { *p -= d; return *p }\n", capitalize(v), v)
  1150  	}
  1151  
  1152  	fmt.Fprintln(b)
  1153  	for _, v := range atomic {
  1154  		fmt.Fprintf(b, "func PreDecAtomic%s(p *%s, d %[2]s) %[2]s { return atomic.Add%[1]s(p, -d) }\n", capitalize(v), v)
  1155  	}
  1156  
  1157  	fmt.Fprintln(b)
  1158  	for _, v := range scalar {
  1159  		fmt.Fprintf(b, "func PostInc%s(p *%s, d %[2]s) %[2]s { r := *p; *p += d; return r }\n", capitalize(v), v)
  1160  	}
  1161  
  1162  	fmt.Fprintln(b)
  1163  	for _, v := range atomic {
  1164  		fmt.Fprintf(b, "func PostIncAtomic%s(p *%s, d %[2]s) %[2]s { return atomic.Add%[1]s(p, d) - d }\n", capitalize(v), v)
  1165  	}
  1166  
  1167  	fmt.Fprintln(b)
  1168  	for _, v := range scalar {
  1169  		fmt.Fprintf(b, "func PostDec%s(p *%s, d %[2]s) %[2]s { r := *p; *p -= d; return r }\n", capitalize(v), v)
  1170  	}
  1171  
  1172  	fmt.Fprintln(b)
  1173  	for _, v := range atomic {
  1174  		fmt.Fprintf(b, "func PostDecAtomic%s(p *%s, d %[2]s) %[2]s { return atomic.Add%[1]s(p, -d) + d }\n", capitalize(v), v)
  1175  	}
  1176  
  1177  	fmt.Fprintln(b)
  1178  	for _, v := range scalar {
  1179  		for _, w := range scalar {
  1180  			switch {
  1181  			case strings.HasPrefix(v, "complex64"):
  1182  				switch {
  1183  				case strings.HasPrefix(w, "complex"):
  1184  					fmt.Fprintf(b, "func %sFrom%s(n %s) %s { return %[4]s(n) }\n", capitalize(v), capitalize(w), w, v)
  1185  				default:
  1186  					fmt.Fprintf(b, "func %sFrom%s(n %s) %s { return %[4]s(complex(float32(n), 0)) }\n", capitalize(v), capitalize(w), w, v)
  1187  				}
  1188  			case strings.HasPrefix(v, "complex128"):
  1189  				switch {
  1190  				case strings.HasPrefix(w, "complex"):
  1191  					fmt.Fprintf(b, "func %sFrom%s(n %s) %s { return %[4]s(n) }\n", capitalize(v), capitalize(w), w, v)
  1192  				default:
  1193  					fmt.Fprintf(b, "func %sFrom%s(n %s) %s { return %[4]s(complex(float64(n), 0)) }\n", capitalize(v), capitalize(w), w, v)
  1194  				}
  1195  			default:
  1196  				switch {
  1197  				case strings.HasPrefix(w, "complex"):
  1198  					fmt.Fprintf(b, "func %sFrom%s(n %s) %s { return %[4]s(real(n)) }\n", capitalize(v), capitalize(w), w, v)
  1199  				default:
  1200  					fmt.Fprintf(b, "func %sFrom%s(n %s) %s { return %[4]s(n) }\n", capitalize(v), capitalize(w), w, v)
  1201  				}
  1202  			}
  1203  		}
  1204  	}
  1205  
  1206  	fmt.Fprintln(b)
  1207  	for _, v := range scalar {
  1208  		fmt.Fprintf(b, "func %s(n %s) %[2]s { return n }\n", capitalize(v), v)
  1209  	}
  1210  
  1211  	fmt.Fprintln(b)
  1212  	for _, v := range intptr {
  1213  		fmt.Fprintf(b, "func Neg%s(n %s) %[2]s { return -n }\n", capitalize(v), v)
  1214  	}
  1215  
  1216  	fmt.Fprintln(b)
  1217  	for _, v := range intptr {
  1218  		fmt.Fprintf(b, "func Cpl%s(n %s) %[2]s { return ^n }\n", capitalize(v), v)
  1219  	}
  1220  
  1221  	fmt.Fprintln(b)
  1222  	for _, v := range intptr {
  1223  		fmt.Fprintf(b, `
  1224  func Bool%s(b bool) %s {
  1225  	if b {
  1226  		return 1
  1227  	}
  1228  	return 0
  1229  }
  1230  `, capitalize(v), v)
  1231  	}
  1232  
  1233  	fmt.Fprintln(b)
  1234  	for _, sz := range sizes {
  1235  		for _, v := range ints {
  1236  			fmt.Fprintf(b, `
  1237  func SetBitFieldPtr%s%s(p uintptr, v %s, off int, mask uint%[1]s) {
  1238  	*(*uint%[1]s)(unsafe.Pointer(p)) = *(*uint%[1]s)(unsafe.Pointer(p))&^uint%[1]s(mask) | uint%[1]s(v)<<off&mask
  1239  }
  1240  
  1241  `, sz, capitalize(v), v)
  1242  		}
  1243  	}
  1244  
  1245  	fmt.Fprintln(b)
  1246  	for _, sz := range []int{8, 16, 32, 64} {
  1247  		for _, v := range []int{8, 16, 32, 64} {
  1248  			fmt.Fprintf(b, `
  1249  func AssignBitFieldPtr%dInt%d(p uintptr, v int%[2]d, w, off int, mask uint%[1]d) int%[2]d {
  1250  	*(*uint%[1]d)(unsafe.Pointer(p)) = *(*uint%[1]d)(unsafe.Pointer(p))&^uint%[1]d(mask) | uint%[1]d(v)<<off&mask
  1251  	s := %[2]d - w
  1252  	return v << s >> s
  1253  }
  1254  
  1255  `, sz, v)
  1256  		}
  1257  	}
  1258  
  1259  	fmt.Fprintln(b)
  1260  	for _, sz := range []int{8, 16, 32, 64} {
  1261  		for _, v := range []int{8, 16, 32, 64} {
  1262  			fmt.Fprintf(b, `
  1263  func AssignBitFieldPtr%dUint%d(p uintptr, v uint%[2]d, w, off int, mask uint%[1]d) uint%[2]d {
  1264  	*(*uint%[1]d)(unsafe.Pointer(p)) = *(*uint%[1]d)(unsafe.Pointer(p))&^uint%[1]d(mask) | uint%[1]d(v)<<off&mask
  1265  	return v & uint%[2]d(mask >> off)
  1266  }
  1267  
  1268  `, sz, v)
  1269  		}
  1270  	}
  1271  
  1272  	fmt.Fprintln(b)
  1273  	for _, sz := range []int{8, 16, 32, 64} {
  1274  		for _, v := range []int{8, 16, 32, 64} {
  1275  			fmt.Fprintf(b, `
  1276  func PostDecBitFieldPtr%dInt%d(p uintptr, d int%[2]d, w, off int, mask uint%[1]d) (r int%[2]d) {
  1277  	x0 := *(*uint%[1]d)(unsafe.Pointer(p))
  1278  	s := %[2]d - w - off
  1279  	r = int%[2]d(x0) & int%[2]d(mask) << s >> (s+off)
  1280  	*(*uint%[1]d)(unsafe.Pointer(p)) = x0&^uint%[1]d(mask) | uint%[1]d(r-d)<<off&mask
  1281  	return r
  1282  }
  1283  
  1284  `, sz, v)
  1285  		}
  1286  	}
  1287  
  1288  	fmt.Fprintln(b)
  1289  	for _, sz := range []int{8, 16, 32, 64} {
  1290  		for _, v := range []int{8, 16, 32, 64} {
  1291  			fmt.Fprintf(b, `
  1292  func PostDecBitFieldPtr%dUint%d(p uintptr, d uint%[2]d, w, off int, mask uint%[1]d) (r uint%[2]d) {
  1293  	x0 := *(*uint%[1]d)(unsafe.Pointer(p))
  1294  	r = uint%[2]d(x0) & uint%[2]d(mask) >> off
  1295  	*(*uint%[1]d)(unsafe.Pointer(p)) = x0&^uint%[1]d(mask) | uint%[1]d(r-d)<<off&mask
  1296  	return r
  1297  }
  1298  
  1299  `, sz, v)
  1300  		}
  1301  	}
  1302  
  1303  	fmt.Fprintln(b)
  1304  	for _, sz := range []int{8, 16, 32, 64} {
  1305  		for _, v := range []int{8, 16, 32, 64} {
  1306  			fmt.Fprintf(b, `
  1307  func PostIncBitFieldPtr%dInt%d(p uintptr, d int%[2]d, w, off int, mask uint%[1]d) (r int%[2]d) {
  1308  	x0 := *(*uint%[1]d)(unsafe.Pointer(p))
  1309  	s := %[2]d - w - off
  1310  	r = int%[2]d(x0) & int%[2]d(mask) << s >> (s+off)
  1311  	*(*uint%[1]d)(unsafe.Pointer(p)) = x0&^uint%[1]d(mask) | uint%[1]d(r+d)<<off&mask
  1312  	return r
  1313  }
  1314  
  1315  `, sz, v)
  1316  		}
  1317  	}
  1318  
  1319  	fmt.Fprintln(b)
  1320  	for _, sz := range []int{8, 16, 32, 64} {
  1321  		for _, v := range []int{8, 16, 32, 64} {
  1322  			fmt.Fprintf(b, `
  1323  func PostIncBitFieldPtr%dUint%d(p uintptr, d uint%[2]d, w, off int, mask uint%[1]d) (r uint%[2]d) {
  1324  	x0 := *(*uint%[1]d)(unsafe.Pointer(p))
  1325  	r = uint%[2]d(x0) & uint%[2]d(mask) >> off
  1326  	*(*uint%[1]d)(unsafe.Pointer(p)) = x0&^uint%[1]d(mask) | uint%[1]d(r+d)<<off&mask
  1327  	return r
  1328  }
  1329  
  1330  `, sz, v)
  1331  		}
  1332  	}
  1333  
  1334  	b.WriteString("\n")
  1335  	if err := ioutil.WriteFile(fmt.Sprintf("ccgo.go"), b.Bytes(), 0660); err != nil {
  1336  		fail(err)
  1337  	}
  1338  }
  1339  
  1340  func capitalize(s string) string { return strings.ToUpper(s[:1]) + s[1:] }