mirror of
https://codeberg.org/scip/tablizer.git
synced 2025-12-18 21:11:03 +01:00
added
This commit is contained in:
125
vendor/github.com/glycerine/zygomys/zygo/system.go
generated
vendored
Normal file
125
vendor/github.com/glycerine/zygomys/zygo/system.go
generated
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
package zygo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var ShellCmd string = "/bin/bash"
|
||||
|
||||
func init() {
|
||||
SetShellCmd()
|
||||
}
|
||||
|
||||
// set ShellCmd as used by SystemFunction
|
||||
func SetShellCmd() {
|
||||
if runtime.GOOS == "windows" {
|
||||
ShellCmd = os.Getenv("COMSPEC")
|
||||
return
|
||||
}
|
||||
try := []string{"/usr/bin/bash"}
|
||||
if !FileExists(ShellCmd) {
|
||||
for i := range try {
|
||||
b := try[i]
|
||||
if FileExists(b) {
|
||||
ShellCmd = b
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sys is a builder. shell out, return the combined output.
|
||||
func SystemBuilder(env *Zlisp, name string, args []Sexp) (Sexp, error) {
|
||||
//P("SystemBuilder called with args='%#v'", args)
|
||||
return SystemFunction(env, name, args)
|
||||
}
|
||||
|
||||
func SystemFunction(env *Zlisp, name string, args []Sexp) (Sexp, error) {
|
||||
if len(args) == 0 {
|
||||
return SexpNull, WrongNargs
|
||||
}
|
||||
|
||||
flat, err := flattenToWordsHelper(args)
|
||||
if err != nil {
|
||||
return SexpNull, fmt.Errorf("flatten on '%#v' failed with error '%s'", args, err)
|
||||
}
|
||||
if len(flat) == 0 {
|
||||
return SexpNull, WrongNargs
|
||||
}
|
||||
|
||||
joined := strings.Join(flat, " ")
|
||||
cmd := ShellCmd
|
||||
|
||||
var out []byte
|
||||
if runtime.GOOS == "windows" {
|
||||
out, err = exec.Command(cmd, "/c", joined).CombinedOutput()
|
||||
} else {
|
||||
out, err = exec.Command(cmd, "-c", joined).CombinedOutput()
|
||||
}
|
||||
if err != nil {
|
||||
return SexpNull, fmt.Errorf("error from command: '%s'. Output:'%s'", err, string(Chomp(out)))
|
||||
}
|
||||
return &SexpStr{S: string(Chomp(out))}, nil
|
||||
}
|
||||
|
||||
// given strings/lists of strings with possible whitespace
|
||||
// flatten out to a array of SexpStr with no internal whitespace,
|
||||
// suitable for passing along to (system) / exec.Command()
|
||||
func FlattenToWordsFunction(env *Zlisp, name string, args []Sexp) (Sexp, error) {
|
||||
if len(args) == 0 {
|
||||
return SexpNull, WrongNargs
|
||||
}
|
||||
stringArgs, err := flattenToWordsHelper(args)
|
||||
if err != nil {
|
||||
return SexpNull, err
|
||||
}
|
||||
|
||||
// Now convert to []Sexp{SexpStr}
|
||||
res := make([]Sexp, len(stringArgs))
|
||||
for i := range stringArgs {
|
||||
res[i] = &SexpStr{S: stringArgs[i]}
|
||||
}
|
||||
return env.NewSexpArray(res), nil
|
||||
}
|
||||
|
||||
func flattenToWordsHelper(args []Sexp) ([]string, error) {
|
||||
stringArgs := []string{}
|
||||
|
||||
for i := range args {
|
||||
switch c := args[i].(type) {
|
||||
case *SexpStr:
|
||||
many := strings.Split(c.S, " ")
|
||||
stringArgs = append(stringArgs, many...)
|
||||
case *SexpSymbol:
|
||||
stringArgs = append(stringArgs, c.name)
|
||||
case *SexpPair:
|
||||
carry, err := ListToArray(c)
|
||||
if err != nil {
|
||||
return []string{}, fmt.Errorf("tried to convert list of strings to array but failed with error '%s'. Input was type %T / val = '%#v'", err, c, c)
|
||||
}
|
||||
moreWords, err := flattenToWordsHelper(carry)
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
stringArgs = append(stringArgs, moreWords...)
|
||||
default:
|
||||
return []string{}, fmt.Errorf("arguments to system must be strings; instead we have %T / val = '%#v'", c, c)
|
||||
}
|
||||
} // end i over args
|
||||
// INVAR: stringArgs has our flattened list.
|
||||
return stringArgs, nil
|
||||
}
|
||||
|
||||
func Chomp(by []byte) []byte {
|
||||
if len(by) > 0 {
|
||||
n := len(by)
|
||||
if by[n-1] == '\n' {
|
||||
return by[:n-1]
|
||||
}
|
||||
}
|
||||
return by
|
||||
}
|
||||
Reference in New Issue
Block a user