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