add new input types and fix input bug that only shows up on windows (how predictable)

This commit is contained in:
2024-10-15 22:52:27 +01:00
parent 5eb2a0e789
commit 60cbda6d9d
7 changed files with 133 additions and 50 deletions

View File

@@ -1,2 +1,2 @@
@echo off
go build -trimpath -ldflags="-s -w" -o bin/argon.exe ./src
go build -trimpath -ldflags="-s -w" -tags WINDOWS -o bin/argon.exe ./src

View File

@@ -3,4 +3,4 @@
:: run the go run command passing the path to the main.go file, with the working directory set to the bin folder. pass in the arguments
set __ARGON_DEBUG__=true
go run ./src %*
go run -tags WINDOWS ./src %*

View File

@@ -2,59 +2,13 @@ package main
import (
"fmt"
"log"
"os"
"github.com/chzyer/readline"
"golang.org/x/term"
)
var tempFilePath = os.TempDir() + "/argon_input_history.tmp"
func input(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
message := fmt.Sprint(output...)
rl, err := readline.NewEx(&readline.Config{
Prompt: message,
HistoryFile: tempFilePath,
HistorySearchFold: true,
})
if err != nil {
log.Fatalf("Failed to create readline instance: %v", err)
}
defer rl.Close()
line, err := rl.Readline()
if err != nil { // io.EOF or other error
return "", err
}
return line, nil
}
func getPassword(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
message := fmt.Sprint(output...)
rl, err := readline.NewEx(&readline.Config{
Prompt: message,
MaskRune: '*',
EnableMask: true,
})
if err != nil {
log.Fatalf("Failed to create readline instance: %v", err)
}
defer rl.Close()
line, err := rl.Readline()
if err != nil { // io.EOF or other error
return "", err
}
return line, nil
}
func pause() {
fmt.Print("Press Enter to continue...")
term.ReadPassword(int(os.Stdin.Fd()))

55
src/input_unix.go Normal file
View File

@@ -0,0 +1,55 @@
//go:build !WINDOWS
// +build !WINDOWS
package main
import (
"fmt"
"log"
"github.com/chzyer/readline"
)
func input(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
message := fmt.Sprint(output...)
rl, err := readline.NewEx(&readline.Config{
Prompt: message,
HistoryFile: tempFilePath,
HistorySearchFold: true,
})
if err != nil {
log.Fatalf("Failed to create readline instance: %v", err)
}
defer rl.Close()
line, err := rl.Readline()
if err != nil { // io.EOF or other error
return "", err
}
return line, nil
}
func getPassword(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
message := fmt.Sprint(output...)
rl, err := readline.NewEx(&readline.Config{
Prompt: message,
MaskRune: '*',
EnableMask: true,
})
if err != nil {
log.Fatalf("Failed to create readline instance: %v", err)
}
defer rl.Close()
line, err := rl.Readline()
if err != nil { // io.EOF or other error
return "", err
}
return line, nil
}

63
src/input_windows.go Normal file
View File

@@ -0,0 +1,63 @@
//go:build WINDOWS
// +build WINDOWS
package main
import (
"bufio"
"fmt"
"os"
"golang.org/x/term"
)
func input(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
fmt.Print(output...)
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
input := scanner.Text()
return input, nil
}
func getPassword(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
fmt.Print(output...)
password := []byte{}
oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
if err != nil {
panic(err)
}
defer term.Restore(int(os.Stdin.Fd()), oldState)
for {
char := make([]byte, 1)
_, err := os.Stdin.Read(char)
if err != nil {
return "", err
}
if char[0] == 3 || char[0] == 4 {
return "", fmt.Errorf("keyboard interupt")
} else if char[0] == '\r' || char[0] == '\n' {
fmt.Println()
break
} else if char[0] == '\b' || char[0] == 127 {
if len(password) > 0 {
password = password[:len(password)-1]
fmt.Print("\b \b")
}
} else {
password = append(password, char[0])
fmt.Print("*")
}
}
fmt.Print("\r")
return string(password), nil
}

View File

@@ -10,8 +10,8 @@ var Args = os.Args[1:]
type stack = []ArObject
const VERSION = "3.0.8"
const VERSION_NUM = 6
const VERSION = "3.0.9"
const VERSION_NUM = 7
func newscope() ArObject {
return Map(anymap{})

View File

@@ -3,11 +3,22 @@ package main
import (
"fmt"
"os"
"os/signal"
"strings"
)
func shell(global ArObject) {
stack := stack{global, newscope()}
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
go func() {
for sig := range c {
if sig == os.Interrupt {
fmt.Println("\x1b[0m\n\x1b[32;5;240mBye :)\x1b[0m")
os.Exit(0)
}
}
}()
fmt.Print("\x1b[32;240mWelcome to the Argon v3!\x1b[0m\n\n")
for {
indent := 0