#!/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 </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