home *** CD-ROM | disk | FTP | other *** search
- ############################################################################
- #
- # File: slashbal.icn
- #
- # Subject: Procedure for balanced scanning with backslash escaping
- #
- # Author: Richard L. Goerwitz
- #
- # Date: May 5, 1992
- #
- ###########################################################################
- #
- # Version: 1.12
- #
- ###########################################################################
- #
- # I am often frustrated at bal()'s inability to deal elegantly with
- # the common \backslash escaping convention (a way of telling UNIX
- # Bourne and C shells, for instance, not to interpret a given
- # character as a "metacharacter"). I recognize that bal()'s generic
- # behavior is a must, and so I wrote slashbal() to fill the gap.
- #
- # Slashbal behaves like bal, except that it ignores, for purposes of
- # balancing, any c2/c3 char which is preceded by a backslash. Note
- # that we are talking about internally represented backslashes, and
- # not necessarily the backslashes used in Icon string literals. If
- # you have "\(" in your source code, the string produced will have no
- # backslash. To get this effect, you would need to write "\\(."
- #
- # BUGS: Note that, like bal() (v8), slashbal() cannot correctly
- # handle cases where c2 and c3 intersect. Note also that older ver-
- # sions of this routine counted from the beginning of the string,
- # instead of from i. This feature came to be regarded as a bug when
- # put into actual use (especially when I realized that bal() doesn't
- # work this way).
- #
- ############################################################################
-
- procedure slashbal(c1, c2, c3, s, i, j)
-
- local twocs, allcs, default_val, POS, chr2, count, chr
-
- /c1 := &cset
- /c2 := '('
- /c3 := ')'
- twocs := c2 ++ c3
- allcs := c1 ++ c2 ++ c3 ++ '\\'
-
- if /s := &subject
- then default_val := &pos
- else default_val := 1
-
- if \i then {
- if i < 1 then
- i := *s + (i+1)
- }
- else i := default_val
- if \j then {
- if j < 1 then
- j := *s + (j+1)
- }
- else j := *s + 1
-
- count := 0; POS := i - 1
- s[i:j] ? {
- while tab(upto(allcs)) do {
- chr := move(1)
- if chr == "\\" & any(twocs) then {
- chr2 := move(1)
- if any(c1, chr) & count = 0 then
- suspend POS + .&pos - 2
- if any(c1, chr2) & count = 0 then
- suspend POS + .&pos - 1
- }
- else {
- if any(c1, chr) & count = 0 then
- suspend POS + .&pos - 1
- if any(c2, chr) then
- count +:= 1
- else if any(c3, chr) & count > 0 then
- count -:= 1
- }
- }
- }
-
- end
-