public class ClearStream extends ReversibleReader
The reason it takes a stream implementation is that all of the above may happen in the middle of token creation by the lexer. To complete the token, the input stream must handle those transformations transparently and produce a 'clear' input.
This class extends the PushbackInputStream. The latter provides functionality needed for input stream mutations and rescanning of substitutions.
This is what this class does to the underlying input stream:
Include file processing involves creation of a new scope in the preprocessor dictionary. When EOF is signalled for the included input file, its scope is removed from the dictionary and input is resumed from the including file. Input files form a stack that is represented by stackable scopes in the dictionary.
Modifier and Type | Field and Description |
---|---|
private int |
clearCount
Count of bytes currently on top of the stream that have to be read
without translation.
|
private Environment |
env
Reference to the environment object
|
private int |
inBraces
Nesting count of how many brace parsers are in use.
|
private boolean |
inComment
true if current input is within a Progress comment. |
private boolean |
inString
true if current input is within a Progress string. |
private boolean |
keepTildes
true if tildes have to be retained on output. |
private char |
marker
Configurable marker character.
|
private MultiReader |
mlt
Reference to the MultiReader object
|
private boolean |
unixEscapes
true if backslash is honored as an escape character. |
Constructor and Description |
---|
ClearStream(MultiReader mlt,
Options opts)
Constructor.
|
Modifier and Type | Method and Description |
---|---|
void |
dumpState()
Dumps the internal state variables.
|
static int |
getAlternativeCoding(int b)
Translates a valid alternative coding into a character.
|
MultiReader |
getStream()
Gets the input stream.
|
private void |
insertArgumentsHints(Environment env,
FileScope fs)
Creates include file arguments hints and inserts the corresponding
markers into the input stream.
|
static boolean |
isAlternativeCoding(int a,
int b)
Tells if the character sequence represented by parameters a and b is
a valid alternative coding.
|
boolean |
isInString()
Detects if the processing is inside a string literal.
|
private int |
mread()
Reads from the stream and switches to the previous stacked stream
at EOF.
|
private void |
processBraces()
Invoke the braces parser to consume and handle any include file or
reference expansions.
|
void |
pushMarker(java.lang.String prefix,
int index)
Pushes a marker into the input stream.
|
int |
read()
Returns the logically next byte from the stream after all due handling
of escape sequences, alternative coding and braces.
|
int |
read(byte[] b,
int off,
int len)
Reads up to len bytes of data from this input stream into an array
of bytes.
|
void |
setEnvironment(Environment env)
Sets the reference to environment where the braces grammar parser
and lexer were created.
|
void |
setInComment(boolean inComment)
Sets the inComment state flag.
|
void |
setInString(boolean inString)
Sets the inString state flag.
|
private Environment env
private MultiReader mlt
private int clearCount
private char marker
private int inBraces
private boolean inComment
true
if current input is within a Progress comment.private boolean inString
true
if current input is within a Progress string.private boolean keepTildes
true
if tildes have to be retained on output.private boolean unixEscapes
true
if backslash is honored as an escape character.public ClearStream(MultiReader mlt, Options opts)
mlt
- The input source.opts
- Preprocessor options to honor.public static boolean isAlternativeCoding(int a, int b)
a
- first character from a pairb
- second character from a pairtrue
if the pair represents a valid alternative
codingpublic static int getAlternativeCoding(int b)
b
- second, significant character from a pairpublic void setEnvironment(Environment env)
env
- Environment object where the braces grammar parser and lexer
were createdpublic void setInComment(boolean inComment)
inComment
- new value of the flagpublic void setInString(boolean inString)
inString
- new value of the flagpublic boolean isInString()
true
if the current processing is inside a
string literal.public MultiReader getStream()
public int read() throws java.io.IOException
From this perspective, the input is made of comments, strings and regular text.
Alternative codings are translated in comments and text (not in strings).
Braces are translated in strings and text (not in comments).
Escapes are handled as follows:
Newlines are normalized. This means all variations of "\r", "\n", "\r\n" that are allowed on input, are replaced with single "\n". To help the preprocessor handle newlines within strings, this method has to provide enough information to the lexer about all newlines inserted during the ~n, \n, ~nnn or \nnn substitutions (the lexer deletes only the original newlines and has to keep all the escapes).
As due to the normalization, all CRs are deleted, the CR is used as an other "escape" character between this method and the lexer. If, after a substitution, a CR or NL character is created, one more CR is inserted into the stream just in front of it. This first CR triggers special CR or NL processing inside the strings in the lexer. The first CR is removed and the second character that follows it (CR or LF) is kept.
Multiple tildes and backslashes need special consideration, because the rightmost ~ or \ in the group is converted first and that conversion affects the meaning of the previous tilde or backslash. They all are accumulated in a temporary array until another character (or sequence in case of ~nnn, \nnn, ~;... and \;...) is read, then converted as a group and pushed back into the stream with the proper clearCount set. The first character of the resulting group is returned.
This method also inserts a special marker into the input stream designating the start of the included file. This marker is made of:
read
in class ReversibleReader
java.io.IOException
- if a character matching the marker character is found on input.public int read(byte[] b, int off, int len) throws java.io.IOException
b
- the buffer into which the data is read.off
- the start offset in array b
at which
the data is written.len
- the maximum number of bytes to read.java.io.IOException
public void dumpState()
public void pushMarker(java.lang.String prefix, int index) throws java.io.IOException
prefix
- prefix of the marker.index
- marker's index.java.io.IOException
- when the pushback buffer is fullprivate void processBraces() throws java.io.IOException
java.io.IOException
private int mread() throws java.io.IOException
java.io.IOException
private void insertArgumentsHints(Environment env, FileScope fs) throws java.io.IOException
The include file argument hints report the name, type and value of every argument along with the flag indicating whether the argument was ever referenced by the include file.
java.io.IOException
- if pushback buffer is too small