/* * Copyright (c) 2002-2006 Samit Basu * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "Array.hpp" #include "Interpreter.hpp" #include "Utils.hpp" #include #include "System.hpp" #include //! //@Module CD Change Working Directory Function //@@Section OS //@@Usage //Changes the current working directory to the one specified as the argument. The general syntax for its use is //@[ // cd('dirname') //@] //but this can also be expressed as //@[ // cd 'dirname' //@] //or //@[ // cd dirname //@] //Examples of all three usages are given below. //Generally speaking, @|dirname| is any string that would be accepted //by the underlying OS as a valid directory name. For example, on most //systems, @|'.'| refers to the current directory, and @|'..'| refers //to the parent directory. Also, depending on the OS, it may be necessary //to ``escape'' the directory seperators. In particular, if directories //are seperated with the backwards-slash character @|'\\'|, then the //path specification must use double-slashes @|'\\\\'|. Note: to get //file-name completion to work at this time, you must use one of the //first two forms of the command. // //@@Example //The @|pwd| command returns the current directory location. First, //we use the simplest form of the @|cd| command, in which the directory //name argument is given unquoted. //@< //pwd //cd .. //pwd //@> //Next, we use the ``traditional'' form of the function call, using //both the parenthesis and a variable to store the quoted string. //@< //a = pwd; //cd(a) //pwd //@> //! ArrayVector ChangeDirFunction(int nargout, const ArrayVector& arg, Interpreter* eval) { if (arg.size() != 1) throw Exception("cd function requires exactly one argument"); if (!QDir::setCurrent(TildeExpand(ArrayToString(arg[0])))) throw Exception(std::string("Unable to change to specified directory:") + ArrayToString(arg[0])); eval->rescanPath(); return ArrayVector(); } static void TabledOutput(std::vector sysresult, Interpreter* eval) { int maxlen = 0; // Find the maximal length for (int i=0;igetTerminalWidth()-1; outcolumns = termwidth/(maxlen+1); if (outcolumns < 1) outcolumns = 1; int colwidth = termwidth/outcolumns; int entryCount = 0; while (entryCount < sysresult.size()) { char buffer[4096]; sprintf(buffer,"%s",sysresult[entryCount].c_str()); int wlen; wlen = strlen(buffer); for (int j=wlen;joutputMessage(buffer); entryCount++; if (entryCount % outcolumns == 0) eval->outputMessage("\n"); } eval->outputMessage("\n"); } //! //@Module DIR List Files Function //@@Section OS //@@Usage //In some versions of FreeMat (pre 3.1), the @|dir| function was aliased //to the @|ls| function. Starting with version @|3.1|, the @|dir| function //has been rewritten to provide compatibility with MATLAB. The general syntax //for its use is //@[ // dir //@] //in which case, a listing of the files in the current directory are output to the //console. Alternately, you can specify a target via //@[ // dir('name') //@] //or using the string syntax //@[ // dir name //@] //If you want to capture the output of the @|dir| command, you can assign the output //to an array //@[ // result = dir('name') //@] //(or you can omit @|'name'| to get a directory listing of the current directory. The //resulting array @|result| is a structure array containing the fields: //\begin{itemize} // \item @|name| the filename as a string // \item @|date| the modification date and time stamp as a string // \item @|bytes| the size of the file in bytes as a @|uint64| // \item @|isdir| a logical that is @|1| if the file corresponds to a directory. //\end{itemize} //Note that @|'name'| can also contain wildcards (e.g., @|dir *.m| to get a listing of //all FreeMat scripts in the current directory. //! ArrayVector DirFunction(int nargout, const ArrayVector& arg, Interpreter* eval) { // Check for the case that the given name QString dirarg; if (arg.size() > 0) dirarg = QString::fromStdString(ArrayToString(arg[0])); QDir pdir(QDir::current()); QFileInfoList foo; if (pdir.cd(dirarg)) foo = pdir.entryInfoList(); else { if (dirarg.lastIndexOf(QDir::separator()) == -1) // it must be a pattern foo = pdir.entryInfoList(QStringList() << dirarg); else { // its not a pattern - its a mixed directory and pattern // combination. int path_length(dirarg.lastIndexOf(QDir::separator())); if (pdir.cd(dirarg.left(path_length+1))) foo = pdir.entryInfoList(QStringList() << dirarg.right(dirarg.size()-path_length-1)); } } if (nargout == 0) { std::vector filelist; for (int i=0;i //Next, we use the ``traditional'' form of the function call, using both the parenthesis and the quoted string. //@< //ls('m*.m') //@> //In the third version, we use only the quoted string argument without parenthesis. //@< //ls 'm*.m' //@> //! ArrayVector ListFilesFunction(int nargout, const ArrayVector& arg, Interpreter* eval) { stringVector sysresult; string buffer; int i; #ifdef WIN32 buffer = "dir "; for (i=0;ioutputMessage(sysresult[i]); eval->outputMessage("\n"); } #else buffer = "ls "; for (i=0;i //! ArrayVector PrintWorkingDirectoryFunction(int nargout, const ArrayVector& arg) { return ArrayVector() << Array::stringConstructor(QDir::currentPath().toStdString()); } //! //@Module GETPATH Get Current Search Path //@@Section OS //@@Usage //Returns a @|string| containing the current FreeMat search path. The general syntax for //its use is //@[ // y = getpath //@] //The delimiter between the paths depends on the system being used. For Win32, the //delimiter is a semicolon. For all other systems, the delimiter is a colon. // //@@Example //The @|getpath| function is straightforward. //@< //getpath //@> //! ArrayVector GetPathFunction(int nargout, const ArrayVector& arg, Interpreter* eval) { ArrayVector retval; retval.push_back(Array::stringConstructor(eval->getPath())); return retval; } //! //@Module SETPATH Set Current Search Path //@@Section OS //@@Usage //Changes the current FreeMat search path. The general syntax for //its use is //@[ // setpath(y) //@] //where @|y| is a @|string| containing a delimited list of directories //to be searched for M files and libraries. //The delimiter between the paths depends on the system being used. For Win32, the //delimiter is a semicolon. For all other systems, the delimiter is a colon. // //@Example //The @|setpath| function is straightforward. //@< //getpath //setpath('/usr/local/FreeMat/MFiles:/localhome/basu/MFiles') //getpath //@> //! ArrayVector SetPathFunction(int nargout, const ArrayVector& arg, Interpreter* eval) { if (arg.size() != 1) throw Exception("setpath function requires exactly one string argument"); eval->setPath(arg[0].getContentsAsString()); return ArrayVector(); } //! //@Module RMDIR Remove Directory //@@Section OS //@@Usage //Deletes a directory. The general syntax for its use is //@[ // rmdir('dirname') //@] //which removes the directory @|dirname| if it is empty. If you //want to delete the directory and all subdirectories and files //in it, use the syntax //@[ // rmdir('dirname','s') //@] //! void RemoveDirectory(string dirname) { QDir::current().rmdir(QString::fromStdString(dirname)); } void RemoveDirectoryRecursive(string dirname) { QDir dir(QString::fromStdString(dirname)); dir.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); QFileInfoList list = dir.entryInfoList(); for (unsigned i=0;i 0) suffix = Array::stringConstructor("." + fi.suffix().toStdString()); else suffix = Array::stringConstructor(""); return ArrayVector() << path << name << suffix << Array::stringConstructor(""); } //! //@Module DELETE Delete a File //@@Section OS //@@Usage //Deletes a file. The general syntax for its use is //@[ // delete('filename') //@] //or alternately //@[ // delete filename //@] //which removes the file described by @|filename| which must //be relative to the current path. //! ArrayVector DeleteFunction(int nargout, const ArrayVector& arg) { if (arg.size() == 0) throw Exception("delete requires at least one argument"); QString filename(QString::fromStdString(ArrayToString(arg[0]))); QFileInfo fname(filename); if (fname.exists()) fname.dir().remove(fname.fileName()); else { QFileInfoList foo(QDir::current().entryInfoList(QStringList() << filename)); for (int i=0;i 0) && (dest_info.isDir() || !dest_info.exists())) { // Try and get to the directory QDir sourcedir(source_info.path()); if (!sourcedir.exists()) return ArrayVector(); sourcedir.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); sourcedir.setNameFilters(QStringList() << source_info.fileName()); QFileInfoList list = sourcedir.entryInfoList(); for (unsigned i=0;i