// home: https://github.com/glycerine/vprint // Copyright 2019 Jason E. Aten, Ph.D. All rights reserved. // License: MIT // // MIT License // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. package synthload import ( "fmt" "io" "os" "path" "runtime" "runtime/debug" "sync" "time" ) const RFC3339MsecTz0 = "2006-01-02T15:04:05.000Z07:00" const RFC3339UsecTz0 = "2006-01-02T15:04:05.000000Z07:00" // for tons of debug output var VerboseVerbose bool = false // convience functions for . import var pp = PP var vv = VV var panicOn = PanicOn var _ = panicOn func init() { // keeper linter happy _ = pp _ = vv } func PanicOn(err error) { if err != nil { panic(err) } } func PP(format string, a ...interface{}) { if VerboseVerbose { TSPrintf(format, a...) } } func VV(format string, a ...interface{}) { TSPrintf(format, a...) } func AlwaysPrintf(format string, a ...interface{}) { TSPrintf(format, a...) } var tsPrintfMut sync.Mutex // time-stamped printf func TSPrintf(format string, a ...interface{}) { tsPrintfMut.Lock() Printf("\n%s %s ", FileLine(3), ts()) Printf(format+"\n", a...) tsPrintfMut.Unlock() } // get timestamp for logging purposes func ts() string { return time.Now().Format(RFC3339UsecTz0) } // so we can multi write easily, use our own printf var OurStdout io.Writer = os.Stdout // Printf formats according to a format specifier and writes to standard output. // It returns the number of bytes written and any write error encountered. func Printf(format string, a ...interface{}) (n int, err error) { return fmt.Fprintf(OurStdout, format, a...) } func FileLine(depth int) string { _, fileName, fileLine, ok := runtime.Caller(depth) var s string if ok { s = fmt.Sprintf("%s:%d", path.Base(fileName), fileLine) } else { s = "" } return s } func stack() string { return string(debug.Stack()) } var _ = stack func FileExists(name string) bool { fi, err := os.Stat(name) if err != nil { return false } if fi.IsDir() { return false } return true } func DirExists(name string) bool { fi, err := os.Stat(name) if err != nil { return false } if fi.IsDir() { return true } return false } func FileSize(name string) (int64, error) { fi, err := os.Stat(name) if err != nil { return -1, err } return fi.Size(), nil } // Caller returns the name of the calling function. func Caller(upStack int) string { // elide ourself and runtime.Callers target := upStack + 2 pc := make([]uintptr, target+2) n := runtime.Callers(0, pc) f := runtime.Frame{Function: "unknown"} if n > 0 { frames := runtime.CallersFrames(pc[:n]) for i := 0; i <= target; i++ { contender, more := frames.Next() if i == target { f = contender } if !more { break } } } return f.Function }