Synonym streams, EOL conventions, and external formats
This is one of the remaining rough edges of trying to centralize and systematize the external format behavior. In the first round of implementation, I steered clear of some built-in streams--the terminal input and output in particular--letting them continue with their default behavior. Their creators filled in a few of the function fields and left others an initialized at NIL, which then would fall through to the default functions (from XCCS) if the relevant operations were ever applied. Putting :XCCS as the default for devices had the effect of filling in those function fields from XCCS, and thus maintained the previous behavior (presumably not really thought out).
But there is one respect where the behavior accidentally determined by an uninitialized field is not consistent with the behavior described by the explicit default :XCCS format. The format has a default EOL convention, a number between 0 and 3, where 0 means CR, 1 means LF, 2 means CRLF, and 3 means any (only for input streams).
The EOLCONVENTION is copied up from the external format of a device into the stream when the stream is created on that device (if the format as the EOLVALID bit set--otherwise it is left alone).
Previously, the uninitialized value 0 for synonym streams like ERROR-OUTPUT mapped onto CR, even though we changed the default EOLCONVENTION for the XCCS and UTF-8 formats to LF. Now, the default behavior is to copy the LF into the stream when it is created, because it gets the external format (now :XCCS) of the stream (usually the terminal stream) that it shadows. The effect is that EOL's printed to the error stream don't go back to the left margin, just do a linefeed.
I think the previous behavior is restored if a synonym stream on the terminal takes EOL (and maybe all of its other settings) from the terminal. But is this true only for synonyms to the terminal? I presume that the syonym stream is not a splitter that can go to difference kinds of devices, it really is a synonym in that the output/input still goes through to the original stream and behaves as the stream in all respects.
Is that the right way of thinking about this?
On more thought and after looking at CLTL2, I think the correct way of doing this, for all synonym streams, is to set up a file device that has 4 external-format functions that simply pass through to the target stream's functions on the target stream. That will get the EOL right. The mapping to the target stream, according to the spec, is dynamic by a known variable whose value is a possibly changeable target stream. So the EOL convention of the synonym stream is irrelevant.
The concept is simple, but I haven't been able to get it to work. The ERROR-STREAM starts out as a synonym stream when it is defined, but somewhere later in the loadup it gets changed to a two-way stream. I can't figure out where that is happening, or why. I think somehow it is getting reset to the QUERY-IO stream, that also happens when you go into a break. But why in the loadup sequence? Masterscope doesn't think anybody other than the original creator (and the compiler) is resetting the variable.
Probably I have to jigger the two-way device as well, to catch the query IO stream.
it might have been better to embed the EOL convention with the external-format (at the risk of increasing the number of EOLs you would deal with) -- and just define UTF-8 means eol.lf and XCCS means eol.cr and XCCS-LF means XCCS but with LF as the end-of-line.
At least then you wouldn't have to worry about them being inconsistent.
I'm not sure this is still a problem, I seemed to have done more work on this after the initial diagnosis and comments. Maybe this should have been closed?