Pass encoded values to External Program.

This commit is contained in:
anseki 2015-04-08 17:33:53 +09:00
parent cc0cfa5044
commit feb0cf4f5c
4 changed files with 43 additions and 38 deletions

View file

@ -24,7 +24,7 @@ var
})(), })(),
confLc = {}, key; confLc = {}, key;
function decodeDOS(arg) { function decodeArg(arg) {
return arg.replace(/#(\d+);/g, function(str, charCode) { return arg.replace(/#(\d+);/g, function(str, charCode) {
return String.fromCharCode(+charCode); return String.fromCharCode(+charCode);
}); });
@ -47,7 +47,7 @@ var
for (key in conf) { for (key in conf) {
if (conf.hasOwnProperty(key) && conf[key] === 'string') { if (conf.hasOwnProperty(key) && conf[key] === 'string') {
if (typeof options[key] !== 'string') { options[key] = ''; } if (typeof options[key] !== 'string') { options[key] = ''; }
else if (options.encoded) { options[key] = decodeDOS(options[key]); } else { options[key] = decodeArg(options[key]); }
} }
} }
return options; return options;
@ -55,8 +55,7 @@ var
display: 'string', display: 'string',
keyIn: 'boolean', keyIn: 'boolean',
hideEchoBack: 'boolean', hideEchoBack: 'boolean',
mask: 'string', mask: 'string'
encoded: 'boolean'
}); });
if (!options.hideEchoBack && !options.keyIn) { if (!options.hideEchoBack && !options.keyIn) {

View file

@ -10,8 +10,7 @@ Param(
[switch] $hideEchoBack, [switch] $hideEchoBack,
[string] $mask, [string] $mask,
[string] $limit, [string] $limit,
[switch] $caseSensitive, [switch] $caseSensitive
[switch] $encoded
) )
$ErrorActionPreference = 'Stop' # for cmdlet $ErrorActionPreference = 'Stop' # for cmdlet
@ -21,21 +20,19 @@ trap {
exit 1 exit 1
} }
function decodeDOS ($arg) { function decodeArg ($arg) {
[Regex]::Replace($arg, '#(\d+);', { [char][int] $args[0].Groups[1].Value }) [Regex]::Replace($arg, '#(\d+);', { [char][int] $args[0].Groups[1].Value })
} }
$options = @{} $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)) $options.Add($arg, (Get-Variable $arg -ValueOnly))
} }
if ($options.encoded) { $argList = New-Object string[] $options.Keys.Count
$argList = New-Object string[] $options.Keys.Count $options.Keys.CopyTo($argList, 0)
$options.Keys.CopyTo($argList, 0) foreach ($arg in $argList) {
foreach ($arg in $argList) { if ($options[$arg] -is [string] -and $options[$arg])
if ($options[$arg] -is [string] -and $options[$arg]) { $options[$arg] = decodeArg $options[$arg] }
{ $options[$arg] = decodeDOS $options[$arg] }
}
} }
[string] $inputTTY = '' [string] $inputTTY = ''
@ -59,7 +56,8 @@ function execWithTTY ($command, $getRes = $False) {
} }
function writeTTY ($text) { function writeTTY ($text) {
execWithTTY ('Write-Host ''' + ($text -replace '''', '''''') + ''' -NoNewline') execWithTTY ('Write-Host (''' +
(($text -replace '''', '''''') -replace '\n', '''+"`n"+''') + ''') -NoNewline')
} }
if ($options.display) { if ($options.display) {

View file

@ -4,17 +4,20 @@
# Copyright (c) 2015 anseki # Copyright (c) 2015 anseki
# Licensed under the MIT license. # Licensed under the MIT license.
decode_arg() {
printf '%s' "$(printf '%s' "$1" | perl -pe 's/#(\d+);/sprintf("%c", $1)/ge')"
}
# getopt(s) # getopt(s)
while [ $# -ge 1 ]; do while [ $# -ge 1 ]; do
arg="$(printf '%s' "$1" | grep -E '^-+[^-]+$' | tr '[A-Z]' '[a-z]' | tr -d '-')" arg="$(printf '%s' "$1" | grep -E '^-+[^-]+$' | tr '[A-Z]' '[a-z]' | tr -d '-')"
case "$arg" in case "$arg" in
'display') shift; options_display="$1";; 'display') shift; options_display="$(decode_arg "$1")";;
'keyin') options_keyIn=true;; 'keyin') options_keyIn=true;;
'hideechoback') options_hideEchoBack=true;; 'hideechoback') options_hideEchoBack=true;;
'mask') shift; options_mask="$1";; 'mask') shift; options_mask="$(decode_arg "$1")";;
'limit') shift; options_limit="$1";; 'limit') shift; options_limit="$(decode_arg "$1")";;
'casesensitive') options_caseSensitive=true;; 'casesensitive') options_caseSensitive=true;;
'encoded') options_encoded=true;;
esac esac
shift shift
done done
@ -29,6 +32,10 @@ reset_tty() {
trap 'reset_tty' EXIT 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 $?)" 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 write_tty() { # 2nd arg: enable escape sequence
if [ "$2" = true ]; then if [ "$2" = true ]; then
printf '%b' "$1" >/dev/tty printf '%b' "$1" >/dev/tty
@ -46,10 +53,6 @@ replace_allchars() { (
printf '%s' "$text" 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 if [ -n "$options_display" ]; then
write_tty "$options_display" write_tty "$options_display"
fi fi
@ -71,7 +74,9 @@ if [ "$options_keyIn" = true ] && [ -n "$options_limit" ]; then
limit_ptn="$options_limit" limit_ptn="$options_limit"
else else
# Safe list # 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
fi fi

View file

@ -228,7 +228,6 @@ function readlineExt(options) {
} }
} }
if (IS_WIN && !process.env.PSModulePath) { // Windows Script Host 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. // ScriptPW (Win XP and Server2003) needs TTY stream as STDIN.
// In this case, If STDIN isn't TTY, an error is thrown. // In this case, If STDIN isn't TTY, an error is thrown.
execOptions.stdio = [process.stdin]; execOptions.stdio = [process.stdin];
@ -296,7 +295,6 @@ function _execFileSync(options, execOptions) {
password = shasum.digest('hex'); password = shasum.digest('hex');
decipher = crypto.createDecipher(ALGORITHM_CIPHER, password); decipher = crypto.createDecipher(ALGORITHM_CIPHER, password);
if (IS_WIN) { options.encoded = true; }
hostArgs = getHostArgs(options); hostArgs = getHostArgs(options);
if (IS_WIN) { if (IS_WIN) {
shellPath = process.env.ComSpec || 'cmd.exe'; shellPath = process.env.ComSpec || 'cmd.exe';
@ -360,7 +358,7 @@ function _execFileSync(options, execOptions) {
function getHostArgs(options) { function getHostArgs(options) {
// To send any text to crazy Windows shell safely. // 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 arg.replace(/[^\w\u0080-\uFFFF]/g, function(chr) {
return '#' + chr.charCodeAt(0) + ';'; return '#' + chr.charCodeAt(0) + ';';
}); });
@ -373,8 +371,7 @@ function getHostArgs(options) {
if (options[optionName]) { args.push('--' + optionName); } if (options[optionName]) { args.push('--' + optionName); }
} else if (conf[optionName] === 'string') { } else if (conf[optionName] === 'string') {
if (options[optionName]) { if (options[optionName]) {
args.push('--' + optionName, args.push('--' + optionName, encodeArg(options[optionName]));
options.encoded ? encodeDOS(options[optionName]) : options[optionName]);
} }
} }
}); });
@ -385,8 +382,7 @@ function getHostArgs(options) {
hideEchoBack: 'boolean', hideEchoBack: 'boolean',
mask: 'string', mask: 'string',
limit: 'string', limit: 'string',
caseSensitive: 'boolean', caseSensitive: 'boolean'
encoded: 'boolean' // added by readlineExt, _execFileSync
})); }));
} }
@ -422,13 +418,20 @@ function margeOptions() {
if (optionsPart == null) { return options; } if (optionsPart == null) { return options; }
/* jshint eqnull:false */ /* 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); } if (!fromDefault) { optionNames = Object.keys(optionsPart); }
optionNames.forEach(function(optionName) { optionNames.forEach(function(optionName) {
var value; var value;
// ======== DEPRECATED ========
if (optionName === 'noEchoBack') { optionName = 'hideEchoBack'; }
else if (optionName === 'noTrim') { optionName = 'keepWhitespace'; }
// ======== /DEPRECATED ========
if (!optionsPart.hasOwnProperty(optionName)) { return; } if (!optionsPart.hasOwnProperty(optionName)) { return; }
value = optionsPart[optionName]; value = optionsPart[optionName];
switch (optionName) { switch (optionName) {
@ -568,9 +571,9 @@ function placeholderInMessage(param, options) {
text = values.join(values.length > 2 ? ', ' : suppressed ? ' / ' : '/'); text = values.join(values.length > 2 ? ', ' : suppressed ? ' / ' : '/');
break; break;
case 'limitCount': case 'limitCount':
case 'limitCountNoZero': case 'limitCountNotZero':
text = options[options.hasOwnProperty('limitSrc') ? 'limitSrc' : 'limit'].length; text = options[options.hasOwnProperty('limitSrc') ? 'limitSrc' : 'limit'].length;
text = (text ? text : param === 'limitCountNoZero' ? '' : text) + ''; text = (text ? text : param === 'limitCountNotZero' ? '' : text) + '';
break; break;
} }
return text; return text;