Commit 662c8077 authored by Kirill Smelkov's avatar Kirill Smelkov

myname: Factor out routines to get current function name & package from exc

Usage would be:

	myname.Func(),	and
	myname.Pkg()
parent 422741ea
......@@ -17,6 +17,8 @@ import (
"fmt"
"runtime"
"strings"
"lab.nexedi.com/kirr/go123/myname"
)
// error type which is raised by raise(arg)
......@@ -133,43 +135,6 @@ func erraddcontext(e *Error, arg interface{}) *Error {
return &Error{arg, e}
}
func _myfuncname(nskip int) string {
pcv := [1]uintptr{}
runtime.Callers(nskip, pcv[:])
f := runtime.FuncForPC(pcv[0])
if f == nil {
return ""
}
return f.Name()
}
// get name of currently running function (caller of myfuncname())
// name is fully qualified package/name.function(.x)
func myfuncname() string {
return _myfuncname(3)
}
// get name of currently running function's package
// package is fully qualified package/name
func mypkgname() string {
myfunc := _myfuncname(3)
if myfunc == "" {
return ""
}
// NOTE dots in package name are after last slash are escaped by go as %2e
// this way the first '.' after last '/' is delimiter between package and function
//
// lab.nexedi.com/kirr/git-backup/package%2ename.Function
// lab.nexedi.com/kirr/git-backup/pkg2.qqq/name%2ezzz.Function
islash := strings.LastIndexByte(myfunc, '/')
iafterslash := islash + 1 // NOTE if '/' not found iafterslash = 0
idot := strings.IndexByte(myfunc[iafterslash:], '.')
if idot == -1 {
panic(fmt.Errorf("funcname %q is not fully qualified", myfunc))
}
return myfunc[:iafterslash+idot]
}
// TODO(go1.7) goes away in favour of runtime.Frame
type Frame struct {
*runtime.Func
......@@ -216,7 +181,7 @@ var (
)
func init() {
_errorpkgname = mypkgname()
_errorpkgname = myname.Pkg()
_errorpkgdot = _errorpkgname + "."
_errorraise = _errorpkgname + ".raise"
}
......
......@@ -14,8 +14,9 @@ package main
import (
"errors"
"strings"
"testing"
"lab.nexedi.com/kirr/go123/myname"
)
func do_raise1() {
......@@ -94,16 +95,6 @@ func TestErrContext(t *testing.T) {
t.Fatal("error not caught")
}
func TestMyFuncName(t *testing.T) {
myfunc := myfuncname()
// go test changes full package name (putting filesystem of the tree into ti)
// thus we check only for suffix
wantsuffix := ".TestMyFuncName"
if !strings.HasSuffix(myfunc, wantsuffix) {
t.Errorf("myfuncname() -> %v ; want *%v", myfunc, wantsuffix)
}
}
func do_raise11() {
do_raise1()
}
......@@ -134,7 +125,7 @@ func TestErrAddCallingContext(t *testing.T) {
for _, tt := range tests {
func() {
myfunc := myfuncname()
myfunc := myname.Func()
defer errcatch(func(e *Error) {
e = erraddcallingcontext(myfunc, e)
msg := e.Error()
......
// Copyright (C) 2015-2016 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
// Package myname provides easy way to determine current function's name and package
package myname
import (
"fmt"
"runtime"
"strings"
)
func _myfuncname(nskip int) string {
pcv := [1]uintptr{}
runtime.Callers(nskip, pcv[:])
f := runtime.FuncForPC(pcv[0])
if f == nil {
return ""
}
return f.Name()
}
// get name of currently running function (caller of Func())
// name is fully qualified package/name.function(.x)
func Func() string {
return _myfuncname(3)
}
// get name of currently running function's package
// package is fully qualified package/name
func Pkg() string {
myfunc := _myfuncname(3)
if myfunc == "" {
return ""
}
// NOTE dots in package name are after last slash are escaped by go as %2e
// this way the first '.' after last '/' is delimiter between package and function
//
// lab.nexedi.com/kirr/git-backup/package%2ename.Function
// lab.nexedi.com/kirr/git-backup/pkg2.qqq/name%2ezzz.Function
islash := strings.LastIndexByte(myfunc, '/')
iafterslash := islash + 1 // NOTE if '/' not found iafterslash = 0
idot := strings.IndexByte(myfunc[iafterslash:], '.')
if idot == -1 {
panic(fmt.Errorf("funcname %q is not fully qualified", myfunc))
}
return myfunc[:iafterslash+idot]
}
// Copyright (C) 2015-2016 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
package myname
import (
"strings"
"testing"
)
func TestMyFuncName(t *testing.T) {
myfunc := Func()
// go test changes full package name (putting filesystem of the tree into ti)
// thus we check only for suffix
wantsuffix := ".TestMyFuncName"
if !strings.HasSuffix(myfunc, wantsuffix) {
t.Errorf("myname.Func() -> %v ; want *%v", myfunc, wantsuffix)
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment