1#!/bin/sh
2
3# Copyright 2016 The Go Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style
5# license that can be found in the LICENSE file.
6
7# Given a source directory, returns the non-test Go files that should
8# be built for this target.  This implements Go's build constraints in
9# a shell script.  There is similar code in testsuite/gotest.
10
11set -e
12
13LANG=C
14LC_ALL=C
15LC_CTYPE=C
16export LANG LC_ALL LC_CTYPE
17
18srcdir=""
19goarch=""
20goos=""
21extrafiles=""
22cmdlinetag="nosuchtag"
23cgotag="cgo"
24
25for arg; do
26    case "x$arg" in
27	x--srcdir)
28	    srcdir=$2
29	    shift
30	    shift
31	    ;;
32	x--srcdir=*)
33	    srcdir=`echo $1 | sed -e 's/^--srcdir=//'`
34	    shift
35	    ;;
36	x--goarch)
37	    goarch=$2
38	    shift
39	    shift
40	    ;;
41	x--goarch=*)
42	    goarch=`echo $1 | sed -e 's/^--goarch=//'`
43	    shift
44	    ;;
45	x--goos)
46	    goos=$2
47	    shift
48	    shift
49	    ;;
50	x--goos=*)
51	    goos=`echo $1 | sed -e 's/^--goos=//'`
52	    shift
53	    ;;
54	x--extrafiles)
55	    extrafiles=$2
56	    shift
57	    shift
58	    ;;
59	x--extrafiles=*)
60	    extrafiles=`echo $1 | sed -e 's/^--extrafiles=//'`
61	    shift
62	    ;;
63	x--tag)
64	    cmdlinetag=$2
65	    shift
66	    shift
67	    ;;
68	x--tag=*)
69	    cmdlinetag=`echo $1 | sed -e 's/^--tag=//'`
70	    shift
71	    ;;
72	x--nocgo)
73	    cgotag="nosuchtag"
74	    shift
75	    ;;
76	*)
77	    echo 1>&2 "unknown argument $arg"
78	    exit 1
79	    ;;
80    esac
81done
82
83cd $srcdir
84
85gofiles=
86for f in *.go; do
87    case $f in
88	*_test.go)
89	    ;;
90	*.go)
91	    gofiles="$gofiles $f"
92	    ;;
93    esac
94done
95
96if test "$gofiles" = ""; then
97    echo 1>&2 "no non-test .go files in $srcdir"
98    exit 1
99fi
100
101matched=
102for f in $gofiles; do
103    tag1=`echo $f | sed -e 's/^.*_\([^_]*\).go$/\1/'`
104    tag2=`echo $f | sed -e 's/^.*_\([^_]*\)_[^_]*.go$/\1/'`
105    if test x$tag1 = x$f; then
106	tag1=
107    fi
108    if test x$tag2 = x$f; then
109	tag2=
110    fi
111
112    case "$tag1" in
113	"") ;;
114	$goarch) ;;
115	$goos) ;;
116	aix | android | darwin | dragonfly | freebsd | linux | nacl | netbsd | openbsd | plan9 | solaris | windows)
117	    tag1=nonmatchingtag
118	    ;;
119	386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | ppc64 | ppc64le | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | ppc | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64)
120	    tag1=nonmatchingtag
121	    ;;
122    esac
123
124    case "$tag2" in
125	"") ;;
126	$goarch) ;;
127	$goos) ;;
128	aix | android | darwin | dragonfly | freebsd | linux | nacl | netbsd | openbsd | plan9 | solaris | windows)
129	    tag2=nonmatchingtag
130	    ;;
131	386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | ppc64 | ppc64le | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | ppc | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64)
132	    tag2=nonmatchingtag
133	    ;;
134    esac
135
136    if test x$tag1 != xnonmatchingtag -a x$tag2 != xnonmatchingtag; then
137	# Pipe through cat so that `set -e` doesn't affect fgrep.
138	tags=`sed '/^package /q' < $f | grep '^// +build ' | cat`
139	omatch=true
140	first=true
141	match=false
142	for tag in $tags; do
143	    case $tag in
144		"//")
145		    ;;
146		"+build")
147		    if test "$first" = "true"; then
148			first=false
149		    elif test "$match" = "false"; then
150			omatch=false
151		    fi
152		    match=false
153		    ;;
154		$goos | $goarch | $cgotag | $cmdlinetag | "gccgo" | go1.[0-9])
155		    match=true
156		    ;;
157		"!"$goos | "!"$goarch | "!"$cgotag | "!"$cmdlinetag | "!gccgo" | "!"go1.[0-9])
158		    ;;
159		*,*)
160		    cmatch=true
161		    for ctag in `echo $tag | sed -e 's/,/ /g'`; do
162			case $ctag in
163			    $goos | $goarch | $cgotag | $cmdlinetag | "gccgo" | go1.[0-9])
164				;;
165			    "!"$goos | "!"$goarch | "!"$cgotag | "!"$cmdlinetag | "!gccgo" | "!"go1.[0-9])
166				cmatch=false
167				;;
168			    "!"*)
169				;;
170			    *)
171				cmatch=false
172				;;
173			esac
174		    done
175		    if test "$cmatch" = "true"; then
176			match=true
177		    fi
178		    ;;
179		"!"*)
180		    match=true
181		    ;;
182	    esac
183	done
184
185	if test "$match" = "false" -a "$first" = "false"; then
186	    omatch=false
187	fi
188
189	if test "$omatch" = "true"; then
190	    matched="$matched $srcdir/$f"
191	fi
192    fi
193done
194
195echo $matched $extrafiles
196
197exit 0
198