5 * Created by Pat Schloss on 8/15/08.
6 * Copyright 2008 Patrick D. Schloss. All rights reserved.
8 * There's a TON of duplicated code between InteractEngine and BatchEngine
9 * I couldn't figure out how to transition between ifstream (batch) and cin (interact)
10 * Fix later, don't have time now.
17 /***********************************************************************/
20 cFactory = CommandFactory::getInstance();
21 mout = MothurOut::getInstance();
24 mout->errorOut(e, "Engine", "Engine");
28 /***********************************************************************/
30 /***********************************************************************/
32 InteractEngine::InteractEngine(string path){
35 string temppath = path.substr(0, (path.find_last_of("othur")-5));
37 //this will happen if you set the path variable to contain mothur's exe location
38 if (temppath == "") { path = mout->findProgramPath("mothur"); }
43 /***********************************************************************/
45 InteractEngine::~InteractEngine(){}
47 /***********************************************************************/
48 //This function allows the user to input commands one line at a time until they quit.
49 //If the command is garbage it does nothing.
50 bool InteractEngine::getInput(){
53 string commandName = "";
55 int quitCommandCalled = 0;
57 while(quitCommandCalled != 1){
62 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
63 MPI_Comm_size(MPI_COMM_WORLD, &processors);
69 if (mout->changedSeqNames) { mout->mothurOut("[WARNING]: your sequence names contained ':'. I changed them to '_' to avoid problems in your downstream analysis.\n"); }
71 mout->mothurOutEndLine();
74 mout->mothurOutEndLine();
76 if (mout->control_pressed) { input = "quit()"; }
78 //allow user to omit the () on the quit command
79 if (input == "quit") { input = "quit()"; }
84 for(int i = 1; i < processors; i++) {
85 int length = input.length();
86 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
87 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
92 MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
94 char* tempBuf = new char[length];
95 MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
98 if (input.length() > length) { input = input.substr(0, length); }
105 CommandOptionParser parser(input);
106 commandName = parser.getCommandString();
108 options = parser.getOptionString();
110 if (commandName != "") {
111 mout->executing = true;
114 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
116 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
117 //cout << pid << " is in execute " << commandName << endl;
119 //executes valid command
120 mout->changedSeqNames = false;
121 mout->runParse = true;
123 mout->clearAllGroups();
124 mout->Treenames.clear();
125 mout->saveNextLabel = "";
126 mout->commandInputsConvertError = false;
127 mout->printedSharedHeaders = false;
128 mout->currentSharedBinLabels.clear();
129 mout->sharedBinLabelsInFile.clear();
130 mout->printedListHeaders = false;
131 mout->listBinLabelsInFile.clear();
133 Command* command = cFactory->getCommand(commandName, options);
134 if (mout->commandInputsConvertError) { quitCommandCalled = 2; }
135 else { quitCommandCalled = command->execute(); }
137 //if we aborted command
138 if (quitCommandCalled == 2) { mout->mothurOut("[ERROR]: did not complete " + commandName + "."); mout->mothurOutEndLine(); }
140 mout->control_pressed = 0;
141 mout->executing = false;
147 mout->mothurOut("Invalid.");
148 mout->mothurOutEndLine();
153 catch(exception& e) {
154 mout->errorOut(e, "InteractEngine", "getInput");
158 /***********************************************************************/
159 string Engine::getCommand() {
162 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
164 char* nextCommand = NULL;
165 nextCommand = readline("mothur > ");
167 if(nextCommand != NULL) { add_history(nextCommand); }
168 else{ //^D causes null string and we want it to quit mothur
169 nextCommand = strdup("quit");
170 mout->mothurOut(nextCommand);
173 mout->mothurOutJustToLog("mothur > " + toString(nextCommand));
176 string nextCommand = "";
177 mout->mothurOut("mothur > ");
178 getline(cin, nextCommand);
179 mout->mothurOutJustToLog("mothur > " + toString(nextCommand));
184 string nextCommand = "";
186 mout->mothurOut("mothur > ");
187 getline(cin, nextCommand);
188 mout->mothurOutJustToLog(toString(nextCommand));
195 catch(exception& e) {
196 mout->errorOut(e, "Engine", "getCommand");
200 /***********************************************************************/
201 //This function opens the batchfile to be used by BatchEngine::getInput.
202 BatchEngine::BatchEngine(string path, string batchFileName){
205 openedBatch = mout->openInputFile(batchFileName, inputBatchFile);
207 string temppath = path.substr(0, (path.find_last_of("othur")-5));
209 //this will happen if you set the path variable to contain mothur's exe location
210 if (temppath == "") { path = mout->findProgramPath("mothur"); }
215 catch(exception& e) {
216 mout->errorOut(e, "BatchEngine", "BatchEngine");
221 /***********************************************************************/
223 BatchEngine::~BatchEngine(){ }
225 /***********************************************************************/
226 //This Function allows the user to run a batchfile containing several commands on Dotur
227 bool BatchEngine::getInput(){
229 //check if this is a valid batchfile
230 if (openedBatch == 1) {
231 mout->mothurOut("unable to open batchfile");
232 mout->mothurOutEndLine();
237 string commandName = "";
240 //CommandFactory cFactory;
241 int quitCommandCalled = 0;
243 while(quitCommandCalled != 1){
248 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
249 MPI_Comm_size(MPI_COMM_WORLD, &processors);
255 input = getNextCommand(inputBatchFile);
260 for(int i = 1; i < processors; i++) {
261 int length = input.length();
262 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
263 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
268 MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
270 char* tempBuf = new char[length];
271 MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
274 if (input.length() > length) { input = input.substr(0, length); }
283 if (input[0] != '#') {
284 if (mout->changedSeqNames) { mout->mothurOut("[WARNING]: your sequence names contained ':'. I changed them to '_' to avoid problems in your downstream analysis.\n"); }
285 mout->mothurOutEndLine();
286 mout->mothurOut("mothur > " + input);
287 mout->mothurOutEndLine();
289 if (mout->control_pressed) { input = "quit()"; }
291 //allow user to omit the () on the quit command
292 if (input == "quit") { input = "quit()"; }
294 CommandOptionParser parser(input);
295 commandName = parser.getCommandString();
296 options = parser.getOptionString();
298 if (commandName != "") {
299 mout->executing = true;
302 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
304 //cout << pid << " is here " << commandName << '\t' << count << endl;
305 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
307 //executes valid command
308 mout->changedSeqNames = false;
309 mout->runParse = true;
311 mout->clearAllGroups();
312 mout->Treenames.clear();
313 mout->saveNextLabel = "";
314 mout->commandInputsConvertError = false;
315 mout->printedSharedHeaders = false;
316 mout->currentSharedBinLabels.clear();
317 mout->sharedBinLabelsInFile.clear();
318 mout->printedListHeaders = false;
319 mout->listBinLabelsInFile.clear();
322 Command* command = cFactory->getCommand(commandName, options);
323 if (mout->commandInputsConvertError) { quitCommandCalled = 2; }
324 else { quitCommandCalled = command->execute(); }
326 //if we aborted command
327 if (quitCommandCalled == 2) { mout->mothurOut("[ERROR]: did not complete " + commandName + "."); mout->mothurOutEndLine(); }
329 mout->control_pressed = 0;
330 mout->executing = false;
336 mout->mothurOut("Invalid.");
337 mout->mothurOutEndLine();
341 mout->gobble(inputBatchFile);
344 inputBatchFile.close();
347 catch(exception& e) {
348 mout->errorOut(e, "BatchEngine", "getInput");
352 /***********************************************************************/
353 string BatchEngine::getNextCommand(ifstream& inputBatchFile) {
356 string nextcommand = "";
358 if (inputBatchFile.eof()) { nextcommand = "quit()"; }
359 else { nextcommand = mout->getline(inputBatchFile); }
363 catch(exception& e) {
364 mout->errorOut(e, "BatchEngine", "getNextCommand");
369 /***********************************************************************/
370 /***********************************************************************/
371 //This function opens the batchfile to be used by BatchEngine::getInput.
372 ScriptEngine::ScriptEngine(string path, string commandString){
376 listOfCommands = commandString.substr(1, (commandString.length()-1));
378 string temppath = path.substr(0, (path.find_last_of("othur")-5));
380 //this will happen if you set the path variable to contain mothur's exe location
381 if (temppath == "") { path = mout->findProgramPath("mothur"); }
386 catch(exception& e) {
387 mout->errorOut(e, "ScriptEngine", "ScriptEngine");
392 /***********************************************************************/
394 ScriptEngine::~ScriptEngine(){ }
396 /***********************************************************************/
397 //This Function allows the user to run a batchfile containing several commands on mothur
398 bool ScriptEngine::getInput(){
402 string commandName = "";
406 //CommandFactory cFactory;
407 int quitCommandCalled = 0;
409 while(quitCommandCalled != 1){
414 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
415 MPI_Comm_size(MPI_COMM_WORLD, &processors);
421 input = getNextCommand(listOfCommands);
423 if (input == "") { input = "quit()"; }
425 if (mout->changedSeqNames) { mout->mothurOut("[WARNING]: your sequence names contained ':'. I changed them to '_' to avoid problems in your downstream analysis.\n"); }
428 if ((input.find("quit") != string::npos) || (input.find("set.logfile") != string::npos)) {}
429 else if ((input.find("get.current") != string::npos) && (!mout->hasCurrentFiles())) {}
430 else { mout->mothurOutEndLine(); mout->mothurOut("mothur > " + input); mout->mothurOutEndLine(); }
432 mout->mothurOutEndLine(); mout->mothurOut("mothur > " + input); mout->mothurOutEndLine();
437 for(int i = 1; i < processors; i++) {
438 int length = input.length();
439 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
440 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
445 MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
447 char* tempBuf = new char[length];
448 MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
451 if (input.length() > length) { input = input.substr(0, length); }
459 if (mout->control_pressed) { input = "quit()"; }
461 //allow user to omit the () on the quit command
462 if (input == "quit") { input = "quit()"; }
464 CommandOptionParser parser(input);
465 commandName = parser.getCommandString();
466 options = parser.getOptionString();
468 if (commandName != "") {
469 mout->executing = true;
471 int pid, numProcesses;
473 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
474 MPI_Comm_size(MPI_COMM_WORLD, &numProcesses);
476 //cout << pid << " is here " << commandName << endl;
477 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
478 //cout << pid << " is in execute" << endl;
480 //executes valid command
481 mout->changedSeqNames = false;
482 mout->runParse = true;
484 mout->clearAllGroups();
485 mout->Treenames.clear();
486 mout->saveNextLabel = "";
487 mout->commandInputsConvertError = false;
488 mout->printedSharedHeaders = false;
489 mout->currentSharedBinLabels.clear();
490 mout->sharedBinLabelsInFile.clear();
491 mout->printedListHeaders = false;
492 mout->listBinLabelsInFile.clear();
494 Command* command = cFactory->getCommand(commandName, options);
495 if (mout->commandInputsConvertError) { quitCommandCalled = 2; }
496 else { quitCommandCalled = command->execute(); }
498 //if we aborted command
499 if (quitCommandCalled == 2) { mout->mothurOut("[ERROR]: did not complete " + commandName + "."); mout->mothurOutEndLine(); }
501 mout->control_pressed = 0;
502 mout->executing = false;
505 //cout << pid << " is done in execute" << endl;
509 mout->mothurOut("Invalid.");
510 mout->mothurOutEndLine();
518 catch(exception& e) {
519 mout->errorOut(e, "ScriptEngine", "getInput");
523 /***********************************************************************/
524 string ScriptEngine::getNextCommand(string& commandString) {
527 string nextcommand = "";
529 bool ignoreSemiColons = false;
531 //go through string until you reach ; or end
532 while (count < commandString.length()) {
534 //you want to ignore any ; until you reach the next '
535 if ((commandString[count] == '\'') && (!ignoreSemiColons)) { ignoreSemiColons = true; }
536 else if ((commandString[count] == '\'') && (ignoreSemiColons)) { ignoreSemiColons = false; }
538 if ((commandString[count] == ';') && (!ignoreSemiColons)) { break; }
539 else { nextcommand += commandString[count]; }
544 //if you are not at the end
545 if (count != commandString.length()) { commandString = commandString.substr(count+1, commandString.length()); }
546 else { commandString = ""; }
549 //get rid of spaces in between commands if any
550 if (commandString.length() > 0) {
551 while (commandString[0] == ' ') {
552 commandString = commandString.substr(1,commandString.length());
553 if (commandString.length() == 0) { break; }
559 catch(exception& e) {
560 mout->errorOut(e, "ScriptEngine", "getNextCommand");
564 /***********************************************************************/