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");
29 /***********************************************************************/
31 InteractEngine::InteractEngine(string path){
33 globaldata = GlobalData::getInstance();
35 string temppath = path.substr(0, (path.find_last_of('m')));
37 //this will happen if you set the path variable to contain mothur's exe location
40 string envPath = getenv("PATH");
42 //delimiting path char
44 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
50 //break apart path variable by ':'
52 mout->splitAtChar(envPath, dirs, delim);
54 //get path related to mothur
55 string mothurPath = "";
56 for (int i = 0; i < dirs.size(); i++) {
57 //to lower so we can find it
58 string tempLower = "";
59 for (int j = 0; j < dirs[i].length(); j++) { tempLower += tolower(dirs[i][j]); }
61 //is this mothurs path?
62 if (tempLower.find("mothur") != -1) { mothurPath = dirs[i]; break; }
65 //add mothur so it looks like what argv would look like
66 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
67 mothurPath += "/mothur";
69 mothurPath += "\\mothur";
75 globaldata->argv = path;
78 /***********************************************************************/
80 InteractEngine::~InteractEngine(){}
82 /***********************************************************************/
83 //This function allows the user to input commands one line at a time until they quit.
84 //If the command is garbage it does nothing.
85 bool InteractEngine::getInput(){
88 string commandName = "";
90 int quitCommandCalled = 0;
92 while(quitCommandCalled != 1){
97 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
98 MPI_Comm_size(MPI_COMM_WORLD, &processors);
104 mout->mothurOutEndLine();
106 input = getCommand();
107 mout->mothurOutEndLine();
109 if (mout->control_pressed) { input = "quit()"; }
111 //allow user to omit the () on the quit command
112 if (input == "quit") { input = "quit()"; }
117 for(int i = 1; i < processors; i++) {
118 int length = input.length();
119 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
120 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
125 MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
127 char* tempBuf = new char[length];
128 MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
131 if (input.length() > length) { input = input.substr(0, length); }
138 CommandOptionParser parser(input);
139 commandName = parser.getCommandString();
141 options = parser.getOptionString();
143 if (commandName != "") {
144 mout->executing = true;
147 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
149 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
150 //cout << pid << " is in execute " << commandName << endl;
152 //executes valid command
153 Command* command = cFactory->getCommand(commandName, options);
154 quitCommandCalled = command->execute();
156 //if we aborted command
157 if (quitCommandCalled == 2) { mout->mothurOut("[ERROR]: did not complete " + commandName + "."); mout->mothurOutEndLine(); }
159 mout->control_pressed = 0;
160 mout->executing = false;
166 mout->mothurOut("Invalid.");
167 mout->mothurOutEndLine();
172 catch(exception& e) {
173 mout->errorOut(e, "InteractEngine", "getInput");
177 /***********************************************************************/
178 string Engine::getCommand() {
181 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
183 char* nextCommand = NULL;
184 nextCommand = readline("mothur > ");
186 if(nextCommand != NULL) { add_history(nextCommand); }
187 else{ //^D causes null string and we want it to quit mothur
188 strcpy(nextCommand, "quit");
189 mout->mothurOut(nextCommand);
192 mout->mothurOutJustToLog("mothur > " + toString(nextCommand));
195 string nextCommand = "";
196 mout->mothurOut("mothur > ");
197 getline(cin, nextCommand);
198 mout->mothurOutJustToLog("mothur > " + toString(nextCommand));
203 string nextCommand = "";
205 mout->mothurOut("mothur > ");
206 getline(cin, nextCommand);
207 mout->mothurOutJustToLog(toString(nextCommand));
214 catch(exception& e) {
215 mout->errorOut(e, "Engine", "getCommand");
219 /***********************************************************************/
220 //This function opens the batchfile to be used by BatchEngine::getInput.
221 BatchEngine::BatchEngine(string path, string batchFileName){
223 globaldata = GlobalData::getInstance();
225 openedBatch = mout->openInputFile(batchFileName, inputBatchFile);
227 string temppath = path.substr(0, (path.find_last_of('m')));
229 //this will happen if you set the path variable to contain mothur's exe location
230 if (temppath == "") {
232 string envPath = getenv("PATH");
234 //delimiting path char
236 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
242 //break apart path variable by ':'
244 mout->splitAtChar(envPath, dirs, delim);
246 //get path related to mothur
247 string mothurPath = "";
248 for (int i = 0; i < dirs.size(); i++) {
249 //to lower so we can find it
250 string tempLower = "";
251 for (int j = 0; j < dirs[i].length(); j++) { tempLower += tolower(dirs[i][j]); }
253 //is this mothurs path?
254 if (tempLower.find("mothur") != -1) { mothurPath = dirs[i]; break; }
257 //add mothur so it looks like what argv would look like
258 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
259 mothurPath += "/mothur";
261 mothurPath += "\\mothur";
267 globaldata->argv = path;
270 catch(exception& e) {
271 mout->errorOut(e, "BatchEngine", "BatchEngine");
276 /***********************************************************************/
278 BatchEngine::~BatchEngine(){ }
280 /***********************************************************************/
281 //This Function allows the user to run a batchfile containing several commands on Dotur
282 bool BatchEngine::getInput(){
284 //check if this is a valid batchfile
285 if (openedBatch == 1) {
286 mout->mothurOut("unable to open batchfile");
287 mout->mothurOutEndLine();
292 string commandName = "";
295 //CommandFactory cFactory;
296 int quitCommandCalled = 0;
298 while(quitCommandCalled != 1){
303 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
304 MPI_Comm_size(MPI_COMM_WORLD, &processors);
310 input = getNextCommand(inputBatchFile);
315 for(int i = 1; i < processors; i++) {
316 int length = input.length();
317 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
318 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
323 MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
325 char* tempBuf = new char[length];
326 MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
329 if (input.length() > length) { input = input.substr(0, length); }
338 if (input[0] != '#') {
340 mout->mothurOutEndLine();
341 mout->mothurOut("mothur > " + input);
342 mout->mothurOutEndLine();
344 if (mout->control_pressed) { input = "quit()"; }
346 //allow user to omit the () on the quit command
347 if (input == "quit") { input = "quit()"; }
349 CommandOptionParser parser(input);
350 commandName = parser.getCommandString();
351 options = parser.getOptionString();
353 if (commandName != "") {
354 mout->executing = true;
357 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
359 //cout << pid << " is here " << commandName << '\t' << count << endl;
360 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
362 //executes valid command
363 Command* command = cFactory->getCommand(commandName, options);
364 quitCommandCalled = command->execute();
366 //if we aborted command
367 if (quitCommandCalled == 2) { mout->mothurOut("[ERROR]: did not complete " + commandName + "."); mout->mothurOutEndLine(); }
369 mout->control_pressed = 0;
370 mout->executing = false;
376 mout->mothurOut("Invalid.");
377 mout->mothurOutEndLine();
381 mout->gobble(inputBatchFile);
384 inputBatchFile.close();
387 catch(exception& e) {
388 mout->errorOut(e, "BatchEngine", "getInput");
392 /***********************************************************************/
393 string BatchEngine::getNextCommand(ifstream& inputBatchFile) {
396 string nextcommand = "";
398 if (inputBatchFile.eof()) { nextcommand = "quit()"; }
399 else { nextcommand = mout->getline(inputBatchFile); }
403 catch(exception& e) {
404 mout->errorOut(e, "BatchEngine", "getNextCommand");
409 /***********************************************************************/
410 /***********************************************************************/
411 //This function opens the batchfile to be used by BatchEngine::getInput.
412 ScriptEngine::ScriptEngine(string path, string commandString){
414 globaldata = GlobalData::getInstance();
417 listOfCommands = commandString.substr(1, (commandString.length()-1));
419 string temppath = path.substr(0, (path.find_last_of('m')));
421 //this will happen if you set the path variable to contain mothur's exe location
422 if (temppath == "") {
424 string envPath = getenv("PATH");
426 //delimiting path char
428 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
434 //break apart path variable by ':'
436 mout->splitAtChar(envPath, dirs, delim);
438 //get path related to mothur
439 string mothurPath = "";
440 for (int i = 0; i < dirs.size(); i++) {
441 //to lower so we can find it
442 string tempLower = "";
443 for (int j = 0; j < dirs[i].length(); j++) { tempLower += tolower(dirs[i][j]); }
445 //is this mothurs path?
446 if (tempLower.find("mothur") != -1) { mothurPath = dirs[i]; break; }
449 //add mothur so it looks like what argv would look like
450 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
451 mothurPath += "/mothur";
453 mothurPath += "\\mothur";
459 globaldata->argv = path;
462 catch(exception& e) {
463 mout->errorOut(e, "ScriptEngine", "ScriptEngine");
468 /***********************************************************************/
470 ScriptEngine::~ScriptEngine(){ }
472 /***********************************************************************/
473 //This Function allows the user to run a batchfile containing several commands on mothur
474 bool ScriptEngine::getInput(){
478 string commandName = "";
482 //CommandFactory cFactory;
483 int quitCommandCalled = 0;
485 while(quitCommandCalled != 1){
490 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
491 MPI_Comm_size(MPI_COMM_WORLD, &processors);
497 input = getNextCommand(listOfCommands);
499 if (input == "") { input = "quit()"; }
501 mout->mothurOutEndLine();
502 mout->mothurOut("mothur > " + input);
503 mout->mothurOutEndLine();
507 for(int i = 1; i < processors; i++) {
508 int length = input.length();
509 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
510 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
515 MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
517 char* tempBuf = new char[length];
518 MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
521 if (input.length() > length) { input = input.substr(0, length); }
529 if (mout->control_pressed) { input = "quit()"; }
531 //allow user to omit the () on the quit command
532 if (input == "quit") { input = "quit()"; }
534 CommandOptionParser parser(input);
535 commandName = parser.getCommandString();
536 options = parser.getOptionString();
538 if (commandName != "") {
539 mout->executing = true;
541 int pid, numProcesses;
543 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
544 MPI_Comm_size(MPI_COMM_WORLD, &numProcesses);
546 //cout << pid << " is here " << commandName << endl;
547 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
548 //cout << pid << " is in execute" << endl;
550 //executes valid command
551 Command* command = cFactory->getCommand(commandName, options);
552 quitCommandCalled = command->execute();
554 //if we aborted command
555 if (quitCommandCalled == 2) { mout->mothurOut("[ERROR]: did not complete " + commandName + "."); mout->mothurOutEndLine(); }
557 mout->control_pressed = 0;
558 mout->executing = false;
561 //cout << pid << " is done in execute" << endl;
565 mout->mothurOut("Invalid.");
566 mout->mothurOutEndLine();
574 catch(exception& e) {
575 mout->errorOut(e, "ScriptEngine", "getInput");
579 /***********************************************************************/
580 string ScriptEngine::getNextCommand(string& commandString) {
583 string nextcommand = "";
585 bool ignoreSemiColons = false;
587 //go through string until you reach ; or end
588 while (count < commandString.length()) {
590 //you want to ignore any ; until you reach the next '
591 if ((commandString[count] == '\'') && (!ignoreSemiColons)) { ignoreSemiColons = true; }
592 else if ((commandString[count] == '\'') && (ignoreSemiColons)) { ignoreSemiColons = false; }
594 if ((commandString[count] == ';') && (!ignoreSemiColons)) { break; }
595 else { nextcommand += commandString[count]; }
600 //if you are not at the end
601 if (count != commandString.length()) { commandString = commandString.substr(count+1, commandString.length()); }
602 else { commandString = ""; }
605 //get rid of spaces in between commands if any
606 if (commandString.length() > 0) {
607 while (commandString[0] == ' ') {
608 commandString = commandString.substr(1,commandString.length());
609 if (commandString.length() == 0) { break; }
615 catch(exception& e) {
616 mout->errorOut(e, "ScriptEngine", "getNextCommand");
620 /***********************************************************************/