mirror of
https://github.com/RoBaertschi/tt.git
synced 2025-04-16 05:53:30 +00:00
begin term lib for build system
This commit is contained in:
parent
b175ee2bee
commit
dbaa77aa1b
@ -12,11 +12,17 @@ func _() {
|
||||
_ = x[Subtract-1]
|
||||
_ = x[Multiply-2]
|
||||
_ = x[Divide-3]
|
||||
_ = x[Equal-4]
|
||||
_ = x[NotEqual-5]
|
||||
_ = x[LessThan-6]
|
||||
_ = x[LessThanEqual-7]
|
||||
_ = x[GreaterThan-8]
|
||||
_ = x[GreaterThanEqual-9]
|
||||
}
|
||||
|
||||
const _BinaryOperator_name = "AddSubtractMultiplyDivide"
|
||||
const _BinaryOperator_name = "AddSubtractMultiplyDivideEqualNotEqualLessThanLessThanEqualGreaterThanGreaterThanEqual"
|
||||
|
||||
var _BinaryOperator_index = [...]uint8{0, 3, 11, 19, 25}
|
||||
var _BinaryOperator_index = [...]uint8{0, 3, 11, 19, 25, 30, 38, 46, 59, 70, 86}
|
||||
|
||||
func (i BinaryOperator) String() string {
|
||||
if i < 0 || i >= BinaryOperator(len(_BinaryOperator_index)-1) {
|
||||
|
@ -3,13 +3,14 @@ package build
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"robaertschi.xyz/robaertschi/tt/asm"
|
||||
"robaertschi.xyz/robaertschi/tt/utils"
|
||||
)
|
||||
|
||||
type ToPrintFlags int
|
||||
@ -38,14 +39,14 @@ func NewSourceProgram(inputFile string, outputFile string) *SourceProgram {
|
||||
}
|
||||
|
||||
func (sp *SourceProgram) Build(backend asm.Backend, emitAsmOnly bool, toPrint ToPrintFlags) error {
|
||||
l := log.New(os.Stderr, "[build] ", log.Lshortfile)
|
||||
l := utils.NewLogger(os.Stderr, "[build] ", utils.Info)
|
||||
|
||||
nodes := make(map[int]*node)
|
||||
rootNodes := []int{}
|
||||
id := 0
|
||||
|
||||
addRootNode := func(task task) int {
|
||||
l.Printf("registering root task %d", id)
|
||||
l.Debugf("registering root task %d", id)
|
||||
node := &node{task: task}
|
||||
nodes[id] = node
|
||||
rootNodes = append(rootNodes, id)
|
||||
@ -54,7 +55,7 @@ func (sp *SourceProgram) Build(backend asm.Backend, emitAsmOnly bool, toPrint To
|
||||
}
|
||||
|
||||
addNode := func(task task, deps ...int) int {
|
||||
l.Printf("registering task %d", id)
|
||||
l.Debugf("registering task %d", id)
|
||||
if len(deps) <= 0 {
|
||||
panic("node without dep is useless")
|
||||
}
|
||||
@ -91,12 +92,14 @@ func (sp *SourceProgram) buildFasm(addRootNode func(task) int, addNode func(task
|
||||
|
||||
mainAsmOutput := strings.TrimSuffix(sp.InputFile, filepath.Ext(sp.InputFile)) + ".asm"
|
||||
|
||||
asmFile := addRootNode(NewFuncTask(func() error {
|
||||
return build(sp.InputFile, mainAsmOutput, toPrint)
|
||||
asmFile := addRootNode(NewFuncTask("generating assembly for "+sp.InputFile, func(output io.Writer) error {
|
||||
return build(output, sp.InputFile, mainAsmOutput, toPrint)
|
||||
}))
|
||||
|
||||
if !emitAsmOnly {
|
||||
fasmTask := addNode(NewProcessTask(fasmPath, mainAsmOutput, sp.OutputFile), asmFile)
|
||||
task := NewProcessTask(fasmPath, mainAsmOutput, sp.OutputFile)
|
||||
task.WithName("assembling " + mainAsmOutput)
|
||||
fasmTask := addNode(task, asmFile)
|
||||
|
||||
// Cleanup
|
||||
|
||||
|
@ -4,10 +4,10 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"robaertschi.xyz/robaertschi/tt/asm/amd64"
|
||||
"robaertschi.xyz/robaertschi/tt/lexer"
|
||||
@ -19,27 +19,35 @@ import (
|
||||
)
|
||||
|
||||
type task interface {
|
||||
Run(id int, doneChan chan taskResult)
|
||||
Run(id int, output io.Writer, doneChan chan taskResult)
|
||||
Name() string
|
||||
WithName(string)
|
||||
}
|
||||
|
||||
type processTask struct {
|
||||
taskName string
|
||||
name string
|
||||
args []string
|
||||
}
|
||||
|
||||
func NewProcessTask(name string, args ...string) task {
|
||||
return &processTask{
|
||||
taskName: name,
|
||||
name: name,
|
||||
args: args,
|
||||
}
|
||||
}
|
||||
|
||||
func (pt *processTask) Run(id int, doneChan chan taskResult) {
|
||||
func (pt *processTask) WithName(name string) {
|
||||
pt.taskName = name
|
||||
}
|
||||
|
||||
func (pt *processTask) Run(id int, output io.Writer, doneChan chan taskResult) {
|
||||
cmd := exec.Command(pt.name, pt.args...)
|
||||
cmd.Stdout = utils.NewPrefixWriterString(os.Stdout, pt.name+" output: ")
|
||||
cmd.Stdout = utils.NewPrefixWriterString(output, pt.name+" output: ")
|
||||
cmd.Stderr = cmd.Stdout
|
||||
|
||||
fmt.Printf("starting %q %v\n", pt.name, pt.args)
|
||||
io.WriteString(output, fmt.Sprintf("starting %q %v\n", pt.name, pt.args))
|
||||
err := cmd.Run()
|
||||
var exitError error
|
||||
if cmd.ProcessState.ExitCode() != 0 {
|
||||
@ -51,15 +59,20 @@ func (pt *processTask) Run(id int, doneChan chan taskResult) {
|
||||
}
|
||||
}
|
||||
|
||||
func (pt *processTask) Name() string {
|
||||
return pt.taskName
|
||||
}
|
||||
|
||||
type removeFileTask struct {
|
||||
file string
|
||||
name string
|
||||
}
|
||||
|
||||
func NewRemoveFileTask(file string) task {
|
||||
return &removeFileTask{file: file}
|
||||
return &removeFileTask{file: file, name: fmt.Sprintf("removing file %q", file)}
|
||||
}
|
||||
|
||||
func (rft *removeFileTask) Run(id int, doneChan chan taskResult) {
|
||||
func (rft *removeFileTask) Run(id int, output io.Writer, doneChan chan taskResult) {
|
||||
err := os.Remove(rft.file)
|
||||
doneChan <- taskResult{
|
||||
Id: id,
|
||||
@ -67,22 +80,35 @@ func (rft *removeFileTask) Run(id int, doneChan chan taskResult) {
|
||||
}
|
||||
}
|
||||
|
||||
func (rft *removeFileTask) Name() string { return rft.name }
|
||||
|
||||
func (rft *removeFileTask) WithName(name string) { rft.name = name }
|
||||
|
||||
type funcTask struct {
|
||||
f func() error
|
||||
f func(io.Writer) error
|
||||
name string
|
||||
}
|
||||
|
||||
func NewFuncTask(f func() error) task {
|
||||
return &funcTask{f: f}
|
||||
func NewFuncTask(taskName string, f func(io.Writer) error) task {
|
||||
return &funcTask{f: f, name: taskName}
|
||||
}
|
||||
|
||||
func (rft *funcTask) Run(id int, doneChan chan taskResult) {
|
||||
func (rft *funcTask) Run(id int, output io.Writer, doneChan chan taskResult) {
|
||||
doneChan <- taskResult{
|
||||
Id: id,
|
||||
Err: rft.f(),
|
||||
Err: rft.f(output),
|
||||
}
|
||||
}
|
||||
|
||||
func build(input string, output string, toPrint ToPrintFlags) error {
|
||||
func (rft *funcTask) Name() string {
|
||||
return rft.name
|
||||
}
|
||||
|
||||
func (rft *funcTask) WithName(name string) {
|
||||
rft.name = name
|
||||
}
|
||||
|
||||
func build(outputWriter io.Writer, input string, output string, toPrint ToPrintFlags) error {
|
||||
file, err := os.Open(input)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not open file %q because: %v", input, err)
|
||||
@ -114,7 +140,8 @@ func build(input string, output string, toPrint ToPrintFlags) error {
|
||||
return fmt.Errorf("parser encountered 1 or more errors")
|
||||
}
|
||||
if (toPrint & PrintAst) != 0 {
|
||||
fmt.Printf("AST:\n%s\n%+#v\n", program.String(), program)
|
||||
io.WriteString(outputWriter,
|
||||
fmt.Sprintf("AST:\n%s\n%+#v\n", program.String(), program))
|
||||
}
|
||||
|
||||
tprogram, err := typechecker.New().CheckProgram(program)
|
||||
@ -122,12 +149,14 @@ func build(input string, output string, toPrint ToPrintFlags) error {
|
||||
return err
|
||||
}
|
||||
if (toPrint & PrintTAst) != 0 {
|
||||
fmt.Printf("TAST:\n%s\n%+#v\n", tprogram.String(), tprogram)
|
||||
io.WriteString(outputWriter,
|
||||
fmt.Sprintf("TAST:\n%s\n%+#v\n", tprogram.String(), tprogram))
|
||||
}
|
||||
|
||||
ir := ttir.EmitProgram(tprogram)
|
||||
if (toPrint & PrintIr) != 0 {
|
||||
fmt.Printf("TTIR:\n%s\n%+#v\n", ir.String(), ir)
|
||||
io.WriteString(outputWriter,
|
||||
fmt.Sprintf("TTIR:\n%s\n%+#v\n", ir.String(), ir))
|
||||
}
|
||||
asm := amd64.CgProgram(ir)
|
||||
|
||||
@ -167,9 +196,10 @@ const (
|
||||
failed
|
||||
)
|
||||
|
||||
func runTasks(nodes map[int]*node, rootNodes []int, l *log.Logger) error {
|
||||
func runTasks(nodes map[int]*node, rootNodes []int, l *utils.Logger) error {
|
||||
|
||||
done := make(map[int]executionState)
|
||||
output := make(map[int]*strings.Builder)
|
||||
running := []int{}
|
||||
doneChan := make(chan taskResult)
|
||||
errs := []error{}
|
||||
@ -178,9 +208,10 @@ func runTasks(nodes map[int]*node, rootNodes []int, l *log.Logger) error {
|
||||
if done[id] != notStarted {
|
||||
panic(fmt.Sprintf("tried starting task %d twice", id))
|
||||
}
|
||||
// fmt.Printf("executing task %d\n", id)
|
||||
l.Debugf("executing task %d", id)
|
||||
node := nodes[id]
|
||||
go node.task.Run(id, doneChan)
|
||||
output[id] = &strings.Builder{}
|
||||
go node.task.Run(id, output[id], doneChan)
|
||||
running = append(running, id)
|
||||
done[id] = executing
|
||||
}
|
||||
@ -206,7 +237,7 @@ func runTasks(nodes map[int]*node, rootNodes []int, l *log.Logger) error {
|
||||
}
|
||||
}
|
||||
|
||||
// fmt.Printf("starting rootNodes %v\n", rootNodes)
|
||||
l.Debugf("starting rootNodes %v", rootNodes)
|
||||
for _, rootNode := range rootNodes {
|
||||
startTask(rootNode)
|
||||
}
|
||||
@ -216,7 +247,7 @@ func runTasks(nodes map[int]*node, rootNodes []int, l *log.Logger) error {
|
||||
for !allFinished {
|
||||
select {
|
||||
case result := <-doneChan:
|
||||
// fmt.Printf("task %d is done with err: %v\n", result.Id, result.Err)
|
||||
l.Debugf("task %d is done with err: %v", result.Id, result.Err)
|
||||
for i, id := range running {
|
||||
if id == result.Id {
|
||||
running = slices.Delete(running, i, i+1)
|
||||
@ -252,6 +283,12 @@ func runTasks(nodes map[int]*node, rootNodes []int, l *log.Logger) error {
|
||||
}
|
||||
}
|
||||
|
||||
for id, node := range nodes {
|
||||
if output[id].Len() > 0 {
|
||||
l.Infof("task %q output: %s", node.task.Name(), output[id])
|
||||
}
|
||||
}
|
||||
|
||||
return errors.Join(errs...)
|
||||
|
||||
}
|
||||
|
6
main.go
6
main.go
@ -10,9 +10,13 @@ import (
|
||||
|
||||
"robaertschi.xyz/robaertschi/tt/asm"
|
||||
"robaertschi.xyz/robaertschi/tt/build"
|
||||
"robaertschi.xyz/robaertschi/tt/term"
|
||||
)
|
||||
|
||||
func main() {
|
||||
r, c, err := term.GetCursorPosition()
|
||||
fmt.Printf("%d, %d, %v\n", r, c, err)
|
||||
|
||||
flag.Usage = func() {
|
||||
fmt.Fprintf(flag.CommandLine.Output(), "Usage of %s [flags] input\nPossible flags:\n", os.Args[0])
|
||||
flag.PrintDefaults()
|
||||
@ -51,7 +55,7 @@ func main() {
|
||||
|
||||
logger := log.New(os.Stderr, "", log.Lshortfile)
|
||||
|
||||
err := build.NewSourceProgram(input, output).Build(asm.Fasm, *emitAsmOnly, build.ToPrintFlags(toPrint))
|
||||
err = build.NewSourceProgram(input, output).Build(asm.Fasm, *emitAsmOnly, build.ToPrintFlags(toPrint))
|
||||
if err != nil {
|
||||
logger.Fatalln(err)
|
||||
os.Exit(1)
|
||||
|
186
term/term.go
Normal file
186
term/term.go
Normal file
@ -0,0 +1,186 @@
|
||||
package term
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"internal/syscall/unix"
|
||||
"os"
|
||||
)
|
||||
|
||||
const ESC = "\x1b"
|
||||
const CSI = ESC + "["
|
||||
const Reset = CSI + "0m"
|
||||
|
||||
// Colors
|
||||
|
||||
const (
|
||||
BlackFg = "30"
|
||||
BlackBg = "40"
|
||||
RedFg = "31"
|
||||
RedBg = "41"
|
||||
GreenFg = "32"
|
||||
GreenBg = "42"
|
||||
YellowFg = "33"
|
||||
YellowBg = "43"
|
||||
BlueFg = "34"
|
||||
BlueBg = "44"
|
||||
MagentaFg = "35"
|
||||
MagentaBg = "35"
|
||||
CyanFg = "36"
|
||||
CyanBg = "46"
|
||||
WhiteFg = "37"
|
||||
WhiteBg = "47"
|
||||
)
|
||||
|
||||
func Color(col string) string {
|
||||
return CSI + col + "m"
|
||||
}
|
||||
|
||||
// Other CSI
|
||||
|
||||
func CursorUp(amount int) string {
|
||||
return fmt.Sprintf("%s%dA", CSI, amount)
|
||||
}
|
||||
|
||||
func CursorDown(amount int) string {
|
||||
return fmt.Sprintf("%s%dB", CSI, amount)
|
||||
}
|
||||
|
||||
func CursorForward(amount int) string {
|
||||
return fmt.Sprintf("%s%dC", CSI, amount)
|
||||
}
|
||||
|
||||
func CursorBack(amount int) string {
|
||||
return fmt.Sprintf("%s%dD", CSI, amount)
|
||||
}
|
||||
|
||||
// Not ANSI.SYS
|
||||
func CursorNextLine(amount int) string {
|
||||
return fmt.Sprintf("%s%dE", CSI, amount)
|
||||
}
|
||||
|
||||
// Not ANSI.SYS
|
||||
func CursorPreviousLine(amount int) string {
|
||||
return fmt.Sprintf("%s%dF", CSI, amount)
|
||||
}
|
||||
|
||||
// Not ANSI.SYS
|
||||
// Moves cursor to column amount
|
||||
func CursorHorizontalAbsolute(amount int) string {
|
||||
return fmt.Sprintf("%s%dG", CSI, amount)
|
||||
}
|
||||
|
||||
// Moves the cursor on the 1-based grid in the terminal
|
||||
func CursorPostition(x, y int) string {
|
||||
return fmt.Sprintf("%s%d;%dH", CSI, x, y)
|
||||
}
|
||||
|
||||
type EraseInDisplayMode int
|
||||
|
||||
const (
|
||||
ClearFromCursor EraseInDisplayMode = iota // clear from cursor to the end of the screen
|
||||
ClearToCursor // clear to cursor from the begining of the screen
|
||||
ClearEntireScreen
|
||||
ClearEntireScreenAndScrollbackBuffer // xterm extension
|
||||
)
|
||||
|
||||
func EraseInDisplay(mode EraseInDisplayMode) string {
|
||||
return fmt.Sprintf("%s%dJ", CSI, mode)
|
||||
}
|
||||
|
||||
type EraseInLineMode int
|
||||
|
||||
const (
|
||||
FromCursorToEnd EraseInLineMode = iota
|
||||
FromCursorToBegin
|
||||
EntireLine
|
||||
)
|
||||
|
||||
func EraseInLine(mode EraseInLineMode) string {
|
||||
return fmt.Sprintf("%s%dK", CSI, mode)
|
||||
}
|
||||
|
||||
// Not ANSI.SYS
|
||||
func ScrollUp(amount int) string {
|
||||
return fmt.Sprintf("%s%dS", CSI, amount)
|
||||
}
|
||||
|
||||
// Not ANSI.SYS
|
||||
func ScrollDown(amount int) string {
|
||||
return fmt.Sprintf("%s%dT", CSI, amount)
|
||||
}
|
||||
|
||||
// Moves the cursor on the 1-based grid in the terminal
|
||||
// Same as Cursor Position but a format effector, not a editor function
|
||||
// see https://en.wikipedia.org/wiki/ANSI_escape_code#Control_Sequence_Introducer_commands
|
||||
func HorizontalVerticalPosition(x, y int) string {
|
||||
return fmt.Sprintf("%s%d;%dH", CSI, x, y)
|
||||
}
|
||||
|
||||
// Gets the cursor position by transmitting CSIn;mR n = row, m = column
|
||||
// see https://en.wikipedia.org/wiki/ANSI_escape_code#Control_Sequence_Introducer_commands
|
||||
// Use GetCursorPosition to get x and y
|
||||
func DeviceStatusReport() string {
|
||||
return CSI + "6n"
|
||||
}
|
||||
|
||||
var DidNotGetCsi = errors.New("could not get csi from Device Status Report sequence")
|
||||
|
||||
func GetCursorPosition() (row, column int, err error) {
|
||||
// _, err = os.Stdin.Seek(0, 2)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
os.Stdout.Write([]byte(DeviceStatusReport()))
|
||||
// CSI is ESC and [
|
||||
csiBuffer := [2]byte{}
|
||||
os.Stdin.Read(csiBuffer[:])
|
||||
|
||||
if string(csiBuffer[:]) != CSI {
|
||||
err = DidNotGetCsi
|
||||
return
|
||||
}
|
||||
|
||||
miniBuff := [1]byte{}
|
||||
for {
|
||||
_, err = os.Stdin.Read(miniBuff[:])
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if miniBuff[0] == ';' {
|
||||
break
|
||||
}
|
||||
|
||||
if '0' <= miniBuff[0] && miniBuff[0] <= '9' {
|
||||
row *= 10
|
||||
row += int(miniBuff[0] - '0')
|
||||
} else {
|
||||
err = fmt.Errorf("invalid byte for number %b", miniBuff[0])
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
_, err = os.Stdin.Read(miniBuff[:])
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if miniBuff[0] == 'R' {
|
||||
break
|
||||
}
|
||||
|
||||
if '0' <= miniBuff[0] && miniBuff[0] <= '9' {
|
||||
column *= 10
|
||||
column += int(miniBuff[0] - '0')
|
||||
} else {
|
||||
err = fmt.Errorf("invalid byte for number %b", miniBuff[0])
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
27
utils/level_string.go
Normal file
27
utils/level_string.go
Normal file
@ -0,0 +1,27 @@
|
||||
// Code generated by "stringer -type=Level -linecomment"; DO NOT EDIT.
|
||||
|
||||
package utils
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[Debug-0]
|
||||
_ = x[Info-1]
|
||||
_ = x[Warn-2]
|
||||
_ = x[Error-3]
|
||||
_ = x[Fatal-4]
|
||||
}
|
||||
|
||||
const _Level_name = "DEBUGINFOWARNERRORFATAL"
|
||||
|
||||
var _Level_index = [...]uint8{0, 5, 9, 13, 18, 23}
|
||||
|
||||
func (i Level) String() string {
|
||||
if i < 0 || i >= Level(len(_Level_index)-1) {
|
||||
return "Level(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _Level_name[_Level_index[i]:_Level_index[i+1]]
|
||||
}
|
122
utils/utils.go
122
utils/utils.go
@ -2,7 +2,13 @@ package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"robaertschi.xyz/robaertschi/tt/term"
|
||||
)
|
||||
|
||||
// Prefix writer writes a prefix before each new line from another io.Writer
|
||||
@ -53,3 +59,119 @@ func (w *PrefixWriter) Write(p []byte) (n int, err error) {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
//go:generate stringer -type=Level -linecomment
|
||||
type Level int
|
||||
|
||||
const (
|
||||
Debug Level = iota // DEBUG
|
||||
Info // INFO
|
||||
Warn // WARN
|
||||
Error // ERROR
|
||||
Fatal // FATAL
|
||||
)
|
||||
|
||||
type LoggerFormatFunc func(prefix string, level Level, msg string) string
|
||||
|
||||
type Logger struct {
|
||||
outMu sync.Mutex
|
||||
out io.Writer
|
||||
prefix string
|
||||
format LoggerFormatFunc
|
||||
filter Level
|
||||
}
|
||||
|
||||
func DefaultLoggerFormatFunc(prefix string, level Level, msg string) string {
|
||||
|
||||
colorString := ""
|
||||
switch level {
|
||||
case Debug:
|
||||
colorString = term.CSI + "90m"
|
||||
case Info:
|
||||
case Warn:
|
||||
colorString = term.Color(term.YellowFg)
|
||||
case Error:
|
||||
colorString = term.Color(term.RedFg)
|
||||
case Fatal:
|
||||
colorString = term.CSI + term.WhiteFg + term.RedBg + "m"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s%s[%s] %s%s", colorString, prefix, level, msg, term.Reset)
|
||||
}
|
||||
|
||||
// filter filters anything below that level out, it does not stop a os.Exit() from a fatal
|
||||
func NewLogger(output io.Writer, prefix string, filter Level) *Logger {
|
||||
l := new(Logger)
|
||||
l.SetPrefix(prefix)
|
||||
l.SetOutput(output)
|
||||
l.format = DefaultLoggerFormatFunc
|
||||
l.filter = filter
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *Logger) SetPrefix(prefix string) {
|
||||
l.prefix = prefix
|
||||
}
|
||||
|
||||
func (l *Logger) SetOutput(output io.Writer) {
|
||||
// NOTE(Robin): Do some research/testing if we need to look the mutex for this
|
||||
l.out = output
|
||||
}
|
||||
|
||||
func (l *Logger) Msg(level Level, msg string) {
|
||||
if level >= l.filter {
|
||||
l.outMu.Lock()
|
||||
result := l.format(l.prefix, level, strings.TrimRight(msg, " \n\t"))
|
||||
io.WriteString(l.out, result)
|
||||
io.WriteString(l.out, "\n")
|
||||
l.outMu.Unlock()
|
||||
}
|
||||
|
||||
if level == Fatal {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) Msgf(level Level, msg string, args ...any) {
|
||||
l.Msg(level, fmt.Sprintf(msg, args...))
|
||||
}
|
||||
|
||||
func (l *Logger) Debug(msg string) {
|
||||
l.Msg(Debug, msg)
|
||||
}
|
||||
|
||||
func (l *Logger) Debugf(msg string, args ...any) {
|
||||
l.Msgf(Debug, msg, args...)
|
||||
}
|
||||
|
||||
func (l *Logger) Info(msg string) {
|
||||
l.Msg(Info, msg)
|
||||
}
|
||||
|
||||
func (l *Logger) Infof(msg string, args ...any) {
|
||||
l.Msgf(Info, msg, args...)
|
||||
}
|
||||
|
||||
func (l *Logger) Warn(msg string) {
|
||||
l.Msg(Warn, msg)
|
||||
}
|
||||
|
||||
func (l *Logger) Warnf(msg string, args ...any) {
|
||||
l.Msgf(Warn, msg, args...)
|
||||
}
|
||||
|
||||
func (l *Logger) Error(msg string) {
|
||||
l.Msg(Error, msg)
|
||||
}
|
||||
|
||||
func (l *Logger) Errorf(msg string, args ...any) {
|
||||
l.Msgf(Error, msg, args...)
|
||||
}
|
||||
|
||||
func (l *Logger) Fatal(msg string) {
|
||||
l.Msg(Fatal, msg)
|
||||
}
|
||||
|
||||
func (l *Logger) Fatalf(msg string, args ...any) {
|
||||
l.Msgf(Fatal, msg, args...)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user