############################################################################ # # 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