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 /***********************************************************************/
29 string Engine::findMothursPath(){
32 string envPath = getenv("PATH");
33 string mothurPath = "";
35 //delimiting path char
37 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
43 //break apart path variable by ':'
45 mout->splitAtChar(envPath, dirs, delim);
47 //get path related to mothur
48 for (int i = 0; i < dirs.size(); i++) {
49 //to lower so we can find it
50 string tempLower = "";
51 for (int j = 0; j < dirs[i].length(); j++) { tempLower += tolower(dirs[i][j]); }
53 //is this mothurs path?
54 if (tempLower.find("mothur") != -1) { mothurPath = dirs[i]; break; }
57 if (mothurPath != "") {
58 //add mothur so it looks like what argv would look like
59 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
60 mothurPath += "/mothur";
62 mothurPath += "\\mothur";
65 //okay mothur is not in the path, so the folder mothur is in must be in the path
66 //lets find out which one
68 //get path related to mothur
69 for (int i = 0; i < dirs.size(); i++) {
71 //is this mothurs path?
73 string tempIn = dirs[i];
74 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
79 mout->openInputFile(tempIn, in, "");
82 if (in) { in.close(); mothurPath = tempIn; break; }
90 mout->errorOut(e, "Engine", "findMothursPath");
94 /***********************************************************************/
96 InteractEngine::InteractEngine(string path){
98 globaldata = GlobalData::getInstance();
100 string temppath = path.substr(0, (path.find_last_of("othur")-5));
102 //this will happen if you set the path variable to contain mothur's exe location
103 if (temppath == "") { path = findMothursPath(); }
105 globaldata->argv = path;
108 /***********************************************************************/
110 InteractEngine::~InteractEngine(){}
112 /***********************************************************************/
113 //This function allows the user to input commands one line at a time until they quit.
114 //If the command is garbage it does nothing.
115 bool InteractEngine::getInput(){
118 string commandName = "";
120 int quitCommandCalled = 0;
122 while(quitCommandCalled != 1){
127 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
128 MPI_Comm_size(MPI_COMM_WORLD, &processors);
134 mout->mothurOutEndLine();
136 input = getCommand();
137 mout->mothurOutEndLine();
139 if (mout->control_pressed) { input = "quit()"; }
141 //allow user to omit the () on the quit command
142 if (input == "quit") { input = "quit()"; }
147 for(int i = 1; i < processors; i++) {
148 int length = input.length();
149 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
150 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
155 MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
157 char* tempBuf = new char[length];
158 MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
161 if (input.length() > length) { input = input.substr(0, length); }
168 CommandOptionParser parser(input);
169 commandName = parser.getCommandString();
171 options = parser.getOptionString();
173 if (commandName != "") {
174 mout->executing = true;
177 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
179 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
180 //cout << pid << " is in execute " << commandName << endl;
182 //executes valid command
183 Command* command = cFactory->getCommand(commandName, options);
184 quitCommandCalled = command->execute();
186 //if we aborted command
187 if (quitCommandCalled == 2) { mout->mothurOut("[ERROR]: did not complete " + commandName + "."); mout->mothurOutEndLine(); }
189 mout->control_pressed = 0;
190 mout->executing = false;
196 mout->mothurOut("Invalid.");
197 mout->mothurOutEndLine();
202 catch(exception& e) {
203 mout->errorOut(e, "InteractEngine", "getInput");
207 /***********************************************************************/
208 string Engine::getCommand() {
211 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
213 char* nextCommand = NULL;
214 nextCommand = readline("mothur > ");
216 if(nextCommand != NULL) { add_history(nextCommand); }
217 else{ //^D causes null string and we want it to quit mothur
218 strcpy(nextCommand, "quit");
219 mout->mothurOut(nextCommand);
222 mout->mothurOutJustToLog("mothur > " + toString(nextCommand));
225 string nextCommand = "";
226 mout->mothurOut("mothur > ");
227 getline(cin, nextCommand);
228 mout->mothurOutJustToLog("mothur > " + toString(nextCommand));
233 string nextCommand = "";
235 mout->mothurOut("mothur > ");
236 getline(cin, nextCommand);
237 mout->mothurOutJustToLog(toString(nextCommand));
244 catch(exception& e) {
245 mout->errorOut(e, "Engine", "getCommand");
249 /***********************************************************************/
250 //This function opens the batchfile to be used by BatchEngine::getInput.
251 BatchEngine::BatchEngine(string path, string batchFileName){
253 globaldata = GlobalData::getInstance();
255 openedBatch = mout->openInputFile(batchFileName, inputBatchFile);
257 string temppath = path.substr(0, (path.find_last_of("othur")-5));
259 //this will happen if you set the path variable to contain mothur's exe location
260 if (temppath == "") { path = findMothursPath(); }
262 globaldata->argv = path;
265 catch(exception& e) {
266 mout->errorOut(e, "BatchEngine", "BatchEngine");
271 /***********************************************************************/
273 BatchEngine::~BatchEngine(){ }
275 /***********************************************************************/
276 //This Function allows the user to run a batchfile containing several commands on Dotur
277 bool BatchEngine::getInput(){
279 //check if this is a valid batchfile
280 if (openedBatch == 1) {
281 mout->mothurOut("unable to open batchfile");
282 mout->mothurOutEndLine();
287 string commandName = "";
290 //CommandFactory cFactory;
291 int quitCommandCalled = 0;
293 while(quitCommandCalled != 1){
298 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
299 MPI_Comm_size(MPI_COMM_WORLD, &processors);
305 input = getNextCommand(inputBatchFile);
310 for(int i = 1; i < processors; i++) {
311 int length = input.length();
312 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
313 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
318 MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
320 char* tempBuf = new char[length];
321 MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
324 if (input.length() > length) { input = input.substr(0, length); }
333 if (input[0] != '#') {
335 mout->mothurOutEndLine();
336 mout->mothurOut("mothur > " + input);
337 mout->mothurOutEndLine();
339 if (mout->control_pressed) { input = "quit()"; }
341 //allow user to omit the () on the quit command
342 if (input == "quit") { input = "quit()"; }
344 CommandOptionParser parser(input);
345 commandName = parser.getCommandString();
346 options = parser.getOptionString();
348 if (commandName != "") {
349 mout->executing = true;
352 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
354 //cout << pid << " is here " << commandName << '\t' << count << endl;
355 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
357 //executes valid command
358 Command* command = cFactory->getCommand(commandName, options);
359 quitCommandCalled = command->execute();
361 //if we aborted command
362 if (quitCommandCalled == 2) { mout->mothurOut("[ERROR]: did not complete " + commandName + "."); mout->mothurOutEndLine(); }
364 mout->control_pressed = 0;
365 mout->executing = false;
371 mout->mothurOut("Invalid.");
372 mout->mothurOutEndLine();
376 mout->gobble(inputBatchFile);
379 inputBatchFile.close();
382 catch(exception& e) {
383 mout->errorOut(e, "BatchEngine", "getInput");
387 /***********************************************************************/
388 string BatchEngine::getNextCommand(ifstream& inputBatchFile) {
391 string nextcommand = "";
393 if (inputBatchFile.eof()) { nextcommand = "quit()"; }
394 else { nextcommand = mout->getline(inputBatchFile); }
398 catch(exception& e) {
399 mout->errorOut(e, "BatchEngine", "getNextCommand");
404 /***********************************************************************/
405 /***********************************************************************/
406 //This function opens the batchfile to be used by BatchEngine::getInput.
407 ScriptEngine::ScriptEngine(string path, string commandString){
409 globaldata = GlobalData::getInstance();
412 listOfCommands = commandString.substr(1, (commandString.length()-1));
414 string temppath = path.substr(0, (path.find_last_of("othur")-5));
416 //this will happen if you set the path variable to contain mothur's exe location
417 if (temppath == "") { path = findMothursPath(); }
419 globaldata->argv = path;
422 catch(exception& e) {
423 mout->errorOut(e, "ScriptEngine", "ScriptEngine");
428 /***********************************************************************/
430 ScriptEngine::~ScriptEngine(){ }
432 /***********************************************************************/
433 //This Function allows the user to run a batchfile containing several commands on mothur
434 bool ScriptEngine::getInput(){
438 string commandName = "";
442 //CommandFactory cFactory;
443 int quitCommandCalled = 0;
445 while(quitCommandCalled != 1){
450 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
451 MPI_Comm_size(MPI_COMM_WORLD, &processors);
457 input = getNextCommand(listOfCommands);
459 if (input == "") { input = "quit()"; }
461 mout->mothurOutEndLine();
462 mout->mothurOut("mothur > " + input);
463 mout->mothurOutEndLine();
467 for(int i = 1; i < processors; i++) {
468 int length = input.length();
469 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
470 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
475 MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
477 char* tempBuf = new char[length];
478 MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
481 if (input.length() > length) { input = input.substr(0, length); }
489 if (mout->control_pressed) { input = "quit()"; }
491 //allow user to omit the () on the quit command
492 if (input == "quit") { input = "quit()"; }
494 CommandOptionParser parser(input);
495 commandName = parser.getCommandString();
496 options = parser.getOptionString();
498 if (commandName != "") {
499 mout->executing = true;
501 int pid, numProcesses;
503 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
504 MPI_Comm_size(MPI_COMM_WORLD, &numProcesses);
506 //cout << pid << " is here " << commandName << endl;
507 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
508 //cout << pid << " is in execute" << endl;
510 //executes valid command
511 Command* command = cFactory->getCommand(commandName, options);
512 quitCommandCalled = command->execute();
514 //if we aborted command
515 if (quitCommandCalled == 2) { mout->mothurOut("[ERROR]: did not complete " + commandName + "."); mout->mothurOutEndLine(); }
517 mout->control_pressed = 0;
518 mout->executing = false;
521 //cout << pid << " is done in execute" << endl;
525 mout->mothurOut("Invalid.");
526 mout->mothurOutEndLine();
534 catch(exception& e) {
535 mout->errorOut(e, "ScriptEngine", "getInput");
539 /***********************************************************************/
540 string ScriptEngine::getNextCommand(string& commandString) {
543 string nextcommand = "";
545 bool ignoreSemiColons = false;
547 //go through string until you reach ; or end
548 while (count < commandString.length()) {
550 //you want to ignore any ; until you reach the next '
551 if ((commandString[count] == '\'') && (!ignoreSemiColons)) { ignoreSemiColons = true; }
552 else if ((commandString[count] == '\'') && (ignoreSemiColons)) { ignoreSemiColons = false; }
554 if ((commandString[count] == ';') && (!ignoreSemiColons)) { break; }
555 else { nextcommand += commandString[count]; }
560 //if you are not at the end
561 if (count != commandString.length()) { commandString = commandString.substr(count+1, commandString.length()); }
562 else { commandString = ""; }
565 //get rid of spaces in between commands if any
566 if (commandString.length() > 0) {
567 while (commandString[0] == ' ') {
568 commandString = commandString.substr(1,commandString.length());
569 if (commandString.length() == 0) { break; }
575 catch(exception& e) {
576 mout->errorOut(e, "ScriptEngine", "getNextCommand");
580 /***********************************************************************/