# HG changeset patch # User jwe # Date 1144173046 0 # Node ID 17d87fbd7010df00ab77a57f1a2bcee1c3fa9d8a # Parent c7d5a534afa521d9e17e9428dcfb8b73b0e064b6 [project @ 2006-04-04 17:50:46 by jwe] diff --git a/scripts/ChangeLog b/scripts/ChangeLog --- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,12 @@ +2006-04-04 John W. Eaton + + * path/Makefile.in, path/addpath.m, path/rmpath.m, path/savepath.m: + New files, adapted from Octave Forge by Keith Goodman + . + * path: New directory. + * Makefile.in (SUBDIRS): Add it to the list. + * configure.in (AC_CONFIG_FILES): Include path/Makefile here. + 2006-04-02 David Bateman * general/tril.m, general.triu.m: diff --git a/scripts/Makefile.in b/scripts/Makefile.in --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -30,7 +30,7 @@ skip-autoheader DOCSTRINGS SUBDIRS = audio control deprecated elfun finance general image io \ - linear-algebra miscellaneous optimization plot polynomial \ + linear-algebra miscellaneous optimization path plot polynomial \ quaternion set signal sparse specfun special-matrix startup \ statistics strings testfun time diff --git a/scripts/configure.in b/scripts/configure.in --- a/scripts/configure.in +++ b/scripts/configure.in @@ -34,7 +34,7 @@ control/util/Makefile deprecated/Makefile elfun/Makefile \ finance/Makefile general/Makefile image/Makefile io/Makefile \ linear-algebra/Makefile miscellaneous/Makefile \ - optimization/Makefile plot/Makefile \ + optimization/Makefile path/Makefile plot/Makefile \ polynomial/Makefile quaternion/Makefile set/Makefile \ signal/Makefile sparse/Makefile specfun/Makefile \ special-matrix/Makefile startup/Makefile statistics/Makefile \ diff --git a/scripts/path/Makefile.in b/scripts/path/Makefile.in new file mode 100644 --- /dev/null +++ b/scripts/path/Makefile.in @@ -0,0 +1,67 @@ +# +# Makefile for octave's scripts/path directory +# +# John W. Eaton +# jwe@bevo.che.wisc.edu +# University of Wisconsin-Madison +# Department of Chemical Engineering + +TOPDIR = ../.. + +script_sub_dir = path + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +include $(TOPDIR)/Makeconf + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +SOURCES = *.m + +DISTFILES = Makefile.in $(SOURCES) + +FCN_FILES = $(wildcard $(srcdir)/*.m) +FCN_FILES_NO_DIR = $(notdir $(FCN_FILES)) + +all: PKG_ADD +.PHONY: all + +install install-strip: + $(do-script-install) +.PHONY: install install-strip + +uninstall: + $(do-script-uninstall) +.PHONY: uninstall + +clean: +.PHONY: clean + +PKG_ADD: $(FCN_FILES) + @echo "making PKG_ADD" + @$(do-mkpkgadd) + +tags: $(SOURCES) + ctags $(SOURCES) + +TAGS: $(SOURCES) + etags $(SOURCES) + +mostlyclean: clean +.PHONY: mostlyclean + +distclean: clean + rm -f Makefile +.PHONY: distclean + +maintainer-clean: distclean + rm -f tags TAGS +.PHONY: maintainer-clean + +dist: + ln $(DISTFILES) ../../`cat ../../.fname`/scripts/path +.PHONY: dist diff --git a/scripts/path/addpath.m b/scripts/path/addpath.m new file mode 100644 --- /dev/null +++ b/scripts/path/addpath.m @@ -0,0 +1,126 @@ +## Copyright (C) 2005 Bill Denney +## +## 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 +## +## Based on code Copyright (C) 2000 Etienne Grossmann + +## -*- texinfo -*- +## @deftypefn {Function File} {} addpath(dir1, ...) +## Prepends @code{dir1}, @code{...} to the current @code{LOADPATH}. +## If the directory is already in the path, it will place it where you +## specify in the path (defaulting to prepending it). +## +## @example +## addpath(dir1,'-end',dir2,'-begin',dir3,'-END',dir4,'-BEGIN',dir5) +## @result{} Prepends dir1, dir3 and dir5 and appends dir2 and dir4. +## @end example +## +## An error will be returned if the string is not a directory, the +## directory doesn't exist or you don't have read access to it. +## +## BUG: This function can't add directories called @code{-end} or +## @code{-begin} (case insensitively). +## @end deftypefn + +## Author: Etienne Grossmann +## Modified-By: Bill Denney +## Last modified: June 2005 + +##PKGADD: mark_as_command addpath + +function ret = addpath (varargin) + + if (nargout > 0) + path = varargin{1}; + varargin = varargin(2:end); + else + path = LOADPATH; + endif + + dir = ''; + if (length (varargin) > 0) + append = 0; + switch varargin{end} + case { 0, '0', '-begin', '-BEGIN' } + varargin = varargin(1:end-1); + case { 1, '1', '-end', '-END' } + varargin = varargin(1:end-1); + append = 1; + endswitch + + ## Avoid duplicates by stripping pre-existing entries + path = rmpath (path, varargin{:}); + + ## Check if the directories are valid + for arg = 1:length (varargin) + p = varargin{arg}; + if (nargout == 0 && ! isempty (p)) + [s, err, m] = stat (p); + if (err ~= 0) + warning ("addpath %s : %s\n", p, m); + continue; + elseif (index (s.modestr, "d") != 1) + warning ("addpath %s : not a directory (mode=%s)\n", p, s.modestr); + continue; + elseif ! ((s.modestr(8) == 'r') || ... + ((getgid == s.gid) && (s.modestr(5) == 'r')) || ... + ((getuid == s.uid) && (s.modestr(2) == 'r'))) + warning ("addpath %s : not readable (mode=%s)\n", p, s.modestr); + continue; + endif + endif + dir = sprintf ("%s:%s", dir, p); + endfor + + ## Add the directories to the current path + if (! isempty (dir)) + dir = dir(2:end); + if (isempty (path) && ! isempty (dir)) + path = dir; + else + if strcmp (path, ':'), path = ''; end + if append + path = sprintf ("%s:%s", path, dir); + else + path = sprintf ("%s:%s", dir, path); + endif + endif + endif + endif + + if nargout + ret = path; + else + LOADPATH = path; + endif + +endfunction + +%!assert(addpath('','hello'),'hello'); +%!assert(addpath('','hello','world'),'hello:world') +%!assert(addpath(':','hello'),'hello:'); +%!assert(addpath(':','hello','-end'),':hello'); +%!assert(addpath('hello','hello'),'hello'); +%!assert(addpath('hello','world'),'world:hello') +%!assert(addpath('hello','world','-end'),'hello:world') +%!assert(addpath('hello:','world','-end'),'hello::world') +%!assert(addpath('hello:','hello','world','-end'),':hello:world') + +%!assert(addpath('',''),':') +%!assert(addpath(':',''),':') +%!assert(addpath('hello',''),':hello') +%!assert(addpath('hello:world',''),':hello:world') +%!assert(addpath('hello:world:',''),':hello:world') +%!assert(addpath('hello::world',''),':hello:world') diff --git a/scripts/path/rmpath.m b/scripts/path/rmpath.m new file mode 100644 --- /dev/null +++ b/scripts/path/rmpath.m @@ -0,0 +1,120 @@ +## Copyright (C) 2000 Etienne Grossmann +## +## 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 + +## -*- texinfo -*- +## @deftypefn {Function File} {} rmpath(dir1, ...) +## Removes dir1,... from the current LOADPATH. +## +## newpath = rmpath(path, dir1, ...) +## +## Removes dir1,... from path. +## @end deftypefn + +## Author: Etienne Grossmann +## Last modified: June 2005 + +##PKGADD: mark_as_command rmpath + +function ret = rmpath (varargin) + + if (nargout == 0) + path = LOADPATH; + else + path = varargin{1}; + endif + + strip_system_path = 0; + for arg = nargout + 1:length (varargin) + p = varargin{arg}; + lp = length (p); + + ## '' is the system path + if (lp==0) + strip_system_path = 1; + endif + + ## strip '...:p:...' -> '...:...' + lo = 0 ; + while (lo != length (path)) # Loop while I can substitute + lo = length (path); + path = strrep (path, sprintf(":%s:", p), ":"); + endwhile + + ## strip 'p:...' and '...:p' -> '...' + if (length (path) > lp+1 && strcmp (path(1:lp+1), sprintf ("%s:", p))) + path = path(lp+2:end); + endif + if (length (path) > lp+1 && strcmp (path(end-lp:end), sprintf (":%s", p))) + path = path(1:end-lp-1); + endif + + ## strip 'p:' and ':p' -> ':' + if (length (path) == lp+1 && (strcmp (path, sprintf("%s:", p)) || strcmp (path, sprintf (":%s", p)))) + path = ':'; + endif + + ## strip 'p' -> '' + if (length (path) == lp && strcmp (path, p)) + path = ''; + endif + + endfor + + if (strip_system_path && strcmp (path, ':')) + path = ''; + endif + + if (nargout > 0) + ret = path; + elseif (! strcmp (LOADPATH, path)) + LOADPATH = path; + endif + +endfunction + +%!assert(rmpath(':',''),''); +%!assert(rmpath('hello:',''),'hello'); +%!assert(rmpath('hello:world',''),'hello:world'); +%!assert(rmpath(':hello:world',''),'hello:world'); +%!assert(rmpath(':hello:world:',''),'hello:world'); +%!assert(rmpath(':hello::world:',''),'hello:world'); + +%!assert(rmpath('hello','hello'),''); +%!assert(rmpath(':hello','hello'),':'); +%!assert(rmpath('hello:','hello'),':'); +%!assert(rmpath('hello:hello','hello'),''); +%!assert(rmpath('hello:hello:hello','hello'),''); +%!assert(rmpath('hello:hello:hello:hello','hello'),''); +%!assert(rmpath(':hello:hello','hello'),':'); +%!assert(rmpath('hello:hello:','hello'),':'); +%!assert(rmpath('hello','world'),'hello'); +%!assert(rmpath(':hello','','hello'),''); +%!assert(rmpath(':hello','hello',''),''); + +%!assert(rmpath('hello:world','hello','world'),''); +%!assert(rmpath('hello:world:','hello','world'),':'); +%!assert(rmpath(':hello:world:','hello','world'),':'); + +%!assert(rmpath('hello:world','','hello','world'),''); +%!assert(rmpath('hello:world:','','hello','world'),''); +%!assert(rmpath(':hello:world:','','hello','world'),''); + +%!assert(rmpath('hello:world','hello'),'world'); +%!assert(rmpath('hello:world','world'),'hello'); +%!assert(rmpath('hello:world:','hello'),'world:'); +%!assert(rmpath('hello:world:','world'),'hello:'); +%!assert(rmpath(':hello:world:','hello'),':world:'); +%!assert(rmpath(':hello:world:','world'),':hello:'); diff --git a/scripts/path/savepath.m b/scripts/path/savepath.m new file mode 100644 --- /dev/null +++ b/scripts/path/savepath.m @@ -0,0 +1,131 @@ +## Copyright (C) 2005 Bill Denney +## +## This file is part of Octave. +## +## Octave 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, or (at your option) +## any later version. +## +## Octave 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 Octave; see the file COPYING. If not, write to the Free +## Software Foundation, 59 Temple Place - Suite 330, Boston, MA +## 02111-1307, USA. + +## -*- texinfo -*- +## @deftypefn {Function File} {} savepath (@var{file}) +## This function saves the current @code{LOADPATH} to your personal +## default initilization file or optionally the @var{file} that you +## specify. +## +## It will return 0 if it was successful. +## +## @seealso{LOADPATH,addpath,rmpath} +## @end deftypefn + +## Author: Bill Denney + +function varargout = savepath (savefile) + + retval = 1; + + beginstring = "## Begin savepath auto-created section, do not edit"; + endstring = "## End savepath auto-created section"; + + if nargin == 0 + savefile = fullfile (getenv ("HOME"), strcat (filesep, ".octaverc")); + endif + + %% parse the file if it exists to see if we should replace a section + %% or create a section + startline = 0; + endline = 0; + filelines = {}; + if (exist (savefile) == 2) + %% read in all lines of the file + [fid, msg] = fopen (savefile, "rt"); + if (fid < 0) + error ("savepath: could not open savefile, %s: %s", savefile, msg); + endif + linenum = 0; + while (linenum >= 0) + result = fgetl (fid); + if (isnumeric (result)) + %% end at the end of file + linenum = -1; + else + linenum = linenum + 1; + filelines{linenum} = result; + %% find the first and last lines if they exist in the file + if (strcmp (result, beginstring)) + startline = linenum; + elseif (strcmp (result, endstring)) + endline = linenum; + endif + endif + endwhile + closeread = fclose (fid); + if (closeread < 0) + error ("savepath: could not close savefile after reading, %s", savefile); + endif + endif + + if (startline > endline) || ((startline > 0) && (endline == 0)) + error ("savepath: unable to parse file, %s. There was probably a start line without an end line or end without start.", savefile); + endif + + %% put the path into a cell array + pathlines = { beginstring, [" LOADPATH=\"", LOADPATH, "\";"], endstring }; + + %% put the current savepath lines into the file + if (isempty(filelines)) || ... + ((startline == 1) && (endline == length(filelines))) + %% savepath is the entire file + pre = post = {}; + elseif (endline == 0) + %% drop the savepath statements at the end of the file + pre = filelines; + post = {}; + elseif (startline == 1) + pre = {}; + post = filelines(endline+1:end); + elseif (endline == length(filelines)) + pre = filelines(1:startline-1); + post = {}; + else + %% insert in the middle + pre = filelines(1:startline-1); + post = filelines(endline+1:end); + endif + + %% write the results + [fid, msg] = fopen (savefile, "wt"); + if (fid < 0) + error ("savepath: unable to open file for writing, %s, %s", savefile, msg); + end + for i = 1:length (pre) + fprintf (fid, "%s\n", pre{i}) + endfor + for i = 1:length (pathlines) + fprintf (fid, "%s\n", pathlines{i}); + endfor + for i = 1:length (post) + fprintf (fid, "%s\n", post{i}); + endfor + closeread = fclose (fid); + if (closeread < 0) + error ("savepath: could not close savefile after writing, %s", savefile); + endif + + retval = 0; + + if (nargout == 1) + varargout{1} = retval; + endif + +endfunction