WIP: Waifufetch by JGH0 working in windows-bash
This commit is contained in:
@@ -70,7 +70,10 @@ func splitPipe(input string) []string {
|
||||
current.WriteByte(c)
|
||||
case c == '|' && !inSingle && !inDouble && parenDepth == 0:
|
||||
if i+1 < len(input) && input[i+1] == '|' {
|
||||
current.WriteByte(c) // part of ||, pass through
|
||||
// || operator — pass both chars through
|
||||
current.WriteByte(c)
|
||||
current.WriteByte(input[i+1])
|
||||
i++
|
||||
} else {
|
||||
parts = append(parts, strings.TrimSpace(current.String()))
|
||||
current.Reset()
|
||||
@@ -87,6 +90,63 @@ func splitPipe(input string) []string {
|
||||
return parts
|
||||
}
|
||||
|
||||
// parseArrayAssign detects NAME=(...) or NAME+=(...) at start of input.
|
||||
func (s *Shell) parseArrayAssign(input string) (name string, appendMode bool, elements []string, ok bool) {
|
||||
input = strings.TrimSpace(input)
|
||||
// Read identifier
|
||||
i := 0
|
||||
for i < len(input) && isVarChar(input[i]) {
|
||||
i++
|
||||
}
|
||||
if i == 0 {
|
||||
return
|
||||
}
|
||||
name = input[:i]
|
||||
if !isValidIdentifier(name) {
|
||||
return
|
||||
}
|
||||
// Optional +
|
||||
if i < len(input) && input[i] == '+' {
|
||||
appendMode = true
|
||||
i++
|
||||
}
|
||||
// Require =
|
||||
if i >= len(input) || input[i] != '=' {
|
||||
return
|
||||
}
|
||||
i++
|
||||
// Require (
|
||||
if i >= len(input) || input[i] != '(' {
|
||||
return
|
||||
}
|
||||
i++
|
||||
// Find matching )
|
||||
depth := 1
|
||||
j := i
|
||||
inSingle := false
|
||||
inDouble := false
|
||||
for j < len(input) && depth > 0 {
|
||||
c := input[j]
|
||||
switch {
|
||||
case c == '\'' && !inDouble:
|
||||
inSingle = !inSingle
|
||||
case c == '"' && !inSingle:
|
||||
inDouble = !inDouble
|
||||
case c == '(' && !inSingle && !inDouble:
|
||||
depth++
|
||||
case c == ')' && !inSingle && !inDouble:
|
||||
depth--
|
||||
}
|
||||
if depth > 0 {
|
||||
j++
|
||||
}
|
||||
}
|
||||
content := input[i:j]
|
||||
elements = s.tokenize(content)
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
// executeCommand executes a single command (no pipes, no &&/||).
|
||||
func (s *Shell) executeCommand(input string) error {
|
||||
input = strings.TrimSpace(input)
|
||||
@@ -94,12 +154,22 @@ func (s *Shell) executeCommand(input string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Detect array assignment NAME=(...) or NAME+=(...)
|
||||
if name, appendMode, elems, ok := s.parseArrayAssign(input); ok {
|
||||
if appendMode {
|
||||
s.appendArray(name, elems)
|
||||
} else {
|
||||
s.setArray(name, elems)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
tokens := s.tokenize(input)
|
||||
if len(tokens) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
cmdArgs, redirects := extractRedirects(tokens)
|
||||
cmdArgs, redirects := s.extractRedirects(tokens)
|
||||
if len(cmdArgs) == 0 {
|
||||
// Pure redirection, e.g. "> file" creates/truncates file
|
||||
return s.withRedirects(redirects, func() error { return nil })
|
||||
@@ -132,7 +202,7 @@ func (s *Shell) executeCommand(input string) error {
|
||||
})
|
||||
}
|
||||
|
||||
func extractRedirects(tokens []string) ([]string, []redirect) {
|
||||
func (s *Shell) extractRedirects(tokens []string) ([]string, []redirect) {
|
||||
var args []string
|
||||
var redirects []redirect
|
||||
|
||||
@@ -194,11 +264,24 @@ func extractRedirects(tokens []string) ([]string, []redirect) {
|
||||
case strings.HasPrefix(tok, ">") && len(tok) > 1:
|
||||
redirects = append(redirects, redirect{1, ">", tok[1:]})
|
||||
i++
|
||||
// < (stdin)
|
||||
// < (stdin) — also handle process substitution <(...)
|
||||
case tok == "<":
|
||||
if i+1 < len(tokens) {
|
||||
redirects = append(redirects, redirect{0, "<", tokens[i+1]})
|
||||
i += 2
|
||||
next := tokens[i+1]
|
||||
// Process substitution: < <(cmd)
|
||||
if strings.HasPrefix(next, "<(") && strings.HasSuffix(next, ")") {
|
||||
cmd := next[2 : len(next)-1]
|
||||
tmpf, err := os.CreateTemp("", "procsub*")
|
||||
if err == nil {
|
||||
s.withIO(nil, tmpf, nil, func() error { return s.Execute(cmd) })
|
||||
tmpf.Close()
|
||||
redirects = append(redirects, redirect{0, "<", tmpf.Name()})
|
||||
}
|
||||
i += 2
|
||||
} else {
|
||||
redirects = append(redirects, redirect{0, "<", next})
|
||||
i += 2
|
||||
}
|
||||
} else {
|
||||
i++
|
||||
}
|
||||
@@ -296,7 +379,7 @@ func (s *Shell) executeCommandBg(input string) error {
|
||||
if len(tokens) == 0 {
|
||||
return nil
|
||||
}
|
||||
cmdArgs, _ := extractRedirects(tokens)
|
||||
cmdArgs, _ := s.extractRedirects(tokens)
|
||||
if len(cmdArgs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user