Home Docs Forums Bugzilla LXR Doxygen CVS Bonsai

ExecutionManagerT.cpp

Go to the documentation of this file.
00001 /* $Id: ExecutionManagerT.cpp,v 1.18 2004/09/28 15:35:37 paklein Exp $ */ 00002 /* created: paklein (08/27/1997) */ 00003 #include "ExecutionManagerT.h" 00004 00005 #include <iostream.h> 00006 #include <iomanip.h> 00007 #include <time.h> 00008 00009 #include "ifstreamT.h" 00010 #include "ofstreamT.h" 00011 #include "StringT.h" 00012 #include "CommunicatorT.h" 00013 00014 using namespace Tahoe; 00015 00016 /* maximum batch file recursion depth */ 00017 const int kMaxRecursionDepth = 10; 00018 00019 /* Constructor */ 00020 ExecutionManagerT::ExecutionManagerT(int argc, char* argv[], char job_char, char batch_char, 00021 CommunicatorT& comm, 00022 int jobcharputback): 00023 fJobChar(job_char), 00024 fBatchChar(batch_char), 00025 fComm(comm), 00026 fJobCharPutBack(jobcharputback), 00027 fRecursionDepth(0) 00028 { 00029 if (fJobCharPutBack != 1 && fJobCharPutBack != 0) throw ExceptionT::kBadInputValue; 00030 00031 /* store command line arguments */ 00032 fCommandLineOptions.Dimension(argc); 00033 for (int i = 0; i < fCommandLineOptions.Length(); i++) 00034 fCommandLineOptions[i] = argv[i]; 00035 00036 /* format standard output */ 00037 ofstreamT::format_stream(cout); 00038 } 00039 00040 /* Destructor */ 00041 ExecutionManagerT::~ExecutionManagerT(void) { } 00042 00043 /* Prompt input files until "quit" */ 00044 void ExecutionManagerT::Run(void) 00045 { 00046 /* get rank */ 00047 int rank = fComm.Rank(); 00048 00049 /* file name passed on command line */ 00050 int index; 00051 if (CommandLineOption("-f", index)) 00052 { 00053 /* path name */ 00054 StringT& file = fCommandLineOptions[index+1]; 00055 file.ToNativePathName(); 00056 00057 /* open stream */ 00058 ifstreamT input('#', file); 00059 if (!input.is_open()) 00060 { 00061 cout << "\n ExecutionManagerT::Run_parallel: unable to open file: \"" 00062 << file << '\"' << endl; 00063 throw ExceptionT::kBadInputValue; 00064 } 00065 00066 /* dispatch */ 00067 JobOrBatch(input, cout); 00068 } 00069 else 00070 { 00071 StringT lastfilename; 00072 int count = 0; 00073 while (count++ < 10) 00074 { 00075 /* broadcast file name or command-line option */ 00076 StringT line(255); 00077 if (rank == 0) 00078 Prompt("Enter input file path or option (\"quit\" to exit)", lastfilename, line); 00079 fComm.Broadcast(0, line); 00080 00081 /* command line option */ 00082 if (line[0] == '-') { 00083 00084 /* reset count */ 00085 count = 0; 00086 00087 /* add command line option */ 00088 if (AddCommandLineOption(line)) 00089 cout << " added command line option: \"" << line << '\"' << endl; 00090 } 00091 else if (strncmp(line, "quit", 4) == 0) 00092 break; 00093 else /* try to open file */ 00094 { 00095 line.ToNativePathName(); 00096 ifstreamT input('#', line); 00097 if (input.is_open()) { 00098 00099 /* reset count */ 00100 count = 0; 00101 00102 /* keep last file name */ 00103 lastfilename = input.filename(); 00104 00105 /* Recursive dispatch */ 00106 JobOrBatch(input, cout); 00107 } 00108 else 00109 cout << "\nError: filename: \"" << line << "\" not found\n"; 00110 } 00111 } 00112 00113 /* exit message */ 00114 if (count >= 10) cout << "\nNo valid input after " << count << " attempts." << endl; 00115 } 00116 } 00117 00118 // returns true if the option was passed on the command line, moved to public DEF 3 Aug 04 00119 bool ExecutionManagerT::CommandLineOption(const char* str, int& index) const 00120 { 00121 for (int i = 0; i < fCommandLineOptions.Length(); i++) 00122 if (fCommandLineOptions[i] == str) 00123 { 00124 index = i; 00125 return true; 00126 } 00127 00128 /* dummy */ 00129 index = 0; 00130 return false; 00131 } 00132 00133 00134 /********************************************************************** 00135 * Protected 00136 **********************************************************************/ 00137 00138 bool ExecutionManagerT::AddCommandLineOption(const char* str) 00139 { 00140 /* only if not present */ 00141 int index; 00142 if (!CommandLineOption(str, index)) 00143 { 00144 /* append */ 00145 fCommandLineOptions.Append(str); 00146 return true; 00147 } 00148 else return false; 00149 } 00150 00151 bool ExecutionManagerT::RemoveCommandLineOption(const char* str) 00152 { 00153 /* only if not present */ 00154 int index; 00155 if (CommandLineOption(str, index)) 00156 { 00157 /* append */ 00158 fCommandLineOptions.DeleteAt(index); 00159 return true; 00160 } 00161 else return false; 00162 } 00163 00164 /********************************************************************** 00165 * Private 00166 **********************************************************************/ 00167 00168 /* Recursive dispatch */ 00169 void ExecutionManagerT::JobOrBatch(ifstreamT& in, ostream& status) 00170 { 00171 /* get first char */ 00172 char filetypechar; 00173 in >> filetypechar; 00174 00175 if (filetypechar != fJobChar && filetypechar != fBatchChar) 00176 { 00177 status << "\n ExecutionManagerT::JobOrBatch: invalid filetype character: "; 00178 status << filetypechar << '\n'; 00179 return; 00180 } 00181 00182 /* check recursion depth */ 00183 if (++fRecursionDepth > kMaxRecursionDepth) throw ExceptionT::kGeneralFail; 00184 00185 /* JOB file */ 00186 if (filetypechar == fJobChar) 00187 { 00188 /* putback first character */ 00189 if (fJobCharPutBack) in.putback(filetypechar); 00190 00191 /* derived */ 00192 RunJob(in, status); 00193 } 00194 /* BATCH file */ 00195 else 00196 { 00197 /* process batch file */ 00198 RunBatch(in, status); 00199 } 00200 00201 /* reduce depth on exit */ 00202 fRecursionDepth--; 00203 } 00204 00205 /* Batch file processing */ 00206 void ExecutionManagerT::RunBatch(ifstreamT& in, ostream& status) 00207 { 00208 /* mark status */ 00209 status << "\n Processing batch file: " << in.filename() << '\n'; 00210 00211 /* start day/date info */ 00212 time_t starttime; 00213 time(&starttime); 00214 00215 /* get 1st entry */ 00216 StringT nextinfilename; 00217 in >> nextinfilename; 00218 00219 /* repeat to end of file */ 00220 while (in.good()) 00221 { 00222 /* adjusting execution options */ 00223 if (nextinfilename[0] == '-') 00224 AddCommandLineOption(nextinfilename); 00225 else /* execute regular file */ 00226 { 00227 /* file path format */ 00228 nextinfilename.ToNativePathName(); 00229 00230 /* path to source file */ 00231 StringT path; 00232 path.FilePath(in.filename()); 00233 00234 /* open new input stream */ 00235 nextinfilename.Prepend(path); 00236 ifstreamT nextin('#', nextinfilename); 00237 00238 /* process if valid */ 00239 if (nextin.is_open()) 00240 JobOrBatch(nextin, cout); 00241 else 00242 cout << " File not found: " << nextinfilename << '\n'; 00243 } 00244 00245 /* get next entry */ 00246 in >> nextinfilename; 00247 } 00248 00249 /* stop day/date info */ 00250 time_t stoptime; 00251 time(&stoptime); 00252 cout << "\n Batch start time : " << ctime(&starttime); 00253 cout << " Batch stop time : " << ctime(&stoptime); 00254 } 00255 00256 void ExecutionManagerT::Prompt(const char* prompt, const char* default_input, StringT& line) const 00257 { 00258 cout << '\n' << prompt; 00259 00260 /* default */ 00261 if (default_input != NULL && strlen(default_input) > 0) 00262 { 00263 cout << "\nEnter <RETURN> for \"" << default_input << "\": "; 00264 #ifdef __SGI__ 00265 cout.flush(); 00266 #endif 00267 00268 /* new filename */ 00269 char test = cin.peek(); 00270 if (test != '\n') 00271 { 00272 /* take first word */ 00273 cin >> line; 00274 } 00275 else 00276 { 00277 /* copy default */ 00278 line = default_input; 00279 } 00280 } 00281 else 00282 { 00283 cout << ": "; 00284 #ifdef __SGI__ 00285 cout.flush(); 00286 #endif 00287 cin >> line; 00288 } 00289 00290 /* clear to end of line */ 00291 fstreamT::ClearLine(cin); 00292 }