[colobot] 25/62: Add escape codes for string literals
Didier Raboud
odyx at moszumanska.debian.org
Fri Nov 10 11:53:56 UTC 2017
This is an automated email from the git hooks/post-receive script.
odyx pushed a commit to branch debian/master
in repository colobot.
commit c03dfc12848682fd0083f19706239381c659d991
Author: melex750 <melex750 at users.noreply.github.com>
Date: Sat Jul 22 14:29:05 2017 -0400
Add escape codes for string literals
---
po/colobot.pot | 18 ++++
po/de.po | 18 ++++
po/fr.po | 18 ++++
po/pl.po | 18 ++++
po/ru.po | 18 ++++
src/CBot/CBotEnums.h | 6 ++
src/CBot/CBotInstr/CBotExprLitString.cpp | 144 ++++++++++++++++++++++++++++---
src/CBot/CBotInstr/CBotExprLitString.h | 3 +
src/CBot/CBotToken.cpp | 25 ++----
src/CBot/CBotUtils.cpp | 45 ++++++++++
src/CBot/CBotUtils.h | 15 ++++
src/common/restext.cpp | 6 ++
test/unit/CBot/CBot_test.cpp | 114 ++++++++++++++++++++++++
13 files changed, 417 insertions(+), 31 deletions(-)
diff --git a/po/colobot.pot b/po/colobot.pot
index 509a3c7..419b88e 100644
--- a/po/colobot.pot
+++ b/po/colobot.pot
@@ -1770,6 +1770,24 @@ msgstr ""
msgid "This parameter needs a default value"
msgstr ""
+msgid "Missing end quote"
+msgstr ""
+
+msgid "Unknown escape sequence"
+msgstr ""
+
+msgid "Octal value out of range"
+msgstr ""
+
+msgid "Missing hex digits after escape sequence"
+msgstr ""
+
+msgid "Hex value out of range"
+msgstr ""
+
+msgid "Invalid universal character name"
+msgstr ""
+
msgid "Dividing by zero"
msgstr ""
diff --git a/po/de.po b/po/de.po
index 5e2f4a5..1c839a0 100644
--- a/po/de.po
+++ b/po/de.po
@@ -680,6 +680,9 @@ msgstr "Anweisungen über das ausgewählte Objekt"
msgid "Help balloons\\Explain the function of the buttons"
msgstr "Hilfeblasen\\Hilfeblasen"
+msgid "Hex value out of range"
+msgstr ""
+
#, fuzzy
msgid "Higher speed\\Doubles speed"
msgstr "Geschwindigkeit 2.0x\\Spielgeschwindigkeit doppelt so schnell"
@@ -759,6 +762,9 @@ msgstr "Anweisungen\\Anweisungen für die Mission oder Übung"
msgid "Internal error - tell the developers"
msgstr "Interner Fehler - Benachrichtige bitte die Entwickler"
+msgid "Invalid universal character name"
+msgstr ""
+
msgid "Invert\\Invert values on this axis"
msgstr "Invertieren\\Die Werte dieser Achse invertieren"
@@ -869,6 +875,12 @@ msgstr "Verkleinern"
msgid "Mipmap level\\Mipmap level"
msgstr "Mipmap-Level\\Mipmap-Level"
+msgid "Missing end quote"
+msgstr ""
+
+msgid "Missing hex digits after escape sequence"
+msgstr ""
+
msgid "Mission name"
msgstr "Name der Mission"
@@ -1031,6 +1043,9 @@ msgstr "OK\\Programm kompilieren"
msgid "Object too close"
msgstr "Gegenstand zu nahe"
+msgid "Octal value out of range"
+msgstr ""
+
msgid "One step"
msgstr "Ein Schritt"
@@ -1632,6 +1647,9 @@ msgstr "Das Objekt existiert nicht"
msgid "Unknown command"
msgstr "Befehl unbekannt"
+msgid "Unknown escape sequence"
+msgstr ""
+
msgid "Unknown function"
msgstr "Unbekannte Funktion"
diff --git a/po/fr.po b/po/fr.po
index 01ca9de..a287717 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -677,6 +677,9 @@ msgstr "Instructions sur la sélection"
msgid "Help balloons\\Explain the function of the buttons"
msgstr "Bulles d'aide\\Bulles explicatives"
+msgid "Hex value out of range"
+msgstr ""
+
#, fuzzy
msgid "Higher speed\\Doubles speed"
msgstr "Vitesse 2.0x\\Deux fois plus rapide"
@@ -756,6 +759,9 @@ msgstr "Instructions mission\\Marche à suivre"
msgid "Internal error - tell the developers"
msgstr "Erreur interne - contacter les développeurs"
+msgid "Invalid universal character name"
+msgstr ""
+
msgid "Invert\\Invert values on this axis"
msgstr "Inversion\\Inverse les valeurs sur cet axe"
@@ -866,6 +872,12 @@ msgstr "Taille réduite"
msgid "Mipmap level\\Mipmap level"
msgstr "Niveau de MIP mapping\\Niveau de MIP mapping"
+msgid "Missing end quote"
+msgstr ""
+
+msgid "Missing hex digits after escape sequence"
+msgstr ""
+
msgid "Mission name"
msgstr "Nom de la mission"
@@ -1028,6 +1040,9 @@ msgstr "D'accord\\Compiler le programme"
msgid "Object too close"
msgstr "Objet trop proche"
+msgid "Octal value out of range"
+msgstr ""
+
msgid "One step"
msgstr "Un pas"
@@ -1629,6 +1644,9 @@ msgstr "Objet n'existe pas"
msgid "Unknown command"
msgstr "Commande inconnue"
+msgid "Unknown escape sequence"
+msgstr ""
+
msgid "Unknown function"
msgstr "Routine inconnue"
diff --git a/po/pl.po b/po/pl.po
index 07a6328..bb28851 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -678,6 +678,9 @@ msgstr "Pomoc na temat zaznaczonego obiektu"
msgid "Help balloons\\Explain the function of the buttons"
msgstr "Dymki pomocy\\Wyjaśnia funkcje przycisków"
+msgid "Hex value out of range"
+msgstr ""
+
msgid "Higher speed\\Doubles speed"
msgstr "Zwiększ prędkość\\Podwaja prędkość"
@@ -756,6 +759,9 @@ msgstr "Rozkazy\\Pokazuje rozkazy dotyczące bieżącej misji"
msgid "Internal error - tell the developers"
msgstr "Błąd wewnętrzny - powiadom twórców gry"
+msgid "Invalid universal character name"
+msgstr ""
+
msgid "Invert\\Invert values on this axis"
msgstr "Odwróć\\Odwróć wartości na tej osi"
@@ -852,6 +858,12 @@ msgstr "Pomniejsz"
msgid "Mipmap level\\Mipmap level"
msgstr "Poziom mipmap\\Poziom mipmap"
+msgid "Missing end quote"
+msgstr ""
+
+msgid "Missing hex digits after escape sequence"
+msgstr ""
+
msgid "Mission name"
msgstr "Nazwa misji"
@@ -1014,6 +1026,9 @@ msgstr "OK\\Zamyka edytor programu i powraca do gry"
msgid "Object too close"
msgstr "Obiekt za blisko"
+msgid "Octal value out of range"
+msgstr ""
+
msgid "One step"
msgstr "Jeden krok"
@@ -1614,6 +1629,9 @@ msgstr "Obiekt nieznany"
msgid "Unknown command"
msgstr "Nieznane polecenie"
+msgid "Unknown escape sequence"
+msgstr ""
+
msgid "Unknown function"
msgstr "Funkcja nieznana"
diff --git a/po/ru.po b/po/ru.po
index fdcf909..f2b2535 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -686,6 +686,9 @@ msgstr "Справка о выбранном объекте"
msgid "Help balloons\\Explain the function of the buttons"
msgstr "Подсказки\\Объяснение функций кнопок"
+msgid "Hex value out of range"
+msgstr ""
+
#, fuzzy
msgid "Higher speed\\Doubles speed"
msgstr "Скорость 2.0х\\В два раза быстрее"
@@ -765,6 +768,9 @@ msgstr "Инструкции\\Показывает инструкции по т
msgid "Internal error - tell the developers"
msgstr "Внутренняя ошибка - сообщите разработчикам"
+msgid "Invalid universal character name"
+msgstr ""
+
msgid "Invert\\Invert values on this axis"
msgstr "Инвертир.\\Инвертировать значения по этой оси"
@@ -875,6 +881,12 @@ msgstr "Свернуть"
msgid "Mipmap level\\Mipmap level"
msgstr "Уровень уменьшающей фильтрации\\Уровень уменьшающей фильтрации"
+msgid "Missing end quote"
+msgstr ""
+
+msgid "Missing hex digits after escape sequence"
+msgstr ""
+
msgid "Mission name"
msgstr "Название миссии"
@@ -1039,6 +1051,9 @@ msgstr "ОК\\Закрыть редактор программ и вернуть
msgid "Object too close"
msgstr "Объект слишком близок"
+msgid "Octal value out of range"
+msgstr ""
+
msgid "One step"
msgstr "Один шаг"
@@ -1645,6 +1660,9 @@ msgstr "Неизвестный объект"
msgid "Unknown command"
msgstr "Неизвестная команда"
+msgid "Unknown escape sequence"
+msgstr ""
+
msgid "Unknown function"
msgstr "Неизвестная функция"
diff --git a/src/CBot/CBotEnums.h b/src/CBot/CBotEnums.h
index f98d4e9..fb701bc 100644
--- a/src/CBot/CBotEnums.h
+++ b/src/CBot/CBotEnums.h
@@ -241,6 +241,12 @@ enum CBotError : int
CBotErrNoClassName = 5046, //!< class name expected
CBotErrNoReturn = 5047, //!< non-void function needs "return;"
CBotErrDefaultValue = 5048, //!< this parameter needs a default value
+ CBotErrEndQuote = 5049, //!< missing end quote
+ CBotErrBadEscape = 5050, //!< unknown escape sequence
+ CBotErrOctalRange = 5051, //!< octal value out of range
+ CBotErrHexDigits = 5052, //!< missing hex digits after escape sequence
+ CBotErrHexRange = 5053, //!< hex value out of range
+ CBotErrUnicodeName = 5054, //!< invalid universal character name
// Runtime errors
CBotErrZeroDiv = 6000, //!< division by zero
diff --git a/src/CBot/CBotInstr/CBotExprLitString.cpp b/src/CBot/CBotInstr/CBotExprLitString.cpp
index ad85f7a..58d5fe1 100644
--- a/src/CBot/CBotInstr/CBotExprLitString.cpp
+++ b/src/CBot/CBotInstr/CBotExprLitString.cpp
@@ -42,15 +42,136 @@ CBotInstr* CBotExprLitString::Compile(CBotToken* &p, CBotCStack* pStack)
{
CBotCStack* pStk = pStack->TokenStack();
- CBotExprLitString* inst = new CBotExprLitString();
-
- inst->SetToken(p);
- p = p->GetNext();
-
- CBotVar* var = CBotVar::Create("", CBotTypString);
- pStk->SetVar(var);
-
- return pStack->Return(inst, pStk);
+ std::string s = p->GetString();
+
+ auto it = s.cbegin();
+ if (++it != s.cend())
+ {
+ int pos = p->GetStart();
+ std::string valstring = "";
+ while (it != s.cend() && *it != '\"')
+ {
+ pStk->SetStartError(++pos);
+ if (*it != '\\') // not escape sequence ?
+ {
+ valstring += *(it++);
+ continue;
+ }
+
+ if (++it == s.cend()) break;
+
+ if (CharInList(*it, "01234567")) // octal
+ {
+ std::string octal = "";
+
+ for (int i = 0; i < 3; i++)
+ {
+ if (!CharInList(*it, "01234567")) break;
+ ++pos;
+ octal += *it;
+ if (++it == s.cend()) break;
+ }
+
+ unsigned int val = std::stoi(octal, nullptr, 8);
+ if (val <= 255)
+ {
+ valstring.push_back(val);
+ continue;
+ }
+ pStk->SetError(CBotErrOctalRange, pos + 1);
+ }
+ else
+ {
+ ++pos;
+ unsigned char c = *(it++);
+ if (c == '\"' || c == '\'' || c == '\\') valstring += c;
+ else if (c == 'a') valstring += '\a'; // alert bell
+ else if (c == 'b') valstring += '\b'; // backspace
+ else if (c == 'f') valstring += '\f'; // form feed
+ else if (c == 'n') valstring += '\n'; // new line
+ else if (c == 'r') valstring += '\r'; // carriage return
+ else if (c == 't') valstring += '\t'; // horizontal tab
+ else if (c == 'v') valstring += '\v'; // vertical tab
+ else if (c == 'x' || c == 'u' || c == 'U') // hex or unicode
+ {
+ if (it != s.cend())
+ {
+ std::string hex = "";
+ bool isHexCode = (c == 'x');
+ size_t maxlen = (c == 'u') ? 4 : 8;
+
+ for (size_t i = 0; isHexCode || i < maxlen; i++)
+ {
+ if (!CharInList(*it, "0123456789ABCDEFabcdef")) break;
+ ++pos;
+ hex += *it;
+ if (++it == s.cend()) break;
+ }
+
+ if (!hex.empty())
+ {
+ unsigned int val = 0;
+ try
+ {
+ val = std::stoi(hex, nullptr, 16);
+ }
+ catch (const std::out_of_range& e)
+ {
+ pStk->SetError(CBotErrHexRange, pos + 1);
+ }
+
+ if (pStk->IsOk())
+ {
+ if (isHexCode) // hexadecimal
+ {
+ if (val <= 255)
+ {
+ valstring.push_back(val);
+ continue;
+ }
+ pStk->SetError(CBotErrHexRange, pos + 1);
+ }
+ else if (maxlen == hex.length()) // unicode character
+ {
+ if (val < 0xD800 || (0xDFFF < val && val < 0x110000))
+ {
+ valstring += CodePointToUTF8(val);
+ continue;
+ }
+ pStk->SetError(CBotErrUnicodeName, pos + 1);
+ }
+ }
+ }
+ }
+
+ pStk->SetError(CBotErrHexDigits, pos + 1);
+ }
+ else
+ pStk->SetError(CBotErrBadEscape, pos + 1); // unknown escape code
+ }
+
+ if (!pStk->IsOk()) break;
+ }
+
+ if (it == s.cend() || *it != '\"')
+ pStk->SetError(CBotErrEndQuote, p);
+
+ if (pStk->IsOk())
+ {
+ CBotExprLitString* inst = new CBotExprLitString();
+ inst->m_valstring.swap(valstring);
+ inst->SetToken(p);
+ p = p->GetNext();
+
+ CBotVar* var = CBotVar::Create("", CBotTypString);
+ pStk->SetVar(var);
+
+ return pStack->Return(inst, pStk);
+ }
+ }
+
+ pStk->SetError(CBotErrEndQuote, p);
+ return pStack->Return(nullptr, pStk);
}
////////////////////////////////////////////////////////////////////////////////
@@ -62,10 +183,7 @@ bool CBotExprLitString::Execute(CBotStack* &pj)
CBotVar* var = CBotVar::Create("", CBotTypString);
- std::string chaine = m_token.GetString();
- chaine = chaine.substr(1, chaine.length()-2); // removes the quotes
-
- var->SetValString(chaine); // value of the number
+ var->SetValString(m_valstring);
pile->SetVar(var); // put on the stack
diff --git a/src/CBot/CBotInstr/CBotExprLitString.h b/src/CBot/CBotInstr/CBotExprLitString.h
index 4336dd1..55c3965 100644
--- a/src/CBot/CBotInstr/CBotExprLitString.h
+++ b/src/CBot/CBotInstr/CBotExprLitString.h
@@ -58,6 +58,9 @@ public:
protected:
virtual const std::string GetDebugName() override { return "CBotExprLitString"; }
virtual std::string GetDebugData() override;
+
+private:
+ std::string m_valstring = "";
};
} // namespace CBot
diff --git a/src/CBot/CBotToken.cpp b/src/CBot/CBotToken.cpp
index d9e33ff..3c4bc7d 100644
--- a/src/CBot/CBotToken.cpp
+++ b/src/CBot/CBotToken.cpp
@@ -241,23 +241,13 @@ void CBotToken::SetPos(int start, int end)
}
////////////////////////////////////////////////////////////////////////////////
-bool CharInList(const char c, const char* list)
-{
- int i = 0;
-
- while (true)
- {
- if (c == list[i++]) return true;
- if (list[i] == 0) return false;
- }
-}
-static char sep1[] = " \r\n\t,:()[]{}-+*/=;><!~^|&%.";
+static char sep1[] = " \r\n\t,:()[]{}-+*/=;><!~^|&%.\"\'?";
static char sep2[] = " \r\n\t"; // only separators
-static char sep3[] = ",:()[]{}-+*/=;<>!~^|&%."; // operational separators
+static char sep3[] = ",:()[]{}-+*/=;<>!~^|&%.?"; // operational separators
static char num[] = "0123456789"; // point (single) is tested separately
static char hexnum[] = "0123456789ABCDEFabcdef";
-static char nch[] = "\"\r\n\t"; // forbidden in chains
+static char nch[] = "\r\n\t"; // forbidden in chains
////////////////////////////////////////////////////////////////////////////////
CBotToken* CBotToken::NextToken(const char*& program, bool first)
@@ -278,14 +268,13 @@ CBotToken* CBotToken::NextToken(const char*& program, bool first)
// special case for strings
if (token[0] == '\"' )
{
- while (c != 0 && !CharInList(c, nch))
+ while (c != 0 && c != '\"' && !CharInList(c, nch))
{
if ( c == '\\' )
{
- c = *(program++); // next character
- if ( c == 'n' ) c = '\n';
- if ( c == 'r' ) c = '\r';
- if ( c == 't' ) c = '\t';
+ token += c;
+ c = *(program++);
+ if (c == 0 || CharInList(c, nch)) break;
}
token += c;
c = *(program++);
diff --git a/src/CBot/CBotUtils.cpp b/src/CBot/CBotUtils.cpp
index 4e28931..2bb4d8e 100644
--- a/src/CBot/CBotUtils.cpp
+++ b/src/CBot/CBotUtils.cpp
@@ -236,4 +236,49 @@ float GetNumFloat(const std::string& str)
return static_cast<float>(num);
}
+bool CharInList(const char c, const char* list)
+{
+ int i = 0;
+
+ while (list[i] != 0)
+ {
+ if (c == list[i++]) return true;
+ }
+
+ return false;
+}
+
+std::string CodePointToUTF8(unsigned int val)
+{
+ std::string s = "";
+
+ if (val < 0xD800 || (0xDFFF < val && val < 0x110000))
+ {
+ if (val < 0x80)
+ {
+ s.push_back(val);
+ }
+ else if (val < 0x800)
+ {
+ s.push_back(0xC0 + (val >> 6));
+ s.push_back(0x80 + (val & 0x3F));
+ }
+ else if (val < 0x10000)
+ {
+ s.push_back(0xE0 + (val >> 12));
+ s.push_back(0x80 + ((val >> 6) & 0x3F));
+ s.push_back(0x80 + (val & 0x3F));
+ }
+ else
+ {
+ s.push_back(0xF0 + (val >> 18));
+ s.push_back(0x80 + ((val >> 12) & 0x3F));
+ s.push_back(0x80 + ((val >> 6) & 0x3F));
+ s.push_back(0x80 + (val & 0x3F));
+ }
+ }
+
+ return s;
+}
+
} // namespace CBot
diff --git a/src/CBot/CBotUtils.h b/src/CBot/CBotUtils.h
index 418e10b..6db107a 100644
--- a/src/CBot/CBotUtils.h
+++ b/src/CBot/CBotUtils.h
@@ -96,6 +96,21 @@ long GetNumInt(const std::string& str);
*/
float GetNumFloat(const std::string& str);
+/*!
+ * \brief Search a null-terminated string for a char value.
+ * \param c The char to find.
+ * \param list The string to search.
+ * \return true if the char is found.
+ */
+bool CharInList(const char c, const char* list);
+
+/*!
+ * \brief Converts a Unicode code point to UTF-8 encoded character.
+ * \param val Code point value.
+ * \return UTF-8 encoded string or empty string.
+ */
+std::string CodePointToUTF8(unsigned int val);
+
template<typename T> class CBotLinkedList
{
public:
diff --git a/src/common/restext.cpp b/src/common/restext.cpp
index 3d16603..ac526af 100644
--- a/src/common/restext.cpp
+++ b/src/common/restext.cpp
@@ -731,6 +731,12 @@ void InitializeRestext()
stringsCbot[CBot::CBotErrNoClassName] = TR("Class name expected");
stringsCbot[CBot::CBotErrNoReturn] = TR("Non-void function needs \"return;\"");
stringsCbot[CBot::CBotErrDefaultValue] = TR("This parameter needs a default value");
+ stringsCbot[CBot::CBotErrEndQuote] = TR("Missing end quote");
+ stringsCbot[CBot::CBotErrBadEscape] = TR("Unknown escape sequence");
+ stringsCbot[CBot::CBotErrOctalRange] = TR("Octal value out of range");
+ stringsCbot[CBot::CBotErrHexDigits] = TR("Missing hex digits after escape sequence");
+ stringsCbot[CBot::CBotErrHexRange] = TR("Hex value out of range");
+ stringsCbot[CBot::CBotErrUnicodeName] = TR("Invalid universal character name");
stringsCbot[CBot::CBotErrZeroDiv] = TR("Dividing by zero");
stringsCbot[CBot::CBotErrNotInit] = TR("Variable not initialized");
diff --git a/test/unit/CBot/CBot_test.cpp b/test/unit/CBot/CBot_test.cpp
index 9e264e1..f94b72d 100644
--- a/test/unit/CBot/CBot_test.cpp
+++ b/test/unit/CBot/CBot_test.cpp
@@ -1533,6 +1533,120 @@ TEST_F(CBotUT, String)
" ASSERT(c == \"Colobot!\");\n"
"}\n"
);
+
+ ExecuteTest(
+ "extern void MissingEndQuote()\n"
+ "{\n"
+ " \"Colobot...\n"
+ "}\n",
+ CBotErrEndQuote
+ );
+}
+
+TEST_F(CBotUT, StringEscapeCodes)
+{
+ ExecuteTest(
+ "extern void HexEscapeCodes()\n"
+ "{\n"
+ " ASSERT(\" \\x07 \" == \" \\a \");\n"
+ " ASSERT(\" \\x08 \" == \" \\b \");\n"
+ " ASSERT(\" \\x09 \" == \" \\t \");\n"
+ " ASSERT(\" \\x0A \" == \" \\n \");\n"
+ " ASSERT(\" \\x0B \" == \" \\v \");\n"
+ " ASSERT(\" \\x0C \" == \" \\f \");\n"
+ " ASSERT(\" \\x0D \" == \" \\r \");\n"
+ " ASSERT(\" \\x22 \" == \" \\\" \");\n"
+ " ASSERT(\" \\x27 \" == \" \\\' \");\n"
+ " ASSERT(\" \\x5C \" == \" \\\\ \");\n"
+ " string test = \"\\x31 \\x32 \\x33\";\n"
+ " ASSERT(test == \"1 2 3\");\n"
+ "}\n"
+ "extern void OctalEscapeCodes()\n"
+ "{\n"
+ " ASSERT(\" \\000 \" == \" \\x00 \");\n"
+ " ASSERT(\" \\007 \" == \" \\x07 \");\n"
+ " ASSERT(\" \\010 \" == \" \\x08 \");\n"
+ " ASSERT(\" \\011 \" == \" \\x09 \");\n"
+ " ASSERT(\" \\012 \" == \" \\x0A \");\n"
+ " ASSERT(\" \\013 \" == \" \\x0B \");\n"
+ " ASSERT(\" \\014 \" == \" \\x0C \");\n"
+ " ASSERT(\" \\015 \" == \" \\x0D \");\n"
+ " ASSERT(\" \\042 \" == \" \\x22 \");\n"
+ " ASSERT(\" \\047 \" == \" \\x27 \");\n"
+ " ASSERT(\" \\134 \" == \" \\x5C \");\n"
+ " string test = \"\\101 \\102 \\103\";\n"
+ " ASSERT(test == \"A B C\");\n"
+ "}\n"
+ "extern void UnicodeEscapeCodesToUTF_8()\n"
+ "{\n"
+ " ASSERT(\" \\u0000 \" == \" \\0 \");\n"
+ " ASSERT(\" \\u0007 \" == \" \\a \");\n"
+ " ASSERT(\" \\u0008 \" == \" \\b \");\n"
+ " ASSERT(\" \\u0009 \" == \" \\t \");\n"
+ " ASSERT(\" \\u000A \" == \" \\n \");\n"
+ " ASSERT(\" \\u000B \" == \" \\v \");\n"
+ " ASSERT(\" \\u000C \" == \" \\f \");\n"
+ " ASSERT(\" \\u000D \" == \" \\r \");\n"
+ " ASSERT(\" \\u0022 \" == \" \\\" \");\n"
+ " ASSERT(\" \\u0027 \" == \" \\\' \");\n"
+ " ASSERT(\" \\u005C \" == \" \\\\ \");\n"
+ "\n"
+ " ASSERT(\"\\u00A9\" == \"\\xC2\\xA9\");\n"
+ " ASSERT(\"\\u00AE\" == \"\\xC2\\xAE\");\n"
+ " ASSERT(\"\\u262E\" == \"\\xE2\\x98\\xAE\");\n"
+ " ASSERT(\"\\u262F\" == \"\\xE2\\x98\\xAF\");\n"
+ " ASSERT(\"\\U0001F60E\" == \"\\xF0\\x9F\\x98\\x8E\");\n"
+ " ASSERT(\"\\U0001F61C\" == \"\\xF0\\x9F\\x98\\x9C\");\n"
+ " ASSERT(\"\\U0001F6E0\" == \"\\xF0\\x9F\\x9B\\xA0\");\n"
+ "}\n"
+ "extern void UnicodeMaxCharacterNameToUTF_8()\n"
+ "{\n"
+ " ASSERT(\"\\U0010FFFF\" == \"\\xF4\\x8F\\xBF\\xBF\");\n"
+ "}\n"
+ );
+}
+
+TEST_F(CBotUT, StringEscapeCodeErrors)
+{
+ ExecuteTest(
+ "extern void UnknownEscapeSequence()\n"
+ "{\n"
+ " \"Unknown: \\p \";\n"
+ "}\n",
+ CBotErrBadEscape
+ );
+
+ ExecuteTest(
+ "extern void MissingHexDigits()\n"
+ "{\n"
+ " \" \\x \";\n"
+ "}\n",
+ CBotErrHexDigits
+ );
+
+ ExecuteTest(
+ "extern void HexValueOutOfRange()\n"
+ "{\n"
+ " \" \\x100 \";\n"
+ "}\n",
+ CBotErrHexRange
+ );
+
+ ExecuteTest(
+ "extern void OctalValueOutOfRange()\n"
+ "{\n"
+ " \" \\400 \";\n"
+ "}\n",
+ CBotErrOctalRange
+ );
+
+ ExecuteTest(
+ "extern void BadUnicodeCharacterName()\n"
+ "{\n"
+ " \" \\U00110000 \";\n"
+ "}\n",
+ CBotErrUnicodeName
+ );
}
// TODO: not implemented, see issue #694
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/colobot.git
More information about the Pkg-games-commits
mailing list