115 lines
2.9 KiB
PHP
115 lines
2.9 KiB
PHP
<?php
|
||
|
||
/*
|
||
* This file is part of Psy Shell.
|
||
*
|
||
* (c) 2012-2018 Justin Hileman
|
||
*
|
||
* For the full copyright and license information, please view the LICENSE
|
||
* file that was distributed with this source code.
|
||
*/
|
||
|
||
namespace Psy\Util;
|
||
|
||
/**
|
||
* String utility methods.
|
||
*
|
||
* @author ju1ius
|
||
*/
|
||
class Str
|
||
{
|
||
const UNVIS_RX = <<<'EOS'
|
||
/
|
||
\\(?:
|
||
((?:040)|s)
|
||
| (240)
|
||
| (?: M-(.) )
|
||
| (?: M\^(.) )
|
||
| (?: \^(.) )
|
||
)
|
||
/xS
|
||
EOS;
|
||
|
||
/**
|
||
* Decodes a string encoded by libsd's strvis.
|
||
*
|
||
* From `man 3 vis`:
|
||
*
|
||
* Use an ‘M’ to represent meta characters (characters with the 8th bit set),
|
||
* and use a caret ‘^’ to represent control characters (see iscntrl(3)).
|
||
* The following formats are used:
|
||
*
|
||
* \040 Represents ASCII space.
|
||
*
|
||
* \240 Represents Meta-space (  in HTML).
|
||
*
|
||
* \M-C Represents character ‘C’ with the 8th bit set.
|
||
* Spans characters ‘\241’ through ‘\376’.
|
||
*
|
||
* \M^C Represents control character ‘C’ with the 8th bit set.
|
||
* Spans characters ‘\200’ through ‘\237’, and ‘\377’ (as ‘\M^?’).
|
||
*
|
||
* \^C Represents the control character ‘C’.
|
||
* Spans characters ‘\000’ through ‘\037’, and ‘\177’ (as ‘\^?’).
|
||
*
|
||
* The other formats are supported by PHP's stripcslashes,
|
||
* except for the \s sequence (ASCII space).
|
||
*
|
||
* @param string $input The string to decode
|
||
*
|
||
* @return string
|
||
*/
|
||
public static function unvis($input)
|
||
{
|
||
$output = \preg_replace_callback(self::UNVIS_RX, 'self::unvisReplace', $input);
|
||
// other escapes & octal are handled by stripcslashes
|
||
return \stripcslashes($output);
|
||
}
|
||
|
||
/**
|
||
* Callback for Str::unvis.
|
||
*
|
||
* @param array $match The matches passed by preg_replace_callback
|
||
*
|
||
* @return string
|
||
*/
|
||
protected static function unvisReplace($match)
|
||
{
|
||
// \040, \s
|
||
if (!empty($match[1])) {
|
||
return "\x20";
|
||
}
|
||
// \240
|
||
if (!empty($match[2])) {
|
||
return "\xa0";
|
||
}
|
||
// \M-(.)
|
||
if (isset($match[3]) && $match[3] !== '') {
|
||
$chr = $match[3];
|
||
// unvis S_META1
|
||
$cp = 0200;
|
||
$cp |= \ord($chr);
|
||
|
||
return \chr($cp);
|
||
}
|
||
// \M^(.)
|
||
if (isset($match[4]) && $match[4] !== '') {
|
||
$chr = $match[4];
|
||
// unvis S_META | S_CTRL
|
||
$cp = 0200;
|
||
$cp |= ($chr === '?') ? 0177 : \ord($chr) & 037;
|
||
|
||
return \chr($cp);
|
||
}
|
||
// \^(.)
|
||
if (isset($match[5]) && $match[5] !== '') {
|
||
$chr = $match[5];
|
||
// unvis S_CTRL
|
||
$cp = 0;
|
||
$cp |= ($chr === '?') ? 0177 : \ord($chr) & 037;
|
||
|
||
return \chr($cp);
|
||
}
|
||
}
|
||
}
|