+++ /dev/null
-// Copyright (C) 2024 early (LGPL)
-package include
-
-import (
- "errors"
- "runtime"
- "slices"
- "strings"
-)
-
-var ErrNoEligibleCaller = errors.New("no eligible caller on the stack")
-var ErrNoRuntimeAccess = errors.New("couldn't access the runtime")
-
-var callStackNotEligible = []string{
- "runtime",
- "git.earlybird.gay/today-engine/include",
-}
-
-// SetNotEligible marks a package as ineligible for including files.
-// You should use the arguments of include to to this if you can, but if you are
-// using a package that passes through to include, you can call this in an init
-// function.
-func SetNotEligible(pkg string) {
- callStackNotEligible = append(callStackNotEligible, pkg)
-}
-
-func isNotEligible(caller string, ignorePackages []string) bool {
- return slices.ContainsFunc(callStackNotEligible, func(notEligible string) bool {
- return strings.HasPrefix(caller, notEligible+".")
- }) || slices.ContainsFunc(ignorePackages, func(notEligible string) bool {
- return strings.HasPrefix(caller, notEligible+".")
- })
-}
-
-// getCallStackButt gets the calling file, ignoring any file in an ignored
-// package.
-func getCallStackButt(ignorePackages []string) (string, error) {
- const incr int = 2
- const max int = incr * 10
- for skip := 0; skip < max; skip += incr {
- callers := make([]uintptr, incr)
- count := runtime.Callers(skip, callers)
- frames := runtime.CallersFrames(callers)
-
- frame, more := frames.Next()
- for {
- // If getCallStackButt gets called from main, use the runtime to
- // determine what module main is in.
- if isNotEligible(frame.Function, ignorePackages) {
- if !more {
- break
- }
- frame, more = frames.Next()
- } else {
- return frame.File, nil
- }
- }
- if count < incr {
- break
- }
- }
-
- return "", ErrNoEligibleCaller
-}
+++ /dev/null
-// Copyright (C) 2024 early (LGPL)
-package include
-
-import (
- "io"
- "os"
- "path"
-)
-
-type Opener interface {
- Open() (io.ReadCloser, error)
-}
-
-type FileOpener interface {
- Opener
- FileName() string
-}
-
-type OpenerFunc func() (io.ReadCloser, error)
-
-func (opener OpenerFunc) Open() (io.ReadCloser, error) {
- return opener()
-}
-
-type fileOpener struct {
- absPath string
- alwaysErr error
-}
-
-func (opener *fileOpener) Open() (io.ReadCloser, error) {
- if opener.alwaysErr != nil {
- return nil, opener.alwaysErr
- }
- return os.Open(opener.absPath)
-}
-
-func (fopener *fileOpener) FileName() string {
- return fopener.absPath
-}
-
-// File returns an Opener that Opens() a file.
-// If filename is a relative path, it is considered relative to the *calling
-// file*, not the working directory.
-// If ignorePackages is nonempty, callers in any package specified are ignored.
-func File(filename string, ignorePackages ...string) FileOpener {
- opener := new(fileOpener)
- if path.IsAbs(filename) {
- opener.absPath = filename
- } else {
- caller, err := getCallStackButt(ignorePackages)
- if err != nil {
- opener.alwaysErr = err
- } else {
- opener.absPath = path.Join(path.Dir(caller), filename)
- }
- }
- return opener
-}
--- /dev/null
+// Copyright (C) 2024 early (LGPL)
+package include
+
+import (
+ "errors"
+ "runtime"
+ "slices"
+ "strings"
+)
+
+var ErrNoEligibleCaller = errors.New("no eligible caller on the stack")
+var ErrNoRuntimeAccess = errors.New("couldn't access the runtime")
+
+var callStackNotEligible = []string{
+ "runtime",
+ "git.earlybird.gay/today/include",
+}
+
+// SetNotEligible marks a package as ineligible for including files.
+// You should use the arguments of include to to this if you can, but if you are
+// using a package that passes through to include, you can call this in an init
+// function.
+func SetNotEligible(pkg string) {
+ callStackNotEligible = append(callStackNotEligible, pkg)
+}
+
+func isNotEligible(caller string, ignorePackages []string) bool {
+ return slices.ContainsFunc(callStackNotEligible, func(notEligible string) bool {
+ return strings.HasPrefix(caller, notEligible+".")
+ }) || slices.ContainsFunc(ignorePackages, func(notEligible string) bool {
+ return strings.HasPrefix(caller, notEligible+".")
+ })
+}
+
+// getCallStackButt gets the calling file, ignoring any file in an ignored
+// package.
+func getCallStackButt(ignorePackages []string) (string, error) {
+ const incr int = 2
+ const max int = incr * 10
+ for skip := 0; skip < max; skip += incr {
+ callers := make([]uintptr, incr)
+ count := runtime.Callers(skip, callers)
+ frames := runtime.CallersFrames(callers)
+
+ frame, more := frames.Next()
+ for {
+ // If getCallStackButt gets called from main, use the runtime to
+ // determine what module main is in.
+ if isNotEligible(frame.Function, ignorePackages) {
+ if !more {
+ break
+ }
+ frame, more = frames.Next()
+ } else {
+ return frame.File, nil
+ }
+ }
+ if count < incr {
+ break
+ }
+ }
+
+ return "", ErrNoEligibleCaller
+}
--- /dev/null
+// Copyright (C) 2024 early (LGPL)
+package include
+
+import (
+ "io"
+ "os"
+ "path"
+)
+
+type Opener interface {
+ Open() (io.ReadCloser, error)
+}
+
+type FileOpener interface {
+ Opener
+ FileName() string
+}
+
+type OpenerFunc func() (io.ReadCloser, error)
+
+func (opener OpenerFunc) Open() (io.ReadCloser, error) {
+ return opener()
+}
+
+type fileOpener struct {
+ absPath string
+ alwaysErr error
+}
+
+func (opener *fileOpener) Open() (io.ReadCloser, error) {
+ if opener.alwaysErr != nil {
+ return nil, opener.alwaysErr
+ }
+ return os.Open(opener.absPath)
+}
+
+func (fopener *fileOpener) FileName() string {
+ return fopener.absPath
+}
+
+func Abs(filename string, ignorePackages ...string) (string, error) {
+ if path.IsAbs(filename) {
+ return filename, nil
+ } else {
+ caller, err := getCallStackButt(ignorePackages)
+ if err != nil {
+ return "", err
+ } else {
+ return path.Join(path.Dir(caller), filename), nil
+ }
+ }
+}
+
+// File returns an Opener that Opens() a file.
+// If filename is a relative path, it is considered relative to the *calling
+// file*, not the working directory.
+// If ignorePackages is nonempty, callers in any package specified are ignored.
+func File(filename string, ignorePackages ...string) FileOpener {
+ opener := new(fileOpener)
+ if path.IsAbs(filename) {
+ opener.absPath = filename
+ } else {
+ caller, err := getCallStackButt(ignorePackages)
+ if err != nil {
+ opener.alwaysErr = err
+ } else {
+ opener.absPath = path.Join(path.Dir(caller), filename)
+ }
+ }
+ return opener
+}