Generate correct C literals for non-ascii characters

This commit is contained in:
Max Brunsfeld 2014-09-28 18:27:47 -07:00
parent cb5ecbd491
commit 070dc76050
4 changed files with 35 additions and 26 deletions

View file

@ -0,0 +1,27 @@
#include "compiler/compiler_spec_helper.h"
#include "compiler/util/string_helpers.h"
using namespace rules;
using util::escape_char;
START_TEST
describe("escape_char", []() {
it("returns ascii characters as strings", [&]() {
AssertThat(escape_char('x'), Equals("'x'"));
});
it("escapes special characters with backslashes", [&]() {
AssertThat(escape_char('\\'), Equals("'\\\\'"));
AssertThat(escape_char('\n'), Equals("'\\n'"));
AssertThat(escape_char('\t'), Equals("'\\t'"));
AssertThat(escape_char('\r'), Equals("'\\r'"));
AssertThat(escape_char('\''), Equals("'\\''"));
});
it("prints non-ascii characters as numbers", [&]() {
AssertThat(escape_char(256), Equals("256"));
});
});
END_TEST

View file

@ -1,4 +1,5 @@
#include "compiler/rules/character_range.h"
#include "compiler/util/string_helpers.h"
#include <algorithm>
#include <string>
@ -27,29 +28,11 @@ bool CharacterRange::operator<(const CharacterRange &other) const {
return false;
}
string escape_character(uint32_t input) {
if (input >= 255)
return to_string(input);
switch (input) {
case '\0':
return "\\0";
case '\n':
return "\\n";
case '\r':
return "\\r";
case '\t':
return "\\t";
default:
return string() + static_cast<char>(input);
}
}
string CharacterRange::to_string() const {
if (min == max)
return escape_character(min);
return util::escape_char(min);
else
return string() + escape_character(min) + "-" + escape_character(max);
return string() + util::escape_char(min) + "-" + util::escape_char(max);
}
ostream &operator<<(ostream &stream, const CharacterRange &range) {

View file

@ -7,6 +7,7 @@ namespace util {
using std::string;
using std::vector;
using std::set;
using std::to_string;
void str_replace(string *input, const string &search, const string &replace) {
size_t pos = 0;
@ -26,7 +27,7 @@ string escape_string(string input) {
return input;
}
string escape_char(char character) {
string escape_char(uint32_t character) {
switch (character) {
case '"':
return "'\\\"'";
@ -42,11 +43,9 @@ string escape_char(char character) {
return "'\\\\'";
default:
if (character >= ' ' && character <= '~') {
return string("'") + character + "'";
return string("'") + static_cast<char>(character) + "'";
} else {
char buffer[5];
snprintf(buffer, sizeof(buffer), "%d", static_cast<int>(character));
return string(buffer);
return to_string(character);
}
}
}

View file

@ -11,7 +11,7 @@ namespace util {
void str_replace(std::string *input, const std::string &search,
const std::string &replace);
std::string escape_string(std::string input);
std::string escape_char(char character);
std::string escape_char(uint32_t character);
} // namespace util
} // namespace tree_sitter