示例#1
0
/*----------------------------------------------------------------------------------------------------------------------
|	This function provides the ability to read everything following the block name (which is read by the NxsReader 
|	object) to the END or ENDBLOCK statement. Characters are read from the input stream `in'. Overrides the pure 
|	virtual function in the base class.
*/
void NxsEmptyBlock::Read(
  NxsToken &token)	/* the token used to read from `in'*/
	{
	isEmpty = false;

	// This should be the semicolon after the block name
	//
	token.GetNextToken();

	if (!token.Equals(";"))
		{
		errormsg = "Expecting ';' after ";
		errormsg += id;
		errormsg += " block name, but found ";
		errormsg += token.GetToken();
		errormsg += " instead";
		throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
		}

	for(;;)
		{
		token.GetNextToken();

		if (token.Equals("END"))
			{
			HandleEndblock(token);
			break;
			}

		else if(token.Equals("ENDBLOCK"))
			{
			HandleEndblock(token);
			break;
			}

		else
			{
			SkippingCommand(token.GetToken());

			do
				{
				token.GetNextToken();
				}
			while (!token.AtEOF() && !token.Equals(";"));

			if (token.AtEOF())
				{
				errormsg = "Unexpected end of file encountered";
				throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}
			}
		}
	}
示例#2
0
/*----------------------------------------------------------------------------------------------------------------------
|	Called when the HELP command needs to be parsed from within the GarliReader block.
*/
void GarliReader::HandleHelp(
  NxsToken &token)	/* the token used to read from `in' */
	{
	// Retrieve all tokens for this command, stopping only in the event
	// of a semicolon or an unrecognized keyword
	//
	for (;;)
		{
		token.GetNextToken();

		if (token.Equals(";"))
			{
			break;
			}
		else
			{
			errormsg = "Unexpected keyword (";
			errormsg += token.GetToken();
			errormsg += ") encountered reading HELP command";
			throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
			}
		}

	message = "\nExamples of use of available commands:";
	message += "\n  help                     -> shows this message";
	message += "\n  log file=mylog.txt start -> opens log file named mylog.txt";
	message += "\n  log stop                 -> closes current log file";
	message += "\n  exe mydata.nex           -> executes nexus file mydata.nex";
	message += "\n  show                     -> reports on blocks currently stored";
	message += "\n  quit                     -> terminates application";
	message += "\n";
	PrintMessage();
	}
示例#3
0
/*----------------------------------------------------------------------------------------------------------------------
|	Tries to interpret `token' as a number. Failing that, tries to interpret `token' as a character or taxon label, 
|	which it then converts to a number. Failing that, it throws a NxsException exception.
*/
unsigned NxsSetReader::GetTokenValue()
	{
	unsigned v = atoi(token.GetToken().c_str());

	if (v == 0 && settype != NxsSetReader::generic)
		{
		if (settype == NxsSetReader::charset)
			v = block.CharLabelToNumber(token.GetToken());
		else if (settype == NxsSetReader::taxset)
			v = block.TaxonLabelToNumber(token.GetToken());
		}

	if (v == 0)
		{
		block.errormsg = "Set element (";
		block.errormsg += token.GetToken();
		block.errormsg += ") not a number ";
		if (settype == NxsSetReader::charset)
			block.errormsg += "and not a valid character label";
		else if (settype == NxsSetReader::taxset)
			block.errormsg += "and not a valid taxon label";

		throw NxsException(block.errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
		}

	return v;
	}
示例#4
0
/*----------------------------------------------------------------------------------------------------------------------
|	Advances the token, and returns the unsigned int that the token represents
|
| 	Sets errormsg and raises a NxsException on failure.
|	`contextString` is used in error messages:
|		"Expecting ';' to terminate the ${contextString} command"
*/
void NxsToken::DemandEndSemicolon(NxsToken &token, NxsString & errormsg, const char *contextString)
	{
	token.GetNextToken();
	if (!token.Equals(";"))
		{
		errormsg = "Expecting ';' to terminate the ";
		errormsg += contextString;
		errormsg += " command, but found ";
		errormsg += token.GetToken();
		errormsg += " instead";
		throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
		}
	}
示例#5
0
/*----------------------------------------------------------------------------------------------------------------------
|	Advances the token, and returns the unsigned int that the token represents
|
| 	Sets errormsg and raises a NxsException on failure.
|	`contextString` is used in error messages:
|		"${contextString} must be a number greater than 0"
*/
unsigned NxsToken::DemandPositiveInt(NxsToken &token, NxsString & errormsg, const char *contextString)
	{
	token.GetNextToken();
	int i = atoi(token.GetToken().c_str());
	if (i <= 0)
		{
		errormsg.assign(contextString);
		errormsg += " must be a number greater than 0. Found";
		errormsg += token.GetToken();
		errormsg += " instead";
		throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
		}
	return (unsigned) i;
	}
示例#6
0
/*----------------------------------------------------------------------------------------------------------------------
|	Called when the END or ENDBLOCK command needs to be parsed from within the GarliReader block. Basically just 
|	checks to make sure the next token in the data file is a semicolon.
*/
void GarliBlock::HandleEndblock(
  NxsToken &token)	/*  the token used to read from `in' */
	{
	// Get the semicolon following END or ENDBLOCK token
	//
	token.GetNextToken();

	if (!token.Equals(";"))
		{
		errormsg = "Expecting ';' to terminate the END or ENDBLOCK command, but found ";
		errormsg += token.GetToken();
		errormsg += " instead";
		throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
		}
	}
示例#7
0
bool NxsFilePath::IsDirectory() const
	{
	if (!this->Exists())
		return false;
	const char *const natDirName = this->GetNative().c_str();
	struct NCL_STAT_STRUCT dStat;
	if (NCL_STAT(natDirName, &dStat) != 0)
		{
		std::string msg;
		msg += "stat call failed for ";
		msg += natDirName;
		throw NxsException(msg);
		}
	bool retCode = NCL_S_ISDIR(dStat.st_mode);
	//std::cerr << "IsDirectory is returning "<< retCode << " for " << natDirName <<std::endl;
	return retCode;
	}
示例#8
0
/*----------------------------------------------------------------------------------------------------------------------
|	Called whenever a file name needs to be read from either the command line or a file. Expects next token to be "=" 
|	followed by the token representing the file name. Call this function after, say, the keyword "file" has been read 
|	in the following LOG command:
|>
|	log file=doofus.txt start replace;
|>
|	Note that this function will read only the "=doofus.txt " leaving "start replace;" in the stream for reading at 
|	a later time.
*/
NxsString GarliReader::GetFileName(
  NxsToken &token)	/* the token used to read from `in' */
	{
	// Eat the equals sign
	//
	token.GetNextToken();

	if (!token.Equals("="))
		{
		errormsg = "Expecting an equals sign, but found ";
		errormsg += token.GetToken();
		errormsg += " instead";
		throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
		}

	// Now get the filename itself
	//
	token.GetNextToken();

	return token.GetToken();
	}
示例#9
0
/*----------------------------------------------------------------------------------------------------------------------
|	Called when the LOG command needs to be parsed from within the GarliReader block.
*/
void GarliReader::HandleLog(
  NxsToken &token)	/* the token used to read from `in' */
	{
	bool starting = false;
	bool stopping = false;
	bool appending = false;
	bool replacing = false;
	bool name_provided = false;
	NxsString logfname;

	// Retrieve all tokens for this command, stopping only in the event
	// of a semicolon or an unrecognized keyword
	//
	for (;;)
		{
		token.GetNextToken();

		if (token.Equals(";"))
			{
			break;
			}
		else if (token.Abbreviation("STOp"))
			{
			stopping = true;
			}
		else if (token.Abbreviation("STArt"))
			{
			starting = true;
			}
		else if (token.Abbreviation("Replace"))
			{
			replacing = true;
			}
		else if (token.Abbreviation("Append"))
			{
			appending = true;
			}
		else if (token.Abbreviation("File"))
			{
			logfname = GetFileName(token);
			name_provided = true;
			}
		else
			{
			errormsg = "Unexpected keyword (";
			errormsg += token.GetToken();
			errormsg += ") encountered reading LOG command";
			throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
			}
		}

	// Check for incompatible combinations of keywords
	//
	if (stopping && (starting || appending || replacing || name_provided))
		{
		errormsg = "Cannot specify STOP with any of the following START, APPEND, REPLACE, FILE";
		throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
		}

	if (appending && replacing)
		{
		errormsg = "Cannot specify APPEND and REPLACE at the same time";
		throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
		}

	if (logf_open && (starting || name_provided || appending || replacing))
		{
		errormsg = "Cannot start log file since log file is already open";
		throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
		}

	// Is user closing an open log file?
	//
	if (stopping)
		{
		logf.close();
		logf_open = false;

		message = "\nLog file closed";
		PrintMessage();

		return;
		}

	// If this far, must be attempting to open a log file
	//
	if (!name_provided)
		{
		errormsg = "Must provide a file name when opening a log file\n";
		errormsg += "e.g., log file=doofus.txt start replace;";
		throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
		}   

	if (appending)
		{
		logf_open = true;
		logf.open(logfname.c_str(), ios::out | ios::app);

		message = "\nAppending to log file ";
		message += logfname;
		PrintMessage();
		}

	else if (replacing)
		{
		logf_open = true;
		logf.open(logfname.c_str());

		message = "\nReplacing log file ";
		message += logfname;
		PrintMessage();
		}

	else 
		{
		bool exists = FileExists(logfname.c_str());
		bool userok = true;
		if (exists && !UserQuery("Ok to replace?", "Log file specified already exists", GarliReader::UserQueryEnum(GarliReader::uq_yes | GarliReader::uq_no)))
			userok = false;

		if (userok)
			{
			logf_open = true;
			logf.open(logfname.c_str());
			}

		if (exists && userok)
			{
			message = "\nReplacing log file ";
			message += logfname;
			}

		else if (userok)
			{
			message = "\nLog file ";
			message += logfname;
			message += " opened";
			}

		else
			{
			message = "\nLog command aborted";
			}

		PrintMessage();
		}
	}
示例#10
0
/*----------------------------------------------------------------------------------------------------------------------
|	Handles everything after the EXECUTE keyword and the terminating semicolon. Purges all blocks before executing 
|	file specified, and no warning is given of this.
| DJZ THIS IS NOT THE VERSION OF HandleExecute USED.  See the other overloaded version below.
*/
void GarliReader::HandleExecute(
  NxsToken &token)	/* the token used to read from `in' */
	{
	// Issuing the EXECUTE command from within a file is a no-no (at least in this program)
	//
	if (inf_open)
		{
		errormsg = "Cannot issue execute command from within a GarliReader block";
		throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
		}

	// Get the file name to execute (note: if filename contains underscores, these will be
	// automatically converted to spaces; user should surround such filenames with single quotes)
	//
	token.GetNextToken();

	NxsString fn = token.GetToken();

	// Get the semicolon terminating the EXECUTE command
	//
	token.GetNextToken();

	if (!token.Equals(";"))
		{
		errormsg = "Expecting ';' to terminate the EXECUTE command, but found ";
		errormsg += token.GetToken();
		errormsg += " instead";
		throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
		}

	if (FileExists(fn.c_str()))
		{
		cerr << endl;
		cerr << "Opening " << fn << "..." << endl;

		ifstream inf(fn.c_str(), ios::binary | ios::in);

		inf_open = true;

		MyNexusToken ftoken(inf);

		try
			{
			Execute(ftoken);
			}
		catch(NxsException x)
			{
			NexusError(errormsg, x.pos, x.line, x.col);
			}

		if (inf_open)
			inf.close();
		inf_open = false;

		// Users are allowed to put DATA blocks in their NEXUS files, but internally the data is always
		// stored in a NxsCharacterBlock object.
		//
		if (characters->IsEmpty() && !data->IsEmpty())
			{
			data->TransferTo(*characters);
			}

		}	// if (FileExists(fn.c_str()))

	else
		{
		cerr << endl;
		cerr << "Oops! Could not find specified file: " << fn << endl;
		}
	}
示例#11
0
/*----------------------------------------------------------------------------------------------------------------------
|	This function provides the ability to read everything following the block name (which is read by the NxsReader 
|	object) to the END or ENDBLOCK statement. Characters are read from the input stream `in'. Overrides the virtual 
|	function in the base class.
*/
void GarliBlock::Read(
  NxsToken &token)	/* the token used to read from `in' */
	{
	isEmpty = false;
	//if we already read a garli block with a model string, clear it
	modelString.clear();

	// This should be the semicolon after the block name
	//
	token.GetNextToken();

	if (!token.Equals(";"))
		{
		errormsg = "Expecting ';' after ";
		errormsg += id;
		errormsg += " block name, but found ";
		errormsg += token.GetToken();
		errormsg += " instead";
		throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
		}

	for (;;)
		{//only allowing three things to happen here 
		//1. endblock is reached, sucessfully exiting the garli block
		//2. something besides an endblock is read.  This is interpreted as part of the model string, with minimal error checking
		//3. eof is hit before an endblock
		token.GetNextToken();

		if (token.Abbreviation("ENdblock"))
			{
			HandleEndblock(token);
			break;
			}
		else if(token.AtEOF() == false){
			NxsString s = token.GetToken();
			if(s.size() > 1 && (s.IsADouble() == false && s.IsALong() == false)){
				errormsg = "Unexpected character(s) in Garli block.\n     See manual for model parameter format.";
				throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}
			if(token.IsPunctuationToken() == false){//toss semicolons and such
				modelString += token.GetToken();
				modelString += ' ';
				}
			}
		else
			{
			errormsg = "Unexpected end of file encountered before \"end;\" or\n     \"endblock;\" command in Garli block";
			throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
			}
		}
/*
		else if (token.Abbreviation("GarliReader"))
			{
			HandleGarliReader(token);
			}
		else if (token.Abbreviation("Help"))
			{
			HandleHelp(token);
			}
		else if (token.Abbreviation("Log"))
			{
			HandleLog(token);
			}
		else if (token.Abbreviation("EXecute"))
			{
			HandleExecute(token);
			}
		else if (token.Abbreviation("Show"))
			{
			HandleShow(token);
			}
		else if (token.Abbreviation("Quit"))
			{
			quit_now = true;

			message = "\nGarliReader says goodbye\n";
			PrintMessage();

			break;
			}
		else
			{
			SkippingCommand(token.GetToken());
			do
				{
				token.GetNextToken();
				}
			while (!token.AtEOF() && !token.Equals(";"));

			if (token.AtEOF())
				{
				errormsg = "Unexpected end of file encountered";
				throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}
			}
*/
	}
示例#12
0
/*----------------------------------------------------------------------------------------------------------------------
|	Reads rest of comment (starting '[' already input) and acts accordingly. If comment is an output comment, and if 
|	an output stream has been attached, writes the output comment to the output stream. Otherwise, output comments are 
|	simply ignored like regular comments. If the labileFlag bit saveCommandComments is in effect, the comment (without 
|	the square brackets) will be stored in token. 
*/
void NxsToken::GetComment()
	{
	// Set comment level to 1 initially.  Every ']' encountered reduces
	// level by one, so that we know we can stop when level becomes 0.
	//
	int level = 1;

	// Get first character
	//
	char ch = GetNextChar();
	if (atEOF)
		{
		errormsg = "Unexpected end of file inside comment";
		throw NxsException( errormsg, GetFilePosition(), GetFileLine(), GetFileColumn());
		}

	// See if first character is the output comment symbol ('!')
	// or command comment symbol (&)
	//
	int printing = 0;
	int command = 0;
	if (ch == '!')
		printing = 1;
	else if (ch == '&' && labileFlags & saveCommandComments)
		{
		command = 1;
		AppendToToken(ch);
		}
	else if (ch == ']')
		return;

	// Now read the rest of the comment
	//
	for(;;)
		{
		ch = GetNextChar();
		if (atEOF)
			break;

		if (ch == ']')
			level--;
		else if (ch == '[')
			level++;

		if (level == 0)
			break;

		if (printing)
			AppendToComment(ch);
		else if (command)
			AppendToToken(ch);
		}

	if (printing)
		{
		// Allow output comment to be printed or displayed in most appropriate
		// manner for target operating system
		//
		OutputComment(comment);
		}
	}
示例#13
0
/*----------------------------------------------------------------------------------------------------------------------
|	Reads in a set from a NEXUS data file. Returns true if the set was terminated by a semicolon, false otherwise.
*/
bool NxsSetReader::Run()
	{
	bool ok;
	bool retval = false;

	unsigned rangeBegin = UINT_MAX;
	unsigned rangeEnd = rangeBegin;
	bool insideRange = false;
	unsigned modValue = 0;

	for (;;)
		{
		// Next token should be one of the following:
		//   ';'        --> set definition finished
		//   '-'        --> range being defined
		//   <integer>  --> member of set (or beginning or end of a range)
		//   '.'        --> signifies the number max
		//   '\'        --> signifies modulus value coming next
		//
		token.GetNextToken();

		if (token.Equals("-"))
			{
			// We should not be inside a range when we encounter a hyphenation symbol.
			// The hyphen is what _puts_ us inside a range!
			//
			if (insideRange)
				{
				block.errormsg = "The symbol '-' is out of place here";
				throw NxsException(block.errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}
			insideRange = true;
			}

		else if (token.Equals("."))
			{
			// We _should_ be inside a range if we encounter a period, as this
			// is a range termination character
			//
			if (!insideRange)
				{
				block.errormsg = "The symbol '.' can only be used to specify the end of a range";
				throw NxsException(block.errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}
			rangeEnd = max;
			}

		else if (token.Equals("\\"))
			{
			// The backslash character is used to specify a modulus to a range, and
			// thus should only be encountered if currently inside a range
			//
			if (!insideRange)
				{
				block.errormsg = "The symbol '\\' can only be used after the end of a range has been specified";
				throw NxsException(block.errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}

			// This should be the modulus value
			//
			modValue = NxsToken::DemandPositiveInt(token, block.errormsg, "The modulus value");
			}

		else if (insideRange && rangeEnd == UINT_MAX)
			{
			// The beginning of the range and the hyphen symbol have been read
			// already, just need to store the end of the range at this point
			//
			rangeEnd = GetTokenValue();
			}

		else if (insideRange)
			{
			// If insideRange is true, we must have already stored the beginning
			// of the range and read in the hyphen character. We would not have
			// made it this far if we had also not already stored the range end.
			// Thus, we can go ahead and add the range.
			//
			ok = AddRange(rangeBegin, rangeEnd, modValue);

			if (!ok)
				{
				block.errormsg = "Character number out of range (or range incorrectly specified) in set specification";
				throw NxsException(block.errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}

			// We have actually already read in the next token, so deal with it
			// now so that we don't end up skipping a token
			//
			if (token.Equals(";"))
				{
				retval = true;
				break;
				}
			else if (token.Equals(","))
				{
				break;
				}

			rangeBegin = GetTokenValue();
			rangeEnd = UINT_MAX;
			insideRange = false;
			}

		else if (rangeBegin != UINT_MAX)
			{
			// If we were inside a range, we would have not gotten this far.
			// If not in a range, we are either getting ready to begin a new
			// range or have previously read in a single value. Handle the
			// latter possibility here.
			//
			ok = AddRange(rangeBegin, rangeBegin, modValue);

			if (!ok)
				{
				block.errormsg = "Character number out of range (or range incorrectly specified) in set specification";
				throw NxsException(block.errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}

			if (token.Equals(";"))
				{
				retval = true;
				break;
				}
			else if (token.Equals(","))
				{
				break;
				}

			rangeBegin = GetTokenValue();
			rangeEnd = UINT_MAX;
			}

		else if (token.Equals(";"))
			{
			retval = true;
			break;
			}

		else if (token.Equals(","))
			{
			break;
			}

		else if (token.Equals("ALL"))
			{
			rangeBegin = 1;
			rangeEnd = max;
			ok = AddRange(rangeBegin, rangeEnd);
			}

		else
			{
			// Can only get here if rangeBegin still equals UINT_MAX and thus we
			// are reading in the very first token and that token is neither
			// the word "all" nor is it a semicolon
			//
			rangeBegin = GetTokenValue();
			rangeEnd = UINT_MAX;
			}
		}

	return retval;
	}
示例#14
0
/*----------------------------------------------------------------------------------------------------------------------
|	This function provides the ability to read everything following the block name (which is read by the NxsReader
|	object) to the END or ENDBLOCK statement. Characters are read from the input stream `in'. Overrides the virtual
|	function in the base class.
*/
void GarliReader::Read(
    NxsToken &token)	/* the token used to read from `in' */
{
    isEmpty = false;

    // This should be the semicolon after the block name
    //
    token.GetNextToken();

    if (!token.Equals(";"))
    {
        errormsg = "Expecting ';' after ";
        errormsg += id;
        errormsg += " block name, but found ";
        errormsg += token.GetToken();
        errormsg += " instead";
        throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
    }

    for (;;)
    {
        token.GetNextToken();

        if (token.Abbreviation("ENdblock"))
        {
            HandleEndblock(token);
            break;
        }
        else if (token.Abbreviation("GarliReader"))
        {
            HandleGarliReader(token);
        }
        else if (token.Abbreviation("Help"))
        {
            HandleHelp(token);
        }
        else if (token.Abbreviation("Log"))
        {
            HandleLog(token);
        }
        else if (token.Abbreviation("EXecute"))
        {
            HandleExecute(token);
        }
        else if (token.Abbreviation("Show"))
        {
            HandleShow(token);
        }
        else if (token.Abbreviation("Quit"))
        {
            quit_now = true;

            message = "\nGarliReader says goodbye\n";
            PrintMessage();

            break;
        }
        else
        {
            SkippingCommand(token.GetToken());
            do
            {
                token.GetNextToken();
            }
            while (!token.AtEOF() && !token.Equals(";"));

            if (token.AtEOF())
            {
                errormsg = "Unexpected end of file encountered";
                throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
            }
        }
    }
}
示例#15
0
/*----------------------------------------------------------------------------------------------------------------------
|	Called when the HELP command needs to be parsed from within the GarliReader block.
*/
void GarliReader::HandleShow(
    NxsToken &token)	/* the token used to read from `in' */
{
    // Retrieve all tokens for this command, stopping only in the event
    // of a semicolon or an unrecognized keyword
    //
    for (;;)
    {
        token.GetNextToken();

        if (token.Equals(";"))
            break;
        else
        {
            errormsg = "Unexpected keyword (";
            errormsg += token.GetToken();
            errormsg += ") encountered reading HELP command";
            throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
        }
    }

    message = "\nNexus blocks currently stored:";
    PrintMessage();

    if (!taxa->IsEmpty())
    {
        cerr << "\n  TAXA block found" << endl;
        taxa->Report(cerr);
        if (logf_open)
            taxa->Report(logf);
    }

    if (!trees->IsEmpty())
    {
        cerr << "\n  TREES block found" << endl;
        trees->Report(cerr);
        if (logf_open)
            trees->Report(logf);
    }

    if (!assumptions->IsEmpty())
    {
        cerr << "\n  ASSUMPTIONS block found" << endl;
        assumptions->Report(cerr);
        if (logf_open)
            assumptions->Report(logf);
    }

    if (!distances->IsEmpty())
    {
        cerr << "\n  DISTANCES block found" << endl;
        distances->Report(cerr);
        if (logf_open)
            distances->Report(logf);
    }

    if (!characters->IsEmpty())
    {
        cerr << "\n  CHARACTERS block found" << endl;
        characters->Report(cerr);
        if (logf_open)
            characters->Report(logf);
    }

    if (!data->IsEmpty())
    {
        cerr << "\n  DATA block found" << endl;
        data->Report(cerr);
        if (logf_open)
            data->Report(logf);
    }
}
示例#16
0
/*----------------------------------------------------------------------------------------------------------------------
|	Reads characters from in until a complete token has been read and stored in token. GetNextToken performs a number 
|	of useful operations in the process of retrieving tokens:
|~
|	o any underscore characters encountered are stored as blank spaces (unless the labile flag bit preserveUnderscores
|	  is set)
|	o if the first character of the next token is an isolated single quote, then the entire quoted NxsString is saved 
|	  as the next token
|	o paired single quotes are automatically converted to single quotes before being stored
|	o comments are handled automatically (normal comments are treated as whitespace and output comments are passed to 
|	  the function OutputComment which does nothing in the NxsToken class but can be overridden in a derived class to 
|	  handle these in an appropriate fashion)
|	o leading whitespace (including comments) is automatically skipped
|	o if the end of the file is reached on reading this token, the atEOF flag is set and may be queried using the AtEOF 
|	  member function
|	o punctuation characters are always returned as individual tokens (see the Maddison, Swofford, and Maddison paper 
|	  for the definition of punctuation characters) unless the flag ignorePunctuation is set in labileFlags,
|	  in which case the normal punctuation symbols are treated just like any other darkspace character.
|~
|	The behavior of GetNextToken may be altered by using labile flags. For example, the labile flag saveCommandComments 
|	can be set using the member function SetLabileFlagBit. This will cause comments of the form [&X] to be saved as 
|	tokens (without the square brackets), but only for the aquisition of the next token. Labile flags are cleared after 
|	each application.
*/
void NxsToken::GetNextToken()
	{
	ResetToken();

	char ch = ' ';
	if (saved == '\0' || IsWhitespace(saved))
		{
		// Skip leading whitespace
		//
		while( IsWhitespace(ch) && !atEOF)
			ch = GetNextChar();
		saved = ch;
		}

	for(;;)
		{
		// Break now if singleCharacterToken mode on and token length > 0.
		//
		if (labileFlags & singleCharacterToken && token.size() > 0)
			break;

		// Get next character either from saved or from input stream.
		//
		if (saved != '\0')
			{
			ch = saved;
			saved = '\0';
			}
		else
			ch = GetNextChar();

		// Break now if we've hit EOF.
		//
		if (atEOF)
			break;

		if (ch == '\n' && labileFlags & newlineIsToken)
			{
			if (token.size() > 0)
				{
				// Newline came after token, save newline until next time when it will be 
				// reported as a separate token.
				//
				atEOL = 0;
				saved = ch;
				}
			else
				{
				atEOL = 1;
				AppendToToken(ch);
				}
			break;
			}

		else if (IsWhitespace(ch))
			{
			// Break only if we've begun adding to token (remember, if we hit a comment before a token,
			// there might be further white space between the comment and the next token).
			//
			if (token.size() > 0)
				break;
			}

		else if (ch == '_')
			{
			// If underscores are discovered in unquoted tokens, they should be 
			// automatically converted to spaces.
			//
			if (!(labileFlags & preserveUnderscores))
				ch = ' ';
			AppendToToken(ch);
			}

		else if (ch == '[')
			{
			// Get rest of comment and deal with it, but notice that we only break if the comment ends a token,
			// not if it starts one (comment counts as whitespace). In the case of command comments 
			// (if saveCommandComment) GetComment will add to the token NxsString, causing us to break because
			// token.size() will be greater than 0.
			comment.clear();
			GetComment();
			if (token.size() > 0)
			break;
			}

		else if (ch == '(' && labileFlags & parentheticalToken)
			{
			AppendToToken(ch);

			// Get rest of parenthetical token.
			//
			GetParentheticalToken();
			break;
			}

		else if (ch == '{' && labileFlags & curlyBracketedToken)
			{
			AppendToToken(ch);

			// Get rest of curly-bracketed token.
			//
			GetCurlyBracketedToken();
			break;
			}

		else if (ch == '\"' && labileFlags & doubleQuotedToken)
			{
			// Get rest of double-quoted token.
			//
			GetDoubleQuotedToken();
			break;
			}

		else if (ch == '\'')
			{
			if (token.size() > 0)
				{
				// We've encountered a single quote after a token has
				// already begun to be read; should be another tandem
				// single quote character immediately following.
				//
				ch = GetNextChar();
				if (ch == '\'')
					AppendToToken(ch);
				else
					{
					errormsg = "Expecting second single quote character";
					throw NxsException( errormsg, GetFilePosition(), GetFileLine(), GetFileColumn());
					}
				}
			else
				{
				// Get rest of quoted NEXUS word and break, since
				// we will have eaten one token after calling GetQuoted.
				//
				GetQuoted();
				}
			break;
			}

		else if (IsPunctuation(ch))
			{
			if (token.size() > 0)
				{
				// If we've already begun reading the token, encountering
				// a punctuation character means we should stop, saving
				// the punctuation character for the next token.
				//
				saved = ch;
				break;
				}
			else
				{
				// If we haven't already begun reading the token, encountering
				// a punctuation character means we should stop and return
				// the punctuation character as this token (i.e., the token
				// is just the single punctuation character.
				//
				AppendToToken(ch);
				break;
				}
			}

		else
			{
			AppendToToken(ch);
			}

		}

	labileFlags = 0;
	}
示例#17
0
/*----------------------------------------------------------------------------------------------------------------------
|	This function provides the ability to read everything following the block name (which is read by the NxsReader 
|	object) to the end or endblock statement. Characters are read from the input stream in. Overrides the abstract 
|	virtual function in the base class. 
*/
void NxsTaxaBlock::Read(
  NxsToken &token)	/* the token used to read from in */
	{
	ntax				= 0;
	unsigned nominal_ntax	= 0;
	isEmpty				= false;
	isUserSupplied		= true;

	DemandEndSemicolon(token, "BEGIN TAXA");

	for (;;)
		{
		token.GetNextToken();

		if (token.Equals("DIMENSIONS"))
			{
			// This should be the NTAX keyword
			//
			token.GetNextToken(); 

			if (!token.Equals("NTAX"))
				{
				errormsg = "Expecting NTAX keyword, but found ";
				errormsg += token.GetToken();
				errormsg += " instead";
				throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}

			DemandEquals(token, "after NTAX");
			nominal_ntax = DemandPositiveInt(token, "NTAX");
			DemandEndSemicolon(token, "DIMENSIONS");
			}	// if (token.Equals("DIMENSIONS"))

		else if (token.Equals("TAXLABELS")) 
			{
			if (nominal_ntax <= 0) 
				{
				errormsg = "NTAX must be specified before TAXLABELS command";
				throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}

			for (unsigned i = 0; i < nominal_ntax; i++)
				{
				token.GetNextToken();
				//@pol should check to make sure this is not punctuation
				AddTaxonLabel(token.GetToken());
				}
			DemandEndSemicolon(token, "TAXLABELS");
			}	// if (token.Equals("TAXLABELS")) 

		else if (token.Equals("END") || token.Equals("ENDBLOCK"))
			{
			DemandEndSemicolon(token, "ENDBLOCK");
			break;
			}	// if (token.Equals("END") || token.Equals("ENDBLOCK"))

		else
			{
			SkippingCommand(token.GetToken());
			do
				{
				token.GetNextToken();
				}
			while (!token.AtEOF() && !token.Equals(";"));

			if (token.AtEOF())
				{
				errormsg = "Unexpected end of file encountered";
				throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}
			}	// token not END, ENDBLOCK, TAXLABELS, or DIMENSIONS
		}	// GetNextToken loop
	}
示例#18
0
/*----------------------------------------------------------------------------------------------------------------------
|	This function provides the ability to read everything following the block name (which is read by the NxsReader 
|	object) to the end or endblock statement. Characters are read from the input stream in. Overrides the abstract 
|	virtual function in the base class. 
*/
void NxsTaxaBlock::Read(
  NxsToken &token)	/* the token used to read from in */
	{
	ntax				= 0;
	int nominal_ntax	= 0;
	isEmpty				= false;
	isUserSupplied		= true;

	// This should be the semicolon after the block name
	//
	token.GetNextToken();

	if (!token.Equals(";")) 
		{
		errormsg = "Expecting ';' after TAXA block name, but found ";
		errormsg += token.GetToken();
		errormsg += " instead";
		throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
		}

	for (;;)
		{
		token.GetNextToken();

		if (token.Equals("DIMENSIONS"))
			{
			// This should be the NTAX keyword
			//
			token.GetNextToken(); 

			if (!token.Equals("NTAX"))
				{
				errormsg = "Expecting NTAX keyword, but found ";
				errormsg += token.GetToken();
				errormsg += " instead";
				throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}

			// This should be the equals sign
			//
			token.GetNextToken(); 

			if (!token.Equals("=")) 
				{
				errormsg = "Expecting '=', but found ";
				errormsg += token.GetToken();
				errormsg += " instead";
				throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}

			// This should be the number of taxa
			//
			token.GetNextToken();

			nominal_ntax = atoi(token.GetToken().c_str());
			if (nominal_ntax <= 0)
				{
				errormsg = "NTAX should be greater than zero (";
				errormsg += token.GetToken();
				errormsg += " was specified)";
				throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}

			// This should be the terminating semicolon
			//
			token.GetNextToken(); 

			if (!token.Equals(";"))
				{
				errormsg = "Expecting ';' to terminate DIMENSIONS command, but found ";
				errormsg += token.GetToken();
				errormsg += " instead";
				throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}
			}	// if (token.Equals("DIMENSIONS"))

		else if (token.Equals("TAXLABELS")) 
			{
			if (nominal_ntax <= 0) 
				{
				errormsg = "NTAX must be specified before TAXLABELS command";
				throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}

			for (unsigned i = 0; (int)i < nominal_ntax; i++)
				{
                token.SetLabileFlagBit(NxsToken::hyphenNotPunctuation + NxsToken::preserveUnderscores);
				token.GetNextToken();
				//@pol should check to make sure this is not punctuation
				AddTaxonLabel(token.GetToken());
				}

			// This should be terminating semicolon
			//
			token.GetNextToken(); 

			if (!token.Equals(";"))
				{
				errormsg = "Expecting ';' to terminate TAXLABELS command, but found ";
				errormsg += token.GetToken();
				errormsg += " instead";
				throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}
			}	// if (token.Equals("TAXLABELS")) 

		else if (token.Equals("END") || token.Equals("ENDBLOCK"))
			{
			// Get the semicolon following END
			//
			token.GetNextToken();

			if (!token.Equals(";"))
				{
				errormsg = "Expecting ';' to terminate the ENDBLOCK command, but found ";
				errormsg += token.GetToken();
				errormsg += " instead";
				throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}
			break;
			}	// if (token.Equals("END") || token.Equals("ENDBLOCK"))

		else
			{
			SkippingCommand(token.GetToken());
			do
				{
				token.GetNextToken();
				}
			while (!token.AtEOF() && !token.Equals(";"));

			if (token.AtEOF())
				{
				errormsg = "Unexpected end of file encountered";
				throw NxsException(errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
				}
			}	// token not END, ENDBLOCK, TAXLABELS, or DIMENSIONS
		}	// GetNextToken loop
	}