diff --git a/lib/read.cs.js b/lib/read.cs.js index b80ea15..cdc9c63 100644 --- a/lib/read.cs.js +++ b/lib/read.cs.js @@ -24,7 +24,7 @@ var })(), confLc = {}, key; - function decodeDOS(arg) { + function decodeArg(arg) { return arg.replace(/#(\d+);/g, function(str, charCode) { return String.fromCharCode(+charCode); }); @@ -47,7 +47,7 @@ var for (key in conf) { if (conf.hasOwnProperty(key) && conf[key] === 'string') { if (typeof options[key] !== 'string') { options[key] = ''; } - else if (options.encoded) { options[key] = decodeDOS(options[key]); } + else { options[key] = decodeArg(options[key]); } } } return options; @@ -55,8 +55,7 @@ var display: 'string', keyIn: 'boolean', hideEchoBack: 'boolean', - mask: 'string', - encoded: 'boolean' + mask: 'string' }); if (!options.hideEchoBack && !options.keyIn) { diff --git a/lib/read.ps1 b/lib/read.ps1 index b676e4b..c23098c 100644 --- a/lib/read.ps1 +++ b/lib/read.ps1 @@ -10,8 +10,7 @@ Param( [switch] $hideEchoBack, [string] $mask, [string] $limit, - [switch] $caseSensitive, - [switch] $encoded + [switch] $caseSensitive ) $ErrorActionPreference = 'Stop' # for cmdlet @@ -21,21 +20,19 @@ trap { exit 1 } -function decodeDOS ($arg) { +function decodeArg ($arg) { [Regex]::Replace($arg, '#(\d+);', { [char][int] $args[0].Groups[1].Value }) } $options = @{} -foreach ($arg in @('display', 'keyIn', 'hideEchoBack', 'mask', 'limit', 'caseSensitive', 'encoded')) { +foreach ($arg in @('display', 'keyIn', 'hideEchoBack', 'mask', 'limit', 'caseSensitive')) { $options.Add($arg, (Get-Variable $arg -ValueOnly)) } -if ($options.encoded) { - $argList = New-Object string[] $options.Keys.Count - $options.Keys.CopyTo($argList, 0) - foreach ($arg in $argList) { - if ($options[$arg] -is [string] -and $options[$arg]) - { $options[$arg] = decodeDOS $options[$arg] } - } +$argList = New-Object string[] $options.Keys.Count +$options.Keys.CopyTo($argList, 0) +foreach ($arg in $argList) { + if ($options[$arg] -is [string] -and $options[$arg]) + { $options[$arg] = decodeArg $options[$arg] } } [string] $inputTTY = '' @@ -59,7 +56,8 @@ function execWithTTY ($command, $getRes = $False) { } function writeTTY ($text) { - execWithTTY ('Write-Host ''' + ($text -replace '''', '''''') + ''' -NoNewline') + execWithTTY ('Write-Host (''' + + (($text -replace '''', '''''') -replace '\n', '''+"`n"+''') + ''') -NoNewline') } if ($options.display) { diff --git a/lib/read.sh b/lib/read.sh index cd34530..3c75ba3 100644 --- a/lib/read.sh +++ b/lib/read.sh @@ -4,17 +4,20 @@ # Copyright (c) 2015 anseki # Licensed under the MIT license. +decode_arg() { + printf '%s' "$(printf '%s' "$1" | perl -pe 's/#(\d+);/sprintf("%c", $1)/ge')" +} + # getopt(s) while [ $# -ge 1 ]; do arg="$(printf '%s' "$1" | grep -E '^-+[^-]+$' | tr '[A-Z]' '[a-z]' | tr -d '-')" case "$arg" in - 'display') shift; options_display="$1";; + 'display') shift; options_display="$(decode_arg "$1")";; 'keyin') options_keyIn=true;; 'hideechoback') options_hideEchoBack=true;; - 'mask') shift; options_mask="$1";; - 'limit') shift; options_limit="$1";; + 'mask') shift; options_mask="$(decode_arg "$1")";; + 'limit') shift; options_limit="$(decode_arg "$1")";; 'casesensitive') options_caseSensitive=true;; - 'encoded') options_encoded=true;; esac shift done @@ -29,6 +32,10 @@ reset_tty() { trap 'reset_tty' EXIT save_tty="$(stty --file=/dev/tty -g 2>/dev/null || stty -F /dev/tty -g 2>/dev/null || stty -f /dev/tty -g || exit $?)" +[ -z "$options_display" ] && [ "$options_keyIn" = true ] && \ + [ "$options_hideEchoBack" = true ] && [ -z "$options_mask" ] && silent=true +[ "$options_hideEchoBack" != true ] && [ "$options_keyIn" != true ] && is_cooked=true + write_tty() { # 2nd arg: enable escape sequence if [ "$2" = true ]; then printf '%b' "$1" >/dev/tty @@ -46,10 +53,6 @@ replace_allchars() { ( printf '%s' "$text" ) } -[ -z "$options_display" ] && [ "$options_keyIn" = true ] && \ - [ "$options_hideEchoBack" = true ] && [ -z "$options_mask" ] && silent=true -[ "$options_hideEchoBack" != true ] && [ "$options_keyIn" != true ] && is_cooked=true - if [ -n "$options_display" ]; then write_tty "$options_display" fi @@ -71,7 +74,9 @@ if [ "$options_keyIn" = true ] && [ -n "$options_limit" ]; then limit_ptn="$options_limit" else # Safe list - limit_ptn="$(printf '%s' "$options_limit" | sed 's/\([a-z]\)/\L\1\U\1/ig')" + # limit_ptn="$(printf '%s' "$options_limit" | sed 's/\([a-z]\)/\L\1\U\1/ig')" + # for compatibility of sed of GNU / POSIX, BSD. (tr too, maybe) + limit_ptn="$(printf '%s' "$options_limit" | perl -pe 's/([a-z])/lc($1) . uc($1)/ige')" fi fi diff --git a/lib/readline-sync.js b/lib/readline-sync.js index f7bdd95..8c0a4dc 100644 --- a/lib/readline-sync.js +++ b/lib/readline-sync.js @@ -228,7 +228,6 @@ function readlineExt(options) { } } if (IS_WIN && !process.env.PSModulePath) { // Windows Script Host - options.encoded = true; // Parsing args is DOS? // ScriptPW (Win XP and Server2003) needs TTY stream as STDIN. // In this case, If STDIN isn't TTY, an error is thrown. execOptions.stdio = [process.stdin]; @@ -296,7 +295,6 @@ function _execFileSync(options, execOptions) { password = shasum.digest('hex'); decipher = crypto.createDecipher(ALGORITHM_CIPHER, password); - if (IS_WIN) { options.encoded = true; } hostArgs = getHostArgs(options); if (IS_WIN) { shellPath = process.env.ComSpec || 'cmd.exe'; @@ -360,7 +358,7 @@ function _execFileSync(options, execOptions) { function getHostArgs(options) { // To send any text to crazy Windows shell safely. - function encodeDOS(arg) { + function encodeArg(arg) { return arg.replace(/[^\w\u0080-\uFFFF]/g, function(chr) { return '#' + chr.charCodeAt(0) + ';'; }); @@ -373,8 +371,7 @@ function getHostArgs(options) { if (options[optionName]) { args.push('--' + optionName); } } else if (conf[optionName] === 'string') { if (options[optionName]) { - args.push('--' + optionName, - options.encoded ? encodeDOS(options[optionName]) : options[optionName]); + args.push('--' + optionName, encodeArg(options[optionName])); } } }); @@ -385,8 +382,7 @@ function getHostArgs(options) { hideEchoBack: 'boolean', mask: 'string', limit: 'string', - caseSensitive: 'boolean', - encoded: 'boolean' // added by readlineExt, _execFileSync + caseSensitive: 'boolean' })); } @@ -422,13 +418,20 @@ function margeOptions() { if (optionsPart == null) { return options; } /* jshint eqnull:false */ + // ======== DEPRECATED ======== + if (optionsPart.hasOwnProperty('noEchoBack')) { + optionsPart.hideEchoBack = optionsPart.noEchoBack; + delete optionsPart.noEchoBack; + } + if (optionsPart.hasOwnProperty('noTrim')) { + optionsPart.keepWhitespace = optionsPart.noTrim; + delete optionsPart.noTrim; + } + // ======== /DEPRECATED ======== + if (!fromDefault) { optionNames = Object.keys(optionsPart); } optionNames.forEach(function(optionName) { var value; - // ======== DEPRECATED ======== - if (optionName === 'noEchoBack') { optionName = 'hideEchoBack'; } - else if (optionName === 'noTrim') { optionName = 'keepWhitespace'; } - // ======== /DEPRECATED ======== if (!optionsPart.hasOwnProperty(optionName)) { return; } value = optionsPart[optionName]; switch (optionName) { @@ -568,9 +571,9 @@ function placeholderInMessage(param, options) { text = values.join(values.length > 2 ? ', ' : suppressed ? ' / ' : '/'); break; case 'limitCount': - case 'limitCountNoZero': + case 'limitCountNotZero': text = options[options.hasOwnProperty('limitSrc') ? 'limitSrc' : 'limit'].length; - text = (text ? text : param === 'limitCountNoZero' ? '' : text) + ''; + text = (text ? text : param === 'limitCountNotZero' ? '' : text) + ''; break; } return text;