Support hex characters in format strings

This commit is contained in:
Allan Odgaard
2013-08-27 00:03:11 +02:00
parent 6af97e5f51
commit e1230653f8
2 changed files with 39 additions and 6 deletions

View File

@@ -1,6 +1,7 @@
#include "parser.h"
#include "parser_base.h"
#include <text/format.h>
#include <text/utf8.h>
#include <oak/oak.h>
/*
@@ -24,7 +25,7 @@
$0-n
\U, \L, \E, \u, \l
\n, \t
\t, \r, \n, \x{HHHH}, \xHH
«variables»
@@ -238,15 +239,33 @@ bool parse_context_t::parse_case_change (nodes_t& nodes)
bool parse_context_t::parse_control_code (nodes_t& nodes)
{
char const* backtrack = it;
if(parse_char("\\") && parse_char("trn"))
if(parse_char("\\") && parse_char("trnx"))
{
switch(it[-1])
{
case 't': text_node(nodes) += '\t'; break;
case 'r': text_node(nodes) += '\r'; break;
case 'n': text_node(nodes) += '\n'; break;
case 't': text_node(nodes) += '\t'; return true;
case 'r': text_node(nodes) += '\r'; return true;
case 'n': text_node(nodes) += '\n'; return true;
case 'x':
{
std::string value;
if(parse_char("{") && parse_until("}", value))
{
if(value.size() <= 8 && std::find_if_not(value.begin(), value.end(), isxdigit) == value.end())
{
text_node(nodes) += utf8::to_s(std::stoul(value, nullptr, 16));
return true;
}
}
else if(it != last && it+1 != last && isxdigit(it[0]) && isxdigit(it[1]))
{
text_node(nodes) += digittoint(it[0]) << 4 | digittoint(it[1]);
it += 2;
return true;
}
}
break;
}
return true;
}
return it = backtrack, false;
}

View File

@@ -54,3 +54,17 @@ void test_escape_format_string ()
OAK_ASSERT_EQ(expand(escape("Escape\\\\me")), "Escape\\\\me");
OAK_ASSERT_EQ(expand(escape("(?1:baz: buz)")), "(?1:baz: buz)");
}
void test_control_codes ()
{
using format_string::expand;
OAK_ASSERT_EQ("\t", expand("\\t"));
OAK_ASSERT_EQ("\r", expand("\\r"));
OAK_ASSERT_EQ("\n", expand("\\n"));
OAK_ASSERT_EQ("\\x", expand("\\x"));
OAK_ASSERT_EQ("\\x{foo}", expand("\\x{foo}"));
OAK_ASSERT_EQ("\u2014", expand("\\x{2014}"));
OAK_ASSERT_EQ("\U00020EF5", expand("\\x{20EF5}"));
OAK_ASSERT_EQ("\U0010FFFF", expand("\\x{0010FFFF}"));
OAK_ASSERT_EQ("Æblegrød", expand("\\xc3\\x86blegr\\xC3\\xB8d"));
}