From 994ce224f1ecc787b1ced49a1420ec3c1103adf1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Christophe=20Beaupr=C3=A9?= Date: Mon, 6 Jun 2016 12:04:00 -0400 Subject: [PATCH] escape_to_c: Escape trigraphs MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Produce more standard-compliant code instead of relying on the default behaviour of gcc (or on its `-Wno-trigraphs` flag). See also: https://github.com/nitlang/nit/pull/1949/commits/000ac8de3c64790b0fbb0e868e406a6a280f3fa9 Signed-off-by: Jean-Christophe Beaupré --- lib/core/text/abstract_text.nit | 26 ++++++++++++++++++++++++-- lib/core/text/flat.nit | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/lib/core/text/abstract_text.nit b/lib/core/text/abstract_text.nit index d7dfa48..90b38b1 100644 --- a/lib/core/text/abstract_text.nit +++ b/lib/core/text/abstract_text.nit @@ -590,10 +590,13 @@ abstract class Text return res.to_s end - # Escape " \ ' and non printable characters using the rules of literal C strings and characters + # Escape `"` `\` `'`, trigraphs and non printable characters using the rules of literal C strings and characters # - # assert "abAB12<>&".escape_to_c == "abAB12<>&" + # assert "abAB12<>&".escape_to_c == "abAB12<>&" # assert "\n\"'\\".escape_to_c == "\\n\\\"\\'\\\\" + # assert "allo???!".escape_to_c == "allo??\\?!" + # assert "??=??/??'??(??)".escape_to_c == "?\\?=?\\?/??\\'?\\?(?\\?)" + # assert "??!????-".escape_to_c == "?\\?!?\\??\\?-" # # Most non-printable characters (bellow ASCII 32) are escaped to an octal form `\nnn`. # Three digits are always used to avoid following digits to be interpreted as an element @@ -617,6 +620,24 @@ abstract class Text b.append("\\\'") else if c == '\\' then b.append("\\\\") + else if c == '?' then + # Escape if it is the last question mark of a ANSI C trigraph. + var j = i + 1 + if j < length then + var next = chars[j] + # We ignore `??'` because it will be escaped as `??\'`. + if + next == '!' or + next == '(' or + next == ')' or + next == '-' or + next == '/' or + next == '<' or + next == '=' or + next == '>' + then b.add('\\') + end + b.add('?') else if c.code_point < 32 then b.add('\\') var oct = c.code_point.to_base(8) @@ -640,6 +661,7 @@ abstract class Text # The result might no be legal in C but be used in other languages # # assert "ab|\{\}".escape_more_to_c("|\{\}") == "ab\\|\\\{\\\}" + # assert "allo???!".escape_more_to_c("") == "allo??\\?!" fun escape_more_to_c(chars: String): String do var b = new Buffer diff --git a/lib/core/text/flat.nit b/lib/core/text/flat.nit index 9e70321..6273609 100644 --- a/lib/core/text/flat.nit +++ b/lib/core/text/flat.nit @@ -225,6 +225,22 @@ redef class FlatText req_esc += 1 else if c == 0x5Cu8 then req_esc += 1 + else if c == 0x3Fu8 then + var j = pos + 1 + if j < length then + var next = its[j] + # We ignore `??'` because it will be escaped as `??\'`. + if + next == 0x21u8 or + next == 0x28u8 or + next == 0x29u8 or + next == 0x2Du8 or + next == 0x2Fu8 or + next == 0x3Cu8 or + next == 0x3Du8 or + next == 0x3Eu8 + then req_esc += 1 + end else if c < 32u8 then req_esc += 3 end @@ -280,6 +296,27 @@ redef class FlatText nns[opos] = 0x5Cu8 nns[opos + 1] = 0x5Cu8 opos += 2 + else if c == 0x3Fu8 then + var j = pos + 1 + if j < length then + var next = its[j] + # We ignore `??'` because it will be escaped as `??\'`. + if + next == 0x21u8 or + next == 0x28u8 or + next == 0x29u8 or + next == 0x2Du8 or + next == 0x2Fu8 or + next == 0x3Cu8 or + next == 0x3Du8 or + next == 0x3Eu8 + then + nns[opos] = 0x5Cu8 + opos += 1 + end + end + nns[opos] = 0x3Fu8 + opos += 1 else if c < 32u8 then nns[opos] = 0x5Cu8 nns[opos + 1] = 0x30u8 -- 1.7.9.5