]> code.delx.au - gnu-emacs/blob - test/indent/octave.m
a7041462f7f3309f2fd1843d088073448af8e3db
[gnu-emacs] / test / indent / octave.m
1 ## -*- mode: octave; coding: utf-8 -*-
2 0; # Don't make this a function file
3 function res = tcomp (fn)
4 %% res = tcomp (fn)
5 %% imports components and rearranges them.
6
7 if nargin ~= 1
8 print_usage()
9 end
10
11 data = dlmread(fn, 3, 0);
12
13 x = data(:,2:end);
14 y = 'hello';
15 z = y';
16
17 ## Bug#14399.
18 vec = [...
19 one;...
20 two;...
21 three];
22
23 cnty = repmat(x(:,1)(:), 10, 1);
24 x = ...
25 12
26
27 pop = x(:,1:10)(:);
28 ## Here and below, we test if the indentation aligns with a previous
29 ## fixindented line. This is important so as to make it easier for the
30 ## user to override some indentation somewhere, and also because it
31 ## reflects the fact that the indentation decision is taken with a minimum
32 ## amount of work (i.e. in the present case, without having to walk back
33 ## until the `function' line).
34 bir = x(:,11:20)(:); # fixindent
35 dth = x(:,21:30)(:);
36 imig = x(:,31:40)(:);
37 dmig = x(:,41:50)(:);
38 gq = x(:,51:60)(:);
39
40 yrs = repmat(2000:2009, 39, 1)(:);
41
42 res = [yrs, cnty, pop, bir, dth, imig, dmig, gq];
43
44 endfunction
45
46 ## Copyright (C) 2005, 2006, 2007, 2008, 2009 Søren Hauberg
47 ##
48 ## This file is part of Octave.
49 ##
50 ## Octave is free software; you can redistribute it and/or modify it
51 ## under the terms of the GNU General Public License as published by
52 ## the Free Software Foundation; either version 3 of the License, or (at
53 ## your option) any later version.
54 ##
55 ## Octave is distributed in the hope that it will be useful, but
56 ## WITHOUT ANY WARRANTY; without even the implied warranty of
57 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
58 ## General Public License for more details.
59 ##
60 ## You should have received a copy of the GNU General Public License
61 ## along with Octave; see the file COPYING. If not, see
62 ## <http://www.gnu.org/licenses/>.
63
64 ## -*- texinfo -*-
65 ## @deftypefn {Command} pkg @var{command} @var{pkg_name}
66 ## @deftypefnx {Command} pkg @var{command} @var{option} @var{pkg_name}
67 ## This command interacts with the package manager. Different actions will
68 ## be taken depending on the value of @var{command}.
69 ##
70 ## @table @samp
71 ## @item install
72 ## Install named packages. For example,
73 ## @example
74 ## pkg install image-1.0.0.tar.gz
75 ## @end example
76 ## @noindent
77 ## installs the package found in the file @file{image-1.0.0.tar.gz}.
78 ##
79 ## The @var{option} variable can contain options that affect the manner
80 ## in which a package is installed. These options can be one or more of
81 ##
82 ## @table @code
83 ## @item -nodeps
84 ## The package manager will disable the dependency checking. That way it
85 ## is possible to install a package even if it depends on another package
86 ## that's not installed on the system. @strong{Use this option with care.}
87 ##
88 ## @item -noauto
89 ## The package manager will not automatically load the installed package
90 ## when starting Octave, even if the package requests that it is.
91 ##
92 ## @item -auto
93 ## The package manager will automatically load the installed package when
94 ## starting Octave, even if the package requests that it isn't.
95 ##
96 ## @item -local
97 ## A local installation is forced, even if the user has system privileges.
98 ##
99 ## @item -global
100 ## A global installation is forced, even if the user doesn't normally have
101 ## system privileges
102 ##
103 ## @item -verbose
104 ## The package manager will print the output of all of the commands that are
105 ## performed.
106 ## @end table
107 ##
108 ## @item uninstall
109 ## Uninstall named packages. For example,
110 ## @example
111 ## pkg uninstall image
112 ## @end example
113 ## @noindent
114 ## removes the @code{image} package from the system. If another installed
115 ## package depends on the @code{image} package an error will be issued.
116 ## The package can be uninstalled anyway by using the @code{-nodeps} option.
117 ## @item load
118 ## Add named packages to the path. After loading a package it is
119 ## possible to use the functions provided by the package. For example,
120 ## @example
121 ## pkg load image
122 ## @end example
123 ## @noindent
124 ## adds the @code{image} package to the path. It is possible to load all
125 ## installed packages at once with the command
126 ## @example
127 ## pkg load all
128 ## @end example
129 ## @item unload
130 ## Removes named packages from the path. After unloading a package it is
131 ## no longer possible to use the functions provided by the package.
132 ## This command behaves like the @code{load} command.
133 ## @item list
134 ## Show a list of the currently installed packages. By requesting one or two
135 ## output argument it is possible to get a list of the currently installed
136 ## packages. For example,
137 ## @example
138 ## installed_packages = pkg list;
139 ## @end example
140 ## @noindent
141 ## returns a cell array containing a structure for each installed package.
142 ## The command
143 ## @example
144 ## [@var{user_packages}, @var{system_packages}] = pkg list
145 ## @end example
146 ## @noindent
147 ## splits the list of installed packages into those who are installed by
148 ## the current user, and those installed by the system administrator.
149 ## @item describe
150 ## Show a short description of the named installed packages, with the option
151 ## '-verbose' also list functions provided by the package, e.g.:
152 ## @example
153 ## pkg describe -verbose all
154 ## @end example
155 ## @noindent
156 ## will describe all installed packages and the functions they provide.
157 ## If one output is requested a cell of structure containing the
158 ## description and list of functions of each package is returned as
159 ## output rather than printed on screen:
160 ## @example
161 ## desc = pkg ("describe", "secs1d", "image")
162 ## @end example
163 ## @noindent
164 ## If any of the requested packages is not installed, pkg returns an
165 ## error, unless a second output is requested:
166 ## @example
167 ## [ desc, flag] = pkg ("describe", "secs1d", "image")
168 ## @end example
169 ## @noindent
170 ## @var{flag} will take one of the values "Not installed", "Loaded" or
171 ## "Not loaded" for each of the named packages.
172 ## @item prefix
173 ## Set the installation prefix directory. For example,
174 ## @example
175 ## pkg prefix ~/my_octave_packages
176 ## @end example
177 ## @noindent
178 ## sets the installation prefix to @file{~/my_octave_packages}.
179 ## Packages will be installed in this directory.
180 ##
181 ## It is possible to get the current installation prefix by requesting an
182 ## output argument. For example,
183 ## @example
184 ## p = pkg prefix
185 ## @end example
186 ##
187 ## The location in which to install the architecture dependent files can be
188 ## independent specified with an addition argument. For example
189 ##
190 ## @example
191 ## pkg prefix ~/my_octave_packages ~/my_arch_dep_pkgs
192 ## @end example
193 ## @item local_list
194 ## Set the file in which to look for information on the locally
195 ## installed packages. Locally installed packages are those that are
196 ## typically available only to the current user. For example
197 ## @example
198 ## pkg local_list ~/.octave_packages
199 ## @end example
200 ## It is possible to get the current value of local_list with the following
201 ## @example
202 ## pkg local_list
203 ## @end example
204 ## @item global_list
205 ## Set the file in which to look for, for information on the globally
206 ## installed packages. Globally installed packages are those that are
207 ## typically available to all users. For example
208 ## @example
209 ## pkg global_list /usr/share/octave/octave_packages
210 ## @end example
211 ## It is possible to get the current value of global_list with the following
212 ## @example
213 ## pkg global_list
214 ## @end example
215 ## @item rebuild
216 ## Rebuilds the package database from the installed directories. This can
217 ## be used in cases where for some reason the package database is corrupted.
218 ## It can also take the @code{-auto} and @code{-noauto} options to allow the
219 ## autoloading state of a package to be changed. For example
220 ##
221 ## @example
222 ## pkg rebuild -noauto image
223 ## @end example
224 ##
225 ## will remove the autoloading status of the image package.
226 ## @item build
227 ## Builds a binary form of a package or packages. The binary file produced
228 ## will itself be an Octave package that can be installed normally with
229 ## @code{pkg}. The form of the command to build a binary package is
230 ##
231 ## @example
232 ## pkg build builddir image-1.0.0.tar.gz @dots{}
233 ## @end example
234 ##
235 ## @noindent
236 ## where @code{builddir} is the name of a directory where the temporary
237 ## installation will be produced and the binary packages will be found.
238 ## The options @code{-verbose} and @code{-nodeps} are respected, while
239 ## the other options are ignored.
240 ## @end table
241 ## @end deftypefn
242
243 function [local_packages, global_packages] = pkg (varargin)
244 ## Installation prefix (FIXME: what should these be on windows?)
245 persistent user_prefix = false;
246 persistent prefix = -1;
247 persistent archprefix = -1;
248 persistent local_list = tilde_expand (fullfile ("~", ".octave_packages"));
249 persistent global_list = fullfile (OCTAVE_HOME (), "share", "octave",
250 "octave_packages");
251 mlock ();
252
253 global_install = issuperuser ();
254
255 if (prefix == -1)
256 if (global_install)
257 prefix = fullfile (OCTAVE_HOME (), "share", "octave", "packages");
258 archprefix = fullfile (octave_config_info ("libexecdir"),
259 "octave", "packages");
260 else
261 prefix = fullfile ("~", "octave");
262 archprefix = prefix;
263 endif
264 prefix = tilde_expand (prefix);
265 archprefix = tilde_expand (archprefix);
266 endif
267
268 available_actions = {"list", "install", "uninstall", "load", ...
269 "unload", "prefix", "local_list", ...
270 "global_list", "rebuild", "build","describe"};
271 ## Handle input
272 if (length (varargin) == 0 || ! iscellstr (varargin))
273 print_usage ();
274 endif
275 files = {};
276 deps = true;
277 auto = 0;
278 action = "none";
279 verbose = false;
280 for i = 1:length (varargin)
281 switch (varargin{i})
282 case "-nodeps"
283 deps = false;
284 case "-noauto"
285 auto = -1;
286 case "-auto"
287 auto = 1;
288 case "-verbose"
289 verbose = true;
290 case "-local"
291 global_install = false;
292 if (! user_prefix)
293 prefix = tilde_expand (fullfile ("~", "octave"));
294 archprefix = prefix;
295 endif
296 case "-global"
297 global_install = true;
298 if (! user_prefix)
299 prefix = fullfile (OCTAVE_HOME (), "share", "octave", "packages");
300 archprefix = fullfile (octave_config_info ("libexecdir"),
301 "octave", "packages");
302 endif
303 case available_actions
304 if (strcmp (action, "none"))
305 action = varargin{i};
306 else
307 error ("more than one action specified");
308 endif
309 otherwise
310 files{end+1} = varargin{i};
311 endswitch
312 endfor
313
314 ## Take action
315 switch (action)
316 case "list"
317 if (nargout == 0)
318 installed_packages (local_list, global_list);
319 elseif (nargout == 1)
320 local_packages = installed_packages (local_list, global_list);
321 elseif (nargout == 2)
322 [local_packages, global_packages] = installed_packages (local_list,
323 global_list);
324 else
325 error ("too many output arguments requested");
326 endif
327
328 case "install"
329 if (length (files) == 0)
330 error ("you must specify at least one filename when calling 'pkg install'");
331 endif
332 install (files, deps, auto, prefix, archprefix, verbose, local_list,
333 global_list, global_install);
334
335 case "uninstall"
336 if (length (files) == 0)
337 error ("you must specify at least one package when calling 'pkg uninstall'");
338 endif
339 uninstall (files, deps, verbose, local_list,
340 global_list, global_install);
341
342 case "load"
343 if (length (files) == 0)
344 error ("you must specify at least one package, 'all' or 'auto' when calling 'pkg load'");
345 endif
346 load_packages (files, deps, local_list, global_list);
347
348 case "unload"
349 if (length (files) == 0)
350 error ("you must specify at least one package or 'all' when calling 'pkg unload'");
351 endif
352 unload_packages (files, deps, local_list, global_list);
353
354 case "prefix"
355 if (length (files) == 0 && nargout == 0)
356 printf ("Installation prefix: %s\n", prefix);
357 printf ("Architecture dependent prefix: %s\n", archprefix);
358 elseif (length (files) == 0 && nargout >= 1)
359 local_packages = prefix;
360 global_packages = archprefix;
361 elseif (length (files) >= 1 && nargout <= 2 && ischar (files{1}))
362 prefix = files{1};
363 prefix = absolute_pathname (prefix);
364 local_packages = prefix;
365 user_prefix = true;
366 if (length (files) >= 2 && ischar (files{2}))
367 archprefix = files{2};
368 try
369 archprefix = absolute_pathname (archprefix);
370 catch
371 mkdir (archprefix);
372 warning ("creating the directory %s\n", archprefix);
373 archprefix = absolute_pathname (archprefix);
374 end_try_catch
375 global_packages = archprefix;
376 endif
377 else
378 error ("you must specify a prefix directory, or request an output argument");
379 endif
380
381 case "local_list"
382 if (length (files) == 0 && nargout == 0)
383 disp (local_list);
384 elseif (length (files) == 0 && nargout == 1)
385 local_packages = local_list;
386 elseif (length (files) == 1 && nargout == 0 && ischar (files{1}))
387 try
388 local_list = absolute_pathname (files{1});
389 catch
390 ## Force file to be created
391 fclose (fopen (files{1}, "wt"));
392 local_list = absolute_pathname (files{1});
393 end_try_catch
394 else
395 error ("you must specify a local_list file, or request an output argument");
396 endif
397
398 case "global_list"
399 if (length (files) == 0 && nargout == 0)
400 disp(global_list);
401 elseif (length (files) == 0 && nargout == 1)
402 local_packages = global_list;
403 elseif (length (files) == 1 && nargout == 0 && ischar (files{1}))
404 try
405 global_list = absolute_pathname (files{1});
406 catch
407 ## Force file to be created
408 fclose (fopen (files{1}, "wt"));
409 global_list = absolute_pathname (files{1});
410 end_try_catch
411 else
412 error ("you must specify a global_list file, or request an output argument");
413 endif
414
415 case "rebuild"
416 if (global_install)
417 global_packages = rebuild (prefix, archprefix, global_list, files,
418 auto, verbose);
419 global_packages = save_order (global_packages);
420 save (global_list, "global_packages");
421 if (nargout > 0)
422 local_packages = global_packages;
423 endif
424 else
425 local_packages = rebuild (prefix, archprefix, local_list, files, auto,
426 verbose);
427 local_packages = save_order (local_packages);
428 save (local_list, "local_packages");
429 if (nargout == 0)
430 clear ("local_packages");
431 endif
432 endif
433
434 case "build"
435 if (length (files) < 2)
436 error ("you must specify at least the build directory and one filename\nwhen calling 'pkg build'");
437 endif
438 build (files, deps, auto, verbose);
439
440 case "describe"
441 if (length (files) == 0)
442 error ("you must specify at least one package or 'all' when calling 'pkg describe'");
443 endif
444 ## FIXME: the name of the output variables is inconsistent
445 ## with their content
446 switch (nargout)
447 case 0
448 describe (files, verbose, local_list, global_list);
449 case 1
450 pkg_desc_list = describe (files, verbose, local_list, ...
451 global_list);
452 local_packages = pkg_desc_list;
453 case 2
454 [pkg_desc_list, flag] = describe (files, verbose, local_list, ...
455 global_list);
456 local_packages = pkg_desc_list;
457 global_packages = flag;
458 otherwise
459 error ("you can request at most two outputs when calling 'pkg describe'");
460 endswitch
461
462 otherwise
463 error ("you must specify a valid action for 'pkg'. See 'help pkg' for details");
464 endswitch
465 endfunction
466
467 function descriptions = rebuild (prefix, archprefix, list, files, auto, verbose)
468 if (isempty (files))
469 [dirlist, err, msg] = readdir (prefix);
470 if (err)
471 error ("couldn't read directory %s: %s", prefix, msg);
472 endif
473 ## the two first entries of dirlist are "." and ".."
474 dirlist([1,2]) = [];
475 else
476 old_descriptions = installed_packages (list, list);
477 wd = pwd ();
478 unwind_protect
479 cd (prefix);
480 dirlist = glob (cellfun(@(x) cstrcat(x, '-*'), files, 'UniformOutput', 0));
481 unwind_protect_cleanup
482 cd (wd);
483 end_unwind_protect
484 endif
485 descriptions = {};
486 for k = 1:length (dirlist)
487 descfile = fullfile (prefix, dirlist{k}, "packinfo", "DESCRIPTION");
488 if (verbose)
489 printf ("recreating package description from %s\n", dirlist{k});
490 endif
491 if (exist (descfile, "file"))
492 desc = get_description (descfile);
493 desc.dir = fullfile (prefix, dirlist{k});
494 desc.archprefix = fullfile (archprefix, cstrcat (desc.name, "-",
495 desc.version));
496 if (auto != 0)
497 if (exist (fullfile (desc.dir, "packinfo", ".autoload"), "file"))
498 unlink (fullfile (desc.dir, "packinfo", ".autoload"));
499 endif
500 if (auto < 0)
501 desc.autoload = 0;
502 elseif (auto > 0)
503 desc.autoload = 1;
504 fclose (fopen (fullfile (desc.dir, "packinfo", ".autoload"), "wt"));
505 endif
506 else
507 if (exist (fullfile (desc.dir, "packinfo", ".autoload"), "file"))
508 desc.autoload = 1;
509 else
510 desc.autoload = 0;
511 endif
512 endif
513 descriptions{end + 1} = desc;
514 elseif (verbose)
515 warning ("directory %s is not a valid package", dirlist{k});
516 endif
517 endfor
518
519 if (! isempty (files))
520 ## We are rebuilding for a particular package(s) so we should take
521 ## care to keep the other untouched packages in the descriptions
522 descriptions = {descriptions{:}, old_descriptions{:}};
523
524 dup = [];
525 for i = 1:length (descriptions)
526 if (find (dup, i))
527 continue;
528 endif
529 for j = (i+1):length (descriptions)
530 if (find (dup, j))
531 continue;
532 endif
533 if (strcmp (descriptions{i}.name, descriptions{j}.name))
534 dup = [dup, j];
535 endif
536 endfor
537 endfor
538 if (! isempty (dup))
539 descriptions (dup) = [];
540 endif
541 endif
542 endfunction
543
544 function build (files, handle_deps, autoload, verbose)
545 if (length (files) < 1)
546 error ("insufficient number of files");
547 endif
548 builddir = files{1};
549 if (! exist (builddir, "dir"))
550 warning ("creating build directory %s", builddir);
551 [status, msg] = mkdir (builddir);
552 if (status != 1)
553 error ("could not create installation directory: %s", msg);
554 endif
555 endif
556 builddir = absolute_pathname (builddir);
557 installdir = fullfile (builddir, "install");
558 if (! exist (installdir, "dir"))
559 [status, msg] = mkdir (installdir);
560 if (status != 1)
561 error ("could not create installation directory: %s", msg);
562 endif
563 endif
564 files(1) = [];
565 buildlist = fullfile (builddir, "octave_packages");
566 install (files, handle_deps, autoload, installdir, installdir, verbose,
567 buildlist, "", false);
568 unwind_protect
569 repackage (builddir, buildlist);
570 unwind_protect_cleanup
571 unload_packages ({"all"}, handle_deps, buildlist, "");
572 if (exist (installdir, "dir"))
573 rm_rf (installdir);
574 endif
575 if (exist (buildlist, "file"))
576 unlink (buildlist);
577 endif
578 end_unwind_protect
579 endfunction
580
581 function install (files, handle_deps, autoload, prefix, archprefix, verbose,
582 local_list, global_list, global_install)
583
584 ## Check that the directory in prefix exist. If it doesn't: create it!
585 if (! exist (prefix, "dir"))
586 warning ("creating installation directory %s", prefix);
587 [status, msg] = mkdir (prefix);
588 if (status != 1)
589 error ("could not create installation directory: %s", msg);
590 endif
591 endif
592
593 ## Get the list of installed packages.
594 [local_packages, global_packages] = installed_packages (local_list,
595 global_list);
596
597 installed_pkgs_lst = {local_packages{:}, global_packages{:}};
598
599 if (global_install)
600 packages = global_packages;
601 else
602 packages = local_packages;
603 endif
604
605 ## Uncompress the packages and read the DESCRIPTION files.
606 tmpdirs = packdirs = descriptions = {};
607 try
608 ## Warn about non existent files.
609 for i = 1:length (files)
610 if (isempty (glob(files{i})))
611 warning ("file %s does not exist", files{i});
612 endif
613 endfor
614
615 ## Unpack the package files and read the DESCRIPTION files.
616 files = glob (files);
617 packages_to_uninstall = [];
618 for i = 1:length (files)
619 tgz = files{i};
620
621 if (exist (tgz, "file"))
622 ## Create a temporary directory.
623 tmpdir = tmpnam ();
624 tmpdirs{end+1} = tmpdir;
625 if (verbose)
626 printf ("mkdir (%s)\n", tmpdir);
627 endif
628 [status, msg] = mkdir (tmpdir);
629 if (status != 1)
630 error ("couldn't create temporary directory: %s", msg);
631 endif
632
633 ## Uncompress the package.
634 if (verbose)
635 printf ("untar (%s, %s)\n", tgz, tmpdir);
636 endif
637 untar (tgz, tmpdir);
638
639 ## Get the name of the directories produced by tar.
640 [dirlist, err, msg] = readdir (tmpdir);
641 if (err)
642 error ("couldn't read directory produced by tar: %s", msg);
643 endif
644
645 if (length (dirlist) > 3)
646 error ("bundles of packages are not allowed")
647 endif
648 endif
649
650 ## The filename pointed to an uncompressed package to begin with.
651 if (exist (tgz, "dir"))
652 dirlist = {".", "..", tgz};
653 endif
654
655 if (exist (tgz, "file") || exist (tgz, "dir"))
656 ## The two first entries of dirlist are "." and "..".
657 if (exist (tgz, "file"))
658 packdir = fullfile (tmpdir, dirlist{3});
659 else
660 packdir = fullfile (pwd(), dirlist{3});
661 endif
662 packdirs{end+1} = packdir;
663
664 ## Make sure the package contains necessary files.
665 verify_directory (packdir);
666
667 ## Read the DESCRIPTION file.
668 filename = fullfile (packdir, "DESCRIPTION");
669 desc = get_description (filename);
670
671 ## Verify that package name corresponds with filename.
672 [dummy, nm] = fileparts (tgz);
673 if ((length (nm) >= length (desc.name))
674 && ! strcmp (desc.name, nm(1:length(desc.name))))
675 error ("package name '%s' doesn't correspond to its filename '%s'",
676 desc.name, nm);
677 endif
678
679 ## Set default installation directory.
680 desc.dir = fullfile (prefix, cstrcat (desc.name, "-", desc.version));
681
682 ## Set default architecture dependent installation directory.
683 desc.archprefix = fullfile (archprefix, cstrcat (desc.name, "-",
684 desc.version));
685
686 ## Save desc.
687 descriptions{end+1} = desc;
688
689 ## Are any of the new packages already installed?
690 ## If so we'll remove the old version.
691 for j = 1:length (packages)
692 if (strcmp (packages{j}.name, desc.name))
693 packages_to_uninstall(end+1) = j;
694 endif
695 endfor
696 endif
697 endfor
698 catch
699 ## Something went wrong, delete tmpdirs.
700 for i = 1:length (tmpdirs)
701 rm_rf (tmpdirs{i});
702 endfor
703 rethrow (lasterror ());
704 end_try_catch
705
706 ## Check dependencies.
707 if (handle_deps)
708 ok = true;
709 error_text = "";
710 for i = 1:length (descriptions)
711 desc = descriptions{i};
712 idx2 = complement (i, 1:length(descriptions));
713 if (global_install)
714 ## Global installation is not allowed to have dependencies on locally
715 ## installed packages.
716 idx1 = complement (packages_to_uninstall,
717 1:length(global_packages));
718 pseudo_installed_packages = {global_packages{idx1}, ...
719 descriptions{idx2}};
720 else
721 idx1 = complement (packages_to_uninstall,
722 1:length(local_packages));
723 pseudo_installed_packages = {local_packages{idx1}, ...
724 global_packages{:}, ...
725 descriptions{idx2}};
726 endif
727 bad_deps = get_unsatisfied_deps (desc, pseudo_installed_packages);
728 ## Are there any unsatisfied dependencies?
729 if (! isempty (bad_deps))
730 ok = false;
731 for i = 1:length (bad_deps)
732 dep = bad_deps{i};
733 error_text = cstrcat (error_text, " ", desc.name, " needs ",
734 dep.package, " ", dep.operator, " ",
735 dep.version, "\n");
736 endfor
737 endif
738 endfor
739
740 ## Did we find any unsatisfied dependencies?
741 if (! ok)
742 error ("the following dependencies where unsatisfied:\n %s", error_text);
743 endif
744 endif
745
746 ## Prepare each package for installation.
747 try
748 for i = 1:length (descriptions)
749 desc = descriptions{i};
750 pdir = packdirs{i};
751 prepare_installation (desc, pdir);
752 configure_make (desc, pdir, verbose);
753 endfor
754 catch
755 ## Something went wrong, delete tmpdirs.
756 for i = 1:length (tmpdirs)
757 rm_rf (tmpdirs{i});
758 endfor
759 rethrow (lasterror ());
760 end_try_catch
761
762 ## Uninstall the packages that will be replaced.
763 try
764 for i = packages_to_uninstall
765 if (global_install)
766 uninstall ({global_packages{i}.name}, false, verbose, local_list,
767 global_list, global_install);
768 else
769 uninstall ({local_packages{i}.name}, false, verbose, local_list,
770 global_list, global_install);
771 endif
772 endfor
773 catch
774 ## Something went wrong, delete tmpdirs.
775 for i = 1:length (tmpdirs)
776 rm_rf (tmpdirs{i});
777 endfor
778 rethrow (lasterror ());
779 end_try_catch
780
781 ## Install each package.
782 try
783 for i = 1:length (descriptions)
784 desc = descriptions{i};
785 pdir = packdirs{i};
786 copy_files (desc, pdir, global_install);
787 create_pkgadddel (desc, pdir, "PKG_ADD", global_install);
788 create_pkgadddel (desc, pdir, "PKG_DEL", global_install);
789 finish_installation (desc, pdir, global_install);
790 generate_lookfor_cache (desc);
791 endfor
792 catch
793 ## Something went wrong, delete tmpdirs.
794 for i = 1:length (tmpdirs)
795 rm_rf (tmpdirs{i});
796 endfor
797 for i = 1:length (descriptions)
798 rm_rf (descriptions{i}.dir);
799 rm_rf (getarchdir (descriptions{i}));
800 endfor
801 rethrow (lasterror ());
802 end_try_catch
803
804 ## Check if the installed directory is empty. If it is remove it
805 ## from the list.
806 for i = length (descriptions):-1:1
807 if (dirempty (descriptions{i}.dir, {"packinfo", "doc"}) &&
808 dirempty (getarchdir (descriptions{i})))
809 warning ("package %s is empty\n", descriptions{i}.name);
810 rm_rf (descriptions{i}.dir);
811 rm_rf (getarchdir (descriptions{i}));
812 descriptions(i) = [];
813 endif
814 endfor
815
816 ## If the package requested that it is autoloaded, or the installer
817 ## requested that it is, then mark the package as autoloaded.
818 for i = length (descriptions):-1:1
819 if (autoload > 0 || (autoload == 0 && isautoload (descriptions(i))))
820 fclose (fopen (fullfile (descriptions{i}.dir, "packinfo",
821 ".autoload"), "wt"));
822 descriptions{i}.autoload = 1;
823 endif
824 endfor
825
826 ## Add the packages to the package list.
827 try
828 if (global_install)
829 idx = complement (packages_to_uninstall, 1:length(global_packages));
830 global_packages = save_order ({global_packages{idx}, descriptions{:}});
831 save (global_list, "global_packages");
832 installed_pkgs_lst = {local_packages{:}, global_packages{:}};
833 else
834 idx = complement (packages_to_uninstall, 1:length(local_packages));
835 local_packages = save_order ({local_packages{idx}, descriptions{:}});
836 save (local_list, "local_packages");
837 installed_pkgs_lst = {local_packages{:}, global_packages{:}};
838 endif
839 catch
840 ## Something went wrong, delete tmpdirs.
841 for i = 1:length (tmpdirs)
842 rm_rf (tmpdirs{i});
843 endfor
844 for i = 1:length (descriptions)
845 rm_rf (descriptions{i}.dir);
846 endfor
847 if (global_install)
848 printf ("error: couldn't append to %s\n", global_list);
849 else
850 printf ("error: couldn't append to %s\n", local_list);
851 endif
852 rethrow (lasterror ());
853 end_try_catch
854
855 ## All is well, let's clean up.
856 for i = 1:length (tmpdirs)
857 [status, msg] = rm_rf (tmpdirs{i});
858 if (status != 1)
859 warning ("couldn't clean up after my self: %s\n", msg);
860 endif
861 endfor
862
863 ## Add the newly installed packages to the path, so the user
864 ## can begin using them. Only load them if they are marked autoload.
865 if (length (descriptions) > 0)
866 idx = [];
867 for i = 1:length (descriptions)
868 if (isautoload (descriptions(i)))
869 nm = descriptions{i}.name;
870 for j = 1:length (installed_pkgs_lst)
871 if (strcmp (nm, installed_pkgs_lst{j}.name))
872 idx (end + 1) = j;
873 break;
874 endif
875 endfor
876 endif
877 endfor
878 load_packages_and_dependencies (idx, handle_deps, installed_pkgs_lst,
879 global_install);
880 endif
881 endfunction
882
883 function uninstall (pkgnames, handle_deps, verbose, local_list,
884 global_list, global_install)
885 ## Get the list of installed packages.
886 [local_packages, global_packages] = installed_packages(local_list,
887 global_list);
888 if (global_install)
889 installed_pkgs_lst = {local_packages{:}, global_packages{:}};
890 else
891 installed_pkgs_lst = local_packages;
892 endif
893
894 num_packages = length (installed_pkgs_lst);
895 delete_idx = [];
896 for i = 1:num_packages
897 cur_name = installed_pkgs_lst{i}.name;
898 if (any (strcmp (cur_name, pkgnames)))
899 delete_idx(end+1) = i;
900 endif
901 endfor
902
903 ## Are all the packages that should be uninstalled already installed?
904 if (length (delete_idx) != length (pkgnames))
905 if (global_install)
906 ## Try again for a locally installed package.
907 installed_pkgs_lst = local_packages;
908
909 num_packages = length (installed_pkgs_lst);
910 delete_idx = [];
911 for i = 1:num_packages
912 cur_name = installed_pkgs_lst{i}.name;
913 if (any (strcmp (cur_name, pkgnames)))
914 delete_idx(end+1) = i;
915 endif
916 endfor
917 if (length (delete_idx) != length (pkgnames))
918 ## FIXME: We should have a better error message.
919 warning ("some of the packages you want to uninstall are not installed");
920 endif
921 else
922 ## FIXME: We should have a better error message.
923 warning ("some of the packages you want to uninstall are not installed");
924 endif
925 endif
926
927 ## Compute the packages that will remain installed.
928 idx = complement (delete_idx, 1:num_packages);
929 remaining_packages = {installed_pkgs_lst{idx}};
930
931 ## Check dependencies.
932 if (handle_deps)
933 error_text = "";
934 for i = 1:length (remaining_packages)
935 desc = remaining_packages{i};
936 bad_deps = get_unsatisfied_deps (desc, remaining_packages);
937
938 ## Will the uninstallation break any dependencies?
939 if (! isempty (bad_deps))
940 for i = 1:length (bad_deps)
941 dep = bad_deps{i};
942 error_text = cstrcat (error_text, " ", desc.name, " needs ",
943 dep.package, " ", dep.operator, " ",
944 dep.version, "\n");
945 endfor
946 endif
947 endfor
948
949 if (! isempty (error_text))
950 error ("the following dependencies where unsatisfied:\n %s", error_text);
951 endif
952 endif
953
954 ## Delete the directories containing the packages.
955 for i = delete_idx
956 desc = installed_pkgs_lst{i};
957 ## If an 'on_uninstall.m' exist, call it!
958 if (exist (fullfile (desc.dir, "packinfo", "on_uninstall.m"), "file"))
959 wd = pwd ();
960 cd (fullfile (desc.dir, "packinfo"));
961 on_uninstall (desc);
962 cd (wd);
963 endif
964 ## Do the actual deletion.
965 if (desc.loaded)
966 rmpath (desc.dir);
967 if (exist (getarchdir (desc)))
968 rmpath (getarchdir (desc));
969 endif
970 endif
971 if (exist (desc.dir, "dir"))
972 [status, msg] = rm_rf (desc.dir);
973 if (status != 1)
974 error ("couldn't delete directory %s: %s", desc.dir, msg);
975 endif
976 [status, msg] = rm_rf (getarchdir (desc));
977 if (status != 1)
978 error ("couldn't delete directory %s: %s", getarchdir (desc), msg);
979 endif
980 if (dirempty (desc.archprefix))
981 rm_rf (desc.archprefix);
982 endif
983 else
984 warning ("directory %s previously lost", desc.dir);
985 endif
986 endfor
987
988 ## Write a new ~/.octave_packages.
989 if (global_install)
990 if (length (remaining_packages) == 0)
991 unlink (global_list);
992 else
993 global_packages = save_order (remaining_packages);
994 save (global_list, "global_packages");
995 endif
996 else
997 if (length (remaining_packages) == 0)
998 unlink (local_list);
999 else
1000 local_packages = save_order (remaining_packages);
1001 save (local_list, "local_packages");
1002 endif
1003 endif
1004
1005 endfunction
1006
1007 function [pkg_desc_list, flag] = describe (pkgnames, verbose,
1008 local_list, global_list)
1009
1010 ## Get the list of installed packages.
1011 installed_pkgs_lst = installed_packages(local_list, global_list);
1012 num_packages = length (installed_pkgs_lst);
1013
1014
1015 describe_all = false;
1016 if (any (strcmp ("all", pkgnames)))
1017 describe_all = true;
1018 flag(1:num_packages) = {"Not Loaded"};
1019 num_pkgnames = num_packages;
1020 else
1021 num_pkgnames = length (pkgnames);
1022 flag(1:num_pkgnames) = {"Not installed"};
1023 endif
1024
1025 for i = 1:num_packages
1026 curr_name = installed_pkgs_lst{i}.name;
1027 if (describe_all)
1028 name_pos = i;
1029 else
1030 name_pos = find(strcmp (curr_name, pkgnames));
1031 endif
1032
1033 if (! isempty (name_pos))
1034 if (installed_pkgs_lst{i}.loaded)
1035 flag{name_pos} = "Loaded";
1036 else
1037 flag{name_pos} = "Not loaded";
1038 endif
1039
1040 pkg_desc_list{name_pos}.name = installed_pkgs_lst{i}.name;
1041 pkg_desc_list{name_pos}.version = installed_pkgs_lst{i}.version;
1042 pkg_desc_list{name_pos}.description = installed_pkgs_lst{i}.description;
1043 pkg_desc_list{name_pos}.provides = parse_pkg_idx (installed_pkgs_lst{i}.dir);
1044
1045 endif
1046 endfor
1047
1048 non_inst = find (strcmp (flag, "Not installed"));
1049 if (! isempty (non_inst))
1050 if (nargout < 2)
1051 non_inst_str = sprintf (" %s ", pkgnames{non_inst});
1052 error ("some packages are not installed: %s", non_inst_str);
1053 else
1054 pkg_desc_list{non_inst} = struct ("name", {}, "description",
1055 {}, "provides", {});
1056 endif
1057 endif
1058
1059 if (nargout == 0)
1060 for i = 1:num_pkgnames
1061 print_package_description (pkg_desc_list{i}.name,
1062 pkg_desc_list{i}.version,
1063 pkg_desc_list{i}.provides,
1064 pkg_desc_list{i}.description,
1065 flag{i}, verbose);
1066 endfor
1067 endif
1068
1069 endfunction
1070
1071 ## AUXILIARY FUNCTIONS
1072
1073 ## Read an INDEX file.
1074 function [pkg_idx_struct] = parse_pkg_idx (packdir)
1075
1076 index_file = fullfile (packdir, "packinfo", "INDEX");
1077
1078 if (! exist (index_file, "file"))
1079 error ("could not find any INDEX file in directory %s, try 'pkg rebuild all' to generate missing INDEX files", packdir);
1080 endif
1081
1082
1083 [fid, msg] = fopen (index_file, "r");
1084 if (fid == -1)
1085 error ("the INDEX file %s could not be read: %s",
1086 index_file, msg);
1087 endif
1088
1089 cat_num = 1;
1090 pkg_idx_struct{1}.category = "Uncategorized";
1091 pkg_idx_struct{1}.functions = {};
1092
1093 line = fgetl (fid);
1094 while (isempty (strfind (line, ">>")) && ! feof (fid))
1095 line = fgetl (fid);
1096 endwhile
1097
1098 while (! feof (fid) || line != -1)
1099 if (! any (! isspace (line)) || line(1) == "#" || any (line == "="))
1100 ## Comments, blank lines or comments about unimplemented
1101 ## functions: do nothing
1102 ## FIXME: probably comments and pointers to external functions
1103 ## could be treated better when printing to screen?
1104 elseif (! isempty (strfind (line, ">>")))
1105 ## Skip package name and description as they are in DESCRIPTION
1106 ## already.
1107 elseif (! isspace (line(1)))
1108 ## Category.
1109 if (! isempty (pkg_idx_struct{cat_num}.functions))
1110 pkg_idx_struct{++cat_num}.functions = {};
1111 endif
1112 pkg_idx_struct{cat_num}.category = deblank (line);
1113 else
1114 ## Function names.
1115 while (any (! isspace (line)))
1116 [fun_name, line] = strtok (line);
1117 pkg_idx_struct{cat_num}.functions{end+1} = deblank (fun_name);
1118 endwhile
1119 endif
1120 line = fgetl (fid);
1121 endwhile
1122 fclose (fid);
1123 endfunction
1124
1125 function print_package_description (pkg_name, pkg_ver, pkg_idx_struct,
1126 pkg_desc, status, verbose)
1127
1128 printf ("---\nPackage name:\n\t%s\n", pkg_name);
1129 printf ("Version:\n\t%s\n", pkg_ver);
1130 printf ("Short description:\n\t%s\n", pkg_desc);
1131 printf ("Status:\n\t%s\n", status);
1132 if (verbose)
1133 printf ("---\nProvides:\n");
1134 for i = 1:length(pkg_idx_struct)
1135 if (! isempty (pkg_idx_struct{i}.functions))
1136 printf ("%s\n", pkg_idx_struct{i}.category);
1137 for j = 1:length(pkg_idx_struct{i}.functions)
1138 printf ("\t%s\n", pkg_idx_struct{i}.functions{j});
1139 endfor
1140 endif
1141 endfor
1142 endif
1143
1144 endfunction
1145
1146
1147 function pth = absolute_pathname (pth)
1148 [status, msg, msgid] = fileattrib (pth);
1149 if (status != 1)
1150 error ("could not find the file or path %s", pth);
1151 else
1152 pth = msg.Name;
1153 endif
1154 endfunction
1155
1156 function repackage (builddir, buildlist)
1157 packages = installed_packages (buildlist, buildlist);
1158
1159 wd = pwd();
1160 for i = 1 : length(packages)
1161 pack = packages{i};
1162 unwind_protect
1163 cd (builddir);
1164 mkdir (pack.name);
1165 mkdir (fullfile (pack.name, "inst"));
1166 copyfile (fullfile (pack.dir, "*"), fullfile (pack.name, "inst"));
1167 movefile (fullfile (pack.name, "inst","packinfo", "*"), pack.name);
1168 if (exist (fullfile (pack.name, "inst","packinfo", ".autoload"), "file"))
1169 unlink (fullfile (pack.name, "inst","packinfo", ".autoload"));
1170 endif
1171 rmdir (fullfile (pack.name, "inst", "packinfo"));
1172 if (exist (fullfile (pack.name, "inst", "doc"), "dir"))
1173 movefile (fullfile (pack.name, "inst", "doc"), pack.name);
1174 endif
1175 if (exist (fullfile (pack.name, "inst", "bin"), "dir"))
1176 movefile (fullfile (pack.name, "inst", "bin"), pack.name);
1177 endif
1178 archdir = fullfile (pack.archprefix, cstrcat (pack.name, "-",
1179 pack.version), getarch ());
1180 if (exist (archdir, "dir"))
1181 if (exist (fullfile (pack.name, "inst", "PKG_ADD"), "file"))
1182 unlink (fullfile (pack.name, "inst", "PKG_ADD"));
1183 endif
1184 if (exist (fullfile (pack.name, "inst", "PKG_DEL"), "file"))
1185 unlink (fullfile (pack.name, "inst", "PKG_DEL"));
1186 endif
1187 if (exist (fullfile (archdir, "PKG_ADD"), "file"))
1188 movefile (fullfile (archdir, "PKG_ADD"),
1189 fullfile (pack.name, "PKG_ADD"));
1190 endif
1191 if (exist (fullfile (archdir, "PKG_DEL"), "file"))
1192 movefile (fullfile (archdir, "PKG_DEL"),
1193 fullfile (pack.name, "PKG_DEL"));
1194 endif
1195 else
1196 if (exist (fullfile (pack.name, "inst", "PKG_ADD"), "file"))
1197 movefile (fullfile (pack.name, "inst", "PKG_ADD"),
1198 fullfile (pack.name, "PKG_ADD"));
1199 endif
1200 if (exist (fullfile (pack.name, "inst", "PKG_DEL"), "file"))
1201 movefile (fullfile (pack.name, "inst", "PKG_DEL"),
1202 fullfile (pack.name, "PKG_DEL"));
1203 endif
1204 endif
1205 tfile = cstrcat (pack.name, "-", pack.version, ".tar");
1206 tar (tfile, pack.name);
1207 try
1208 gzip (tfile);
1209 unlink (tfile);
1210 catch
1211 warning ("failed to compress %s", tfile);
1212 end_try_catch
1213 unwind_protect_cleanup
1214 if (exist (pack.name, "dir"))
1215 rm_rf (pack.name);
1216 endif
1217 cd (wd);
1218 end_unwind_protect
1219 endfor
1220 endfunction
1221
1222 function auto = isautoload (desc)
1223 auto = false;
1224 if (isfield (desc{1}, "autoload"))
1225 a = desc{1}.autoload;
1226 if ((isnumeric (a) && a > 0)
1227 || (ischar (a) && (strcmpi (a, "true")
1228 || strcmpi (a, "on")
1229 || strcmpi (a, "yes")
1230 || strcmpi (a, "1"))))
1231 auto = true;
1232 endif
1233 endif
1234 endfunction
1235
1236 function prepare_installation (desc, packdir)
1237 ## Is there a pre_install to call?
1238 if (exist (fullfile (packdir, "pre_install.m"), "file"))
1239 wd = pwd ();
1240 try
1241 cd (packdir);
1242 pre_install (desc);
1243 cd (wd);
1244 catch
1245 cd (wd);
1246 rethrow (lasterror ());
1247 end_try_catch
1248 endif
1249
1250 ## If the directory "inst" doesn't exist, we create it.
1251 inst_dir = fullfile (packdir, "inst");
1252 if (! exist (inst_dir, "dir"))
1253 [status, msg] = mkdir (inst_dir);
1254 if (status != 1)
1255 rm_rf (desc.dir);
1256 error ("the 'inst' directory did not exist and could not be created: %s",
1257 msg);
1258 endif
1259 endif
1260 endfunction
1261
1262 function configure_make (desc, packdir, verbose)
1263 ## Perform ./configure, make, make install in "src".
1264 if (exist (fullfile (packdir, "src"), "dir"))
1265 src = fullfile (packdir, "src");
1266 ## Configure.
1267 if (exist (fullfile (src, "configure"), "file"))
1268 flags = "";
1269 if (isempty (getenv ("CC")))
1270 flags = cstrcat (flags, " CC=\"", octave_config_info ("CC"), "\"");
1271 endif
1272 if (isempty (getenv ("CXX")))
1273 flags = cstrcat (flags, " CXX=\"", octave_config_info ("CXX"), "\"");
1274 endif
1275 if (isempty (getenv ("AR")))
1276 flags = cstrcat (flags, " AR=\"", octave_config_info ("AR"), "\"");
1277 endif
1278 if (isempty (getenv ("RANLIB")))
1279 flags = cstrcat (flags, " RANLIB=\"", octave_config_info ("RANLIB"), "\"");
1280 endif
1281 [status, output] = shell (strcat ("cd '", src, "'; ./configure --prefix=\"",
1282 desc.dir, "\"", flags));
1283 if (status != 0)
1284 rm_rf (desc.dir);
1285 error ("the configure script returned the following error: %s", output);
1286 elseif (verbose)
1287 printf("%s", output);
1288 endif
1289
1290 endif
1291
1292 ## Make.
1293 if (exist (fullfile (src, "Makefile"), "file"))
1294 [status, output] = shell (cstrcat ("export INSTALLDIR=\"", desc.dir,
1295 "\"; make -C '", src, "'"));
1296 if (status != 0)
1297 rm_rf (desc.dir);
1298 error ("'make' returned the following error: %s", output);
1299 elseif (verbose)
1300 printf("%s", output);
1301 endif
1302 endif
1303
1304 ## Copy files to "inst" and "inst/arch" (this is instead of 'make
1305 ## install').
1306 files = fullfile (src, "FILES");
1307 instdir = fullfile (packdir, "inst");
1308 archdir = fullfile (packdir, "inst", getarch ());
1309
1310 ## Get file names.
1311 if (exist (files, "file"))
1312 [fid, msg] = fopen (files, "r");
1313 if (fid < 0)
1314 error ("couldn't open %s: %s", files, msg);
1315 endif
1316 filenames = char (fread (fid))';
1317 fclose (fid);
1318 if (filenames(end) == "\n")
1319 filenames(end) = [];
1320 endif
1321 filenames = split_by (filenames, "\n");
1322 delete_idx = [];
1323 for i = 1:length (filenames)
1324 if (! all (isspace (filenames{i})))
1325 filenames{i} = fullfile (src, filenames{i});
1326 else
1327 delete_idx(end+1) = i;
1328 endif
1329 endfor
1330 filenames(delete_idx) = [];
1331 else
1332 m = dir (fullfile (src, "*.m"));
1333 oct = dir (fullfile (src, "*.oct"));
1334 mex = dir (fullfile (src, "*.mex"));
1335
1336 filenames = cellfun (@(x) fullfile (src, x),
1337 {m.name, oct.name, mex.name},
1338 "UniformOutput", false);
1339 endif
1340
1341 ## Split into architecture dependent and independent files.
1342 if (isempty (filenames))
1343 idx = [];
1344 else
1345 idx = cellfun (@is_architecture_dependent, filenames);
1346 endif
1347 archdependent = filenames (idx);
1348 archindependent = filenames (!idx);
1349
1350 ## Copy the files.
1351 if (! all (isspace ([filenames{:}])))
1352 if (! exist (instdir, "dir")) # fixindent
1353 mkdir (instdir);
1354 endif
1355 if (! all (isspace ([archindependent{:}])))
1356 if (verbose)
1357 printf ("copyfile");
1358 printf (" %s", archindependent{:});
1359 printf ("%s\n", instdir);
1360 endif
1361 [status, output] = copyfile (archindependent, instdir);
1362 if (status != 1)
1363 rm_rf (desc.dir);
1364 error ("Couldn't copy files from 'src' to 'inst': %s", output);
1365 endif
1366 endif
1367 if (! all (isspace ([archdependent{:}])))
1368 if (verbose)
1369 printf ("copyfile");
1370 printf (" %s", archdependent{:});
1371 printf (" %s\n", archdir);
1372 endif
1373 if (! exist (archdir, "dir"))
1374 mkdir (archdir);
1375 endif
1376 [status, output] = copyfile (archdependent, archdir);
1377 if (status != 1)
1378 rm_rf (desc.dir);
1379 error ("Couldn't copy files from 'src' to 'inst': %s", output);
1380 endif
1381 endif
1382 endif
1383 endif
1384 endfunction
1385
1386 function pkg = extract_pkg (nm, pat)
1387 fid = fopen (nm, "rt");
1388 pkg = "";
1389 if (fid >= 0)
1390 while (! feof (fid))
1391 ln = fgetl (fid);
1392 if (ln > 0)
1393 t = regexp (ln, pat, "tokens");
1394 if (! isempty (t))
1395 pkg = cstrcat (pkg, "\n", t{1}{1});
1396 endif
1397 endif
1398 endwhile
1399 if (! isempty (pkg))
1400 pkg = cstrcat (pkg, "\n");
1401 endif
1402 fclose (fid);
1403 endif
1404 endfunction
1405
1406 function create_pkgadddel (desc, packdir, nm, global_install)
1407 instpkg = fullfile (desc.dir, nm);
1408 instfid = fopen (instpkg, "wt");
1409 ## If it is exists, most of the PKG_* file should go into the
1410 ## architecture dependent directory so that the autoload/mfilename
1411 ## commands work as expected. The only part that doesn't is the
1412 ## part in the main directory.
1413 archdir = fullfile (getarchprefix (desc), cstrcat (desc.name, "-",
1414 desc.version), getarch ());
1415 if (exist (getarchdir (desc, global_install), "dir"))
1416 archpkg = fullfile (getarchdir (desc, global_install), nm);
1417 archfid = fopen (archpkg, "at");
1418 else
1419 archpkg = instpkg;
1420 archfid = instfid;
1421 endif
1422
1423 if (archfid >= 0 && instfid >= 0)
1424 ## Search all dot-m files for PKG commands.
1425 lst = dir (fullfile (packdir, "inst", "*.m"));
1426 for i = 1:length (lst)
1427 nam = fullfile (packdir, "inst", lst(i).name);
1428 fwrite (instfid, extract_pkg (nam, ['^[#%][#%]* *' nm ': *(.*)$']));
1429 endfor
1430
1431 ## Search all C++ source files for PKG commands.
1432 lst = dir (fullfile (packdir, "src", "*.cc"));
1433 for i = 1:length (lst)
1434 nam = fullfile (packdir, "src", lst(i).name);
1435 fwrite (archfid, extract_pkg (nam, ['^//* *' nm ': *(.*)$']));
1436 fwrite (archfid, extract_pkg (nam, ['^/\** *' nm ': *(.*) *\*/$']));
1437 endfor
1438
1439 ## Add developer included PKG commands.
1440 packdirnm = fullfile (packdir, nm);
1441 if (exist (packdirnm, "file"))
1442 fid = fopen (packdirnm, "rt");
1443 if (fid >= 0)
1444 while (! feof (fid))
1445 ln = fgets (fid);
1446 if (ln > 0)
1447 fwrite (archfid, ln);
1448 endif
1449 endwhile
1450 fclose (fid);
1451 endif
1452 endif
1453
1454 ## If the files is empty remove it.
1455 fclose (instfid);
1456 t = dir (instpkg);
1457 if (t.bytes <= 0)
1458 unlink (instpkg);
1459 endif
1460
1461 if (instfid != archfid)
1462 fclose (archfid);
1463 t = dir (archpkg);
1464 if (t.bytes <= 0)
1465 unlink (archpkg);
1466 endif
1467 endif
1468 endif
1469 endfunction
1470
1471 function copy_files (desc, packdir, global_install)
1472 ## Create the installation directory.
1473 if (! exist (desc.dir, "dir"))
1474 [status, output] = mkdir (desc.dir);
1475 if (status != 1)
1476 error ("couldn't create installation directory %s : %s",
1477 desc.dir, output);
1478 endif
1479 endif
1480
1481 octfiledir = getarchdir (desc);
1482
1483 ## Copy the files from "inst" to installdir.
1484 instdir = fullfile (packdir, "inst");
1485 if (! dirempty (instdir))
1486 [status, output] = copyfile (fullfile (instdir, "*"), desc.dir);
1487 if (status != 1)
1488 rm_rf (desc.dir);
1489 error ("couldn't copy files to the installation directory");
1490 endif
1491 if (exist (fullfile (desc.dir, getarch ()), "dir") &&
1492 ! strcmp (fullfile (desc.dir, getarch ()), octfiledir))
1493 if (! exist (octfiledir, "dir"))
1494 ## Can be required to create upto three levels of dirs.
1495 octm1 = fileparts (octfiledir);
1496 if (! exist (octm1, "dir"))
1497 octm2 = fileparts (octm1);
1498 if (! exist (octm2, "dir"))
1499 octm3 = fileparts (octm2);
1500 if (! exist (octm3, "dir"))
1501 [status, output] = mkdir (octm3);
1502 if (status != 1)
1503 rm_rf (desc.dir);
1504 error ("couldn't create installation directory %s : %s",
1505 octm3, output);
1506 endif
1507 endif
1508 [status, output] = mkdir (octm2);
1509 if (status != 1)
1510 rm_rf (desc.dir);
1511 error ("couldn't create installation directory %s : %s",
1512 octm2, output);
1513 endif
1514 endif
1515 [status, output] = mkdir (octm1);
1516 if (status != 1)
1517 rm_rf (desc.dir);
1518 error ("couldn't create installation directory %s : %s",
1519 octm1, output);
1520 endif
1521 endif
1522 [status, output] = mkdir (octfiledir);
1523 if (status != 1)
1524 rm_rf (desc.dir);
1525 error ("couldn't create installation directory %s : %s",
1526 octfiledir, output);
1527 endif
1528 endif
1529 [status, output] = movefile (fullfile (desc.dir, getarch (), "*"),
1530 octfiledir);
1531 rm_rf (fullfile (desc.dir, getarch ()));
1532
1533 if (status != 1)
1534 rm_rf (desc.dir);
1535 rm_rf (octfiledir);
1536 error ("couldn't copy files to the installation directory");
1537 endif
1538 endif
1539
1540 endif
1541
1542 ## Create the "packinfo" directory.
1543 packinfo = fullfile (desc.dir, "packinfo");
1544 [status, msg] = mkdir (packinfo);
1545 if (status != 1)
1546 rm_rf (desc.dir);
1547 rm_rf (octfiledir);
1548 error ("couldn't create packinfo directory: %s", msg);
1549 endif
1550
1551 ## Copy DESCRIPTION.
1552 [status, output] = copyfile (fullfile (packdir, "DESCRIPTION"), packinfo);
1553 if (status != 1)
1554 rm_rf (desc.dir);
1555 rm_rf (octfiledir);
1556 error ("couldn't copy DESCRIPTION: %s", output);
1557 endif
1558
1559 ## Copy COPYING.
1560 [status, output] = copyfile (fullfile (packdir, "COPYING"), packinfo);
1561 if (status != 1)
1562 rm_rf (desc.dir);
1563 rm_rf (octfiledir);
1564 error ("couldn't copy COPYING: %s", output);
1565 endif
1566
1567 ## If the file ChangeLog exists, copy it.
1568 changelog_file = fullfile (packdir, "ChangeLog");
1569 if (exist (changelog_file, "file"))
1570 [status, output] = copyfile (changelog_file, packinfo);
1571 if (status != 1)
1572 rm_rf (desc.dir);
1573 rm_rf (octfiledir);
1574 error ("couldn't copy ChangeLog file: %s", output);
1575 endif
1576 endif
1577
1578 ## Is there an INDEX file to copy or should we generate one?
1579 index_file = fullfile (packdir, "INDEX");
1580 if (exist(index_file, "file"))
1581 [status, output] = copyfile (index_file, packinfo);
1582 if (status != 1)
1583 rm_rf (desc.dir);
1584 rm_rf (octfiledir);
1585 error ("couldn't copy INDEX file: %s", output);
1586 endif
1587 else
1588 try
1589 write_index (desc, fullfile (packdir, "inst"),
1590 fullfile (packinfo, "INDEX"), global_install);
1591 catch
1592 rm_rf (desc.dir);
1593 rm_rf (octfiledir);
1594 rethrow (lasterror ());
1595 end_try_catch
1596 endif
1597
1598 ## Is there an 'on_uninstall.m' to install?
1599 fon_uninstall = fullfile (packdir, "on_uninstall.m");
1600 if (exist (fon_uninstall, "file"))
1601 [status, output] = copyfile (fon_uninstall, packinfo);
1602 if (status != 1)
1603 rm_rf (desc.dir);
1604 rm_rf (octfiledir);
1605 error ("couldn't copy on_uninstall.m: %s", output);
1606 endif
1607 endif
1608
1609 ## Is there a doc/ directory that needs to be installed?
1610 docdir = fullfile (packdir, "doc");
1611 if (exist (docdir, "dir") && ! dirempty (docdir))
1612 [status, output] = copyfile (docdir, desc.dir);
1613 endif
1614
1615 ## Is there a bin/ directory that needs to be installed?
1616 ## FIXME: Need to treat architecture dependent files in bin/
1617 bindir = fullfile (packdir, "bin");
1618 if (exist (bindir, "dir") && ! dirempty (bindir))
1619 [status, output] = copyfile (bindir, desc.dir);
1620 endif
1621 endfunction
1622
1623 function finish_installation (desc, packdir, global_install)
1624 ## Is there a post-install to call?
1625 if (exist (fullfile (packdir, "post_install.m"), "file"))
1626 wd = pwd ();
1627 try
1628 cd (packdir);
1629 post_install (desc);
1630 cd (wd);
1631 catch
1632 cd (wd);
1633 rm_rf (desc.dir);
1634 rm_rf (getarchdir (desc), global_install);
1635 rethrow (lasterror ());
1636 end_try_catch
1637 endif
1638 endfunction
1639
1640 function generate_lookfor_cache (desc)
1641 dirs = split_by (genpath (desc.dir), pathsep ());
1642 for i = 1 : length (dirs)
1643 gen_doc_cache (fullfile (dirs{i}, "doc-cache"), dirs{i});
1644 endfor
1645 endfunction
1646
1647 ## Make sure the package contains the essential files.
1648 function verify_directory (dir)
1649 needed_files = {"COPYING", "DESCRIPTION"};
1650 for f = needed_files
1651 if (! exist (fullfile (dir, f{1}), "file"))
1652 error ("package is missing file: %s", f{1});
1653 endif
1654 endfor
1655 endfunction
1656
1657 ## Parse the DESCRIPTION file.
1658 function desc = get_description (filename)
1659 [fid, msg] = fopen (filename, "r");
1660 if (fid == -1)
1661 error ("the DESCRIPTION file %s could not be read: %s", filename, msg);
1662 endif
1663
1664 desc = struct ();
1665
1666 line = fgetl (fid);
1667 while (line != -1)
1668 if (line(1) == "#")
1669 ## Comments, do nothing.
1670 elseif (isspace(line(1)))
1671 ## Continuation lines
1672 if (exist ("keyword", "var") && isfield (desc, keyword))
1673 desc.(keyword) = cstrcat (desc.(keyword), " ", rstrip(line));
1674 endif
1675 else
1676 ## Keyword/value pair
1677 colon = find (line == ":");
1678 if (length (colon) == 0)
1679 disp ("skipping line");
1680 else
1681 colon = colon(1);
1682 keyword = tolower (strip (line(1:colon-1)));
1683 value = strip (line (colon+1:end));
1684 if (length (value) == 0)
1685 fclose (fid);
1686 error ("the keyword %s has an empty value", desc.keywords{end});
1687 endif
1688 desc.(keyword) = value;
1689 endif
1690 endif
1691 line = fgetl (fid);
1692 endwhile
1693 fclose (fid);
1694
1695 ## Make sure all is okay.
1696 needed_fields = {"name", "version", "date", "title", ...
1697 "author", "maintainer", "description"};
1698 for f = needed_fields
1699 if (! isfield (desc, f{1}))
1700 error ("description is missing needed field %s", f{1});
1701 endif
1702 endfor
1703 desc.version = fix_version (desc.version);
1704 if (isfield (desc, "depends"))
1705 desc.depends = fix_depends (desc.depends);
1706 else
1707 desc.depends = "";
1708 endif
1709 desc.name = tolower (desc.name);
1710 endfunction
1711
1712 ## Make sure the version string v is a valid x.y.z version string
1713 ## Examples: "0.1" => "0.1.0", "monkey" => error(...).
1714 function out = fix_version (v)
1715 dots = find (v == ".");
1716 if (length (dots) == 1)
1717 major = str2num (v(1:dots-1));
1718 minor = str2num (v(dots+1:end));
1719 if (length (major) != 0 && length (minor) != 0)
1720 out = sprintf ("%d.%d.0", major, minor);
1721 return;
1722 endif
1723 elseif (length (dots) == 2)
1724 major = str2num (v(1:dots(1)-1));
1725 minor = str2num (v(dots(1)+1:dots(2)-1));
1726 rev = str2num (v(dots(2)+1:end));
1727 if (length (major) != 0 && length (minor) != 0 && length (rev) != 0)
1728 out = sprintf ("%d.%d.%d", major, minor, rev);
1729 return;
1730 endif
1731 endif
1732 error ("bad version string: %s", v);
1733 endfunction
1734
1735 ## Make sure the depends field is of the right format.
1736 ## This function returns a cell of structures with the following fields:
1737 ## package, version, operator
1738 function deps_cell = fix_depends (depends)
1739 deps = split_by (tolower (depends), ",");
1740 deps_cell = cell (1, length (deps));
1741
1742 ## For each dependency.
1743 for i = 1:length (deps)
1744 dep = deps{i};
1745 lpar = find (dep == "(");
1746 rpar = find (dep == ")");
1747 ## Does the dependency specify a version
1748 ## Example: package(>= version).
1749 if (length (lpar) == 1 && length (rpar) == 1)
1750 package = tolower (strip (dep(1:lpar-1)));
1751 sub = dep(lpar(1)+1:rpar(1)-1);
1752 parts = strsplit (sub, " ", true);
1753 if (length (parts) != 2)
1754 error ("incorrect syntax for dependency `%s' in the DESCRIPTION file\n",
1755 dep);
1756 endif
1757 operator = parts{1};
1758 if (! any (strcmp (operator, {">", ">=", "<=", "<", "=="})))
1759 error ("unsupported operator: %s", operator);
1760 endif
1761 version = fix_version (parts{2});
1762
1763 ## If no version is specified for the dependency
1764 ## we say that the version should be greater than
1765 ## or equal to "0.0.0".
1766 else
1767 package = tolower (strip (dep));
1768 operator = ">=";
1769 version = "0.0.0";
1770 endif
1771 deps_cell{i} = struct ("package", package, "operator", operator,
1772 "version", version);
1773 endfor
1774 endfunction
1775
1776 ## Strip the text of spaces from the right
1777 ## Example: " hello world " => " hello world"
1778 ## FIXME -- is this the same as deblank?
1779 function text = rstrip (text)
1780 chars = find (! isspace (text));
1781 if (length (chars) > 0)
1782 ## FIXME: shouldn't it be text = text(1:chars(end));
1783 text = text (chars(1):end);
1784 else
1785 text = "";
1786 endif
1787 endfunction
1788
1789 ## Strip the text of spaces from the left and the right.
1790 ## Example: " hello world " => "hello world"
1791 function text = strip (text)
1792 chars = find (! isspace (text));
1793 if (length (chars) > 0)
1794 text = text(chars(1):chars(end));
1795 else
1796 text = "";
1797 endif
1798 endfunction
1799
1800 ## Split the text into a cell array of strings by sep.
1801 ## Example: "A, B" => {"A", "B"} (with sep = ",")
1802 function out = split_by (text, sep)
1803 out = strtrim (strsplit (text, sep));
1804 endfunction
1805
1806 ## Create an INDEX file for a package that doesn't provide one.
1807 ## 'desc' describes the package.
1808 ## 'dir' is the 'inst' directory in temporary directory.
1809 ## 'index_file' is the name (including path) of resulting INDEX file.
1810 function write_index (desc, dir, index_file, global_install)
1811 ## Get names of functions in dir
1812 [files, err, msg] = readdir (dir);
1813 if (err)
1814 error ("couldn't read directory %s: %s", dir, msg);
1815 endif
1816
1817 ## Check for architecture dependent files.
1818 tmpdir = getarchdir (desc);
1819 if (exist (tmpdir, "dir"))
1820 [files2, err, msg] = readdir (tmpdir);
1821 if (err)
1822 error ("couldn't read directory %s: %s", tmpdir, msg);
1823 endif
1824 files = [files; files2];
1825 endif
1826
1827 functions = {};
1828 for i = 1:length (files)
1829 file = files{i};
1830 lf = length (file);
1831 if (lf > 2 && strcmp (file(end-1:end), ".m"))
1832 functions{end+1} = file(1:end-2);
1833 elseif (lf > 4 && strcmp (file(end-3:end), ".oct"))
1834 functions{end+1} = file(1:end-4);
1835 endif
1836 endfor
1837
1838 ## Does desc have a categories field?
1839 if (! isfield (desc, "categories"))
1840 error ("the DESCRIPTION file must have a Categories field, when no INDEX file is given");
1841 endif
1842 categories = split_by (desc.categories, ",");
1843 if (length (categories) < 1)
1844 error ("the Category field is empty");
1845 endif
1846
1847 ## Write INDEX.
1848 fid = fopen (index_file, "w");
1849 if (fid == -1)
1850 error ("couldn't open %s for writing.", index_file);
1851 endif
1852 fprintf (fid, "%s >> %s\n", desc.name, desc.title);
1853 fprintf (fid, "%s\n", categories{1});
1854 fprintf (fid, " %s\n", functions{:});
1855 fclose (fid);
1856 endfunction
1857
1858 function bad_deps = get_unsatisfied_deps (desc, installed_pkgs_lst)
1859 bad_deps = {};
1860
1861 ## For each dependency.
1862 for i = 1:length (desc.depends)
1863 dep = desc.depends{i};
1864
1865 ## Is the current dependency Octave?
1866 if (strcmp (dep.package, "octave"))
1867 if (! compare_versions (OCTAVE_VERSION, dep.version, dep.operator))
1868 bad_deps{end+1} = dep;
1869 endif
1870 ## Is the current dependency not Octave?
1871 else
1872 ok = false;
1873 for i = 1:length (installed_pkgs_lst)
1874 cur_name = installed_pkgs_lst{i}.name;
1875 cur_version = installed_pkgs_lst{i}.version;
1876 if (strcmp (dep.package, cur_name)
1877 && compare_versions (cur_version, dep.version, dep.operator))
1878 ok = true;
1879 break;
1880 endif
1881 endfor
1882 if (! ok)
1883 bad_deps{end+1} = dep;
1884 endif
1885 endif
1886 endfor
1887 endfunction
1888
1889 function [out1, out2] = installed_packages (local_list, global_list)
1890 ## Get the list of installed packages.
1891 try
1892 local_packages = load (local_list).local_packages;
1893 catch
1894 local_packages = {};
1895 end_try_catch
1896 try
1897 global_packages = load (global_list).global_packages;
1898 catch
1899 global_packages = {};
1900 end_try_catch
1901 installed_pkgs_lst = {local_packages{:}, global_packages{:}};
1902
1903 ## Eliminate duplicates in the installed package list.
1904 ## Locally installed packages take precedence.
1905 dup = [];
1906 for i = 1:length (installed_pkgs_lst)
1907 if (find (dup, i))
1908 continue;
1909 endif
1910 for j = (i+1):length (installed_pkgs_lst)
1911 if (find (dup, j))
1912 continue;
1913 endif
1914 if (strcmp (installed_pkgs_lst{i}.name, installed_pkgs_lst{j}.name))
1915 dup = [dup, j];
1916 endif
1917 endfor
1918 endfor
1919 if (! isempty(dup))
1920 installed_pkgs_lst(dup) = [];
1921 endif
1922
1923 ## Now check if the package is loaded.
1924 tmppath = strrep (path(), "\\", "/");
1925 for i = 1:length (installed_pkgs_lst)
1926 if (findstr (tmppath, strrep (installed_pkgs_lst{i}.dir, "\\", "/")))
1927 installed_pkgs_lst{i}.loaded = true;
1928 else
1929 installed_pkgs_lst{i}.loaded = false;
1930 endif
1931 endfor
1932 for i = 1:length (local_packages)
1933 if (findstr (tmppath, strrep (local_packages{i}.dir, "\\", "/")))
1934 local_packages{i}.loaded = true;
1935 else
1936 local_packages{i}.loaded = false;
1937 endif
1938 endfor
1939 for i = 1:length (global_packages)
1940 if (findstr (tmppath, strrep (global_packages{i}.dir, "\\", "/")))
1941 global_packages{i}.loaded = true;
1942 else
1943 global_packages{i}.loaded = false;
1944 endif
1945 endfor
1946
1947 ## Should we return something?
1948 if (nargout == 2)
1949 out1 = local_packages;
1950 out2 = global_packages;
1951 return;
1952 elseif (nargout == 1)
1953 out1 = installed_pkgs_lst;
1954 return;
1955 endif
1956
1957 ## We shouldn't return something, so we'll print something.
1958 num_packages = length (installed_pkgs_lst);
1959 if (num_packages == 0)
1960 printf ("no packages installed.\n");
1961 return;
1962 endif
1963
1964 ## Compute the maximal lengths of name, version, and dir.
1965 h1 = "Package Name";
1966 h2 = "Version";
1967 h3 = "Installation directory";
1968 max_name_length = length (h1);
1969 max_version_length = length (h2);
1970 names = cell (num_packages, 1);
1971 for i = 1:num_packages
1972 max_name_length = max (max_name_length,
1973 length (installed_pkgs_lst{i}.name));
1974 max_version_length = max (max_version_length,
1975 length (installed_pkgs_lst{i}.version));
1976 names{i} = installed_pkgs_lst{i}.name;
1977 endfor
1978 max_dir_length = terminal_size()(2) - max_name_length - ...
1979 max_version_length - 7;
1980 if (max_dir_length < 20)
1981 max_dir_length = Inf;
1982 endif
1983
1984 h1 = postpad (h1, max_name_length + 1, " ");
1985 h2 = postpad (h2, max_version_length, " ");
1986
1987 ## Print a header.
1988 header = sprintf("%s | %s | %s\n", h1, h2, h3);
1989 printf (header);
1990 tmp = sprintf (repmat ("-", 1, length(header)-1));
1991 tmp(length(h1)+2) = "+";
1992 tmp(length(h1)+length(h2)+5) = "+";
1993 printf ("%s\n", tmp);
1994
1995 ## Print the packages.
1996 format = sprintf ("%%%ds %%1s| %%%ds | %%s\n", max_name_length,
1997 max_version_length);
1998 [dummy, idx] = sort (names);
1999 for i = 1:num_packages
2000 cur_name = installed_pkgs_lst{idx(i)}.name;
2001 cur_version = installed_pkgs_lst{idx(i)}.version;
2002 cur_dir = installed_pkgs_lst{idx(i)}.dir;
2003 if (length (cur_dir) > max_dir_length)
2004 first_char = length (cur_dir) - max_dir_length + 4;
2005 first_filesep = strfind (cur_dir(first_char:end), filesep());
2006 if (! isempty (first_filesep))
2007 cur_dir = cstrcat ("...",
2008 cur_dir((first_char + first_filesep(1) - 1):end));
2009 else
2010 cur_dir = cstrcat ("...", cur_dir(first_char:end));
2011 endif
2012 endif
2013 if (installed_pkgs_lst{idx(i)}.loaded)
2014 cur_loaded = "*";
2015 else
2016 cur_loaded = " ";
2017 endif
2018 printf (format, cur_name, cur_loaded, cur_version, cur_dir);
2019 endfor
2020 endfunction
2021
2022 function load_packages (files, handle_deps, local_list, global_list)
2023 installed_pkgs_lst = installed_packages (local_list, global_list);
2024 num_packages = length (installed_pkgs_lst);
2025
2026 ## Read package names and installdirs into a more convenient format.
2027 pnames = pdirs = cell (1, num_packages);
2028 for i = 1:num_packages
2029 pnames{i} = installed_pkgs_lst{i}.name;
2030 pdirs{i} = installed_pkgs_lst{i}.dir;
2031 endfor
2032
2033 ## Load all.
2034 if (length (files) == 1 && strcmp (files{1}, "all"))
2035 idx = [1:length(installed_pkgs_lst)];
2036 ## Load auto.
2037 elseif (length (files) == 1 && strcmp (files{1}, "auto"))
2038 idx = [];
2039 for i = 1:length (installed_pkgs_lst)
2040 if (exist (fullfile (pdirs{i}, "packinfo", ".autoload"), "file"))
2041 idx (end + 1) = i;
2042 endif
2043 endfor
2044 ## Load package_name1 ...
2045 else
2046 idx = [];
2047 for i = 1:length (files)
2048 idx2 = find (strcmp (pnames, files{i}));
2049 if (! any (idx2))
2050 error ("package %s is not installed", files{i});
2051 endif
2052 idx (end + 1) = idx2;
2053 endfor
2054 endif
2055
2056 ## Load the packages, but take care of the ordering of dependencies.
2057 load_packages_and_dependencies (idx, handle_deps, installed_pkgs_lst, true);
2058 endfunction
2059
2060 function unload_packages (files, handle_deps, local_list, global_list)
2061 installed_pkgs_lst = installed_packages (local_list, global_list);
2062 num_packages = length (installed_pkgs_lst);
2063
2064 ## Read package names and installdirs into a more convenient format.
2065 pnames = pdirs = cell (1, num_packages);
2066 for i = 1:num_packages
2067 pnames{i} = installed_pkgs_lst{i}.name;
2068 pdirs{i} = installed_pkgs_lst{i}.dir;
2069 pdeps{i} = installed_pkgs_lst{i}.depends;
2070 endfor
2071
2072 ## Get the current octave path.
2073 p = split_by (path(), pathsep ());
2074
2075 if (length (files) == 1 && strcmp (files{1}, "all"))
2076 ## Unload all.
2077 dirs = pdirs;
2078 desc = installed_pkgs_lst;
2079 else
2080 ## Unload package_name1 ...
2081 dirs = {};
2082 desc = {};
2083 for i = 1:length (files)
2084 idx = strcmp (pnames, files{i});
2085 if (! any (idx))
2086 error ("package %s is not installed", files{i});
2087 endif
2088 dirs{end+1} = pdirs{idx};
2089 desc{end+1} = installed_pkgs_lst{idx};
2090 endfor
2091 endif
2092
2093 ## Check for architecture dependent directories.
2094 archdirs = {};
2095 for i = 1:length (dirs)
2096 tmpdir = getarchdir (desc{i});
2097 if (exist (tmpdir, "dir"))
2098 archdirs{end+1} = dirs{i};
2099 archdirs{end+1} = tmpdir;
2100 else
2101 archdirs{end+1} = dirs{i};
2102 endif
2103 endfor
2104
2105 ## Unload the packages.
2106 for i = 1:length (archdirs)
2107 d = archdirs{i};
2108 idx = strcmp (p, d);
2109 if (any (idx))
2110 rmpath (d);
2111 ## FIXME: We should also check if we need to remove items from
2112 ## EXEC_PATH.
2113 endif
2114 endfor
2115 endfunction
2116
2117 function [status_out, msg_out] = rm_rf (dir)
2118 if (exist (dir))
2119 crr = confirm_recursive_rmdir ();
2120 unwind_protect
2121 confirm_recursive_rmdir (false);
2122 [status, msg] = rmdir (dir, "s");
2123 unwind_protect_cleanup
2124 confirm_recursive_rmdir (crr);
2125 end_unwind_protect
2126 else
2127 status = 1;
2128 msg = "";
2129 endif
2130 if (nargout > 0)
2131 status_out = status;
2132 endif
2133 if (nargout > 1)
2134 msg_out = msg;
2135 endif
2136 endfunction
2137
2138 function emp = dirempty (nm, ign)
2139 if (exist (nm, "dir"))
2140 if (nargin < 2)
2141 ign = {".", ".."};
2142 else
2143 ign = [{".", ".."}, ign];
2144 endif
2145 l = dir (nm);
2146 for i = 1:length (l)
2147 found = false;
2148 for j = 1:length (ign)
2149 if (strcmp (l(i).name, ign{j}))
2150 found = true;
2151 break;
2152 endif
2153 endfor
2154 if (! found)
2155 emp = false;
2156 return
2157 endif
2158 endfor
2159 emp = true;
2160 else
2161 emp = true;
2162 endif
2163 endfunction
2164
2165 function arch = getarch ()
2166 persistent _arch = cstrcat (octave_config_info("canonical_host_type"), ...
2167 "-", octave_config_info("api_version"));
2168 arch = _arch;
2169 endfunction
2170
2171 function archprefix = getarchprefix (desc, global_install)
2172 if ((nargin == 2 && global_install) || (nargin < 2 && issuperuser ()))
2173 archprefix = fullfile (octave_config_info ("libexecdir"), "octave",
2174 "packages", cstrcat(desc.name, "-", desc.version));
2175 else
2176 archprefix = desc.dir;
2177 endif
2178 endfunction
2179
2180 function archdir = getarchdir (desc)
2181 archdir = fullfile (desc.archprefix, getarch());
2182 endfunction
2183
2184 function s = issuperuser ()
2185 if ((ispc () && ! isunix ()) || (geteuid() == 0))
2186 s = true;
2187 else
2188 s = false;
2189 endif
2190 endfunction
2191
2192 function [status, output] = shell (cmd)
2193 persistent have_sh;
2194
2195 cmd = strrep (cmd, "\\", "/");
2196 if (ispc () && ! isunix ())
2197 if (isempty(have_sh))
2198 if (system("sh.exe -c \"exit\""))
2199 have_sh = false;
2200 else
2201 have_sh = true;
2202 endif
2203 endif
2204 if (have_sh)
2205 [status, output] = system (cstrcat ("sh.exe -c \"", cmd, "\""));
2206 else
2207 error ("Can not find the command shell")
2208 endif
2209 else
2210 [status, output] = system (cmd);
2211 endif
2212 endfunction
2213
2214 function newdesc = save_order (desc)
2215 newdesc = {};
2216 for i = 1 : length(desc)
2217 deps = desc{i}.depends;
2218 if (isempty (deps) || (length (deps) == 1 &&
2219 strcmp(deps{1}.package, "octave")))
2220 newdesc {end + 1} = desc{i};
2221 else
2222 tmpdesc = {};
2223 for k = 1 : length (deps)
2224 for j = 1 : length (desc)
2225 if (strcmp (desc{j}.name, deps{k}.package))
2226 tmpdesc{end+1} = desc{j};
2227 break;
2228 endif
2229 endfor
2230 endfor
2231 if (! isempty (tmpdesc))
2232 newdesc = {newdesc{:}, save_order(tmpdesc){:}, desc{i}};
2233 else
2234 newdesc{end+1} = desc{i};
2235 endif
2236 endif
2237 endfor
2238 ## Eliminate the duplicates.
2239 idx = [];
2240 for i = 1 : length (newdesc)
2241 for j = (i + 1) : length (newdesc)
2242 if (strcmp (newdesc{i}.name, newdesc{j}.name))
2243 idx (end + 1) = j;
2244 endif
2245 endfor
2246 endfor
2247 newdesc(idx) = [];
2248 endfunction
2249
2250 function load_packages_and_dependencies (idx, handle_deps, installed_pkgs_lst,
2251 global_install)
2252 idx = load_package_dirs (idx, [], handle_deps, installed_pkgs_lst);
2253 dirs = {};
2254 execpath = EXEC_PATH ();
2255 for i = idx;
2256 ndir = installed_pkgs_lst{i}.dir;
2257 dirs{end+1} = ndir;
2258 if (exist (fullfile (dirs{end}, "bin"), "dir"))
2259 execpath = cstrcat (fullfile (dirs{end}, "bin"), ":", execpath);
2260 endif
2261 tmpdir = getarchdir (installed_pkgs_lst{i});
2262 if (exist (tmpdir, "dir"))
2263 dirs{end + 1} = tmpdir;
2264 if (exist (fullfile (dirs{end}, "bin"), "dir"))
2265 execpath = cstrcat (fullfile (dirs{end}, "bin"), ":", execpath);
2266 endif
2267 endif
2268 endfor
2269
2270 ## Load the packages.
2271 if (length (dirs) > 0)
2272 addpath (dirs{:});
2273 endif
2274
2275 ## Add the binaries to exec_path.
2276 if (! strcmp (EXEC_PATH, execpath))
2277 EXEC_PATH (execpath);
2278 endif
2279 endfunction
2280
2281 function idx = load_package_dirs (lidx, idx, handle_deps, installed_pkgs_lst)
2282 for i = lidx
2283 if (isfield (installed_pkgs_lst{i}, "loaded") &&
2284 installed_pkgs_lst{i}.loaded)
2285 continue;
2286 else
2287 if (handle_deps)
2288 deps = installed_pkgs_lst{i}.depends;
2289 if ((length (deps) > 1) || (length (deps) == 1 &&
2290 ! strcmp(deps{1}.package, "octave")))
2291 tmplidx = [];
2292 for k = 1 : length (deps)
2293 for j = 1 : length (installed_pkgs_lst)
2294 if (strcmp (installed_pkgs_lst{j}.name, deps{k}.package))
2295 tmplidx (end + 1) = j;
2296 break;
2297 endif
2298 endfor
2299 endfor
2300 idx = load_package_dirs (tmplidx, idx, handle_deps,
2301 installed_pkgs_lst);
2302 endif
2303 endif
2304 if (isempty (find(idx == i)))
2305 idx (end + 1) = i;
2306 endif
2307 endif
2308 endfor
2309 endfunction
2310
2311 function dep = is_architecture_dependent (nm)
2312 persistent archdepsuffix = {".oct",".mex",".a",".lib",".so",".so.*",".dll","dylib"};
2313
2314 dep = false;
2315 for i = 1 : length (archdepsuffix)
2316 ext = archdepsuffix{i};
2317 if (ext(end) == "*")
2318 isglob = true;
2319 ext(end) = [];
2320 else
2321 isglob = false; # I am a test
2322 #%% me too
2323 ### I shall align to column 0
2324 endif
2325 pos = findstr (nm, ext);
2326 if (pos)
2327 if (! isglob && (length(nm) - pos(end) != length(ext) - 1))
2328 continue;
2329 endif
2330 dep = true;
2331 break;
2332 endif
2333 endfor
2334 endfunction
2335
2336 %!assert(norm(logm([1 -1;0 1]) - [0 -1; 0 0]) < 1e-5);
2337 %!assert(norm(expm(logm([-1 2 ; 4 -1])) - [-1 2 ; 4 -1]) < 1e-5);
2338 %!assert(logm([1 -1 -1;0 1 -1; 0 0 1]), [0 -1 -1.5; 0 0 -1; 0 0 0], 1e-5);
2339 %!assert (logm (expm ([0 1i; -1i 0])), [0 1i; -1i 0], 10 * eps)
2340
2341 %% Test input validation
2342 %!error logm ();
2343 %!error logm (1, 2, 3);
2344 %!error <logm: A must be a square matrix> logm([1 0;0 1; 2 2]);
2345
2346 %!assert (logm (10), log (10))
2347 %!assert (full (logm (eye (3))), logm (full (eye (3))))
2348 %!assert (full (logm (10*eye (3))), logm (full (10*eye (3))), 8*eps)