//[c]Utility functions to manipulate strings //[c] //[of]:license //[c] Code Browser - a folding text editor for programmers //[c] Copyright (C) 2003-07 Marc Kerbiquet //[c] //[c] This program is free software; you can redistribute it and/or modify //[c] it under the terms of the GNU General Public License as published by //[c] the Free Software Foundation; either version 2 of the License, or //[c] (at your option) any later version. //[c] //[c] This program is distributed in the hope that it will be useful, //[c] but WITHOUT ANY WARRANTY; without even the implied warranty of //[c] MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //[c] GNU General Public License for more details. //[c] //[c] You should have received a copy of the GNU General Public License //[c] along with this program; if not, write to the Free Software //[c] Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //[cf] //[of]:imports import "base/types" import "base/memory" import "base/memory-allocator" import "collection/dictionary" import "text/string" import "text/string-buffer" //[cf] //[of]:constants //[c] public equ escape code = $\ public equ field separator = $: //[cf] //[c] //[c]Escape - Unescape a String //[of]:unescape string (string buffer, string) //[c] public func unescape string (t: string buffer, s: string) def p = s repeat def c = p++[] if is nul (c) break end if c == escape code def d = p[] if d == $t c = \t ++p elsif d == escape code ++p end end t << c end end //[cf] //[of]:escape string (string buffer, string) //[c] public func escape string (t: string buffer, s: string) def p = s repeat def c = p++[] if is nul (c) break end if c == \t t << escape code c = $t elsif c == escape code t << escape code end t << c end end //[cf] //[c] //[c]Serialization - Deserialization //[of]:serialize (string buffer, string) //[c]Serializes a string //[c] public func serialize (t: string buffer, s: string) def p = s repeat def c = p++[] if is nul (c) break end if c == field separator t << escape code elsif c == escape code t << escape code end t << c end end //[cf] //[of]:unserialize (string buffer, string) //[c]Unserializes a string //[c] public func unserialize (t: string buffer, s: string) def p = s repeat def c = p++[] if is nul (c) -- p break elsif c == field separator break elsif c == escape code c = p++[] // unexpected end of line if is nul (c) return p - 1 end end t << c end return p end //[cf] //[c] //[c]Enumerate lines //[of]:each line (string) //[c] public equ each line (s: string) equ is end of line (a: char) = is nul (a) || a==\r || a==\n def p = s repeat def start = p def c: char repeat c = p[] if is end of line (c) break end ++p // skip lf if c == \r if p[] == \n ++p end end end yield (start, p-start) if is nul (p[]) break end // skip cr or lf ++p // skip lf if c == \r if p[] == \n ++p end end end end //[cf] //[of]:each line (string, size) //[c] public equ each line (s: string, size: size) def p = s def limit = s:[]byte + size equ is end of line (a: char) = a==\r || a==\n while p:[]byte < limit def start = p def c: char while p:[]byte < limit c = p[] if is end of line (c) break end ++p // skip lf if c == \r && p:[]byte < limit if p[] == \n ++p end end end yield (start, p-start) if p:[]byte < limit // skip cr or lf ++p // skip lf if c == \r && p:[]byte < limit if p[] == \n ++p end end end end end //[cf] //[c] //[c]Parsing //[of]:lexmatch (string1, string2) //[c]lexmatch - similar to 'start with' but returns false if the pattern is empty //[c] public func lexmatch (s: string, str: string) def size = size (str) if size == 0 return false end return is equal (s:mem, str:mem, size) end //[cf] //[c] //[c]Dictionary class for dictionaries where keys are string //[of]:string dictionary class public def string dictionary class = const dictionary class ( ^hash (string), ^is equal (string, string)) //[cf]