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 mout->mothurOutEndLine();
72 mout->mothurOutEndLine();
74 if (mout->control_pressed) { input = "quit()"; }
76 //allow user to omit the () on the quit command
77 if (input == "quit") { input = "quit()"; }
82 for(int i = 1; i < processors; i++) {
83 int length = input.length();
84 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
85 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
90 MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
92 char* tempBuf = new char[length];
93 MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
96 if (input.length() > length) { input = input.substr(0, length); }
103 CommandOptionParser parser(input);
104 commandName = parser.getCommandString();
106 options = parser.getOptionString();
108 if (commandName != "") {
109 mout->executing = true;
112 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
114 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
115 //cout << pid << " is in execute " << commandName << endl;
117 //executes valid command
118 mout->runParse = true;
120 mout->clearAllGroups();
121 mout->Treenames.clear();
122 mout->saveNextLabel = "";
123 mout->printedHeaders = false;
124 mout->commandInputsConvertError = false;
125 mout->currentBinLabels.clear();
126 mout->binLabelsInFile.clear();
128 Command* command = cFactory->getCommand(commandName, options);
129 if (mout->commandInputsConvertError) { quitCommandCalled = 2; }
130 else { quitCommandCalled = command->execute(); }
132 //if we aborted command
133 if (quitCommandCalled == 2) { mout->mothurOut("[ERROR]: did not complete " + commandName + "."); mout->mothurOutEndLine(); }
135 mout->control_pressed = 0;
136 mout->executing = false;
142 mout->mothurOut("Invalid.");
143 mout->mothurOutEndLine();
148 catch(exception& e) {
149 mout->errorOut(e, "InteractEngine", "getInput");
153 /***********************************************************************/
154 string Engine::getCommand() {
157 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
159 char* nextCommand = NULL;
160 nextCommand = readline("mothur > ");
162 if(nextCommand != NULL) { add_history(nextCommand); }
163 else{ //^D causes null string and we want it to quit mothur
164 nextCommand = strdup("quit");
165 mout->mothurOut(nextCommand);
168 mout->mothurOutJustToLog("mothur > " + toString(nextCommand));
171 string nextCommand = "";
172 mout->mothurOut("mothur > ");
173 getline(cin, nextCommand);
174 mout->mothurOutJustToLog("mothur > " + toString(nextCommand));
179 string nextCommand = "";
181 mout->mothurOut("mothur > ");
182 getline(cin, nextCommand);
183 mout->mothurOutJustToLog(toString(nextCommand));
190 catch(exception& e) {
191 mout->errorOut(e, "Engine", "getCommand");
195 /***********************************************************************/
196 //This function opens the batchfile to be used by BatchEngine::getInput.
197 BatchEngine::BatchEngine(string path, string batchFileName){
200 openedBatch = mout->openInputFile(batchFileName, inputBatchFile);
202 string temppath = path.substr(0, (path.find_last_of("othur")-5));
204 //this will happen if you set the path variable to contain mothur's exe location
205 if (temppath == "") { path = mout->findProgramPath("mothur"); }
210 catch(exception& e) {
211 mout->errorOut(e, "BatchEngine", "BatchEngine");
216 /***********************************************************************/
218 BatchEngine::~BatchEngine(){ }
220 /***********************************************************************/
221 //This Function allows the user to run a batchfile containing several commands on Dotur
222 bool BatchEngine::getInput(){
224 //check if this is a valid batchfile
225 if (openedBatch == 1) {
226 mout->mothurOut("unable to open batchfile");
227 mout->mothurOutEndLine();
232 string commandName = "";
235 //CommandFactory cFactory;
236 int quitCommandCalled = 0;
238 while(quitCommandCalled != 1){
243 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
244 MPI_Comm_size(MPI_COMM_WORLD, &processors);
250 input = getNextCommand(inputBatchFile);
255 for(int i = 1; i < processors; i++) {
256 int length = input.length();
257 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
258 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
263 MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
265 char* tempBuf = new char[length];
266 MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
269 if (input.length() > length) { input = input.substr(0, length); }
278 if (input[0] != '#') {
280 mout->mothurOutEndLine();
281 mout->mothurOut("mothur > " + input);
282 mout->mothurOutEndLine();
284 if (mout->control_pressed) { input = "quit()"; }
286 //allow user to omit the () on the quit command
287 if (input == "quit") { input = "quit()"; }
289 CommandOptionParser parser(input);
290 commandName = parser.getCommandString();
291 options = parser.getOptionString();
293 if (commandName != "") {
294 mout->executing = true;
297 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
299 //cout << pid << " is here " << commandName << '\t' << count << endl;
300 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
302 //executes valid command
303 mout->runParse = true;
305 mout->clearAllGroups();
306 mout->Treenames.clear();
307 mout->saveNextLabel = "";
308 mout->printedHeaders = false;
309 mout->commandInputsConvertError = false;
310 mout->currentBinLabels.clear();
311 mout->binLabelsInFile.clear();
314 Command* command = cFactory->getCommand(commandName, options);
315 if (mout->commandInputsConvertError) { quitCommandCalled = 2; }
316 else { quitCommandCalled = command->execute(); }
318 //if we aborted command
319 if (quitCommandCalled == 2) { mout->mothurOut("[ERROR]: did not complete " + commandName + "."); mout->mothurOutEndLine(); }
321 mout->control_pressed = 0;
322 mout->executing = false;
328 mout->mothurOut("Invalid.");
329 mout->mothurOutEndLine();
333 mout->gobble(inputBatchFile);
336 inputBatchFile.close();
339 catch(exception& e) {
340 mout->errorOut(e, "BatchEngine", "getInput");
344 /***********************************************************************/
345 string BatchEngine::getNextCommand(ifstream& inputBatchFile) {
348 string nextcommand = "";
350 if (inputBatchFile.eof()) { nextcommand = "quit()"; }
351 else { nextcommand = mout->getline(inputBatchFile); }
355 catch(exception& e) {
356 mout->errorOut(e, "BatchEngine", "getNextCommand");
361 /***********************************************************************/
362 /***********************************************************************/
363 //This function opens the batchfile to be used by BatchEngine::getInput.
364 ScriptEngine::ScriptEngine(string path, string commandString){
368 listOfCommands = commandString.substr(1, (commandString.length()-1));
370 string temppath = path.substr(0, (path.find_last_of("othur")-5));
372 //this will happen if you set the path variable to contain mothur's exe location
373 if (temppath == "") { path = mout->findProgramPath("mothur"); }
378 catch(exception& e) {
379 mout->errorOut(e, "ScriptEngine", "ScriptEngine");
384 /***********************************************************************/
386 ScriptEngine::~ScriptEngine(){ }
388 /***********************************************************************/
389 //This Function allows the user to run a batchfile containing several commands on mothur
390 bool ScriptEngine::getInput(){
394 string commandName = "";
398 //CommandFactory cFactory;
399 int quitCommandCalled = 0;
401 while(quitCommandCalled != 1){
406 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
407 MPI_Comm_size(MPI_COMM_WORLD, &processors);
413 input = getNextCommand(listOfCommands);
415 if (input == "") { input = "quit()"; }
418 if ((input.find("quit") != string::npos) || (input.find("set.logfile") != string::npos)) {}
419 else if ((input.find("get.current") != string::npos) && (!mout->hasCurrentFiles())) {}
420 else { mout->mothurOutEndLine(); mout->mothurOut("mothur > " + input); mout->mothurOutEndLine(); }
422 mout->mothurOutEndLine(); mout->mothurOut("mothur > " + input); mout->mothurOutEndLine();
427 for(int i = 1; i < processors; i++) {
428 int length = input.length();
429 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
430 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
435 MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
437 char* tempBuf = new char[length];
438 MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
441 if (input.length() > length) { input = input.substr(0, length); }
449 if (mout->control_pressed) { input = "quit()"; }
451 //allow user to omit the () on the quit command
452 if (input == "quit") { input = "quit()"; }
454 CommandOptionParser parser(input);
455 commandName = parser.getCommandString();
456 options = parser.getOptionString();
458 if (commandName != "") {
459 mout->executing = true;
461 int pid, numProcesses;
463 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
464 MPI_Comm_size(MPI_COMM_WORLD, &numProcesses);
466 //cout << pid << " is here " << commandName << endl;
467 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
468 //cout << pid << " is in execute" << endl;
470 //executes valid command
471 mout->runParse = true;
473 mout->clearAllGroups();
474 mout->Treenames.clear();
475 mout->saveNextLabel = "";
476 mout->printedHeaders = false;
477 mout->commandInputsConvertError = false;
478 mout->currentBinLabels.clear();
479 mout->binLabelsInFile.clear();
481 Command* command = cFactory->getCommand(commandName, options);
482 if (mout->commandInputsConvertError) { quitCommandCalled = 2; }
483 else { quitCommandCalled = command->execute(); }
485 //if we aborted command
486 if (quitCommandCalled == 2) { mout->mothurOut("[ERROR]: did not complete " + commandName + "."); mout->mothurOutEndLine(); }
488 mout->control_pressed = 0;
489 mout->executing = false;
492 //cout << pid << " is done in execute" << endl;
496 mout->mothurOut("Invalid.");
497 mout->mothurOutEndLine();
505 catch(exception& e) {
506 mout->errorOut(e, "ScriptEngine", "getInput");
510 /***********************************************************************/
511 string ScriptEngine::getNextCommand(string& commandString) {
514 string nextcommand = "";
516 bool ignoreSemiColons = false;
518 //go through string until you reach ; or end
519 while (count < commandString.length()) {
521 //you want to ignore any ; until you reach the next '
522 if ((commandString[count] == '\'') && (!ignoreSemiColons)) { ignoreSemiColons = true; }
523 else if ((commandString[count] == '\'') && (ignoreSemiColons)) { ignoreSemiColons = false; }
525 if ((commandString[count] == ';') && (!ignoreSemiColons)) { break; }
526 else { nextcommand += commandString[count]; }
531 //if you are not at the end
532 if (count != commandString.length()) { commandString = commandString.substr(count+1, commandString.length()); }
533 else { commandString = ""; }
536 //get rid of spaces in between commands if any
537 if (commandString.length() > 0) {
538 while (commandString[0] == ' ') {
539 commandString = commandString.substr(1,commandString.length());
540 if (commandString.length() == 0) { break; }
546 catch(exception& e) {
547 mout->errorOut(e, "ScriptEngine", "getNextCommand");
551 /***********************************************************************/