Compare commits
4 Commits
d502efaeb1
...
15df6c4a82
Author | SHA1 | Date |
---|---|---|
Sekulum Forka | 15df6c4a82 | |
Sekulum Forka | 5ebbc60ccb | |
Sekulum Forka | 23592c5e15 | |
Sekulum Forka | b1c9159155 |
59
src/fsh.nim
59
src/fsh.nim
|
@ -7,6 +7,7 @@ import streams
|
|||
import osproc
|
||||
import strtabs
|
||||
import os
|
||||
import strutils
|
||||
|
||||
# globals
|
||||
var shellVariables = newStringTable(modeCaseSensitive)
|
||||
|
@ -16,6 +17,14 @@ var envVariables = newStringTable(modeCaseSensitive)
|
|||
for k, v in envPairs():
|
||||
envVariables[k]=v
|
||||
|
||||
# list of builtin commands
|
||||
let builtins: array[4, string] = [
|
||||
"set",
|
||||
"setenv",
|
||||
"echo",
|
||||
"exit",
|
||||
]
|
||||
|
||||
# forward declarations
|
||||
proc eval(cmd: string): string
|
||||
proc substitute(strm: Stream, delim = ";\p"): string
|
||||
|
@ -47,7 +56,7 @@ proc readLiteral(strm: Stream): string =
|
|||
# a forward declaration. Fuck this shit
|
||||
proc readSubstitution(strm: Stream): string
|
||||
|
||||
# readInterpelation reads the interpelation in etween [ and ]
|
||||
# readInterpelation reads the interpelation in between [ and ]
|
||||
proc readInterpelation(strm: Stream): string =
|
||||
while not strm.atEnd():
|
||||
let c = strm.readChar()
|
||||
|
@ -185,11 +194,57 @@ 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"
|
||||
of "exit":
|
||||
if args.len == 0:
|
||||
quit(0)
|
||||
elif args.len == 1:
|
||||
try:
|
||||
quit(args[0].parseInt)
|
||||
except ValueError:
|
||||
quit(0)
|
||||
else:
|
||||
try:
|
||||
let exitcode=args[0].parseInt
|
||||
if exitcode > 0:
|
||||
stderr.write(args[1..^1].join(" "), "\p")
|
||||
else:
|
||||
stdout.write(args[1..^1].join(" "), "\p")
|
||||
quit(exitcode)
|
||||
except ValueError:
|
||||
stdout.write(args.join(" "), "\p")
|
||||
quit(0)
|
||||
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 +254,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
|
||||
|
|
Loading…
Reference in New Issue