############################################################################
#
# File: escapesq.icn
#
# Subject: Procedures to deal with character string escapes
#
# Author: Robert J. Alexander
#
# Date: May 13, 1994
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# Procedure kit for dealing with escape sequences in Icon character
# string representations. Note that Icon escape sequences are
# very similar to C escapes, so this works for C strings, too.
#
# escapeseq() -- a matching procedure for Icon string escape sequences
#
# escchar() -- produces the character value of an Icon string escape sequence
#
# escape() -- converts a string with escape sequences (as in Icon string
# representation) to the string it represents with escape
#
# quotedstring() -- matching routine for a quoted string.
#
############################################################################
procedure escapeseq() # s
#
# Matching routine for Icon string escape sequence.
#
static oct,hex
initial {
oct := '01234567'
hex := '0123456789ABCDEFabcdef'
}
return (
="\\" ||
(
tab(any('bdeflnrtvBDEFLNRTV\'"\\')) |
tab(any(oct)) || (tab(any(oct)) | "") || (tab(any(oct)) | "") |
tab(any('xX')) || tab(any(hex)) || (tab(any(hex)) | "") |
="^" || move(1)
)
)
end
procedure escchar(s1) # s2
#
# Character value of Icon string escape sequence s1.
#
local c
s1 ? {
="\\"
return case c := map(move(1)) of {
"b": "\b" # backspace
"d": "\d" # delete (rubout)
"e": "\e" # escape (altmode)
"f": "\f" # formfeed
"l": "\l" # linefeed (newline)
"n": "\n" # newline (linefeed)
"r": "\r" # carriage return
"t": "\t" # horizontal tab
"v": "\v" # vertical tab
"x": escchar_convert(16,2) # hexadecimal code
"^": char(ord(move(1)) % 32) | &fail # control code
default: { # either octal code or non-escaped character
if any('01234567',c) then { # if octal digit
move(-1)
escchar_convert(8,3)
}
else c # else return escaped character
}
}
}
end
procedure escchar_convert(r,max)
#
# Private utility procedure used by escchar -- performs conversion
# of numeric character strings of radix "r", where 2 <= r <= 16.
# The procedure operates in a string scanning context, and will
# consume a maximum of "max" characters.
#
local n,d,i,c
d := "0123456789abcdef"[1:r + 1]
n := 0
every 1 to max do {
c := move(1) | break
if not (i := find(map(c),d) - 1) then {
move(-1)
break
}
n := n * r + i
}
return char(n)
end
procedure escape(s1) # s2
#
# Returns string s1 with escape sequences (as in Icon string
# representation) converted.
#
local esc
s1 ? {
s1 := ""
while s1 ||:= tab(find("\\")) do {
if esc := escapeseq() then s1 ||:= escchar(esc)
else move(1)
}
s1 ||:= tab(0)
}
return s1
end
procedure quotedstring() # s
#
# Matching routine for a quoted string.
#
suspend ="\"" || 1(tab(find("\"") + 1),&subject[&pos - 2] ~== "\\")
end
This page produced by UniDoc on 2021/04/15 @ 23:59:45.