Skip to content

Commit

Permalink
Fix empty line comment crash, remote plugin retry send, ack remote co…
Browse files Browse the repository at this point in the history
…mmands, file test case
  • Loading branch information
genotrance committed May 15, 2019
1 parent f8f5f12 commit 72cfeee
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 41 deletions.
37 changes: 31 additions & 6 deletions feudc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import cligen, os, rdstdin, strformat, strutils

import "."/src/[globals, plugin, utils]

const
err = "Failed to send through channel locally"

var
gCh: Channel[string]

Expand All @@ -11,11 +14,29 @@ proc handleCommand(ctx: var Ctx, command: string): bool =
let
(cmd, val) = command.splitCmd()

if cmd == "runHook":
return true

ctx.cmdParam = if val.len != 0: @[val] else: @[]
if not ctx.handlePluginCommand(cmd):
ctx.cmdParam = @[command]
discard ctx.handlePluginCommand("sendRemote")

proc handleAck(ctx: var Ctx, command: string) =
let
(cmd, val) = command.splitCmd()
valI = parseInt(val)
for i in 0 .. valI-1:
for j in 0 .. 100:
discard handleCommand(ctx, "getAck")
if ctx.cmdParam.len != 0:
break
ctx.syncPlugins()
sleep(100)
if ctx.cmdParam.len == 0:
echo "Not all commands ack'd"
quit(1)

proc messageLoop(ctx: var Ctx) =
var
run = executing
Expand All @@ -24,10 +45,12 @@ proc messageLoop(ctx: var Ctx) =
let (ready, command) = gCh.tryRecv()

if ready:
discard handleCommand(ctx, command)

if command == "fexit":
run = stopped
elif command.startsWith("ack "):
ctx.handleAck(command)
else:
discard handleCommand(ctx, command)

ctx.syncPlugins()

Expand All @@ -43,7 +66,7 @@ proc initCmd() =
command = readLineFromStdin("feud> ")

if command.len != 0:
doAssert gCh.trySend(command), "Failed to send over channel"
doAssert gCh.trySend(command), err

if command == "fexit":
run = stopped
Expand Down Expand Up @@ -78,14 +101,16 @@ proc main(
while not ctx.ready:
ctx.syncPlugins()

discard ctx.handleCommand(ctx, &"initRemote dial {server}")
discard handleCommand(ctx, &"initRemote dial {server}")

if command.len == 0:
createThread(thread, initCmd)
else:
for cmd in command:
doAssert gCh.trySend(cmd), "Failed to send through channel locally"
doAssert gCh.trySend("fexit"), "Failed to send through channel locally"
doAssert gCh.trySend(cmd), err
if "quit" notin command and "exit" notin command:
doAssert gCh.trySend("ack " & $command.len), err
doAssert gCh.trySend("fexit"), err

ctx.messageLoop()

Expand Down
86 changes: 62 additions & 24 deletions plugins/remote.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import locks, os, strformat, strutils, tables
import deques, locks, os, strformat, strutils, tables

import "../src"/pluginapi

Expand All @@ -13,8 +13,9 @@ type
Remote = object
lock: Lock
run: bool
recvBuf: seq[string]
sendBuf: seq[string]
recvBuf: Deque[string]
sendBuf: Deque[string]
ack: int

proc getRemote(plg: var Plugin): ptr Remote =
return cast[ptr Remote](plg.pluginData)
Expand Down Expand Up @@ -44,16 +45,23 @@ proc monitorRemote(tparam: tuple[premote: ptr Remote, listen, dial: string]) {.t
if ret == 0:
if sz != 0:
withLock tparam.premote[].lock:
tparam.premote[].recvBuf.add $buf
tparam.premote[].recvBuf.addLast $buf
buf.nng_free(sz)
elif ret == NNG_ETIMEDOUT:
echo "Timed out"
elif ret == NNG_EAGAIN:
discard
else:
echo "Recv failed for some reason " & $ret

withLock tparam.premote[].lock:
for i in tparam.premote[].sendBuf:
ret = socket.nng_send(i.cstring, (i.len+1).cuint, NNG_FLAG_NONBLOCK.cint)
if tparam.premote[].sendBuf.len != 0:
tparam.premote[].sendBuf = @[]
buf = tparam.premote[].sendBuf.peekFirst()
ret = socket.nng_send(buf, (buf.len+1).cuint, NNG_FLAG_NONBLOCK.cint)
if ret notin [0, NNG_EAGAIN.int]:
echo "Send failed for some reason " & $ret
else:
discard tparam.premote[].sendBuf.popFirst()

sleep(100)

Expand Down Expand Up @@ -98,6 +106,8 @@ proc initRemote(plg: var Plugin) {.feudCallback.} =

premote[].lock.initLock()
premote[].run = true
premote[].recvBuf = initDeque[string]()
premote[].sendBuf = initDeque[string]()

if plg.ctx.cmdParam.len == 0:
if premoteCtx[].listen.len == 0:
Expand Down Expand Up @@ -125,20 +135,13 @@ proc readRemote(plg: var Plugin) =

var
premote = plg.getRemote()
mode = ""

withLock plg.ctx.pmonitor[].lock:
mode = plg.ctx.pmonitor[].path

plg.ctx.cmdParam = @[]
withLock premote[].lock:
for i in premote[].recvBuf:
if mode == "server":
discard plg.ctx.handleCommand(plg.ctx, $i)
else:
echo $i
for i in premote[].recvBuf.items:
plg.ctx.cmdParam.add $i

if premote[].recvBuf.len != 0:
premote[].recvBuf = @[]
premote[].recvBuf.clear()

proc sendRemote(plg: var Plugin) {.feudCallback.} =
if plg.pluginData.isNil:
Expand All @@ -149,28 +152,63 @@ proc sendRemote(plg: var Plugin) {.feudCallback.} =

if plg.ctx.cmdParam.len != 0:
withLock premote[].lock:
premote[].sendBuf.add plg.ctx.cmdParam[0]
premote[].sendBuf.addLast plg.ctx.cmdParam[0]

proc notifyClient(plg: var Plugin) =
plg.ctx.cmdParam = @[]

proc getAck(plg: var Plugin) {.feudCallback.} =
if plg.pluginData.isNil:
return

var
premote = plg.getRemote()

plg.ctx.cmdParam = @[]
withLock premote[].lock:
if premote[].ack > 0:
premote[].ack -= 1
plg.ctx.cmdParam = @["ack"]

proc notifyClient(plg: var Plugin) =
if plg.pluginData.isNil:
return

var
mode = ""

withLock plg.ctx.pmonitor[].lock:
mode = plg.ctx.pmonitor[].path

if plg.ctx.cmdParam.len != 0:
if mode == "remote":
withLock premote[].lock:
premote[].sendBuf.add plg.ctx.cmdParam[0]
if mode == "server":
plg.sendRemote()

feudPluginLoad()

feudPluginTick:
if plg.pluginData.isNil:
return

var
premote = plg.getRemote()
mode = ""

withLock plg.ctx.pmonitor[].lock:
mode = plg.ctx.pmonitor[].path

plg.readRemote()
if plg.ctx.cmdParam.len != 0:
if mode == "server":
for i in plg.ctx.cmdParam:
discard plg.ctx.handleCommand(plg.ctx, i)
plg.ctx.cmdParam = @["ack"]
plg.sendRemote()
else:
for i in plg.ctx.cmdParam:
if i == "ack":
withLock premote[].lock:
premote[].ack += 1
else:
echo i

feudPluginNotify:
plg.notifyClient()
Expand Down
3 changes: 1 addition & 2 deletions plugins/server/buffer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ proc toggleComment(plg: var Plugin) {.feudCallback.} =
selEndLine -= 1
selEnd = plg.ctx.msg(plg.ctx, SCI_GETLINEENDPOSITION, selEndLine)

if selStart != selEnd:
if selStart < selEnd:
var
length = selEnd - selStart
data = alloc0(length+1)
Expand Down Expand Up @@ -53,4 +53,3 @@ proc toggleComment(plg: var Plugin) {.feudCallback.} =
feudPluginDepends(["config", "window"])

feudPluginLoad()

6 changes: 3 additions & 3 deletions tests/comment.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
let
cmds = @[
commentCmds = @[
"open feud.nim",
"eMsg SCI_SELECTALL",
"toggleComment",
Expand All @@ -9,10 +9,10 @@ let

exec "git checkout feud.nim"

cmds.execFeudC()
discard commentCmds.execFeudC()

doAssert gorgeEx("git diff ..\\feud.nim").output.len != 0, "File didn't change"

cmds.execFeudC()
discard commentCmds.execFeudC()

doAssert gorgeEx("git diff ..\\feud.nim").output.len == 0, "File didn't revert"
3 changes: 1 addition & 2 deletions tests/crash1.ini
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,4 @@ open 2
open 3
open 1
open 2
open 4
quit
open 4
17 changes: 17 additions & 0 deletions tests/file.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
let
newDoc = "tests\\newdoc.txt"

discard @[
"newDoc",
"eMsg SCI_APPENDTEXT 10 HelloWorld",
"saveAs " & newDoc,
"close"
].execFeudC()

doAssert newDoc.fileExists() == true, "Failed newDoc"
newDoc.rmFile()

doAssert @[
"open -r *.xml",
"closeAll"
].execFeudC().contains("langs.model.xml"), "Failed recursive open"
22 changes: 18 additions & 4 deletions tests/test.nims
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,32 @@ let
feudRun = "cmd /c start feud"
feudCRun = "cmd /c feudc"

proc execFeudC(cmds: seq[string]) =
proc execFeudC(cmds: seq[string]): string =
var
fCmd = feudCRun
exitCode = 0

for cmd in cmds:
fCmd &= " " & cmd.strip().quoteShell

exec fCmd
echo fCmd
(result, exitCode) = gorgeEx(fCmd)
echo result
if exitCode != 0:
quit(1)

proc execFeudC(cmd: string): string =
return execFeudC(@[cmd])

proc sleep(t: float) =
exec "sleep " & $t

exec feudRun
exec "sleep 2"
sleep(2)

include "."/comment
include "."/file

doAssert execFeudC("script tests/crash1.ini").contains("globals.nim"), "Failed crash1 test"

execFeudC(@["script tests/crash1.ini"])
discard execFeudC("quit")

0 comments on commit 72cfeee

Please sign in to comment.