// // XSPEC12 November 2003 // // #include #include #include #include #include #include #include #include #include #include #include #include #include #include int XSGlobal::xsSave(ClientData cdata,Tcl_Interp* tclInterp,int objc, Tcl_Obj* CONST objv[]) { using XSContainer::datasets; using XSContainer::models; using XSContainer::fit; using namespace std; static const string DEFAULTFILE("savexspec.xcm"); static const string XCM(".xcm"); int option(0); std::vector allowedOptions(3); allowedOptions[0] = "model"; allowedOptions[1] = "files"; allowedOptions[2] = "all"; const char* cmd = static_cast(cdata); string fileName; try { if ( objc == 1 ) { fileName = DEFAULTFILE; tcout << "Saving model definition to file savexspec.xcm" << endl; // fileExists no longer calls open on its ofstream arg (hence // 'dummy'). This is a patch for a problem with the open call // on 1 instance of Mac Leopard w/ g++-4.0.1 std::ofstream dummy; if(HandlerUtils::fileExists(fileName, dummy)) { std::ostringstream promptStr; promptStr << fileName << " exists. Replace? (y/n) "; if (XSutility::yesToQuestion(promptStr.str(), 0, tcin)<=0) return globalData->autoSave(TCL_ERROR); } std::ofstream outputFile(fileName.c_str()); if (!outputFile) { string errMsg("Unable to open file: "); errMsg += fileName + '\n'; throw YellowAlert(errMsg); } saveModel(outputFile); return globalData->autoSave(TCL_OK); } else { string arg(Tcl_GetString(objv[1])); if (arg == "?") { printDocs(cmd,"?"); return globalData->autoSave(TCL_OK); } else if ( objc >= 2 ) { int n = allowedOptions.size(); while (option < n ) { if ( allowedOptions[option].compare(0, std::min(arg.length(),allowedOptions[option].length()),arg) == 0) break; ++option; } if ( option == n ) { printDocs(cmd,"?"); return globalData->autoSave(TCL_ERROR); } else { if (objc > 2 ) { fileName = Tcl_GetString(objv[2]); if ( fileName.find('.') == XSparse::NOTFOUND()) fileName += XCM; } else { tcout << "Saving to file savexspec.xcm" << endl; fileName = DEFAULTFILE; } // the reason for instantiating the stream // separately in each option is that saveAll // must be "atomic" for use by autosave. // See comments in objc=1 block regarding reasons for // using a dummy ofstream here. std::ofstream dummyOutput; switch (option) { // note that the file is closed // automatically at the end of // the scope. // model default: case 0: { if(HandlerUtils::fileExists(fileName, dummyOutput)) { std::ostringstream promptStr; promptStr << fileName << " exists. Replace? (y/n) "; if(XSutility::yesToQuestion(promptStr.str(), 0, tcin)<=0) return globalData->autoSave(TCL_ERROR); } std::ofstream outputFile(fileName.c_str()); if (!outputFile) { string errMsg("Unable to open file: "); errMsg += fileName + '\n'; throw YellowAlert(errMsg); } saveModel(outputFile); } break; // files case 1: { if(HandlerUtils::fileExists(fileName, dummyOutput)) { std::ostringstream promptStr; promptStr << fileName << " exists. Replace? (y/n) "; if(XSutility::yesToQuestion(promptStr.str(), 0, tcin)<=0) return globalData->autoSave(TCL_ERROR); } std::ofstream outputFile(fileName.c_str()); if (!outputFile) { string errMsg("Unable to open file: "); errMsg += fileName + '\n'; throw YellowAlert(errMsg); } datasets->saveData(outputFile); // the gain setting would // go here. } break; // all - both 0 and 1. case 2: { ifstream in(fileName.c_str()); if(in) { in.close(); std::ostringstream promptStr; promptStr << fileName << " exists. Replace? (y/n) "; if(XSutility::yesToQuestion(promptStr.str(), 0, tcin)==1) saveAll(fileName); } else saveAll(fileName); } break; } } } return globalData->autoSave(TCL_OK); } } catch (YellowAlert&) { return globalData->autoSave(TCL_ERROR); } }