-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
String literals now support proper escaping.
- Now these escape sequences are supported: \\, \", \', \n, \t - Previously "\"" would throw a syntax error. Now it is handled properly. - A literal "\n" (or others) can now be entered by double back-slashing the escape sequence like "\\n", which was previously not supported. - Unknown escape sequences, such as '\a' will now throw an error. - This is a BC break! - Solution for PR #21. - Handling escape sequences is now done outside of StringValue. It is merely a way of how a string literal is interpreted. This means that "\" + "n" will NOT result in a "\n" sequence and thus in a literal newline. This is a BC break, as far as I know. - New StringEscaping helper with methods: escapeString, unescapeString - Modified and added tests for this BC breaking behavior.
- Loading branch information
Showing
13 changed files
with
154 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<?php | ||
|
||
declare(strict_types = 1); | ||
|
||
namespace Smuuf\Primi\Helpers; | ||
|
||
use \Smuuf\Primi\ErrorException; | ||
|
||
class StringEscaping extends \Smuuf\Primi\StrictObject { | ||
|
||
/** | ||
* Escape sequences that are supported in string literals. | ||
* | ||
* Left side represents character after a backslash which together form a | ||
* supported escape sequence. Right side represents a result of such | ||
* sequence. | ||
* | ||
* @const | ||
*/ | ||
private const ESCAPE_PAIRS = [ | ||
'\\\\' => "\\", | ||
'\\n' => "\n", | ||
'\\t' => "\t", | ||
'\\"' => '"', | ||
"\\'" => "'", | ||
]; | ||
|
||
private const QUOTE_CHARS = ['"', "'"]; | ||
|
||
/** | ||
* Return the provided string but with known escape sequences being expanded | ||
* to their literal meaning. For example `\n` will be expanded to literal | ||
* new-line. | ||
*/ | ||
public static function unescapeString(string $str): string { | ||
|
||
return \preg_replace_callback('#(\\\\.)#', function($m) { | ||
|
||
$char = $m[1]; | ||
foreach (self::ESCAPE_PAIRS as $in => $out) { | ||
if ($char === $in) { | ||
return $out; | ||
} | ||
} | ||
|
||
// The backslashed character doesn't represent any known escape | ||
// sequence, therefore error. | ||
throw new ErrorException( | ||
"Unrecognized string escape sequence '{$m[0]}'." | ||
); | ||
|
||
}, $str); | ||
|
||
} | ||
|
||
/** | ||
* The string provided as an argument will be returned, but with added | ||
* escaping for characters that represent a known escape sequence. For | ||
* example a literal new-line will be replaced by `\n`. | ||
* | ||
* This is useful for converting a internal string value of StringValue to | ||
* a source code representaton of it - that is how a string literal would | ||
* have to be written by hand for it to be - as a result - interpreted as | ||
* that original string). | ||
* | ||
* If a third optional $quoteChar argument is passed, all other known | ||
* quote characters will NOT be escaped - only the one specified by the | ||
* third argument. The only known quote characters are `'` and `"`. For | ||
* example the string `hello'there"` without $quoteChar specified will | ||
* be escaped as `hello\'there\"`. But with $quoteChar being `"` it would | ||
* result in `hello'there\"`, since the caller used the third argument to | ||
* specify that the single-quote does NOT have to be escaped. | ||
*/ | ||
public static function escapeString( | ||
string $str, | ||
string $quoteChar = null | ||
): string { | ||
|
||
foreach (self::ESCAPE_PAIRS as $out => $in) { | ||
|
||
// $in = <new line> | ||
// $out = '\n' | ||
|
||
if ( | ||
$quoteChar !== null | ||
&& in_array($in, self::QUOTE_CHARS, true) | ||
&& $in !== $quoteChar | ||
) { | ||
// Do not escape quote characters that aren't necessary to be | ||
// escaped. | ||
continue; | ||
} | ||
|
||
$str = str_replace($in, $out, $str); | ||
|
||
} | ||
|
||
return $str; | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters