1package eval
2
3import (
4	"runtime"
5
6	"src.elv.sh/pkg/logutil"
7	"src.elv.sh/pkg/parse"
8)
9
10func init() {
11	addBuiltinFns(map[string]interface{}{
12		"src":    src,
13		"-gc":    _gc,
14		"-stack": _stack,
15		"-log":   _log,
16	})
17}
18
19//elvdoc:fn src
20//
21// ```elvish
22// src
23// ```
24//
25// Output a map-like value describing the current source being evaluated. The value
26// contains the following fields:
27//
28// -   `name`, a unique name of the current source. If the source originates from a
29//     file, it is the full path of the file.
30//
31// -   `code`, the full body of the current source.
32//
33// -   `is-file`, whether the source originates from a file.
34//
35// Examples:
36//
37// ```elvish-transcript
38// ~> put (src)[name code is-file]
39// ▶ '[tty]'
40// ▶ 'put (src)[name code is-file]'
41// ▶ $false
42// ~> echo 'put (src)[name code is-file]' > show-src.elv
43// ~> elvish show-src.elv
44// ▶ /home/elf/show-src.elv
45// ▶ "put (src)[name code is-file]\n"
46// ▶ $true
47// ```
48//
49// Note: this builtin always returns information of the source of the function
50// calling `src`. Consider the following example:
51//
52// ```elvish-transcript
53// ~> echo 'fn show { put (src)[name] }' > ~/.elvish/lib/src-fsutil.elv
54// ~> use src-util
55// ~> src-util:show
56// ▶ /home/elf/.elvish/lib/src-fsutil.elv
57// ```
58
59func src(fm *Frame) parse.Source {
60	return fm.srcMeta
61}
62
63//elvdoc:fn -gc
64//
65// ```elvish
66// -gc
67// ```
68//
69// Force the Go garbage collector to run.
70//
71// This is only useful for debug purposes.
72
73func _gc() {
74	runtime.GC()
75}
76
77//elvdoc:fn -stack
78//
79// ```elvish
80// -stack
81// ```
82//
83// Print a stack trace.
84//
85// This is only useful for debug purposes.
86
87func _stack(fm *Frame) error {
88	// TODO(xiaq): Dup with main.go.
89	buf := make([]byte, 1024)
90	for runtime.Stack(buf, true) == cap(buf) {
91		buf = make([]byte, cap(buf)*2)
92	}
93	_, err := fm.ByteOutput().Write(buf)
94	return err
95}
96
97//elvdoc:fn -log
98//
99// ```elvish
100// -log $filename
101// ```
102//
103// Direct internal debug logs to the named file.
104//
105// This is only useful for debug purposes.
106
107func _log(fname string) error {
108	return logutil.SetOutputFile(fname)
109}
110