#FEATURE by cg
class: CharacterArray class
added: #readSmalltalkStringFrom:keepCRs:onError:
comment/format in: #readSmalltalkStringFrom:onError:
changed: #readSmalltalkStringWithCRsFrom:onError:
--- a/CharacterArray.st Tue Feb 25 12:30:20 2020 +0100
+++ b/CharacterArray.st Tue Feb 25 14:06:32 2020 +0100
@@ -260,18 +260,25 @@
^ self basicNew:0
!
-readSmalltalkStringFrom:aStreamOrString onError:exceptionBlock
+readSmalltalkStringFrom:aStreamOrString keepCRs:keepCRs onError:exceptionBlock
"read & return the next String from the (character-)stream aStream;
skipping all whitespace first; return the value of exceptionBlock,
if no string can be read. The sequence of characters as read from the
- stream must be one as stored via storeOn: or storeString."
-
- |str collected char|
+ stream must be one as stored via storeOn: or storeString.
+ If keepCRs is true, CRLF is kept as is.
+ A variant of this code is also found in the Scanner class (libcomp);
+ however, libcomp is optional, whereas this is always present,
+ and string reading is needed for resource file and config file parsing (sigh)"
+
+ |str collected char withCEscapes|
str := aStreamOrString readStream.
"skip whiteSpace"
str skipSeparators.
+ (withCEscapes := (str peekOrNil == $c)) ifTrue:[
+ str next.
+ ].
(str peekOrNil == $') ifTrue:[
str next.
collected := self writeStream.
@@ -285,9 +292,31 @@
"eat doubled quote"
str next.
].
- ((char ~~ Character return) or:[str peekOrNil ~~ Character lf]) ifTrue:[
+ (withCEscapes and:[char == $\]) ifTrue:[
+ char := str nextOrNil ? char.
+ char == $r ifTrue:[
+ char := Character return
+ ] ifFalse:[
+ char == $n ifTrue:[
+ char := Character linefeed
+ ] ifFalse:[
+ char == $b ifTrue:[
+ char := Character backspace
+ ] ifFalse:[
+ char == $t ifTrue:[
+ char := Character tab
+ ]
+ ]
+ ]
+ ].
+ ].
+ keepCRs ifTrue:[
+ collected nextPut:char.
+ ] ifFalse:[
"compress CRLF to LF, but keep a single CR"
- collected nextPut:char.
+ ((char ~~ Character return) or:[str peekOrNil ~~ Character lf]) ifTrue:[
+ collected nextPut:char.
+ ]
].
].
"if we come here, we reached the end without finding a closing $'"
@@ -299,6 +328,30 @@
String readSmalltalkStringFrom:('''hello '''' world''' readStream) onError:[self halt]
String readSmalltalkStringFrom:('1 ''hello'' ' readStream) onError:[self halt]
String readSmalltalkStringFrom:('1 ''hello'' ' readStream) onError:['foobar']
+ String readSmalltalkStringFrom:('''hello\nworld''' readStream) onError:[self halt. 'foobar']
+
+ String readSmalltalkStringFrom:('''hello\nworld''' readStream) keepCRs:false onError:[self halt. 'foobar']
+ String readSmalltalkStringFrom:('c''hello\nworld''' readStream) keepCRs:false onError:[self halt. 'foobar']
+ "
+
+ "Created: / 05-07-2006 / 16:41:04 / cg"
+ "Modified: / 06-10-2006 / 14:05:32 / cg"
+ "Modified (comment): / 02-08-2019 / 10:10:46 / Stefan Vogel"
+!
+
+readSmalltalkStringFrom:aStreamOrString onError:exceptionBlock
+ "read & return the next String from the (character-)stream aStream;
+ skipping all whitespace first; return the value of exceptionBlock,
+ if no string can be read. The sequence of characters as read from the
+ stream must be one as stored via storeOn: or storeString."
+
+ ^ self readSmalltalkStringFrom:aStreamOrString keepCRs:false withCEscapes:false onError:exceptionBlock
+
+ "
+ String readSmalltalkStringFrom:('''hello world''' readStream) onError:[self halt]
+ String readSmalltalkStringFrom:('''hello '''' world''' readStream) onError:[self halt]
+ String readSmalltalkStringFrom:('1 ''hello'' ' readStream) onError:[self halt]
+ String readSmalltalkStringFrom:('1 ''hello'' ' readStream) onError:['foobar']
"
"Created: / 05-07-2006 / 16:41:04 / cg"
@@ -314,33 +367,10 @@
Different from #readSmalltalStringFrom:onError: we keep CRLF as is."
- |str collected char|
-
- str := aStreamOrString readStream.
- "skip whiteSpace"
- str skipSeparators.
-
- (str peekOrNil == $') ifTrue:[
- str next.
- collected := self writeStream.
- [(char := str nextOrNil) notNil] whileTrue:[
- char == $' ifTrue:[
- "/ look for another quote
- str peekOrNil ~~ $' ifTrue:[
- "end of string reached"
- ^ collected contents.
- ].
- "eat doubled quote"
- str next.
- ].
- collected nextPut:char.
- ].
- "if we come here, we reached the end without finding a closing $'"
- ].
- ^ exceptionBlock value
-
- "
- String readSmalltalkStringWithCRsFrom:('''hello world''' readStream) onError:[self halt]
+ ^ self readSmalltalkStringFrom:aStreamOrString keepCRs:true onError:exceptionBlock
+
+ "
+ String readSmalltalkStringWithCRsFrom:('''hello world''' readStream) onError:[self halt]
String readSmalltalkStringWithCRsFrom:('''hello '''' world''' readStream) onError:[self halt]
String readSmalltalkStringWithCRsFrom:('1 ''hello'' ' readStream) onError:[self halt]
String readSmalltalkStringWithCRsFrom:('1 ''hello'' ' readStream) onError:['foobar']