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();
34 globaldata->argv = path;
38 /***********************************************************************/
40 InteractEngine::~InteractEngine(){}
42 /***********************************************************************/
43 //This function allows the user to input commands one line at a time until they quit.
44 //If the command is garbage it does nothing.
45 bool InteractEngine::getInput(){
48 string commandName = "";
50 int quitCommandCalled = 0;
52 while(quitCommandCalled != 1){
54 mout->mothurOutEndLine();
57 mout->mothurOutEndLine();
59 if (mout->control_pressed) { input = "quit()"; }
61 //allow user to omit the () on the quit command
62 if (input == "quit") { input = "quit()"; }
64 CommandOptionParser parser(input);
65 commandName = parser.getCommandString();
67 options = parser.getOptionString();
69 if (commandName != "") {
70 mout->executing = true;
73 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
75 if ((pid != 0) && !(cFactory->MPIEnabled(commandName))) {
76 cout << pid << " is waiting " << commandName << endl;
78 MPI_Bcast(buf, 4, MPI_CHAR, 0, MPI_COMM_WORLD); //make everyone wait - just in case
81 cout << pid << " is here " << commandName << endl;
82 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
84 //executes valid command
85 Command* command = cFactory->getCommand(commandName, options);
86 quitCommandCalled = command->execute();
87 mout->control_pressed = 0;
88 mout->executing = false;
91 if (!(cFactory->MPIEnabled(commandName))) {
95 MPI_Bcast(buf, 4, MPI_CHAR, 0, MPI_COMM_WORLD); //make everyone wait - just in case
96 cout << pid << " is broadcasting " << endl;
101 mout->mothurOut("Invalid.");
102 mout->mothurOutEndLine();
107 catch(exception& e) {
108 mout->errorOut(e, "InteractEngine", "getInput");
112 /***********************************************************************/
113 string Engine::getCommand() {
115 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
117 char* nextCommand = NULL;
118 nextCommand = readline("mothur > ");
120 if(nextCommand != NULL) { add_history(nextCommand); }
121 else{ //^D causes null string and we want it to quit mothur
122 nextCommand = "quit";
123 mout->mothurOut(nextCommand);
126 mout->mothurOutJustToLog("mothur > " + toString(nextCommand));
129 string nextCommand = "";
130 mout->mothurOut("mothur > ");
131 getline(cin, nextCommand);
132 mout->mothurOutJustToLog("mothur > " + toString(nextCommand));
137 string nextCommand = "";
139 mout->mothurOut("mothur > ");
140 getline(cin, nextCommand);
141 mout->mothurOutJustToLog(toString(nextCommand));
148 catch(exception& e) {
149 mout->errorOut(e, "Engine", "getCommand");
153 /***********************************************************************/
154 //This function opens the batchfile to be used by BatchEngine::getInput.
155 BatchEngine::BatchEngine(string path, string batchFileName){
157 globaldata = GlobalData::getInstance();
159 openedBatch = openInputFile(batchFileName, inputBatchFile);
160 globaldata->argv = path;
163 catch(exception& e) {
164 mout->errorOut(e, "BatchEngine", "BatchEngine");
169 /***********************************************************************/
171 BatchEngine::~BatchEngine(){ }
173 /***********************************************************************/
174 //This Function allows the user to run a batchfile containing several commands on Dotur
175 bool BatchEngine::getInput(){
177 //check if this is a valid batchfile
178 if (openedBatch == 1) {
179 mout->mothurOut("unable to open batchfile");
180 mout->mothurOutEndLine();
185 string commandName = "";
188 //CommandFactory cFactory;
189 int quitCommandCalled = 0;
191 while(quitCommandCalled == 0){
193 if (inputBatchFile.eof()) { input = "quit()"; }
194 else { input = getline(inputBatchFile); }
196 if (input[0] != '#') {
198 mout->mothurOutEndLine();
199 mout->mothurOut("mothur > " + input);
200 mout->mothurOutEndLine();
202 if (mout->control_pressed) { input = "quit()"; }
204 //allow user to omit the () on the quit command
205 if (input == "quit") { input = "quit()"; }
207 CommandOptionParser parser(input);
208 commandName = parser.getCommandString();
209 options = parser.getOptionString();
211 if (commandName != "") {
212 mout->executing = true;
215 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
217 if ((pid != 0) && !(cFactory->MPIEnabled(commandName))) {
218 cout << pid << " is waiting " << commandName << endl;
220 MPI_Bcast(buf, 4, MPI_CHAR, 0, MPI_COMM_WORLD); //make everyone wait - just in case
223 cout << pid << " is here " << commandName << endl;
224 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
226 //executes valid command
227 Command* command = cFactory->getCommand(commandName, options);
228 quitCommandCalled = command->execute();
229 mout->control_pressed = 0;
230 mout->executing = false;
233 if (!(cFactory->MPIEnabled(commandName))) {
237 MPI_Bcast(buf, 4, MPI_CHAR, 0, MPI_COMM_WORLD); //make everyone wait - just in case
238 cout << pid << " is broadcasting " << endl;
243 mout->mothurOut("Invalid.");
244 mout->mothurOutEndLine();
248 gobble(inputBatchFile);
251 inputBatchFile.close();
254 catch(exception& e) {
255 mout->errorOut(e, "BatchEngine", "getInput");
261 /***********************************************************************/
262 /***********************************************************************/
263 //This function opens the batchfile to be used by BatchEngine::getInput.
264 ScriptEngine::ScriptEngine(string path, string commandString){
266 globaldata = GlobalData::getInstance();
269 listOfCommands = commandString.substr(1, (commandString.length()-1));
271 globaldata->argv = path;
274 catch(exception& e) {
275 mout->errorOut(e, "ScriptEngine", "ScriptEngine");
280 /***********************************************************************/
282 ScriptEngine::~ScriptEngine(){ }
284 /***********************************************************************/
285 //This Function allows the user to run a batchfile containing several commands on mothur
286 bool ScriptEngine::getInput(){
290 string commandName = "";
294 //CommandFactory cFactory;
295 int quitCommandCalled = 0;
297 while(quitCommandCalled == 0){
299 input = getNextCommand(listOfCommands);
301 if (input == "") { input = "quit()"; }
303 mout->mothurOutEndLine();
304 mout->mothurOut("mothur > " + input);
305 mout->mothurOutEndLine();
307 if (mout->control_pressed) { input = "quit()"; }
309 //allow user to omit the () on the quit command
310 if (input == "quit") { input = "quit()"; }
312 CommandOptionParser parser(input);
313 commandName = parser.getCommandString();
314 options = parser.getOptionString();
316 if (commandName != "") {
317 mout->executing = true;
319 int pid, numProcesses;
321 //MPI_Request request;
323 MPI_Comm_rank(MPI_COMM_WORLD, &pid);
324 MPI_Comm_size(MPI_COMM_WORLD, &numProcesses);
326 if ((pid != 0) && (!(cFactory->MPIEnabled(commandName)))) {
327 cout << pid << " is waiting " << commandName << endl;
330 MPI_Recv(buf, 12, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status); //make everyone wait - just in case
331 //MPI_Wait(&request, &status);
332 cout << pid << " received " << buf << endl;
336 cout << pid << " is here " << commandName << endl;
337 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
338 cout << pid << " is in execute" << endl;
340 //executes valid command
341 Command* command = cFactory->getCommand(commandName, options);
342 quitCommandCalled = command->execute();
343 mout->control_pressed = 0;
344 mout->executing = false;
347 cout << pid << " is done in execute" << endl;
348 if ((pid == 0) && (!(cFactory->MPIEnabled(commandName)))) {
350 strcpy(buf, "command done");
352 for(int i = 1; i < numProcesses; i++) {
353 MPI_Send(buf, 12, MPI_CHAR, i, 2001, MPI_COMM_WORLD); //make everyone wait - just in case
354 //MPI_Wait(&request, &status);
355 cout << pid << " sent " << buf << endl;
357 cout << pid << " is sending " << endl;
362 mout->mothurOut("Invalid.");
363 mout->mothurOutEndLine();
371 catch(exception& e) {
372 mout->errorOut(e, "ScriptEngine", "getInput");
376 /***********************************************************************/
377 string ScriptEngine::getNextCommand(string& commandString) {
381 int ierr = MPI_Barrier(MPI_COMM_WORLD);
382 cout << "barrier = " << ierr << endl;
385 string nextcommand = "";
388 //go through string until you reach ; or end
389 while (count < commandString.length()) {
391 if (commandString[count] == ';') { break; }
392 else { nextcommand += commandString[count]; }
397 //if you are not at the end
398 if (count != commandString.length()) { commandString = commandString.substr(count+1, commandString.length()); }
399 else { commandString = ""; }
402 //get rid of spaces in between commands if any
403 if (commandString.length() > 0) {
404 while (commandString[0] == ' ') {
405 commandString = commandString.substr(1,commandString.length());
406 if (commandString.length() == 0) { break; }
412 catch(exception& e) {
413 mout->errorOut(e, "ScriptEngine", "getNextCommand");
417 /***********************************************************************/