Suggesting n1 w1 r1 s1 switch for $read to return the correct string containing leading space(s) while preserving backwards compatibility. Either that, or another switch letter to use with n/w/r/s that preserves leading spaces. This is like the /write -w switch to obtain correct $crlf without affecting existing behavior.

Originally Posted by F1 help
If the n switch is specified then the line read in will not be evaluated and will be treated as plain text.

That identical sentence is in /help for both $read and $readini, and the following command confirms that $readini returns leading + trailing + internal_consecutive spaces when the 'n' switch is used, while it returns the trimmed string $gettok(string,1-,32) when 'n' is not used:

//bset -c &v 1 91 77 93 13 10 97 61 32 32 99 32 32 99 32 32 | bwrite -c test.txt 0 99 &v | bset -t &v 1 $encode($readini(test.txt,n,m,a),m) | noop $decode(&v,bm) | echo -a $bvar(&v,1-)

Quote
with 'n':::: 32 32 99 32 32 99 32 32
without 'n': 99 32 99

However the same thing with $read 'n' switch preserves the internal consecutives and the trailing, but always strips the leading:

//bset -c &v 1 32 32 99 32 32 99 32 32 | bwrite -c test.txt 0 99 &v | bset -t &v 1 $encode($read(test.txt,tn,1),m) | noop $decode(&v,bm) | echo -a $bvar(&v,1-)

Quote
with 'n':::: 99 32 32 99 32 32
without 'n': 99 32 99

... and the following shows that 'nw' and 'nr' also return the same strings with leading spaces chopped but internal_consecutive/trailing preserved:

//bset -c &v 1 32 32 99 32 32 99 32 32 | bwrite -c test.txt 0 99 &v | bset -t &v 1 $encode($read(test.txt,tnw,$chr(32) $+ *),m) | noop $decode(&v,bm) | echo -a $bvar(&v,1-)

//bset -c &v 1 32 32 99 32 32 99 32 32 | bwrite -c test.txt 0 99 &v | bset -t &v 1 $encode($read(test.txt,tnr,.),m) | noop $decode(&v,bm) | echo -a $bvar(&v,1-)

--

The same thing can also be argued for 'ns', where the behavior of 's' is to match a line where 'search string' is followed by a space, where it returns everything except 'search string' and ALL spaces. In the next example, 'ns' is used with a search term that ends with 1 space, and it only matches if the 98 is followed by at least two 32's, but it then returns the string with all 32's following the search term stripped, and should probably return the following string having only the 1st 32 stripped.

//bset -c &v 1 97 32 32 32 98 32 32 32 99 32 32 99 32 32 | bwrite -c test.txt 0 99 &v | bset -t &v 1 $encode($read(test.txt,tns,a $chr(32) b $+ $chr(32)),m) | noop $decode(&v,bm) | echo -a $bvar(&v,1-)

--

I found the same spaces stripping behavior in 6.35, with the exception of a caching bug caused by $read not realizing that the file's content had changed since it had been accessed by $readini.

--

I found this behavior when trying to use $read to re-assemble paragraphs in a text file where there were no blank lines, and the continuation lines of a paragraph were indented like the display you'd see from:

//echo -i5 $str(deadbeef $+ $chr(32),100)

Since the file wasn't exceptionally large, the work-around was to use /filter to send the file content to @hidden, where /filter did output the string containing leading spaces, and $line() returns leading/trailing/consecutive spaces if present.