int GarliReader::HandleExecute(const char *filename) /* the token used to read from `in' */ { // 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) // NxsString fn = filename; int ret = 0; if (FileExists(fn.c_str())) { cerr << endl; cerr << "Opening " << fn << "..." << endl; PurgeBlocks(); 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); ret = 1;//error } 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; ret = 1; } return ret; }
int GarliReader::HandleExecute(const char *filename, bool ) { // The filename to execute is passed in // NxsString fn = filename; int ret = 0; if (FileExists(fn.c_str())) { ifstream inf(fn.c_str(), ios::binary | ios::in); inf_open = true; MyNexusToken ftoken(inf); try{ Execute(ftoken); } catch(NxsException x){ //DJZ 3/24/08 this was a bug that I inherited from the NCL example BasicCmdLine //the actual error message in x.msg was never getting printed because the empty //errormsg member of NexusBlock was being passed instead of the error stored in the //NxsException //NexusError(errormsg, x.pos, x.line, x.col); NexusError(x.msg, x.pos, x.line, x.col); ret = 1;//error } 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 { outman.UserMessage("Sorry, could not find specified file: %s", fn.c_str()); ret = 1; } return ret; }
/*---------------------------------------------------------------------------------------------------------------------- | Accepts a string in the form of a GarliReader block containing one command and processes it just like a real | GarliReader block in a NEXUS data file. */ void GarliReader::HandleNextCommand() { std::istringstream cmdin(next_command); MyNexusToken token(cmdin); try { Read(token); } catch(NxsException x) { NexusError(errormsg, x.pos, x.line, x.col); } }
/*---------------------------------------------------------------------------------------------------------------------- | 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; } }
//DJZ this is my function, replacing an old one that appeared in funcs.cpp //simpler now, since it uses NxsMultiFormatReader bool GarliReader::ReadData(const char* filename, const ModelSpecification &modspec){ //first use a few of my crappy functions to try to diagnose the type of file and data //then call the NxsMultiFormatReader functions to process it if (!FileExists(filename)) { throw ErrorException("data file not found: %s!", filename); } //if it is Nexus, don't need to specify anything else in advance if(FileIsNexus(filename)){ outman.UserMessage("Attempting to read data file in Nexus format (using NCL):\n\t%s ...", filename); ReadFilepath(filename, NEXUS_FORMAT); } else{//if this isn't nexus we'll try a bunch of formats to see if we can get something to work //the idea here is that we create an ordered list of formats to try, then we try them typedef pair<MultiFormatReader::DataFormatType, NxsString> FormatPair; list<FormatPair> formatsToTry; NxsString name; if(FileIsFasta(filename)){ if(modspec.IsAminoAcid()){ formatsToTry.push_back(FormatPair(FASTA_AA_FORMAT, "Fasta amino acid")); } else{ if(modSpec.IsRna() == false) formatsToTry.push_back(FormatPair(FASTA_DNA_FORMAT, "Fasta DNA")); formatsToTry.push_back(FormatPair(FASTA_RNA_FORMAT, "Fasta RNA")); } } else{//otherwise assume phylip format if(modSpec.IsAminoAcid()){ formatsToTry.push_back(FormatPair(RELAXED_PHYLIP_AA_FORMAT, "relaxed Phylip amino acid")); formatsToTry.push_back(FormatPair(INTERLEAVED_RELAXED_PHYLIP_AA_FORMAT, "interleaved relaxed Phylip amino acid")); formatsToTry.push_back(FormatPair(PHYLIP_AA_FORMAT, "strict Phylip amino acid")); formatsToTry.push_back(FormatPair(INTERLEAVED_PHYLIP_AA_FORMAT, "interleaved strict Phylip amino acid")); } else{ if(modSpec.IsRna() == false){ formatsToTry.push_back(FormatPair(RELAXED_PHYLIP_DNA_FORMAT, "relaxed Phylip DNA")); formatsToTry.push_back(FormatPair(INTERLEAVED_RELAXED_PHYLIP_DNA_FORMAT, "interleaved relaxed Phylip DNA")); formatsToTry.push_back(FormatPair(PHYLIP_DNA_FORMAT, "strict Phylip DNA")); formatsToTry.push_back(FormatPair(INTERLEAVED_PHYLIP_DNA_FORMAT, "interleaved strict Phylip DNA")); } formatsToTry.push_back(FormatPair(RELAXED_PHYLIP_RNA_FORMAT, "relaxed Phylip RNA")); formatsToTry.push_back(FormatPair(INTERLEAVED_RELAXED_PHYLIP_RNA_FORMAT, "interleaved relaxed Phylip RNA")); formatsToTry.push_back(FormatPair(PHYLIP_RNA_FORMAT, "strict Phylip RNA")); formatsToTry.push_back(FormatPair(INTERLEAVED_PHYLIP_RNA_FORMAT, "interleaved strict Phylip RNA")); } } //now start trying formats bool success; for(list<FormatPair>::iterator formIt = formatsToTry.begin();formIt != formatsToTry.end();formIt++){ success = true; try{ outman.UserMessage("Attempting to read data file %s as\n\t%s format (using NCL) ...", filename, (*formIt).second.c_str()); ReadFilepath(filename, (*formIt).first); }catch(NxsException err){ NexusError(err.msg, err.pos, err.line, err.col, false); outman.UserMessage("Problem reading data file as %s format...\n", (*formIt).second.c_str()); success = false; } if(success) break; } if(success == false) throw ErrorException("\nUnable to read data file %s in any format.\n", filename); else outman.UserMessage("\nData read successfully."); } return true; }
/** * @method Execute [void:public] * @param token [NexusToken&] the token object used to grab Nexus tokens * @param notifyStartStop [bool] if true, ExecuteStarting and ExecuteStopping will be called (true by default) * * Reads the Nexus data file from the input stream provided by token. This function * is responsible for reading through the name of a each block. Once * it has read a block name, it searches blockList for a block object * to handle reading the remainder of the block's contents. The block * object is responsible for reading the end or endblock command as well * as the trailing semicolon. This function also handles reading * comments that are outside of blocks, as well as the initial #NEXUS * keyword. The notifyStartStop argument is provided in case you do not * wish the ExecuteStart and ExecuteStop functions to be called. These functions * are primarily used for creating and destroying a dialog box to show progress, * and nested Execute calls can thus cause problems (e.g., a dialog box is * destroyed when the inner Execute calls ExecuteStop and the outer Execute * still expects the dialog box to be available). Specifying notifyStartStop * false for all the nested Execute calls thus allows the outermost Execute call * to control creation and destruction of the dialog box. */ void Nexus::Execute( NexusToken& token, bool notifyStartStop /* = true */ ) { char id_str[256]; bool disabledBlock = false; nxsstring errormsg; try { token.GetNextToken(); } catch( XNexus x ) { NexusError( token.errormsg, 0, 0, 0 ); return; } if( !token.Equals("#NEXUS") ) { errormsg = "Expecting #NEXUS to be the first token in the file, but found "; errormsg += token.GetToken(); errormsg += " instead"; NexusError( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); return; } if( notifyStartStop ) ExecuteStarting(); for(;;) { token.SetLabileFlagBit( NexusToken::saveCommandComments ); token.GetNextToken(); if( token.AtEOF() ) break; if( token.Equals("BEGIN") ) { disabledBlock = false; token.GetNextToken(); NexusBlock* curr; for( curr = blockList; curr != NULL; curr = curr->next ) { if( !token.Equals( curr->GetID() ) ) continue; if( !curr->IsEnabled() ) { disabledBlock = true; SkippingDisabledBlock( token.GetToken() ); continue; } strcpy( id_str, curr->GetID().c_str() ); EnteringBlock( id_str /*curr->GetID()*/ ); curr->Reset(); try { curr->Read( token ); } catch( XNexus x ) { NexusError( curr->errormsg, x.pos, x.line, x.col ); curr->Reset(); return; } ExitingBlock( id_str /*curr->GetID()*/ ); break; } if( curr == NULL ) { token.BlanksToUnderscores(); nxsstring currBlock = token.GetToken(); if( !disabledBlock ) SkippingBlock( currBlock ); for(;;) { token.GetNextToken(); if( token.Equals("END") || token.Equals("ENDBLOCK") ) { token.GetNextToken(); if( !token.Equals(";") ) { errormsg = "Expecting ';' after END or ENDBLOCK command, but found "; errormsg += token.GetToken(); errormsg += " instead"; NexusError( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); return; } break; } if( token.AtEOF() ) { errormsg = "Encountered end of file before END or ENDBLOCK in block "; errormsg += currBlock; NexusError( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); return; } } } // if token not found amongst known block IDs } // if token equals BEGIN else if( token.Equals("&SHOWALL") ) { NexusBlock* curr; for( curr = blockList; curr != NULL; curr = curr->next ) { DebugReportBlock(*curr); } } else if( token.Equals("&LEAVE") ) { break; } } // for(;;) if( notifyStartStop ) ExecuteStopping(); }