1######################################################################## 2## 3## Copyright (C) 2005-2021 The Octave Project Developers 4## 5## See the file COPYRIGHT.md in the top-level directory of this 6## distribution or <https://octave.org/copyright/>. 7## 8## This file is part of Octave. 9## 10## Octave is free software: you can redistribute it and/or modify it 11## under the terms of the GNU General Public License as published by 12## the Free Software Foundation, either version 3 of the License, or 13## (at your option) any later version. 14## 15## Octave is distributed in the hope that it will be useful, but 16## WITHOUT ANY WARRANTY; without even the implied warranty of 17## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18## GNU General Public License for more details. 19## 20## You should have received a copy of the GNU General Public License 21## along with Octave; see the file COPYING. If not, see 22## <https://www.gnu.org/licenses/>. 23## 24######################################################################## 25 26## -*- texinfo -*- 27## @deftypefn {} {} install (@var{files}, @var{handle_deps}, @var{prefix}, @var{archprefix}, @var{verbose}, @var{local_list}, @var{global_list}, @var{global_install}) 28## Undocumented internal function. 29## @end deftypefn 30 31function install (files, handle_deps, prefix, archprefix, verbose, 32 local_list, global_list, global_install) 33 34 ## Check that the directory in prefix exist. If it doesn't: create it! 35 if (! isfolder (prefix)) 36 warning ("creating installation directory %s", prefix); 37 [status, msg] = mkdir (prefix); 38 if (status != 1) 39 error ("could not create installation directory: %s", msg); 40 endif 41 endif 42 43 ## Get the list of installed packages. 44 [local_packages, global_packages] = installed_packages (local_list, 45 global_list); 46 47 installed_pkgs_lst = {local_packages{:}, global_packages{:}}; 48 49 if (global_install) 50 packages = global_packages; 51 else 52 packages = local_packages; 53 endif 54 55 ## Uncompress the packages and read the DESCRIPTION files. 56 tmpdirs = packdirs = descriptions = {}; 57 try 58 ## Warn about non existent files. 59 for i = 1:length (files) 60 if (isempty (glob (files{i}))) 61 warning ("file %s does not exist", files{i}); 62 endif 63 endfor 64 65 ## Unpack the package files and read the DESCRIPTION files. 66 files = glob (files); 67 packages_to_uninstall = []; 68 for i = 1:length (files) 69 tgz = files{i}; 70 71 if (exist (tgz, "file")) 72 ## Create a temporary directory. 73 tmpdir = tempname (); 74 tmpdirs{end+1} = tmpdir; 75 if (verbose) 76 printf ("mkdir (%s)\n", tmpdir); 77 endif 78 [status, msg] = mkdir (tmpdir); 79 if (status != 1) 80 error ("couldn't create temporary directory: %s", msg); 81 endif 82 83 ## Uncompress the package. 84 [~, ~, ext] = fileparts (tgz); 85 if (strcmpi (ext, ".zip")) 86 func_uncompress = @unzip; 87 else 88 func_uncompress = @untar; 89 endif 90 if (verbose) 91 printf ("%s (%s, %s)\n", func2str (func_uncompress), tgz, tmpdir); 92 endif 93 func_uncompress (tgz, tmpdir); 94 95 ## Get the name of the directories produced by tar. 96 [dirlist, err, msg] = readdir (tmpdir); 97 if (err) 98 error ("couldn't read directory produced by tar: %s", msg); 99 endif 100 101 if (length (dirlist) > 3) 102 error ("bundles of packages are not allowed"); 103 endif 104 endif 105 106 ## The filename pointed to an uncompressed package to begin with. 107 if (isfolder (tgz)) 108 dirlist = {".", "..", tgz}; 109 endif 110 111 if (exist (tgz, "file") || isfolder (tgz)) 112 ## The two first entries of dirlist are "." and "..". 113 if (exist (tgz, "file")) 114 packdir = fullfile (tmpdir, dirlist{3}); 115 else 116 packdir = fullfile (pwd (), dirlist{3}); 117 endif 118 packdirs{end+1} = packdir; 119 120 ## Make sure the package contains necessary files. 121 verify_directory (packdir); 122 123 ## Read the DESCRIPTION file. 124 filename = fullfile (packdir, "DESCRIPTION"); 125 desc = get_description (filename); 126 127 ## Set default installation directory. 128 desc.dir = fullfile (prefix, [desc.name "-" desc.version]); 129 130 ## Set default architectire dependent installation directory. 131 desc.archprefix = fullfile (archprefix, [desc.name "-" desc.version]); 132 133 ## Save desc. 134 descriptions{end+1} = desc; 135 136 ## Are any of the new packages already installed? 137 ## If so we'll remove the old version. 138 for j = 1:length (packages) 139 if (strcmp (packages{j}.name, desc.name)) 140 packages_to_uninstall(end+1) = j; 141 endif 142 endfor 143 endif 144 endfor 145 catch 146 ## Something went wrong, delete tmpdirs. 147 for i = 1:length (tmpdirs) 148 rmdir (tmpdirs{i}, "s"); 149 endfor 150 rethrow (lasterror ()); 151 end_try_catch 152 153 ## Check dependencies. 154 if (handle_deps) 155 ok = true; 156 error_text = ""; 157 for i = 1:length (descriptions) 158 desc = descriptions{i}; 159 idx2 = setdiff (1:length (descriptions), i); 160 if (global_install) 161 ## Global installation is not allowed to have dependencies on locally 162 ## installed packages. 163 idx1 = setdiff (1:length (global_packages), packages_to_uninstall); 164 pseudo_installed_packages = {global_packages{idx1}, ... 165 descriptions{idx2}}; 166 else 167 idx1 = setdiff (1:length (local_packages), packages_to_uninstall); 168 pseudo_installed_packages = {local_packages{idx1}, ... 169 global_packages{:}, ... 170 descriptions{idx2}}; 171 endif 172 bad_deps = get_unsatisfied_deps (desc, pseudo_installed_packages); 173 ## Are there any unsatisfied dependencies? 174 if (! isempty (bad_deps)) 175 ok = false; 176 for i = 1:length (bad_deps) 177 dep = bad_deps{i}; 178 error_text = [error_text " " desc.name " needs " ... 179 dep.package " " dep.operator " " dep.version "\n"]; 180 endfor 181 endif 182 endfor 183 184 ## Did we find any unsatisfied dependencies? 185 if (! ok) 186 error ("the following dependencies were unsatisfied:\n %s", error_text); 187 endif 188 endif 189 190 ## Prepare each package for installation. 191 try 192 for i = 1:length (descriptions) 193 desc = descriptions{i}; 194 pdir = packdirs{i}; 195 prepare_installation (desc, pdir); 196 configure_make (desc, pdir, verbose); 197 copy_built_files (desc, pdir, verbose); 198 endfor 199 catch 200 ## Something went wrong, delete tmpdirs. 201 for i = 1:length (tmpdirs) 202 rmdir (tmpdirs{i}, "s"); 203 endfor 204 rethrow (lasterror ()); 205 end_try_catch 206 207 ## Uninstall the packages that will be replaced. 208 try 209 for i = packages_to_uninstall 210 if (global_install) 211 uninstall ({global_packages{i}.name}, false, verbose, local_list, 212 global_list, global_install); 213 else 214 uninstall ({local_packages{i}.name}, false, verbose, local_list, 215 global_list, global_install); 216 endif 217 endfor 218 catch 219 ## Something went wrong, delete tmpdirs. 220 for i = 1:length (tmpdirs) 221 rmdir (tmpdirs{i}, "s"); 222 endfor 223 rethrow (lasterror ()); 224 end_try_catch 225 226 ## Install each package. 227 try 228 for i = 1:length (descriptions) 229 desc = descriptions{i}; 230 pdir = packdirs{i}; 231 copy_files (desc, pdir, global_install); 232 create_pkgadddel (desc, pdir, "PKG_ADD", global_install); 233 create_pkgadddel (desc, pdir, "PKG_DEL", global_install); 234 finish_installation (desc, pdir, global_install); 235 generate_lookfor_cache (desc); 236 endfor 237 catch 238 ## Something went wrong, delete tmpdirs. 239 for i = 1:length (tmpdirs) 240 rmdir (tmpdirs{i}, "s"); 241 endfor 242 for i = 1:length (descriptions) 243 rmdir (descriptions{i}.dir, "s"); 244 rmdir (getarchdir (descriptions{i}), "s"); 245 endfor 246 rethrow (lasterror ()); 247 end_try_catch 248 249 ## Check if the installed directory is empty. If it is remove it 250 ## from the list. 251 for i = length (descriptions):-1:1 252 if (dirempty (descriptions{i}.dir, {"packinfo", "doc"}) 253 && dirempty (getarchdir (descriptions{i}))) 254 warning ("package %s is empty\n", descriptions{i}.name); 255 rmdir (descriptions{i}.dir, "s"); 256 rmdir (getarchdir (descriptions{i}), "s"); 257 descriptions(i) = []; 258 endif 259 endfor 260 261 ## Add the packages to the package list. 262 try 263 if (global_install) 264 idx = setdiff (1:length (global_packages), packages_to_uninstall); 265 global_packages = save_order ({global_packages{idx}, descriptions{:}}); 266 if (ispc) 267 ## On Windows ensure LFN paths are saved rather than 8.3 style paths 268 global_packages = standardize_paths (global_packages); 269 endif 270 global_packages = make_rel_paths (global_packages); 271 save (global_list, "global_packages"); 272 installed_pkgs_lst = {local_packages{:}, global_packages{:}}; 273 else 274 idx = setdiff (1:length (local_packages), packages_to_uninstall); 275 local_packages = save_order ({local_packages{idx}, descriptions{:}}); 276 if (ispc) 277 local_packages = standardize_paths (local_packages); 278 endif 279 save (local_list, "local_packages"); 280 installed_pkgs_lst = {local_packages{:}, global_packages{:}}; 281 endif 282 catch 283 ## Something went wrong, delete tmpdirs. 284 for i = 1:length (tmpdirs) 285 rmdir (tmpdirs{i}, "s"); 286 endfor 287 for i = 1:length (descriptions) 288 rmdir (descriptions{i}.dir, "s"); 289 endfor 290 if (global_install) 291 printf ("error: couldn't append to %s\n", global_list); 292 else 293 printf ("error: couldn't append to %s\n", local_list); 294 endif 295 rethrow (lasterror ()); 296 end_try_catch 297 298 ## All is well, let's clean up. 299 for i = 1:length (tmpdirs) 300 [status, msg] = rmdir (tmpdirs{i}, "s"); 301 if (status != 1 && isfolder (tmpdirs{i})) 302 warning ("couldn't clean up after my self: %s\n", msg); 303 endif 304 endfor 305 306 ## If there is a NEWS file, mention it. 307 ## Check if desc exists too because it's possible to get to this point 308 ## without creating it such as giving an invalid filename for the package 309 if (exist ("desc", "var") 310 && exist (fullfile (desc.dir, "packinfo", "NEWS"), "file")) 311 printf (["For information about changes from previous versions " ... 312 "of the %s package, run 'news %s'.\n"], 313 desc.name, desc.name); 314 endif 315 316endfunction 317 318 319function pkg = extract_pkg (nm, pat) 320 321 mfile_encoding = __mfile_encoding__ (); 322 if (strcmp (mfile_encoding, "system")) 323 mfile_encoding = __locale_charset__ (); 324 endif 325 fid = fopen (nm, "rt", "n", mfile_encoding); 326 pkg = ""; 327 if (fid >= 0) 328 while (! feof (fid)) 329 ln = __u8_validate__ (fgetl (fid)); 330 if (ln > 0) 331 t = regexp (ln, pat, "tokens"); 332 if (! isempty (t)) 333 pkg = [pkg "\n" t{1}{1}]; 334 endif 335 endif 336 endwhile 337 if (! isempty (pkg)) 338 pkg = [pkg "\n"]; 339 endif 340 fclose (fid); 341 endif 342 343endfunction 344 345 346## Make sure the package contains the essential files. 347function verify_directory (dir) 348 349 needed_files = {"COPYING", "DESCRIPTION"}; 350 for f = needed_files 351 if (! exist (fullfile (dir, f{1}), "file")) 352 error ("package is missing file: %s", f{1}); 353 endif 354 endfor 355 356endfunction 357 358 359function prepare_installation (desc, packdir) 360 361 ## Is there a pre_install to call? 362 if (exist (fullfile (packdir, "pre_install.m"), "file")) 363 wd = pwd (); 364 try 365 cd (packdir); 366 pre_install (desc); 367 cd (wd); 368 catch 369 cd (wd); 370 rethrow (lasterror ()); 371 end_try_catch 372 endif 373 374 ## If the directory "inst" doesn't exist, we create it. 375 inst_dir = fullfile (packdir, "inst"); 376 if (! isfolder (inst_dir)) 377 [status, msg] = mkdir (inst_dir); 378 if (status != 1) 379 rmdir (desc.dir, "s"); 380 error ("the 'inst' directory did not exist and could not be created: %s", 381 msg); 382 endif 383 endif 384 385endfunction 386 387 388function copy_built_files (desc, packdir, verbose) 389 390 src = fullfile (packdir, "src"); 391 if (! isfolder (src)) 392 return 393 endif 394 395 ## Copy files to "inst" and "inst/arch" (this is instead of 'make install'). 396 files = fullfile (src, "FILES"); 397 instdir = fullfile (packdir, "inst"); 398 archdir = fullfile (packdir, "inst", getarch ()); 399 400 ## Get filenames. 401 if (exist (files, "file")) 402 [fid, msg] = fopen (files, "r"); 403 if (fid < 0) 404 error ("couldn't open %s: %s", files, msg); 405 endif 406 filenames = char (fread (fid))'; 407 fclose (fid); 408 if (filenames(end) == "\n") 409 filenames(end) = []; 410 endif 411 filenames = strtrim (ostrsplit (filenames, "\n")); 412 delete_idx = []; 413 for i = 1:length (filenames) 414 if (! all (isspace (filenames{i}))) 415 filenames{i} = fullfile (src, filenames{i}); 416 else 417 delete_idx(end+1) = i; 418 endif 419 endfor 420 filenames(delete_idx) = []; 421 else 422 m = dir (fullfile (src, "*.m")); 423 oct = dir (fullfile (src, "*.oct")); 424 mex = dir (fullfile (src, "*.mex")); 425 tst = dir (fullfile (src, "*tst")); 426 427 filenames = cellfun (@(x) fullfile (src, x), 428 {m.name, oct.name, mex.name, tst.name}, 429 "uniformoutput", false); 430 endif 431 432 ## Split into architecture dependent and independent files. 433 if (isempty (filenames)) 434 idx = []; 435 else 436 idx = cellfun ("is_architecture_dependent", filenames); 437 endif 438 archdependent = filenames(idx); 439 archindependent = filenames(! idx); 440 441 ## Copy the files. 442 if (! all (isspace ([filenames{:}]))) 443 if (! isfolder (instdir)) 444 mkdir (instdir); 445 endif 446 if (! all (isspace ([archindependent{:}]))) 447 if (verbose) 448 printf ("copyfile"); 449 printf (" %s", archindependent{:}); 450 printf ("%s\n", instdir); 451 endif 452 [status, output] = copyfile (archindependent, instdir); 453 if (status != 1) 454 rmdir (desc.dir, "s"); 455 error ("Couldn't copy files from 'src' to 'inst': %s", output); 456 endif 457 endif 458 if (! all (isspace ([archdependent{:}]))) 459 if (verbose) 460 printf ("copyfile"); 461 printf (" %s", archdependent{:}); 462 printf (" %s\n", archdir); 463 endif 464 if (! isfolder (archdir)) 465 mkdir (archdir); 466 endif 467 [status, output] = copyfile (archdependent, archdir); 468 if (status != 1) 469 rmdir (desc.dir, "s"); 470 error ("Couldn't copy files from 'src' to 'inst': %s", output); 471 endif 472 endif 473 endif 474 475endfunction 476 477 478function dep = is_architecture_dependent (nm) 479 480 persistent archdepsuffix = {".oct", ".mex", ".a", ".lib", ".so", ... 481 "tst", ".so.*", ".dll", "dylib"}; 482 483 dep = false; 484 for i = 1 : length (archdepsuffix) 485 ext = archdepsuffix{i}; 486 if (ext(end) == "*") 487 isglob = true; 488 ext(end) = []; 489 else 490 isglob = false; 491 endif 492 pos = strfind (nm, ext); 493 if (pos) 494 if (! isglob && (length (nm) - pos(end) != length (ext) - 1)) 495 continue; 496 endif 497 dep = true; 498 break; 499 endif 500 endfor 501 502endfunction 503 504 505function copy_files (desc, packdir, global_install) 506 507 ## Create the installation directory. 508 if (! isfolder (desc.dir)) 509 [status, output] = mkdir (desc.dir); 510 if (status != 1) 511 error ("couldn't create installation directory %s : %s", 512 desc.dir, output); 513 endif 514 endif 515 516 octfiledir = getarchdir (desc); 517 518 ## Copy the files from "inst" to installdir. 519 instdir = fullfile (packdir, "inst"); 520 if (! dirempty (instdir)) 521 [status, output] = copyfile (fullfile (instdir, "*"), desc.dir); 522 if (status != 1) 523 rmdir (desc.dir, "s"); 524 error ("couldn't copy files to the installation directory"); 525 endif 526 if (isfolder (fullfile (desc.dir, getarch ())) 527 && ! is_same_file (fullfile (desc.dir, getarch ()), octfiledir)) 528 if (! isfolder (octfiledir)) 529 ## Can be required to create up to three levels of dirs. 530 octm1 = fileparts (octfiledir); 531 if (! isfolder (octm1)) 532 octm2 = fileparts (octm1); 533 if (! isfolder (octm2)) 534 octm3 = fileparts (octm2); 535 if (! isfolder (octm3)) 536 [status, output] = mkdir (octm3); 537 if (status != 1) 538 rmdir (desc.dir, "s"); 539 error ("couldn't create installation directory %s : %s", 540 octm3, output); 541 endif 542 endif 543 [status, output] = mkdir (octm2); 544 if (status != 1) 545 rmdir (desc.dir, "s"); 546 error ("couldn't create installation directory %s : %s", 547 octm2, output); 548 endif 549 endif 550 [status, output] = mkdir (octm1); 551 if (status != 1) 552 rmdir (desc.dir, "s"); 553 error ("couldn't create installation directory %s : %s", 554 octm1, output); 555 endif 556 endif 557 [status, output] = mkdir (octfiledir); 558 if (status != 1) 559 rmdir (desc.dir, "s"); 560 error ("couldn't create installation directory %s : %s", 561 octfiledir, output); 562 endif 563 endif 564 [status, output] = movefile (fullfile (desc.dir, getarch (), "*"), 565 octfiledir); 566 rmdir (fullfile (desc.dir, getarch ()), "s"); 567 568 if (status != 1) 569 rmdir (desc.dir, "s"); 570 rmdir (octfiledir, "s"); 571 error ("couldn't copy files to the installation directory"); 572 endif 573 endif 574 575 endif 576 577 ## Create the "packinfo" directory. 578 packinfo = fullfile (desc.dir, "packinfo"); 579 [status, msg] = mkdir (packinfo); 580 if (status != 1) 581 rmdir (desc.dir, "s"); 582 rmdir (octfiledir, "s"); 583 error ("couldn't create packinfo directory: %s", msg); 584 endif 585 586 packinfo_copy_file ("DESCRIPTION", "required", packdir, packinfo, desc, octfiledir); 587 packinfo_copy_file ("COPYING", "required", packdir, packinfo, desc, octfiledir); 588 packinfo_copy_file ("CITATION", "optional", packdir, packinfo, desc, octfiledir); 589 packinfo_copy_file ("NEWS", "optional", packdir, packinfo, desc, octfiledir); 590 packinfo_copy_file ("ONEWS", "optional", packdir, packinfo, desc, octfiledir); 591 packinfo_copy_file ("ChangeLog", "optional", packdir, packinfo, desc, octfiledir); 592 593 ## Is there an INDEX file to copy or should we generate one? 594 index_file = fullfile (packdir, "INDEX"); 595 if (exist (index_file, "file")) 596 packinfo_copy_file ("INDEX", "required", packdir, packinfo, desc, octfiledir); 597 else 598 try 599 write_index (desc, fullfile (packdir, "inst"), 600 fullfile (packinfo, "INDEX"), global_install); 601 catch 602 rmdir (desc.dir, "s"); 603 rmdir (octfiledir, "s"); 604 rethrow (lasterror ()); 605 end_try_catch 606 endif 607 608 ## Is there an 'on_uninstall.m' to install? 609 packinfo_copy_file ("on_uninstall.m", "optional", packdir, packinfo, desc, octfiledir); 610 611 ## Is there a doc/ directory that needs to be installed? 612 docdir = fullfile (packdir, "doc"); 613 if (isfolder (docdir) && ! dirempty (docdir)) 614 [status, output] = copyfile (docdir, desc.dir); 615 endif 616 617 ## Is there a bin/ directory that needs to be installed? 618 ## FIXME: Need to treat architecture dependent files in bin/ 619 bindir = fullfile (packdir, "bin"); 620 if (isfolder (bindir) && ! dirempty (bindir)) 621 [status, output] = copyfile (bindir, desc.dir); 622 endif 623 624endfunction 625 626 627function packinfo_copy_file (filename, requirement, packdir, packinfo, desc, octfiledir) 628 629 filepath = fullfile (packdir, filename); 630 if (! exist (filepath, "file") && strcmpi (requirement, "optional")) 631 ## do nothing, it's still OK 632 else 633 [status, output] = copyfile (filepath, packinfo); 634 if (status != 1) 635 rmdir (desc.dir, "s"); 636 rmdir (octfiledir, "s"); 637 error ("Couldn't copy %s file: %s", filename, output); 638 endif 639 endif 640 641endfunction 642 643 644## Create an INDEX file for a package that doesn't provide one. 645## 'desc' describes the package. 646## 'dir' is the 'inst' directory in temporary directory. 647## 'index_file' is the name (including path) of resulting INDEX file. 648function write_index (desc, dir, index_file, global_install) 649 650 ## Get names of functions in dir 651 [files, err, msg] = readdir (dir); 652 if (err) 653 error ("couldn't read directory %s: %s", dir, msg); 654 endif 655 656 ## Get classes in dir 657 class_idx = find (strncmp (files, '@', 1)); 658 for k = 1:length (class_idx) 659 class_name = files {class_idx(k)}; 660 class_dir = fullfile (dir, class_name); 661 if (isfolder (class_dir)) 662 [files2, err, msg] = readdir (class_dir); 663 if (err) 664 error ("couldn't read directory %s: %s", class_dir, msg); 665 endif 666 files2 = strcat (class_name, filesep (), files2); 667 files = [files; files2]; 668 endif 669 endfor 670 671 ## Check for architecture dependent files. 672 tmpdir = getarchdir (desc); 673 if (isfolder (tmpdir)) 674 [files2, err, msg] = readdir (tmpdir); 675 if (err) 676 error ("couldn't read directory %s: %s", tmpdir, msg); 677 endif 678 files = [files; files2]; 679 endif 680 681 functions = {}; 682 for i = 1:length (files) 683 file = files{i}; 684 lf = length (file); 685 if (lf > 2 && strcmp (file(end-1:end), ".m")) 686 functions{end+1} = file(1:end-2); 687 elseif (lf > 4 && strcmp (file(end-3:end), ".oct")) 688 functions{end+1} = file(1:end-4); 689 endif 690 endfor 691 692 ## Does desc have a categories field? 693 if (! isfield (desc, "categories")) 694 error ("the DESCRIPTION file must have a Categories field, when no INDEX file is given"); 695 endif 696 categories = strtrim (strsplit (desc.categories, ",")); 697 if (length (categories) < 1) 698 error ("the Category field is empty"); 699 endif 700 701 ## Write INDEX. 702 fid = fopen (index_file, "w"); 703 if (fid == -1) 704 error ("couldn't open %s for writing", index_file); 705 endif 706 fprintf (fid, "%s >> %s\n", desc.name, desc.title); 707 fprintf (fid, "%s\n", categories{1}); 708 fprintf (fid, " %s\n", functions{:}); 709 fclose (fid); 710 711endfunction 712 713 714function create_pkgadddel (desc, packdir, nm, global_install) 715 716 instpkg = fullfile (desc.dir, nm); 717 instfid = fopen (instpkg, "at"); # append to support PKG_ADD at inst/ 718 ## If it is exists, most of the PKG_* file should go into the 719 ## architecture dependent directory so that the autoload/mfilename 720 ## commands work as expected. The only part that doesn't is the 721 ## part in the main directory. 722 archdir = fullfile (getarchprefix (desc, global_install), 723 [desc.name "-" desc.version], getarch ()); 724 if (isfolder (getarchdir (desc, global_install))) 725 archpkg = fullfile (getarchdir (desc, global_install), nm); 726 archfid = fopen (archpkg, "at"); 727 else 728 archpkg = instpkg; 729 archfid = instfid; 730 endif 731 732 if (archfid >= 0 && instfid >= 0) 733 ## Search all dot-m files for PKG commands. 734 lst = glob (fullfile (packdir, "inst", "*.m")); 735 for i = 1:length (lst) 736 nam = lst{i}; 737 fwrite (instfid, extract_pkg (nam, ['^[#%][#%]* *' nm ': *(.*)$'])); 738 endfor 739 740 ## Search all C++ source files for PKG commands. 741 cc_lst = glob (fullfile (packdir, "src", "*.cc")); 742 cpp_lst = glob (fullfile (packdir, "src", "*.cpp")); 743 cxx_lst = glob (fullfile (packdir, "src", "*.cxx")); 744 lst = [cc_lst; cpp_lst; cxx_lst]; 745 for i = 1:length (lst) 746 nam = lst{i}; 747 fwrite (archfid, extract_pkg (nam, ['^//* *' nm ': *(.*)$'])); 748 fwrite (archfid, extract_pkg (nam, ['^/\** *' nm ': *(.*) *\*/$'])); 749 endfor 750 751 ## Add developer included PKG commands. 752 packdirnm = fullfile (packdir, nm); 753 if (exist (packdirnm, "file")) 754 fid = fopen (packdirnm, "rt"); 755 if (fid >= 0) 756 while (! feof (fid)) 757 ln = fgets (fid); 758 if (ln > 0) 759 fwrite (archfid, ln); 760 endif 761 endwhile 762 fclose (fid); 763 endif 764 endif 765 766 ## If the files is empty remove it. 767 fclose (instfid); 768 t = dir (instpkg); 769 if (t.bytes <= 0) 770 unlink (instpkg); 771 endif 772 773 if (instfid != archfid) 774 fclose (archfid); 775 t = dir (archpkg); 776 if (t.bytes <= 0) 777 unlink (archpkg); 778 endif 779 endif 780 endif 781 782endfunction 783 784 785function archprefix = getarchprefix (desc, global_install) 786 787 if (global_install) 788 [~, archprefix] = default_prefix (global_install, desc); 789 else 790 archprefix = desc.dir; 791 endif 792 793endfunction 794 795 796function finish_installation (desc, packdir, global_install) 797 798 ## Is there a post-install to call? 799 if (exist (fullfile (packdir, "post_install.m"), "file")) 800 wd = pwd (); 801 try 802 cd (packdir); 803 post_install (desc); 804 cd (wd); 805 catch 806 cd (wd); 807 rmdir (desc.dir, "s"); 808 rmdir (getarchdir (desc), "s"); 809 rethrow (lasterror ()); 810 end_try_catch 811 endif 812 813endfunction 814 815 816function generate_lookfor_cache (desc) 817 818 dirs = strtrim (ostrsplit (genpath (desc.dir), pathsep ())); 819 if (ispc) 820 dirs = cellfun (@canonicalize_file_name, dirs, "uniformoutput", false); 821 endif 822 for i = 1 : length (dirs) 823 doc_cache_create (fullfile (dirs{i}, "doc-cache"), dirs{i}); 824 endfor 825 826endfunction 827