core :: Text :: escape_to_c
"
\
'
, trigraphs and non printable characters using the rules of literal C strings and charactersassert "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
of the octal sequence.
assert "{0.code_point}{1.code_point}{8.code_point}{31.code_point}{32.code_point}".escape_to_c == "\\000\\001\\010\\037 "
The exceptions are the common \t
and \n
.
# Escape `"` `\` `'`, trigraphs and non printable characters using the rules of literal C strings and characters
#
# ~~~
# 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
# of the octal sequence.
#
# ~~~
# assert "{0.code_point}{1.code_point}{8.code_point}{31.code_point}{32.code_point}".escape_to_c == "\\000\\001\\010\\037 "
# ~~~
#
# The exceptions are the common `\t` and `\n`.
fun escape_to_c: String
do
var b = new Buffer
for i in [0..length[ do
var c = chars[i]
if c == '\n' then
b.append("\\n")
else if c == '\t' then
b.append("\\t")
else if c == '"' then
b.append("\\\"")
else if c == '\'' then
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)
# Force 3 octal digits since it is the
# maximum allowed in the C specification
if oct.length == 1 then
b.add('0')
b.add('0')
else if oct.length == 2 then
b.add('0')
end
b.append(oct)
else
b.add(c)
end
end
return b.to_s
end
lib/core/text/abstract_text.nit:664,2--733,4
redef fun escape_to_c do
var ln_extra = chars_to_escape_to_c
if ln_extra == 0 then return self.to_s
var its = _items
var max = last_byte
var nlen = _byte_length + ln_extra
var nns = new CString(nlen)
var pos = first_byte
var opos = 0
while pos <= max do
var c = its[pos]
# Special codes:
#
# Any byte with value < 32 is a control character
# All their uses will be replaced by their octal
# value in C.
#
# There are two exceptions however:
#
# * 0x09 => \t
# * 0x0A => \n
#
# Aside from the code points above, the following are:
#
# * 0x22 => \"
# * 0x27 => \'
# * 0x5C => \\
if c == u'\t' then
nns[opos] = u'\\'
nns[opos + 1] = u't'
opos += 2
else if c == u'\n' then
nns[opos] = u'\\'
nns[opos + 1] = u'n'
opos += 2
else if c == u'"' then
nns[opos] = u'\\'
nns[opos + 1] = u'"'
opos += 2
else if c == u'\'' then
nns[opos] = u'\\'
nns[opos + 1] = u'\''
opos += 2
else if c == u'\\' then
nns[opos] = u'\\'
nns[opos + 1] = u'\\'
opos += 2
else if c == u'?' then
var j = pos + 1
if j < length then
var next = its[j]
# We ignore `??'` because it will be escaped as `??\'`.
if
next == 0x21 or
next == 0x28 or
next == 0x29 or
next == 0x2D or
next == 0x2F or
next == 0x3C or
next == 0x3D or
next == 0x3E
then
nns[opos] = 0x5C
opos += 1
end
end
nns[opos] = 0x3F
opos += 1
else if c < 32 then
nns[opos] = u'\\'
nns[opos + 1] = u'0'
nns[opos + 2] = ((c & 0x38) >> 3) + u'0'
nns[opos + 3] = (c & 0x07) + u'0'
opos += 4
else
nns[opos] = c
opos += 1
end
pos += 1
end
return nns.to_s_unsafe(nlen, copy=false, clean=false)
end
lib/core/text/flat.nit:245,2--326,4