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