]> git.donarmstrong.com Git - mothur.git/blob - engine.cpp
latest version
[mothur.git] / engine.cpp
1 /*
2  *  engine.cpp
3  *  
4  *
5  *  Created by Pat Schloss on 8/15/08.
6  *  Copyright 2008 Patrick D. Schloss. All rights reserved.
7  *
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.
11  *
12  */
13
14
15 #include "engine.hpp"
16
17 /***********************************************************************/
18 Engine::Engine(){
19         try {
20                 cFactory = CommandFactory::getInstance();
21                 mout = MothurOut::getInstance();
22         }
23         catch(exception& e) {
24                 mout->errorOut(e, "Engine", "Engine");
25                 exit(1);
26         }
27 }
28
29 /***********************************************************************/
30
31 InteractEngine::InteractEngine(string path){
32
33         globaldata = GlobalData::getInstance();
34         globaldata->argv = path;
35         
36 }
37
38 /***********************************************************************/
39
40 InteractEngine::~InteractEngine(){}
41
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(){
46         try {
47                 string input = "";
48                 string commandName = "";
49                 string options = "";
50                 int quitCommandCalled = 0;
51                 
52                 while(quitCommandCalled != 1){
53
54                         mout->mothurOutEndLine();
55                         
56                         input = getCommand();   
57                         mout->mothurOutEndLine();       
58                         
59                         if (mout->control_pressed) { input = "quit()"; }
60                         
61                         //allow user to omit the () on the quit command
62                         if (input == "quit") { input = "quit()"; }
63                         
64                         CommandOptionParser parser(input);
65                         commandName = parser.getCommandString();
66         
67                         options = parser.getOptionString();
68                         
69                         if (commandName != "") {
70                                         mout->executing = true;
71                                         #ifdef USE_MPI
72                                                 int pid;
73                                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
74                                                 
75                                                 if ((pid != 0) && !(cFactory->MPIEnabled(commandName))) {
76 cout << pid << " is waiting " << commandName << endl;                                           
77                                                         char buf[4];
78                                                         MPI_Bcast(buf, 4, MPI_CHAR, 0, MPI_COMM_WORLD); //make everyone wait - just in case
79                                                 }
80  
81 cout << pid << " is here " << commandName << endl;
82                                                 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
83                                         #endif
84                                         //executes valid command
85                                         Command* command = cFactory->getCommand(commandName, options);
86                                         quitCommandCalled = command->execute();
87                                         mout->control_pressed = 0;
88                                         mout->executing = false;
89                                                                                 
90                                         #ifdef USE_MPI
91                                                         if (!(cFactory->MPIEnabled(commandName))) {
92                                                                 char buf[4];
93                                                                 strcpy(buf, "done"); 
94
95                                                                 MPI_Bcast(buf, 4, MPI_CHAR, 0, MPI_COMM_WORLD); //make everyone wait - just in case
96                                 cout << pid << " is broadcasting " << endl;
97                                                         }
98                                                 }
99                                         #endif
100                                 }else {         
101                                         mout->mothurOut("Invalid."); 
102                                         mout->mothurOutEndLine();
103                                 }
104                 }       
105                 return 1;
106         }
107         catch(exception& e) {
108                 mout->errorOut(e, "InteractEngine", "getInput");
109                 exit(1);
110         }
111 }
112 /***********************************************************************/
113 string Engine::getCommand()  {
114         try {
115                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
116                         #ifdef USE_READLINE
117                                 char* nextCommand = NULL;
118                                 nextCommand = readline("mothur > ");
119                                 
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);
124                                 }       
125                                 
126                                 mout->mothurOutJustToLog("mothur > " + toString(nextCommand));
127                                 return nextCommand;
128                         #else
129                                 string nextCommand = "";
130                                 mout->mothurOut("mothur > ");
131                                 getline(cin, nextCommand);
132                                 mout->mothurOutJustToLog("mothur > " + toString(nextCommand));
133                                 
134                                 return nextCommand;
135                         #endif
136                 #else
137                                 string nextCommand = "";
138                                 
139                                 mout->mothurOut("mothur > ");
140                                 getline(cin, nextCommand);
141                                 mout->mothurOutJustToLog(toString(nextCommand));
142                                 
143                                 return nextCommand;
144                 #endif
145         
146                                                 
147         }
148         catch(exception& e) {
149                 mout->errorOut(e, "Engine", "getCommand");
150                 exit(1);
151         }
152 }
153 /***********************************************************************/
154 //This function opens the batchfile to be used by BatchEngine::getInput.
155 BatchEngine::BatchEngine(string path, string batchFileName){
156         try {
157                 globaldata = GlobalData::getInstance();
158         
159                 openedBatch = openInputFile(batchFileName, inputBatchFile);
160                 globaldata->argv = path;
161                                 
162         }
163         catch(exception& e) {
164                 mout->errorOut(e, "BatchEngine", "BatchEngine");
165                 exit(1);
166         }
167 }
168
169 /***********************************************************************/
170
171 BatchEngine::~BatchEngine(){    }
172
173 /***********************************************************************/
174 //This Function allows the user to run a batchfile containing several commands on Dotur
175 bool BatchEngine::getInput(){
176         try {
177                 //check if this is a valid batchfile
178                 if (openedBatch == 1) {  
179                         mout->mothurOut("unable to open batchfile");  
180                         mout->mothurOutEndLine();
181                         return 1; 
182                 }
183         
184                 string input = "";
185                 string commandName = "";
186                 string options = "";
187                 
188                 //CommandFactory cFactory;
189                 int quitCommandCalled = 0;
190         
191                 while(quitCommandCalled == 0){
192         
193                         if (inputBatchFile.eof()) { input = "quit()"; }
194                         else { input = getline(inputBatchFile); }
195                         
196                         if (input[0] != '#') {
197                                 
198                                 mout->mothurOutEndLine();
199                                 mout->mothurOut("mothur > " + input);
200                                 mout->mothurOutEndLine();
201                                                         
202                                 if (mout->control_pressed) { input = "quit()"; }
203                                 
204                                 //allow user to omit the () on the quit command
205                                 if (input == "quit") { input = "quit()"; }
206
207                                 CommandOptionParser parser(input);
208                                 commandName = parser.getCommandString();
209                                 options = parser.getOptionString();
210                                                                                 
211                                 if (commandName != "") {
212                                         mout->executing = true;
213                                         #ifdef USE_MPI
214                                                 int pid;
215                                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
216                                                 
217                                                 if ((pid != 0) && !(cFactory->MPIEnabled(commandName))) {
218 cout << pid << " is waiting " << commandName << endl;                                           
219                                                         char buf[4];
220                                                         MPI_Bcast(buf, 4, MPI_CHAR, 0, MPI_COMM_WORLD); //make everyone wait - just in case
221                                                 }
222  
223 cout << pid << " is here " << commandName << endl;
224                                                 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
225                                         #endif
226                                         //executes valid command
227                                         Command* command = cFactory->getCommand(commandName, options);
228                                         quitCommandCalled = command->execute();
229                                         mout->control_pressed = 0;
230                                         mout->executing = false;
231                                                                                 
232                                         #ifdef USE_MPI
233                                                         if (!(cFactory->MPIEnabled(commandName))) {
234                                                                 char buf[4];
235                                                                 strcpy(buf, "done"); 
236
237                                                                 MPI_Bcast(buf, 4, MPI_CHAR, 0, MPI_COMM_WORLD); //make everyone wait - just in case
238                                 cout << pid << " is broadcasting " << endl;
239                                                         }
240                                                 }
241                                         #endif
242                                 }else {         
243                                         mout->mothurOut("Invalid."); 
244                                         mout->mothurOutEndLine();
245                                 }
246                                 
247                         }
248                         gobble(inputBatchFile);
249                 }
250                 
251                 inputBatchFile.close();
252                 return 1;
253         }
254         catch(exception& e) {
255                 mout->errorOut(e, "BatchEngine", "getInput");
256                 exit(1);
257         }
258 }
259
260
261 /***********************************************************************/
262 /***********************************************************************/
263 //This function opens the batchfile to be used by BatchEngine::getInput.
264 ScriptEngine::ScriptEngine(string path, string commandString){
265         try {
266                 globaldata = GlobalData::getInstance();
267                 
268                 //remove quotes
269                 listOfCommands = commandString.substr(1, (commandString.length()-1));
270
271                 globaldata->argv = path;
272                                 
273         }
274         catch(exception& e) {
275                 mout->errorOut(e, "ScriptEngine", "ScriptEngine");
276                 exit(1);
277         }
278 }
279
280 /***********************************************************************/
281
282 ScriptEngine::~ScriptEngine(){  }
283
284 /***********************************************************************/
285 //This Function allows the user to run a batchfile containing several commands on mothur
286 bool ScriptEngine::getInput(){
287         try {
288                         
289                 string input = "";
290                 string commandName = "";
291                 string options = "";
292                 
293                 
294                 //CommandFactory cFactory;
295                 int quitCommandCalled = 0;
296         
297                 while(quitCommandCalled == 0){
298                 
299                         input = getNextCommand(listOfCommands); 
300                         
301                         if (input == "") { input = "quit()"; }
302                         
303                         mout->mothurOutEndLine();
304                         mout->mothurOut("mothur > " + input);
305                         mout->mothurOutEndLine();
306                         
307                         if (mout->control_pressed) { input = "quit()"; }
308                                 
309                         //allow user to omit the () on the quit command
310                         if (input == "quit") { input = "quit()"; }
311
312                         CommandOptionParser parser(input);
313                         commandName = parser.getCommandString();
314                         options = parser.getOptionString();
315                                                                                 
316                         if (commandName != "") {
317                                         mout->executing = true;
318                                         #ifdef USE_MPI
319                                                 int pid, numProcesses;
320                                                 MPI_Status status; 
321                                                 //MPI_Request request;
322                                                 
323                                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
324                                                 MPI_Comm_size(MPI_COMM_WORLD, &numProcesses); 
325                                                 
326                                                 if ((pid != 0) && (!(cFactory->MPIEnabled(commandName)))) {
327 cout << pid << " is waiting " << commandName << endl;                                           
328                                                         char buf[12];
329                                                         
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;
333                                                 }
334                                                 
335                                         
336 cout << pid << " is here " << commandName  << endl;
337                                                 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
338                                                         cout << pid << " is in execute" << endl;        
339                                         #endif
340                                         //executes valid command
341                                         Command* command = cFactory->getCommand(commandName, options);
342                                         quitCommandCalled = command->execute();
343                                         mout->control_pressed = 0;
344                                         mout->executing = false;
345                                                                         
346                                         #ifdef USE_MPI
347                                         cout << pid << " is done in execute" << endl;
348                                                         if ((pid == 0) && (!(cFactory->MPIEnabled(commandName)))) {
349                                                                 char buf[12];
350                                                                 strcpy(buf, "command done"); 
351                                                                 
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;
356                                                                 }
357                                 cout << pid << " is sending " << endl;
358                                                         }
359                                                 }
360                                         #endif
361                                 }else {         
362                                         mout->mothurOut("Invalid."); 
363                                         mout->mothurOutEndLine();
364                                 }
365
366                         
367                 }
368                 
369                 return 1;
370         }
371         catch(exception& e) {
372                 mout->errorOut(e, "ScriptEngine", "getInput");
373                 exit(1);
374         }
375 }
376 /***********************************************************************/
377 string ScriptEngine::getNextCommand(string& commandString) {
378         try {
379                 
380                 #ifdef USE_MPI
381                 int ierr = MPI_Barrier(MPI_COMM_WORLD);
382 cout << "barrier = " << ierr << endl;
383                 #endif
384                 
385                 string nextcommand = "";
386                 int count = 0;
387                 
388                 //go through string until you reach ; or end
389                 while (count < commandString.length()) { 
390                         
391                         if (commandString[count] == ';') {  break;   }
392                         else {          nextcommand += commandString[count];    }
393                         
394                         count++;
395                 }
396                 
397                 //if you are not at the end
398                 if (count != commandString.length())  {   commandString = commandString.substr(count+1, commandString.length());  }
399                 else { commandString = ""; }
400                                 
401                 
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;  }
407                         }
408                 }
409                 
410                 return nextcommand;
411         }
412         catch(exception& e) {
413                 mout->errorOut(e, "ScriptEngine", "getNextCommand");
414                 exit(1);
415         }
416 }
417 /***********************************************************************/