summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbpc2003 <wpesfriendnva@gmail.com>2025-05-24 13:32:57 -0400
committerbpc2003 <wpesfriendnva@gmail.com>2025-05-24 13:32:57 -0400
commit1a90e3410a9bdaf606a6124930a0913c07b44c87 (patch)
tree0c48ad326663b876ab44af37e5d2a0b8d95cca57
parentf8d0e88585226138b7b17e5f74105dd4abe63559 (diff)
Split builtin commands to separate modules
-rw-r--r--cmds/cd.go13
-rw-r--r--cmds/cmds.go37
-rw-r--r--cmds/cmds_test.go9
-rw-r--r--cmds/exit.go20
-rw-r--r--cmds/export.go18
-rw-r--r--cmds/set.go32
-rw-r--r--global/global.go7
-rw-r--r--main.go44
8 files changed, 135 insertions, 45 deletions
diff --git a/cmds/cd.go b/cmds/cd.go
new file mode 100644
index 0000000..66e5d5e
--- /dev/null
+++ b/cmds/cd.go
@@ -0,0 +1,13 @@
+package cmds
+
+import "os"
+
+func chDir(args []string) error {
+ var dir string
+ if len(args) == 1 {
+ dir, _ = os.UserHomeDir()
+ } else {
+ dir = args[1]
+ }
+ return os.Chdir(dir)
+}
diff --git a/cmds/cmds.go b/cmds/cmds.go
index f61f2b8..6d4d895 100644
--- a/cmds/cmds.go
+++ b/cmds/cmds.go
@@ -20,34 +20,25 @@ func Eval(cmd string) error {
}
break
case "unset":
- if len(args) == 1 || len(args) >= 3{
- return errors.New("unset: usage: name")
+ if len(args) == 1 || len(args) >= 3 {
+ return errors.New("usage: unset {name}")
}
os.Unsetenv(args[1])
break
+ case "set":
+ if len(args) > 1 {
+ set(args)
+ } else {
+ printenv()
+ }
+ break
+ case "exit":
+ if err := exit(args); err != nil {
+ return err
+ }
+ break
case ":":
return nil
}
return nil
}
-
-func chDir(args []string) error {
- var dir string
- if len(args) == 1 {
- dir, _ = os.UserHomeDir()
- } else {
- dir = args[1]
- }
- return os.Chdir(dir)
-}
-
-func export(args []string) error {
- if len(args) == 1 || len(args) >= 3 {
- return errors.New("export: usage: name=value")
- }
- tmp := strings.Split(args[1], "=")
- if len(tmp) != 2 {
- return errors.New("export: usage: name=value")
- }
- return os.Setenv(tmp[0], tmp[1])
-}
diff --git a/cmds/cmds_test.go b/cmds/cmds_test.go
index d59093a..33d6281 100644
--- a/cmds/cmds_test.go
+++ b/cmds/cmds_test.go
@@ -56,3 +56,12 @@ func TestUnset(t *testing.T) {
t.Errorf("Expected empty string, got %q\n", test)
}
}
+
+func TestExitFail(t *testing.T) {
+ err := Eval("exit abc")
+
+ if err == nil {
+ t.Errorf("Didn't get error\n")
+ }
+ t.Logf("%v\n", err)
+}
diff --git a/cmds/exit.go b/cmds/exit.go
new file mode 100644
index 0000000..a295ff4
--- /dev/null
+++ b/cmds/exit.go
@@ -0,0 +1,20 @@
+package cmds
+
+import (
+ "errors"
+ "os"
+ "strconv"
+)
+
+func exit(args []string) error {
+ status := 0
+ if len(args) > 1 {
+ var err error
+ status, err = strconv.Atoi(args[1])
+ if err != nil {
+ return errors.New("usage: exit (status)")
+ }
+ }
+ os.Exit(status)
+ return nil
+}
diff --git a/cmds/export.go b/cmds/export.go
new file mode 100644
index 0000000..1c2632d
--- /dev/null
+++ b/cmds/export.go
@@ -0,0 +1,18 @@
+package cmds
+
+import (
+ "errors"
+ "os"
+ "strings"
+)
+
+func export(args []string) error {
+ if len(args) == 1 || len(args) >= 3 {
+ return errors.New("usage: export {name=value}")
+ }
+ tmp := strings.Split(args[1], "=")
+ if len(tmp) != 2 {
+ return errors.New("usage: export {name=value}")
+ }
+ return os.Setenv(tmp[0], tmp[1])
+}
diff --git a/cmds/set.go b/cmds/set.go
new file mode 100644
index 0000000..a2bc3a6
--- /dev/null
+++ b/cmds/set.go
@@ -0,0 +1,32 @@
+package cmds
+
+import (
+ "fmt"
+ "os"
+
+ "gosh/global"
+)
+
+func printenv() {
+ vars := os.Environ()
+ for i := range vars {
+ fmt.Println(vars[i])
+ }
+ if len(global.Options) > 0 {
+ fmt.Printf("SH_OPTS=%v\n", global.Options)
+ }
+}
+
+func set(args []string) {
+ for i := 1; i < len(args); i++ {
+ if i-1 >= len(global.Options) {
+ global.Options = append(global.Options, args[i])
+ continue
+ }
+ global.Options[i-1] = args[i]
+ }
+
+ if len(args)-1 < len(global.Options) {
+ global.Options = global.Options[:len(args)-1]
+ }
+}
diff --git a/global/global.go b/global/global.go
new file mode 100644
index 0000000..610fa38
--- /dev/null
+++ b/global/global.go
@@ -0,0 +1,7 @@
+package global
+
+var Options []string
+
+func init() {
+ Options = make([]string, 0)
+}
diff --git a/main.go b/main.go
index 82f5bbf..52c7ba0 100644
--- a/main.go
+++ b/main.go
@@ -4,36 +4,36 @@ import (
"bufio"
"fmt"
"os"
- "os/exec"
- "path"
"strings"
+
+ "gosh/cmds"
)
func main() {
r := bufio.NewReader(os.Stdin)
- paths := strings.Split(os.Getenv("PATH"), ":")
for {
- found := false
- cmd, _ := r.ReadString('\n')
- args := strings.Split(strings.TrimSpace(cmd), " ")
- cmd = args[0]
-
- for i := range paths {
- if _, err := os.Stat(path.Join(paths[i], cmd)); err == nil {
- cmd = path.Join(paths[i], cmd)
- found = true
- break
- }
+ d, _ := os.Getwd()
+ fmt.Printf("gosh-0.1:%s$ ", abbr(d))
+ cmd, err := r.ReadString('\n')
+ if err != nil && err.Error() == "EOF" {
+ fmt.Println()
+ continue
}
- if found {
- c := exec.Command(cmd, args[1:]...)
- output, err := c.CombinedOutput()
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- continue
- }
- fmt.Print(string(output))
+
+ cmd = strings.TrimSuffix(cmd, "\n")
+ err = cmds.Eval(cmd)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
}
}
}
+
+func abbr(dir string) string {
+ home, _ := os.UserHomeDir()
+ if dir == home {
+ return "~"
+ }
+ dirs := strings.Split(dir, "/")
+ return dirs[len(dirs)-1]
+}