]> git.donarmstrong.com Git - mothur.git/blob - engine.cpp
1.12.1
[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                         #ifdef USE_MPI
55                                 int pid, processors;
56                                 MPI_Status status;
57                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
58                                 MPI_Comm_size(MPI_COMM_WORLD, &processors);
59                                 
60                                 if (pid == 0) {
61                                 
62                         #endif
63                         
64                         mout->mothurOutEndLine();
65                         
66                         input = getCommand();   
67                         mout->mothurOutEndLine();       
68                         
69                         if (mout->control_pressed) { input = "quit()"; }
70                         
71                         //allow user to omit the () on the quit command
72                         if (input == "quit") { input = "quit()"; }
73
74                         
75                         #ifdef USE_MPI
76                                 //send commandName
77                                 for(int i = 1; i < processors; i++) { 
78                                                 int length = input.length();
79                                                 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
80                                                 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
81         
82                                         }
83                                 }else {
84                                         int length;
85                                         MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
86                                         //recieve container
87                                         char* tempBuf = new char[length];
88                                         MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
89                                         
90                                         input = tempBuf;
91                                         if (input.length() > length) { input = input.substr(0, length);  }
92                                         delete tempBuf; 
93                                 }
94
95                         
96                         #endif
97                 
98                         CommandOptionParser parser(input);
99                         commandName = parser.getCommandString();
100         
101                         options = parser.getOptionString();
102                         
103                         if (commandName != "") {
104                                         mout->executing = true;
105                                         #ifdef USE_MPI
106                                                 int pid;
107                                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
108                                                 
109                                                 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
110                                         //cout << pid << " is in execute " << commandName << endl;
111                                         #endif
112                                         //executes valid command
113                                         Command* command = cFactory->getCommand(commandName, options);
114                                         quitCommandCalled = command->execute();
115                                         mout->control_pressed = 0;
116                                         mout->executing = false;
117                                                                                 
118                                         #ifdef USE_MPI
119                                                 }
120                                         #endif
121                                 }else {         
122                                         mout->mothurOut("Invalid."); 
123                                         mout->mothurOutEndLine();
124                                 }
125                 }       
126                 return 1;
127         }
128         catch(exception& e) {
129                 mout->errorOut(e, "InteractEngine", "getInput");
130                 exit(1);
131         }
132 }
133 /***********************************************************************/
134 string Engine::getCommand()  {
135         try {
136         
137                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
138                         #ifdef USE_READLINE
139                                 char* nextCommand = NULL;
140                                 nextCommand = readline("mothur > ");
141                                 
142                                 if(nextCommand != NULL) {  add_history(nextCommand);  } 
143                                 else{ //^D causes null string and we want it to quit mothur
144                                         nextCommand = "quit"; 
145                                         mout->mothurOut(nextCommand);
146                                 }       
147                                 
148                                 mout->mothurOutJustToLog("mothur > " + toString(nextCommand));
149                                 return nextCommand;
150                         #else
151                                 string nextCommand = "";
152                                 mout->mothurOut("mothur > ");
153                                 getline(cin, nextCommand);
154                                 mout->mothurOutJustToLog("mothur > " + toString(nextCommand));
155                                 
156                                 return nextCommand;
157                         #endif
158                 #else
159                                 string nextCommand = "";
160                                 
161                                 mout->mothurOut("mothur > ");
162                                 getline(cin, nextCommand);
163                                 mout->mothurOutJustToLog(toString(nextCommand));
164                                 
165                                 return nextCommand;
166                 #endif
167         
168                                                 
169         }
170         catch(exception& e) {
171                 mout->errorOut(e, "Engine", "getCommand");
172                 exit(1);
173         }
174 }
175 /***********************************************************************/
176 //This function opens the batchfile to be used by BatchEngine::getInput.
177 BatchEngine::BatchEngine(string path, string batchFileName){
178         try {
179                 globaldata = GlobalData::getInstance();
180         
181                 openedBatch = openInputFile(batchFileName, inputBatchFile);
182                 globaldata->argv = path;
183                                 
184         }
185         catch(exception& e) {
186                 mout->errorOut(e, "BatchEngine", "BatchEngine");
187                 exit(1);
188         }
189 }
190
191 /***********************************************************************/
192
193 BatchEngine::~BatchEngine(){    }
194
195 /***********************************************************************/
196 //This Function allows the user to run a batchfile containing several commands on Dotur
197 bool BatchEngine::getInput(){
198         try {
199                 //check if this is a valid batchfile
200                 if (openedBatch == 1) {  
201                         mout->mothurOut("unable to open batchfile");  
202                         mout->mothurOutEndLine();
203                         return 1; 
204                 }
205         
206                 string input = "";
207                 string commandName = "";
208                 string options = "";
209                 
210                 //CommandFactory cFactory;
211                 int quitCommandCalled = 0;
212             int count = 0;
213                 while(quitCommandCalled == 0){
214                         
215                         #ifdef USE_MPI
216                                 int pid, processors;
217                                 MPI_Status status;
218                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
219                                 MPI_Comm_size(MPI_COMM_WORLD, &processors);
220                                 
221                                 if (pid == 0) {
222                                 
223                         #endif
224                         
225                         input = getNextCommand(inputBatchFile);
226                         count++;
227                         
228                         #ifdef USE_MPI
229                                 //send commandName
230                                 for(int i = 1; i < processors; i++) { 
231                                                 int length = input.length();
232                                                 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
233                                                 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
234         
235                                         }
236                                 }else {
237                                         int length;
238                                         MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
239                                         //recieve container
240                                         char* tempBuf = new char[length];
241                                         MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
242                                         
243                                         input = tempBuf;
244                                         if (input.length() > length) { input = input.substr(0, length);  }
245                                         delete tempBuf; 
246                                 }
247
248                         
249                         #endif
250
251                         
252                         
253                         if (input[0] != '#') {
254                                 
255                                 mout->mothurOutEndLine();
256                                 mout->mothurOut("mothur > " + input);
257                                 mout->mothurOutEndLine();
258                                                         
259                                 if (mout->control_pressed) { input = "quit()"; }
260                                 
261                                 //allow user to omit the () on the quit command
262                                 if (input == "quit") { input = "quit()"; }
263
264                                 CommandOptionParser parser(input);
265                                 commandName = parser.getCommandString();
266                                 options = parser.getOptionString();
267                                                                                 
268                                 if (commandName != "") {
269                                         mout->executing = true;
270                                         #ifdef USE_MPI
271                                                 int pid;
272                                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
273                                                 
274 //cout << pid << " is here " << commandName << '\t' << count << endl;
275                                                 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
276                                         #endif
277                                         //executes valid command
278                                         Command* command = cFactory->getCommand(commandName, options);
279                                         quitCommandCalled = command->execute();
280                                         mout->control_pressed = 0;
281                                         mout->executing = false;
282                                                                                 
283                                         #ifdef USE_MPI
284                                                 }
285                                         #endif
286                                 }else {         
287                                         mout->mothurOut("Invalid."); 
288                                         mout->mothurOutEndLine();
289                                 }
290                                 
291                         }
292                         gobble(inputBatchFile);
293                 }
294                 
295                 inputBatchFile.close();
296                 return 1;
297         }
298         catch(exception& e) {
299                 mout->errorOut(e, "BatchEngine", "getInput");
300                 exit(1);
301         }
302 }
303 /***********************************************************************/
304 string BatchEngine::getNextCommand(ifstream& inputBatchFile) {
305         try {
306                 
307                 string nextcommand = "";
308                 
309                 if (inputBatchFile.eof()) { nextcommand = "quit()"; }
310                 else { nextcommand = getline(inputBatchFile); }
311                 
312                 return nextcommand;
313         }
314         catch(exception& e) {
315                 mout->errorOut(e, "BatchEngine", "getNextCommand");
316                 exit(1);
317         }
318 }
319
320 /***********************************************************************/
321 /***********************************************************************/
322 //This function opens the batchfile to be used by BatchEngine::getInput.
323 ScriptEngine::ScriptEngine(string path, string commandString){
324         try {
325                 globaldata = GlobalData::getInstance();
326                 
327                 //remove quotes
328                 listOfCommands = commandString.substr(1, (commandString.length()-1));
329
330                 globaldata->argv = path;
331                                 
332         }
333         catch(exception& e) {
334                 mout->errorOut(e, "ScriptEngine", "ScriptEngine");
335                 exit(1);
336         }
337 }
338
339 /***********************************************************************/
340
341 ScriptEngine::~ScriptEngine(){  }
342
343 /***********************************************************************/
344 //This Function allows the user to run a batchfile containing several commands on mothur
345 bool ScriptEngine::getInput(){
346         try {
347                         
348                 string input = "";
349                 string commandName = "";
350                 string options = "";
351                 
352                 
353                 //CommandFactory cFactory;
354                 int quitCommandCalled = 0;
355         
356                 while(quitCommandCalled == 0){
357                         
358                         #ifdef USE_MPI
359                                 int pid, processors;
360                                 MPI_Status status;
361                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
362                                 MPI_Comm_size(MPI_COMM_WORLD, &processors);
363                                 
364                                 if (pid == 0) {
365                                 
366                         #endif
367                         
368                         input = getNextCommand(listOfCommands); 
369                         
370                         if (input == "") { input = "quit()"; }
371                         
372                         mout->mothurOutEndLine();
373                         mout->mothurOut("mothur > " + input);
374                         mout->mothurOutEndLine();
375                         
376                         #ifdef USE_MPI
377                                 //send commandName
378                                 for(int i = 1; i < processors; i++) { 
379                                                 int length = input.length();
380                                                 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
381                                                 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
382         
383                                         }
384                                 }else {
385                                         int length;
386                                         MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
387                                         //recieve container
388                                         char* tempBuf = new char[length];
389                                         MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
390                                         
391                                         input = tempBuf;
392                                         if (input.length() > length) { input = input.substr(0, length);  }
393                                         delete tempBuf; 
394                                 }
395
396                         
397                         #endif
398                         
399                         
400                         if (mout->control_pressed) { input = "quit()"; }
401                                 
402                         //allow user to omit the () on the quit command
403                         if (input == "quit") { input = "quit()"; }
404
405                         CommandOptionParser parser(input);
406                         commandName = parser.getCommandString();
407                         options = parser.getOptionString();
408                                                                                 
409                         if (commandName != "") {
410                                         mout->executing = true;
411                                         #ifdef USE_MPI
412                                                 int pid, numProcesses;
413                                                 MPI_Status status; 
414                                                 
415                                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
416                                                 MPI_Comm_size(MPI_COMM_WORLD, &numProcesses); 
417                                         
418 //cout << pid << " is here " << commandName  << endl;
419                                                 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
420                                                         //cout << pid << " is in execute" << endl;      
421                                         #endif
422                                         //executes valid command
423                                         Command* command = cFactory->getCommand(commandName, options);
424                                         quitCommandCalled = command->execute();
425                                         mout->control_pressed = 0;
426                                         mout->executing = false;
427                                                                         
428                                         #ifdef USE_MPI
429                                         //cout << pid << " is done in execute" << endl;
430                                                 }
431                                         #endif
432                                 }else {         
433                                         mout->mothurOut("Invalid."); 
434                                         mout->mothurOutEndLine();
435                                 }
436
437                         
438                 }
439                 
440                 return 1;
441         }
442         catch(exception& e) {
443                 mout->errorOut(e, "ScriptEngine", "getInput");
444                 exit(1);
445         }
446 }
447 /***********************************************************************/
448 string ScriptEngine::getNextCommand(string& commandString) {
449         try {
450                 
451                 string nextcommand = "";
452                 int count = 0;
453                 
454                 //go through string until you reach ; or end
455                 while (count < commandString.length()) { 
456                         
457                         if (commandString[count] == ';') {  break;   }
458                         else {          nextcommand += commandString[count];    }
459                         
460                         count++;
461                 }
462                 
463                 //if you are not at the end
464                 if (count != commandString.length())  {   commandString = commandString.substr(count+1, commandString.length());  }
465                 else { commandString = ""; }
466                                 
467                 
468                 //get rid of spaces in between commands if any
469                 if (commandString.length() > 0) {
470                         while (commandString[0] == ' ') {  
471                                 commandString = commandString.substr(1,commandString.length());
472                                 if (commandString.length() == 0) {  break;  }
473                         }
474                 }
475                 
476                 return nextcommand;
477         }
478         catch(exception& e) {
479                 mout->errorOut(e, "ScriptEngine", "getNextCommand");
480                 exit(1);
481         }
482 }
483 /***********************************************************************/