summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThijs Schreijer <thijs@thijsschreijer.nl>2024-05-22 21:37:27 +0200
committerThijs Schreijer <thijs@thijsschreijer.nl>2024-05-22 21:37:27 +0200
commit2746189f0a504d5929f8aa69edcc116dbbeff105 (patch)
tree2176dde5a3b2a439eef175921c61fc1ec4b1be22
parentb1e250a00406f5268a773f7923bb14708567ce9f (diff)
downloadluasystem-2746189f0a504d5929f8aa69edcc116dbbeff105.zip
add tests for termbackup & termrestore
-rw-r--r--spec/04-term_spec.lua38
-rw-r--r--system/init.lua92
2 files changed, 84 insertions, 46 deletions
diff --git a/spec/04-term_spec.lua b/spec/04-term_spec.lua
index ba58fde..eb975b5 100644
--- a/spec/04-term_spec.lua
+++ b/spec/04-term_spec.lua
@@ -392,13 +392,45 @@ describe("Terminal:", function()
- pending("termbackup()", function()
+ describe("termbackup() & termrestore()", function()
- end)
+ -- this is all Lua code, so testing one platform should be good enough
+ win_it("creates and restores a backup", function()
+ local backup = system.termbackup()
+
+ local old_cp = assert(system.getconsoleoutputcp())
+ finally(function()
+ system.setconsoleoutputcp(old_cp) -- ensure we restore the original one
+ end)
+
+ -- get the console page...
+ local new_cp
+ if old_cp ~= 65001 then
+ new_cp = 65001 -- set to UTF8
+ else
+ new_cp = 850 -- another common one
+ end
+ -- change the console page...
+ local success, err = system.setconsoleoutputcp(new_cp)
+ assert.is_nil(err)
+ assert.is_true(success)
+ -- ... and check it
+ local updated_cp = assert(system.getconsoleoutputcp())
+ assert.equals(new_cp, updated_cp)
+
+ -- restore the console page
+ system.termrestore(backup)
+ local restored_cp = assert(system.getconsoleoutputcp())
+ assert.equals(old_cp, restored_cp)
+ end)
- pending("termrestore()", function()
+ it("termrestore() fails on bad input", function()
+ assert.has.error(function()
+ system.termrestore("invalid")
+ end, "arg #1 to termrestore, expected backup table, got string")
+ end)
end)
diff --git a/system/init.lua b/system/init.lua
index c232cd2..b9a4f6f 100644
--- a/system/init.lua
+++ b/system/init.lua
@@ -4,61 +4,67 @@
local sys = require 'system.core'
+do
+ local backup_mt = {}
+
+ --- Returns a backup of terminal setting for stdin/out/err.
+ -- Handles terminal/console flags, Windows codepage, and non-block flags on the streams.
+ -- Backs up terminal/console flags only if a stream is a tty.
+ -- @return table with backup of terminal settings
+ function sys.termbackup()
+ local backup = setmetatable({}, backup_mt)
+
+ if sys.isatty(io.stdin) then
+ backup.console_in = sys.getconsoleflags(io.stdin)
+ backup.term_in = sys.tcgetattr(io.stdin)
+ end
+ if sys.isatty(io.stdout) then
+ backup.console_out = sys.getconsoleflags(io.stdout)
+ backup.term_out = sys.tcgetattr(io.stdout)
+ end
+ if sys.isatty(io.stderr) then
+ backup.console_err = sys.getconsoleflags(io.stderr)
+ backup.term_err = sys.tcgetattr(io.stderr)
+ end
---- Returns a backup of terminal setting for stdin/out/err.
--- Handles terminal/console flags, Windows codepage, and non-block flags on the streams.
--- Backs up terminal/console flags only if a stream is a tty.
--- @return table with backup of terminal settings
-function sys.termbackup()
- local backup = {}
-
- if sys.isatty(io.stdin) then
- backup.console_in = sys.getconsoleflags(io.stdin)
- backup.term_in = sys.tcgetattr(io.stdin)
- end
- if sys.isatty(io.stdout) then
- backup.console_out = sys.getconsoleflags(io.stdout)
- backup.term_out = sys.tcgetattr(io.stdout)
- end
- if sys.isatty(io.stderr) then
- backup.console_err = sys.getconsoleflags(io.stderr)
- backup.term_err = sys.tcgetattr(io.stderr)
- end
+ backup.block_in = sys.getnonblock(io.stdin)
+ backup.block_out = sys.getnonblock(io.stdout)
+ backup.block_err = sys.getnonblock(io.stderr)
- backup.block_in = sys.getnonblock(io.stdin)
- backup.block_out = sys.getnonblock(io.stdout)
- backup.block_err = sys.getnonblock(io.stderr)
+ backup.consoleoutcodepage = sys.getconsoleoutputcp()
+ backup.consolecp = sys.getconsolecp()
- backup.consoleoutcodepage = sys.getconsoleoutputcp()
- backup.consolecp = sys.getconsolecp()
+ return backup
+ end
- return backup
-end
+ --- Restores terminal settings from a backup
+ -- @tparam table backup the backup of terminal settings, see `termbackup`.
+ -- @treturn boolean true
+ function sys.termrestore(backup)
+ if getmetatable(backup) ~= backup_mt then
+ error("arg #1 to termrestore, expected backup table, got " .. type(backup), 2)
+ end
---- Restores terminal settings from a backup
--- @tparam table backup the backup of terminal settings, see `termbackup`.
--- @treturn boolean true
-function sys.termrestore(backup)
- if backup.console_in then sys.setconsoleflags(io.stdin, backup.console_in) end
- if backup.term_in then sys.tcsetattr(io.stdin, sys.TCSANOW, backup.term_in) end
- if backup.console_out then sys.setconsoleflags(io.stdout, backup.console_out) end
- if backup.term_out then sys.tcsetattr(io.stdout, sys.TCSANOW, backup.term_out) end
- if backup.console_err then sys.setconsoleflags(io.stderr, backup.console_err) end
- if backup.term_err then sys.tcsetattr(io.stderr, sys.TCSANOW, backup.term_err) end
+ if backup.console_in then sys.setconsoleflags(io.stdin, backup.console_in) end
+ if backup.term_in then sys.tcsetattr(io.stdin, sys.TCSANOW, backup.term_in) end
+ if backup.console_out then sys.setconsoleflags(io.stdout, backup.console_out) end
+ if backup.term_out then sys.tcsetattr(io.stdout, sys.TCSANOW, backup.term_out) end
+ if backup.console_err then sys.setconsoleflags(io.stderr, backup.console_err) end
+ if backup.term_err then sys.tcsetattr(io.stderr, sys.TCSANOW, backup.term_err) end
- if backup.block_in ~= nil then sys.setnonblock(io.stdin, backup.block_in) end
- if backup.block_out ~= nil then sys.setnonblock(io.stdout, backup.block_out) end
- if backup.block_err ~= nil then sys.setnonblock(io.stderr, backup.block_err) end
+ if backup.block_in ~= nil then sys.setnonblock(io.stdin, backup.block_in) end
+ if backup.block_out ~= nil then sys.setnonblock(io.stdout, backup.block_out) end
+ if backup.block_err ~= nil then sys.setnonblock(io.stderr, backup.block_err) end
- if backup.consoleoutcodepage then sys.setconsoleoutputcp(backup.consoleoutcodepage) end
- if backup.consolecp then sys.setconsolecp(backup.consolecp) end
- return true
+ if backup.consoleoutcodepage then sys.setconsoleoutputcp(backup.consoleoutcodepage) end
+ if backup.consolecp then sys.setconsolecp(backup.consolecp) end
+ return true
+ end
end
-
do -- autotermrestore
local global_backup -- global backup for terminal settings