Builtins: Added set, setenv, and echo builtins

This commit is contained in:
Sekulum Forka 2021-05-12 14:44:24 +02:00
parent b1c9159155
commit 23592c5e15
1 changed files with 37 additions and 0 deletions

View File

@ -7,6 +7,7 @@ import streams
import osproc
import strtabs
import os
import strutils
# globals
var shellVariables = newStringTable(modeCaseSensitive)
@ -16,6 +17,13 @@ var envVariables = newStringTable(modeCaseSensitive)
for k, v in envPairs():
envVariables[k]=v
# list of builtin commands
let builtins: array[3, string] = [
"set",
"setenv",
"echo",
]
# forward declarations
proc eval(cmd: string): string
proc substitute(strm: Stream, delim = ";\p"): string
@ -185,11 +193,38 @@ proc parseCommand(cmd: string): seq[string] =
discard strm.skipSpaces()
else: newitem.add(c)
# runBuiltin runs a shell builtin
proc runBuiltin(builtin: string, args: openArray[string]): string =
case builtin:
of "set":
if args.len < 2:
raise newException(Exception, "Set: not enough arguments provided")
shellVariables[args[0]] = args[1..^1].join(" ")
return ""
of "setenv":
if args.len < 2:
raise newException(Exception, "setenv: Not enough arguments provided")
try:
envVariables[args[0]] = args[1..^1].join(":")
putEnv(args[0], args[1..^1].join(":"))
except OSError as e:
raise newException(Exception, "setenv: " & e.msg)
return ""
of "echo":
if args[0] == "-n":
return args[1..^1].join(" ")
return args.join(" ") & "\p"
else:
raise newException(Exception, "Fsh: No such builtin implemented")
# executes executes the command. For now it involves catting the command and printing it
proc execute(cmd: string): int =
let parsed = cmd.parseCommand
let progname = parsed[0]
let args = parsed[1..parsed.high]
if progname in builtins:
stdout.write(runBuiltin(progname, args))
return 0
let ps = startProcess(progname, args=args, options={poUsePath, poParentStreams})
result = ps.waitForExit
ps.close
@ -199,6 +234,8 @@ proc eval(cmd: string): string =
let parsed = cmd.parseCommand
let progname=parsed[0]
let args = parsed[1..parsed.high]
if progname in builtins:
return runBuiltin(progname, args)
let ps = startProcess(progname, args=args, options={poUsePath})
result=ps.outputStream.readAll
ps.close