| #!/usr/bin/env bash |
| # Copyright 2010 The Go Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style |
| # license that can be found in the LICENSE file. |
| |
| # Using all the non-test *.go files in the named directory, write |
| # out a file /tmp/$USER.try.go to evaluate the expressions on the |
| # command line, perhaps to discover a function or method that |
| # gives the desired results. See usage message. |
| # Compile the program and run it. |
| |
| # Makes egrep,grep work better in general if we put them |
| # in ordinary C mode instead of what the current language is. |
| unset LANG |
| export LC_ALL=C |
| export LC_CTYPE=C |
| |
| export GOROOT=${GOROOT:-"@@GOROOT@@"} |
| eval $(gomake -j1 --no-print-directory -f "$GOROOT"/src/Make.inc go-env) |
| if [ -z "$O" ]; then |
| echo 'missing $O - maybe no Make.$GOARCH?' 1>&2 |
| exit 2 |
| fi |
| |
| # Allow overrides |
| GC="${_GC:-$GC} -I _test" |
| GL="${GL:-$LD} -L _test" |
| AS="$AS" |
| CC="$CC" |
| LD="$LD" |
| export GC GL O AS CC LD |
| |
| # Macros for tab and quotes for easier readability. |
| T=' ' |
| BQ='`' |
| SQ="'" |
| DQ='"' |
| SD="$SQ$DQ" |
| DS="$DQ$SQ" |
| |
| usage="usage: gotry [packagedirectory] expression ... |
| Given one expression, gotry attempts to evaluate that expression. |
| Given multiple expressions, gotry treats them as a list of arguments |
| and result values and attempts to find a function in the package |
| that, given the first few expressions as arguments, evaluates to |
| the remaining expressions as results. If the first expression has |
| methods, it will also search for applicable methods. |
| |
| If there are multiple expressions, a package directory must be |
| specified. If there is a package argument, the expressions are |
| evaluated in an environment that includes |
| import . ${DQ}packagedirectory${DQ} |
| |
| Examples: |
| gotry 3+4 |
| # evaluates to 7 |
| gotry strings ${SD}abc${DS} ${SD}c${DS} 7-5 |
| # finds strings.Index etc. |
| gotry regexp ${SQ}MustCompile(${DQ}^[0-9]+${DQ})${SQ} ${SD}12345${DS} true |
| # finds Regexp.MatchString |
| |
| " |
| |
| function fail() { |
| echo 2>&1 "$@" |
| exit 2 |
| } |
| |
| case $# in |
| 0) |
| fail "$usage" |
| ;; |
| *) |
| case "$1" in |
| -*help|-*'?'|'?') |
| fail "$usage" |
| esac |
| if test -d "$GOROOT/src/pkg/$1" |
| then |
| pkg=$(basename $1) |
| dir=$GOROOT/src/pkg/$1 |
| importdir=$1 |
| shift |
| case "$pkg" in |
| os|syscall) |
| fail "gotry: cannot try packages os or syscall; they are too dangerous" |
| esac |
| fi |
| ;; |
| esac |
| |
| spaces='[ ][ ]*' |
| |
| function getFunctions() { |
| if [ "$pkg" = "" ] |
| then |
| return |
| fi |
| for file in $dir/*.go |
| do |
| case $file in |
| *_test*) |
| continue |
| esac |
| grep "func$spaces[A-Z]" $file | # TODO: should be Unicode upper case |
| sed "s/func$spaces//;s/(.*//" |
| done | sort -u |
| } |
| |
| # Generate list of public functions. |
| functions=$(getFunctions) |
| |
| # Write file to compile |
| rm -f /tmp/$USER.try.go |
| ( |
| cat <<'!' |
| package main |
| |
| import ( |
| "os" |
| "try" |
| ! |
| |
| if [ "$pkg" != "" ] |
| then |
| echo "$T" . '"'$importdir'"' |
| fi |
| |
| cat <<! |
| ) |
| func main() { |
| try.Main("$pkg", firstArg, functions, args) |
| } |
| var functions = map[string] interface{}{ |
| ! |
| |
| for i in $functions |
| do |
| echo "$T"'"'$i'": '$i',' |
| done |
| echo "}" |
| |
| echo 'var args = []interface{}{' |
| |
| if [ $# = 1 ] |
| then |
| echo "${T}toSlice($1)", |
| else |
| for i |
| do |
| echo "$T$i", |
| done |
| fi |
| echo "}" |
| |
| cat <<! |
| var firstArg = $BQ$1$BQ |
| var _ os.Error |
| func toSlice(a ...interface{}) []interface{} { return a } |
| ! |
| |
| )>/tmp/$USER.try.go |
| |
| $GC -o /tmp/$USER.try.$O /tmp/$USER.try.go && |
| $GL -o /tmp/$USER.try /tmp/$USER.try.$O && |
| /tmp/$USER.try "_$@" |
| rm -f /tmp/$USER.try /tmp/$USER.try.go /tmp/$USER.try.$O |