]> Creatis software - CreaPhase.git/blob - octave_packages/m/path/savepath.m
update packages
[CreaPhase.git] / octave_packages / m / path / savepath.m
1 ## Copyright (C) 2005-2012 Bill Denney
2 ##
3 ## This file is part of Octave.
4 ##
5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
9 ##
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 ## General Public License for more details.
14 ##
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING.  If not, see
17 ## <http://www.gnu.org/licenses/>.
18
19 ## -*- texinfo -*-
20 ## @deftypefn {Function File} {} savepath (@var{file})
21 ## Save the portion of the current function search path, that is
22 ## not set during Octave's initialization process, to @var{file}.
23 ## If @var{file} is omitted, @file{~/.octaverc} is used.  If successful,
24 ## @code{savepath} returns 0.
25 ## @seealso{path, addpath, rmpath, genpath, pathdef, pathsep}
26 ## @end deftypefn
27
28 ## Author: Bill Denney <bill@givebillmoney.com>
29
30 function varargout = savepath (file)
31
32   retval = 1;
33
34   beginstring = "## Begin savepath auto-created section, do not edit";
35   endstring   = "## End savepath auto-created section";
36
37   if (nargin == 0)
38     file = fullfile ("~", ".octaverc");
39   endif
40
41   ## parse the file if it exists to see if we should replace a section
42   ## or create a section
43   startline = 0;
44   endline = 0;
45   filelines = {};
46   if (exist (file) == 2)
47     ## read in all lines of the file
48     [fid, msg] = fopen (file, "rt");
49     if (fid < 0)
50       error ("savepath: could not open file, %s: %s", file, msg);
51     endif
52     unwind_protect
53       linenum = 0;
54       while (linenum >= 0)
55         result = fgetl (fid);
56         if (isnumeric (result))
57           ## end at the end of file
58           linenum = -1;
59         else
60           linenum = linenum + 1;
61           filelines{linenum} = result;
62           ## find the first and last lines if they exist in the file
63           if (strcmp (result, beginstring))
64             startline = linenum;
65           elseif (strcmp (result, endstring))
66             endline = linenum;
67           endif
68         endif
69       endwhile
70     unwind_protect_cleanup
71       closeread = fclose (fid);
72       if (closeread < 0)
73         error ("savepath: could not close file after reading, %s",
74                file);
75       endif
76     end_unwind_protect
77   endif
78
79   if (startline > endline || (startline > 0 && endline == 0))
80     error ("savepath: unable to parse file, %s", file);
81   endif
82
83   ## put the current savepath lines into the file
84   if (isempty (filelines)
85       || (startline == 1 && endline == length (filelines)))
86     ## savepath is the entire file
87     pre = post = {};
88   elseif (endline == 0)
89     ## drop the savepath statements at the end of the file
90     pre = filelines;
91     post = {};
92   elseif (startline == 1)
93     pre = {};
94     post = filelines(endline+1:end);
95   elseif (endline == length (filelines))
96     pre = filelines(1:startline-1);
97     post = {};
98   else
99     ## insert in the middle
100     pre = filelines(1:startline-1);
101     post = filelines(endline+1:end);
102   endif
103
104   ## write the results
105   [fid, msg] = fopen (file, "wt");
106   if (fid < 0)
107     error ("savepath: unable to open file for writing, %s, %s", file, msg);
108   endif
109   unwind_protect
110     for i = 1:length (pre)
111       fprintf (fid, "%s\n", pre{i});
112     endfor
113
114     ## Remove the portion of the path defined via the command line
115     ## and/or the environment.
116     workingpath = parsepath (path);
117     command_line_path = parsepath (command_line_path ());
118     octave_path = parsepath (getenv ("OCTAVE_PATH"));
119     if (isempty (pathdef ()))
120       ## This occurs when running octave via run-octave. In this instance
121       ## the entire path is specified via the command line and pathdef()
122       ## is empty.
123       [tmp, n] = setdiff (workingpath, octave_path);
124       default_path = command_line_path;
125     else
126       [tmp, n] = setdiff (workingpath, union (command_line_path, octave_path));
127       default_path = parsepath (pathdef ());
128     endif
129     ## This is the path we'd like to preserve when octave is run.
130     path_to_preserve = workingpath (sort (n));
131
132     ## Determine the path to Octave's user and sytem wide pkgs.
133     [pkg_user, pkg_system] = pkg ("list");
134     pkg_user_path = cell (1, numel (pkg_user));
135     pkg_system_path = cell (1, numel (pkg_system));
136     for n = 1:numel(pkg_user)
137       pkg_user_path{n} = pkg_user{n}.archprefix;
138     endfor
139     for n = 1:numel(pkg_system)
140       pkg_system_path{n} = pkg_system{n}.archprefix;
141     endfor
142     pkg_path = union (pkg_user_path, pkg_system_path);
143
144     ## Rely on Octave's initialization to include the pkg path elements.
145     if (! isempty (pkg_path))
146       [tmp, n] = setdiff (path_to_preserve, strcat (pkg_path, ":"));
147       path_to_preserve = path_to_preserve (sort (n));
148     endif
149
150     ## Split the path to be saved into two groups. Those path elements that
151     ## belong at the beginning and those at the end.
152     if (! isempty (default_path))
153       n1 = strmatch (default_path{1}, path_to_preserve, "exact");
154       n2 = strmatch (default_path{end}, path_to_preserve, "exact");
155       n_middle = round (0.5*(n1+n2));
156       [tmp, n] = setdiff (path_to_preserve, default_path);
157       path_to_save = path_to_preserve (sort (n));
158       ## Remove pwd
159       path_to_save = path_to_save (! strcmpi (path_to_save,
160                                               strcat (".", pathsep)));
161       n = ones (size (path_to_save));
162       for m = 1:numel(path_to_save)
163         n(m) = strmatch (path_to_save{m}, path_to_preserve);
164       endfor
165       path_to_save_begin = path_to_save(n <= n_middle);
166       path_to_save_end   = path_to_save(n > n_middle);
167     else
168       path_to_save_begin = path_to_preserve;
169       path_to_save_end   = {};
170     endif
171     path_to_save_begin = cell2mat (path_to_save_begin);
172     path_to_save_end   = cell2mat (path_to_save_end);
173
174     ## Use single quotes for PATH argument to avoid string escape
175     ## processing.  Since we are using single quotes around the arg,
176     ## double any single quote characters found in the string.
177     fprintf (fid, "%s\n", beginstring);
178     if (! isempty (path_to_save_begin))
179       n = find (path_to_save_begin != pathsep, 1, "last");
180       fprintf (fid, "  addpath ('%s', '-begin');\n",
181                strrep (path_to_save_begin(1:n), "'", "''"));
182     endif
183     if (! isempty (path_to_save_end))
184       n = find (path_to_save_end != pathsep, 1, "last");
185       fprintf (fid, "  addpath ('%s', '-end');\n",
186                strrep (path_to_save_end(1:n), "'", "''"));
187     endif
188     fprintf (fid, "%s\n", endstring);
189
190     for i = 1:length (post)
191       fprintf (fid, "%s\n", post{i});
192     endfor
193   unwind_protect_cleanup
194     closeread = fclose (fid);
195     if (closeread < 0)
196       error ("savepath: could not close savefile after writing, %s", file);
197     elseif (nargin == 0)
198       warning ("savepath: current path saved to %s", file);
199     endif
200   end_unwind_protect
201
202   retval = 0;
203
204   if (nargout == 1)
205     varargout{1} = retval;
206   endif
207
208 endfunction
209
210 function path_elements = parsepath (p)
211   pat = sprintf ('([^%s]+[%s$])', pathsep, pathsep);
212   [~, ~, ~, path_elements] = regexpi (strcat (p, pathsep), pat);
213 endfunction
214