@param optr_dbg The Outputter to use for debugging. May not be null.
@exception ConfigFormatException If any of the formatting rules for the source text of a <A HREF="~JD~cr~EJD~">ConfigReader</A> are violated.
**/
public CRLineAnalyzer(StringBuffer sb_line, int i_lineNumber, int i_mlcStartLine, int i_varStartLine, StringOrBuffer sob_varStartName, char c_varStartDelim, Outputter optr_dbg, CRLAObjects crla_objects) throws ConfigFormatException {
//Validate parameters...START
SOBStringBuffer ssbLine = new SOBStringBuffer(sb_line);
if(!ssbLine.endsWith(sLINE_SEP)) {
//This is the last line in the source text.
bLastLine = true;
} else {
//The line *does* end with the line separator.
int iAnotherLS = ssbLine.indexOf(sLINE_SEP, 0, ssbLine.length() - sLINE_SEP.length());
if(iAnotherLS != -1) {
throwAX("constructor: sb_line contains a line separator (sLINE_SEP: '" + crlao.uStr.getVisible(sLINE_SEP) + "') at somewhere other than the end (at array index " + iAnotherLS + ").");
}
}
if(i_lineNumber < 1) {
throwAX("constructor: i_lineNumber (" + i_lineNumber + ") is less than one.");
}
cibMLCVarStartLines(i_lineNumber, i_mlcStartLine, "mlc", i_varStartLine, "var");
cibMLCVarStartLines(i_lineNumber, i_varStartLine, "var", i_mlcStartLine, "mlc");
if(i_varStartLine != -1 &&
(sob_varStartName == null || sob_varStartName.length() < 1)) {
throwAX("constructor: i_varStartLine equals (" + i_varStartLine + "), but sob_varStartName ('" + sob_varStartName + "') is null or zero characters in length.");
}
throwAXIfNull(optr_dbg, "optr_dbg", sCNSTR);
//Validate parameters...END
//To shorten code, and for better error messages (see
//throwCFX)
crlao = crla_objects;
iLineNumber = i_lineNumber;
iMLCStartLine = i_mlcStartLine;
iVarStartLine = i_varStartLine;
sobVarStartName = sob_varStartName;
if(sobVarStartName == null) {
cVarStartDelim = ' ';
} else {
cVarStartDelim = c_varStartDelim;
}
optr = optr_dbg;
InsideWhitespace iwLine = new InsideWhitespace(ssbLine, crlao.uSOB);
if(isComment(iwLine)) {
return;
}
//This line is not a comment. It is either the first line
//in a variable, or the second or subsequent line in the
//value.
int iDelimIW = -1;
int iDelimActual = -1;
if(iwLine.length() > 0) {
iDelimIW = crlao.usVarDelims.getIdx1stUnesc2BEsc(iwLine);
iDelimActual = iwLine.getActualIdx(iDelimIW);
}
if(iDelimIW == -1) {
//No delimiters exist on this line. This line is
//either not part of any variable, value or comment, or
//this is the second or subsequent line in a value.
if(iVarStartLine != -1) {
//This is the second or subsequent line in a
//variable's value.
sVarValue = ssbLine.toString();
} else {
//This line is not the second/subsequent line in a
//value. It is a line *between* variables or
//comments.
if(iwLine.length() > 0) {
String sMLCEnd = sES;
if(iwLine.charAt(iwLine.length() - 1) == crlao.crc.getCRCDelimiters().getMLCEnd()) {
//Special condition, for a clearer error message
sMLCEnd = ". Also note: The last character in this line is a multi-line comment end delimiter ('" + crlao.crc.getCRCDelimiters().getMLCEnd() + "'). If this is meant to be the end of a multi-line comment, it was never started";
}
throwCFX(iwLine, "Stray text found. This line is not part of any variable or comment, but contains non-whitespace characters. Note that cr_config.getCRCVariable().is1stLineWSEmptyString() equals " + crlao.crc.getCRCVariable().is1stLineWSEmptyString() + sMLCEnd);
}
}
//This line is whitespace only, and can be safely ignored.
} else {
//This line contains an unescaped variable delimiter
//and is therefore the first in a variable's value.
sVarName = ssbLine.substring(0, iDelimActual);
cDelimiter = ssbLine.charAt(iDelimActual);
iVarStartLine = iLineNumber;
sobVarStartName = new SOBString(sVarName);
cVarStartDelim = cDelimiter;
if(iDelimIW == (iwLine.length() - 1)) {
//The delimiter is the last non-whitespace character on
//the line. There is no space after it for other
//unescaped variable delimiters to exist.
if(iDelimActual == (ssbLine.length() - 1)) {
//The delimiter is truly the last character in the
//line.
sVarValue = sES;
//(This actually means that this line is the last in
//the file. All lines previous to it end with a
//line separator.)
} else {
//The delimiter is followed by some whitespace.
sVarValue = ssbLine.substring(iDelimActual + 1);
}
} else {
//There are non-whitespace characters following the
//delimiter.
int iDelimOther = crlao.usVarDelims.getIdx1stUnesc2BEsc(iwLine, (iDelimIW + 1));
if(iDelimOther != -1) {
throwCFX(iwLine, iDelimOther, "A second unescaped variable delimiter was found");
}
//No other (unescaped) variable delimiters exist.
String s = ssbLine.substring(iDelimActual + 1);
String sPotentiallyNull = s.trim();
if(sPotentiallyNull.equals(crlao.crc.getCRCVariable().getNullValue())) {
sVarValue = null;
bValueNull = true;