00001 /*!@file Matlab/MexModelManager.C 00002 */ 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2002 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Dirk Walther <walther@caltech.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Matlab/MexModelManager.C $ 00035 // $Id: MexModelManager.C 6464 2006-04-13 18:01:55Z rjpeters $ 00036 // 00037 00038 #include "Matlab/MexModelManager.H" 00039 00040 #include "Matlab/mexLog.H" 00041 #include "Neuro/NeuroOpts.H" 00042 #include "Util/fpe.H" 00043 #include "Util/sformat.H" 00044 00045 namespace 00046 { 00047 void mexPrintUsageAndExit(const char *usage) 00048 { 00049 mexFatal(sformat("USAGE: %s\nTry: %s('--help'); " 00050 "for additional information.", 00051 usage,mexFunctionName())); 00052 } 00053 } 00054 00055 // ###################################################################### 00056 MexModelManager::MexModelManager(const std::string& descrName, 00057 const std::string& tagName) 00058 : ModelManager(descrName,tagName,false,false,false) 00059 { 00060 this->setFPE(false); 00061 this->unRequestTestMode(); 00062 this->unRequestUsingFPE(); 00063 fpExceptionsUnlock(); 00064 fpExceptionsOff(); 00065 fpExceptionsLock(); 00066 } 00067 00068 MexModelManager::~MexModelManager() 00069 {} 00070 00071 // ###################################################################### 00072 bool MexModelManager::parseMexCommandLine(const int nrhs, const mxArray *prhs[], 00073 const char *usage, const int minarg, 00074 const int maxarg) 00075 { 00076 // let's export options if it hasn't been done already (note that 00077 // exportOptions() will just return without doing anything if 00078 // somebody had already called it) 00079 exportOptions(MC_RECURSE); 00080 00081 // do a few resets: 00082 clearExtraArgs(); 00083 extraMexArgs.clear(); 00084 00085 // initialize fields 00086 std::vector<char*> buffers; 00087 std::vector<const char*> args; 00088 args.push_back(mexFunctionName()); 00089 00090 // convert the aguments we get from Matlab to something like argc and argv 00091 for (int n = 0; n < nrhs; n++) 00092 { 00093 // Is not a string -> store in itsExtraArgs and go on 00094 if (!mxIsChar(prhs[n])) { 00095 extraMexArgs.push_back(prhs[n]); continue; } 00096 00097 // It's a string. But if it's empty, store it in itsExtraArgs. 00098 int numelem = mxGetNumberOfElements(prhs[n]); 00099 if (numelem == 0) { 00100 extraMexArgs.push_back(prhs[n]); continue; } 00101 00102 // get the string into a buffer 00103 int buflen = numelem * sizeof(mxChar) + 1; 00104 char *buf = new char[buflen]; 00105 mxGetString(prhs[n], buf, buflen); 00106 buffers.push_back(buf); // keep track of buffers to destroy them later 00107 00108 // if the first character isn't a '-', store the string in itsExtraArgs 00109 if (buf[0] != '-') { 00110 extraMexArgs.push_back(prhs[n]); continue; } 00111 00112 // Now separate out the options 00113 for (char *ptr = buf; ptr < (buf+numelem); ++ptr) 00114 { 00115 args.push_back(ptr); //store the address of this argument 00116 // find the next white space 00117 while(!isspace(*ptr) && (ptr < (buf+numelem))) ++ptr; 00118 *ptr = '\0'; // blank this one out 00119 } 00120 } 00121 00122 // do the core of the parsing: 00123 bool ret = parseCommandLineCore(args.size(), &args[0]); 00124 00125 // delete all temporary buffers 00126 for (uint i = 0; i < buffers.size(); ++i) 00127 delete [] buffers[i]; 00128 00129 // Were we successful? 00130 if (ret == false) return false; 00131 00132 // check if the number of extraMexArgs is within the limits we want 00133 if ((int(extraMexArgs.size()) < minarg) || 00134 (maxarg >= 0 && int(extraMexArgs.size()) > maxarg)) 00135 { 00136 if (maxarg == -1) 00137 mexError(sformat("Incorrect number of (non-opt) arg: %"ZU" [%d..Inf]", 00138 extraMexArgs.size(), minarg)); 00139 else 00140 mexError(sformat("Incorrect number of (non-opt) arg: %"ZU" [%d..%d]", 00141 extraMexArgs.size(), minarg, maxarg)); 00142 mexPrintUsageAndExit(usage); 00143 } 00144 00145 // there shouldn't be any leftover text args here 00146 if (this->numExtraArgs() > 0) 00147 { 00148 for (uint i = 0; i < this->numExtraArgs(); ++i) 00149 mexError(sformat("Unknown command line option: %s", 00150 this->getExtraArg(i).c_str())); 00151 00152 mexError("There were unknown command line options."); 00153 mexPrintUsageAndExit(usage); 00154 } 00155 00156 // all went well 00157 return true; 00158 } 00159 00160 // ###################################################################### 00161 uint MexModelManager::numExtraMexArgs() const 00162 { return extraMexArgs.size(); } 00163 00164 // ###################################################################### 00165 const mxArray* MexModelManager::getExtraMexArg(const uint num) const 00166 { 00167 if (num >= extraMexArgs.size()) { 00168 mexFatal(sformat("Invalid arg number %d (0..%"ZU") -- IGNORED", 00169 num, extraMexArgs.size())); 00170 return 0; 00171 } 00172 return extraMexArgs[num]; 00173 } 00174 00175 // ###################################################################### 00176 void MexModelManager::exitMexFunction(int return_code) 00177 { 00178 if (return_code == 0) 00179 mexFatal(sformat("%s finished.",mexFunctionName())); 00180 else 00181 mexFatal(sformat("%s exited with error code %d.", 00182 mexFunctionName(),return_code)); 00183 } 00184 00185 // ###################################################################### 00186 /* So things look consistent in everyone's emacs... */ 00187 /* Local Variables: */ 00188 /* indent-tabs-mode: nil */ 00189 /* End: */