Changeset 3083 for trunk/LMDZ.TITAN/libf/muphytitan/fsystem.F90
- Timestamp:
- Oct 12, 2023, 10:30:22 AM (15 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LMDZ.TITAN/libf/muphytitan/fsystem.F90
r1897 r3083 1 ! Copyright Jérémie Burgalat (2010-2015,2017) 2 ! 3 ! jeremie.burgalat@univ-reims.fr 4 ! 5 ! This software is a computer program whose purpose is to provide configuration 6 ! file and command line arguments parsing features to Fortran programs. 7 ! 8 ! This software is governed by the CeCILL-B license under French law and 9 ! abiding by the rules of distribution of free software. You can use, 10 ! modify and/ or redistribute the software under the terms of the CeCILL-B 11 ! license as circulated by CEA, CNRS and INRIA at the following URL 12 ! "http://www.cecill.info". 13 ! 14 ! As a counterpart to the access to the source code and rights to copy, 15 ! modify and redistribute granted by the license, users are provided only 16 ! with a limited warranty and the software's author, the holder of the 17 ! economic rights, and the successive licensors have only limited 18 ! liability. 19 ! 20 ! In this respect, the user's attention is drawn to the risks associated 21 ! with loading, using, modifying and/or developing or reproducing the 22 ! software by the user in light of its specific status of free software, 23 ! that may mean that it is complicated to manipulate, and that also 24 ! therefore means that it is reserved for developers and experienced 25 ! professionals having in-depth computer knowledge. Users are therefore 26 ! encouraged to load and test the software's suitability as regards their 27 ! requirements in conditions enabling the security of their systems and/or 28 ! data to be ensured and, more generally, to use and operate it in the 29 ! same conditions as regards security. 30 ! 31 ! The fact that you are presently reading this means that you have had 32 ! knowledge of the CeCILL-B license and that you accept its terms. 1 ! Copyright (c) (2013-2015,2017) Jeremie Burgalat (jeremie.burgalat@univ-reims.fr). 2 ! 3 ! This file is part of SWIFT 4 ! 5 ! Permission is hereby granted, free of charge, to any person obtaining a copy of 6 ! this software and associated documentation files (the "Software"), to deal in 7 ! the Software without restriction, including without limitation the rights to 8 ! use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 ! the Software, and to permit persons to whom the Software is furnished to do so, 10 ! subject to the following conditions: 11 ! 12 ! The above copyright notice and this permission notice shall be included in all 13 ! copies or substantial portions of the Software. 14 ! 15 ! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 ! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 ! FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 ! COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 ! IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 ! CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 33 21 34 22 !! file: fsystem.F90 35 23 !! summary: File system methods source file. 36 24 !! author: J. Burgalat 37 !! date: 2013-2015,2017 25 !! date: 2013-2015,2017,2022 38 26 39 27 … … 46 34 IMPLICIT NONE 47 35 48 PUBLIC 36 PUBLIC 49 37 50 38 PRIVATE :: get_umask … … 57 45 !! 58 46 !! This object can be used to get an approximation of the execution of some piece of code. 59 REAL(kind=8), PRIVATE :: cpu_start = 0d0 47 REAL(kind=8), PRIVATE :: cpu_start = 0d0 60 48 !! Starting CPU time 61 INTEGER(kind=8), PRIVATE :: clock_start = 0d0 49 INTEGER(kind=8), PRIVATE :: clock_start = 0d0 62 50 !! Starting clock time 63 51 LOGICAL, PRIVATE :: on_run = .false. 64 52 !! Chrono running state. 65 53 #if HAVE_FTNPROC 66 CONTAINS 67 PROCEDURE :: is_running => chrono_is_running 54 CONTAINS 55 PROCEDURE :: is_running => chrono_is_running 68 56 PROCEDURE :: start => chrono_start 69 57 PROCEDURE :: stop => chrono_stop … … 95 83 END FUNCTION errno_c 96 84 97 FUNCTION usleep_c(usec) BIND(C,name="usleep") 85 FUNCTION usleep_c(usec) BIND(C,name="usleep") 98 86 !! (attemps to) Sleep for a given number of microseconds 99 87 IMPORT C_INT … … 127 115 128 116 FUNCTION access_c(path,perm) BIND(C,name="c_access") 129 !! Check if path is accessible for current user 117 !! Check if path is accessible for current user 130 118 IMPORT c_char, C_INT 131 119 CHARACTER(len=c_char), INTENT(in) :: path(*) !! Path to check … … 134 122 END FUNCTION access_c 135 123 136 FUNCTION create_c(path,mode,asfile,forced) BIND(C,name="c_create") 124 FUNCTION create_c(path,mode,asfile,forced) BIND(C,name="c_create") 137 125 !! Create a directory or a file in given path 138 126 IMPORT c_char, C_INT … … 149 137 INTEGER(kind=C_INT), INTENT(in), VALUE :: uid !! User id 150 138 TYPE(C_PTR) :: uname_c !! C_PTR to the underlying char* pointer storing user name 151 END FUNCTION uname_c 139 END FUNCTION uname_c 152 140 153 141 FUNCTION gname_c(gid) BIND(C, name="c_gname") … … 156 144 INTEGER(kind=C_INT), INTENT(in), VALUE :: gid !! Group id 157 145 TYPE(C_PTR) :: gname_c !! C_PTR to the underlying char* pointer storing group name 158 END FUNCTION gname_c 159 160 FUNCTION dirname_c(path) BIND(C,name="c_dirname") 146 END FUNCTION gname_c 147 148 FUNCTION dirname_c(path) BIND(C,name="c_dirname") 161 149 !! Get the directory name of the path 162 150 IMPORT c_char, c_ptr … … 172 160 END FUNCTION basename_c 173 161 174 FUNCTION getcwd_c() BIND(C,name="c_getcwd") 162 FUNCTION getcwd_c() BIND(C,name="c_getcwd") 175 163 !! Get the current working directory 176 164 IMPORT c_ptr … … 198 186 CHARACTER(kind=c_char), INTENT(in) :: input(*) !! Path to rename 199 187 CHARACTER(kind=c_char), INTENT(in) :: output(*) !! New name of the path 200 INTEGER(kind=C_INT) :: rename_c !! 0 on success, last errno on failure 188 INTEGER(kind=C_INT) :: rename_c !! 0 on success, last errno on failure 201 189 END FUNCTION rename_c 202 190 … … 206 194 CHARACTER(kind=c_char), INTENT(in) :: path(*) !! Path to modify 207 195 INTEGER(kind=C_INT), INTENT(in), VALUE :: mode !! New decimal permissions of the path to set 208 INTEGER(kind=C_INT) :: chmod_c !! 0 on success, last errno on failure 196 INTEGER(kind=C_INT) :: chmod_c !! 0 on success, last errno on failure 209 197 END FUNCTION chmod_c 210 198 … … 213 201 IMPORT c_char, C_INT 214 202 CHARACTER(kind=c_char), INTENT(in) :: new(*) !! Path of the new working directory 215 INTEGER(kind=C_INT) :: chdir_c !! 0 on success, last errno on failure 203 INTEGER(kind=C_INT) :: chdir_c !! 0 on success, last errno on failure 216 204 END FUNCTION chdir_c 217 205 … … 220 208 IMPORT c_char, C_INT 221 209 CHARACTER(kind=c_char), INTENT(in) :: dirname(*) !! Path of the directory to create 222 INTEGER(kind=C_INT), INTENT(in), VALUE :: mode !! Decimal permission to set 223 INTEGER(kind=C_INT) :: mkdir_c !! 0 on success, last errno on failure 210 INTEGER(kind=C_INT), INTENT(in), VALUE :: mode !! Decimal permission to set 211 INTEGER(kind=C_INT) :: mkdir_c !! 0 on success, last errno on failure 224 212 END FUNCTION mkdir_c 225 213 … … 228 216 IMPORT c_char, C_INT 229 217 CHARACTER(kind=c_char), INTENT(in) :: dirname(*) !! Path of the directory to create 230 INTEGER(kind=C_INT), INTENT(in), VALUE :: mode !! Decimal permission to set 231 INTEGER(kind=C_INT) :: mkdirp_c !! 0 on success, last errno on failure 218 INTEGER(kind=C_INT), INTENT(in), VALUE :: mode !! Decimal permission to set 219 INTEGER(kind=C_INT) :: mkdirp_c !! 0 on success, last errno on failure 232 220 END FUNCTION mkdirp_c 233 221 234 FUNCTION copy_c(to,from) BIND(C,name="c_copy") 222 FUNCTION copy_c(to,from) BIND(C,name="c_copy") 235 223 !! Copy a file. 236 224 IMPORT c_char, C_INT … … 240 228 END FUNCTION copy_c 241 229 242 FUNCTION remove_c(path) BIND(C,name="c_remove") 230 FUNCTION remove_c(path) BIND(C,name="c_remove") 243 231 !! Remove a file (or a directory) from the filesystem 244 232 IMPORT c_char, C_INT 245 233 CHARACTER(kind=c_char), INTENT(in) :: path(*) !! Path to delete 246 INTEGER(kind=C_INT) :: remove_c !! 0 on success, last errno on failure 234 INTEGER(kind=C_INT) :: remove_c !! 0 on success, last errno on failure 247 235 END FUNCTION remove_c 248 236 … … 251 239 IMPORT c_char, C_INT 252 240 CHARACTER(kind=c_char), INTENT(in) :: dirpath(*) !! Directory to delete 253 INTEGER(kind=C_INT) :: rmdir_c !! 0 on success, last errno on failure 241 INTEGER(kind=C_INT) :: rmdir_c !! 0 on success, last errno on failure 254 242 END FUNCTION rmdir_c 255 243 … … 258 246 IMPORT c_char, C_INT 259 247 CHARACTER(kind=c_char), INTENT(in) :: dirpath(*) !! Directory to delete 260 INTEGER(kind=C_INT) :: rmdirf_c !! 0 on success, last errno on failure 248 INTEGER(kind=C_INT) :: rmdirf_c !! 0 on success, last errno on failure 261 249 END FUNCTION rmdirf_c 262 250 … … 282 270 INTEGER(kind=C_INT), INTENT(out) :: r, & !! Number of rows 283 271 c !! Number of columns 284 INTEGER(kind=C_INT) :: termsize_c !! 0 on success, last errno on failure 272 INTEGER(kind=C_INT) :: termsize_c !! 0 on success, last errno on failure 285 273 END FUNCTION termsize_c 286 274 … … 289 277 IMPORT C_SIZE_T 290 278 INTEGER(kind=C_SIZE_T) :: getCurrentRSS_c !! Current resident set size in bytes (0 if not available). 291 END FUNCTION getCurrentRSS_c 279 END FUNCTION getCurrentRSS_c 292 280 293 281 FUNCTION getPeakRSS_c() BIND(C, name="c_getPeakRSS") … … 295 283 IMPORT C_SIZE_T 296 284 INTEGER(kind=C_SIZE_T) :: getPeakRSS_c !! Peak resident set size in bytes (0 if not available). 297 END FUNCTION getPeakRSS_c 285 END FUNCTION getPeakRSS_c 298 286 299 287 FUNCTION getSystemMemory_c(total,avail,free) BIND(C, name='c_getSystemMemory') … … 303 291 INTEGER(kind=C_LONG_LONG), INTENT(out) :: avail !! Current available memory. 304 292 INTEGER(kind=C_LONG_LONG), INTENT(out) :: free !! Current free memory. 305 INTEGER(kind=C_INT) :: getSystemMemory_c !! status, 0 on success, 1 otherwise. 293 INTEGER(kind=C_INT) :: getSystemMemory_c !! status, 0 on success, 1 otherwise. 306 294 END FUNCTION getSystemMemory_c 307 295 END INTERFACE … … 311 299 312 300 FUNCTION fstring(string) RESULT(str) 313 !! Convert C string to Fortran string 301 !! Convert C string to Fortran string 314 302 !! 315 303 !! The method copies the input C string up to the last C_NULL_CHAR found (not including it), 316 304 !! and returns the converted Fortran string. 317 305 !! All other C_NULL_CHAR found in the C string are removed. 318 CHARACTER(len=*), INTENT(in) :: string !! A string from C 306 CHARACTER(len=*), INTENT(in) :: string !! A string from C 319 307 CHARACTER(len=:), ALLOCATABLE :: str !! Converted fortran string 320 INTEGER :: i,idx 308 INTEGER :: i,idx 321 309 str = "" 322 310 idx = INDEX(string,C_NULL_CHAR,.true.) … … 335 323 !! 336 324 !! The method build the fortran string from a TYPE(C_PTR) object that represent a 337 !! C char\* pointer string. 325 !! C char\* pointer string. 338 326 !! @note 339 327 !! If __cstr__ is not allocated (i.e. the C_PTR is not associated) or if it is set 340 328 !! to a C empty string (i.e. '\0') then the method returns an empty string. 341 329 !! @attention 342 !! The method does not free the underlying C string and it should be free using 330 !! The method does not free the underlying C string and it should be free using 343 331 !! the subroutine free_c(_cstr_). 344 332 TYPE(C_PTR), INTENT(in) :: cstr … … 366 354 367 355 FUNCTION cstring(string) RESULT(str) 368 !> convert Fortran string to cstring 356 !> convert Fortran string to cstring 369 357 !! 370 358 !! The method returns a copy of the input string suitable for C functions argument. 371 !! @note 359 !! @note 372 360 !! Input string is trimmed during computations 373 361 CHARACTER(len=*), INTENT(in) :: string … … 385 373 !=============================================================================== 386 374 387 FUNCTION fs_getgid() RESULT(ret) 375 FUNCTION fs_getgid() RESULT(ret) 388 376 !! Get Group ID 389 377 INTEGER(kind=4) :: ret !! An integer with the group identifier 390 ret = INT(getgid_c(),kind=4) 378 ret = INT(getgid_c(),kind=4) 391 379 RETURN 392 380 END FUNCTION fs_getgid … … 399 387 END FUNCTION fs_getpid 400 388 401 FUNCTION fs_getuid() RESULT(ret) 389 FUNCTION fs_getuid() RESULT(ret) 402 390 !! Get User ID 403 391 INTEGER(kind=4) :: ret !! An integer with the user identifier … … 413 401 zname = gname_c(gid) 414 402 IF (.NOT.C_ASSOCIATED(zname)) THEN 415 gname = "" 403 gname = "" 416 404 ELSE 417 405 gname = cstr2fstr(zname) … … 427 415 zname = gname_c(uid) 428 416 IF (.NOT.C_ASSOCIATED(zname)) THEN 429 uname = "" 417 uname = "" 430 418 ELSE 431 419 uname = cstr2fstr(zname) … … 438 426 CHARACTER(len=*), INTENT(in) :: path 439 427 !! A string with a (valid) path 440 CHARACTER(len=:), ALLOCATABLE :: opath 428 CHARACTER(len=:), ALLOCATABLE :: opath 441 429 !! A Fortran allocated string with the parent directory path or an empty string if method fails 442 430 TYPE(C_PTR) :: zpath … … 458 446 CHARACTER(len=*), INTENT(in) :: path 459 447 !! A string with a (valid) path 460 CHARACTER(len=:), ALLOCATABLE :: opath 448 CHARACTER(len=:), ALLOCATABLE :: opath 461 449 !! The basename of the path or an empty string if method fails 462 450 TYPE(C_PTR) :: zpath … … 478 466 !! 479 467 !! The method computes the absolute path of the given path using C realpath function. 480 !! @note 468 !! @note 481 469 !! If the input path is empty then current working directory is returned. 482 470 CHARACTER(len=*), INTENT(in) :: path 483 471 !! A string with a (valid) path 484 CHARACTER(len=:), ALLOCATABLE :: opath 472 CHARACTER(len=:), ALLOCATABLE :: opath 485 473 !! The absolute of the path or an empty string if method fails 486 474 TYPE(C_PTR) :: zpath … … 497 485 !! Get the relative representation of two paths 498 486 !! 499 !! The method computes the relative representation of __path__ from __reldir__ if possible. 487 !! The method computes the relative representation of __path__ from __reldir__ if possible. 500 488 !! If no common prefix is found, the method returns __path__. 501 489 CHARACTER(len=*), INTENT(in) :: path, & !! Path to be computed relative to reldir … … 508 496 ELSE 509 497 res = cstr2fstr(zpath) 510 ENDIF 498 ENDIF 511 499 CALL free_c(zpath) 512 500 END FUNCTION fs_relpath 513 501 514 FUNCTION fs_getcwd() RESULT(path) 502 FUNCTION fs_getcwd() RESULT(path) 515 503 !! Get the current working directory 516 504 CHARACTER(len=:), ALLOCATABLE :: path … … 558 546 LOGICAL :: ret !! True on success, false otherwise. 559 547 IF (LEN_TRIM(old) == 0.OR.LEN_TRIM(new) == 0) THEN 560 ret = .false. 548 ret = .false. 561 549 ELSE 562 550 ret = INT(rename_c(cstring(ADJUSTL(old)),cstring(ADJUSTL(new)))) == 0 … … 572 560 INTEGER(kind=C_INT) :: zmode 573 561 IF (LEN_TRIM(path) == 0) THEN 574 ret = .false. 562 ret = .false. 575 563 ELSE 576 564 zmode = INT(oct_2_dec(mode),kind=C_INT) … … 585 573 LOGICAL :: ret !! True on success, false otherwise. 586 574 IF (LEN_TRIM(path) == 0) THEN 587 ret = .false. 575 ret = .false. 588 576 ELSE 589 577 ret = INT(chdir_c(cstring(ADJUSTL(path)))) == 0 … … 597 585 !! The method attempts to create a new directory pointed by __path__ with the permission 598 586 !! given by mode. 599 CHARACTER(len=*), INTENT(in) :: path 587 CHARACTER(len=*), INTENT(in) :: path 600 588 !! The path to modify 601 589 INTEGER, INTENT(in), OPTIONAL :: mode … … 608 596 LOGICAL :: zperm 609 597 IF (LEN_TRIM(path) == 0) THEN 610 ret = .false. 611 ELSE 612 zmode = oct_2_dec(744) 598 ret = .false. 599 ELSE 600 zmode = oct_2_dec(744) 613 601 IF (PRESENT(mode)) THEN 614 IF (.NOT.chk_pm(mode)) THEN 602 IF (.NOT.chk_pm(mode)) THEN 615 603 ret = .false. ; RETURN 616 604 ENDIF 617 605 zmode = oct_2_dec(mode) 618 606 ENDIF 619 zperm = .false. ; IF (PRESENT(permissive)) zperm = permissive 607 zperm = .false. ; IF (PRESENT(permissive)) zperm = permissive 620 608 IF (zperm) THEN 621 609 ret = INT(mkdirp_c(cstring(ADJUSTL(path)),INT(zmode,kind=C_INT))) == 0 … … 630 618 !! Remove directory 631 619 !! 632 !! By default, the function removes an __empty__ directory. If __forced__ is given and set 620 !! By default, the function removes an __empty__ directory. If __forced__ is given and set 633 621 !! to .true. then the function recursively deletes the directory and __ALL__ its content. 634 622 CHARACTER(len=*), INTENT(in) :: path … … 638 626 LOGICAL :: ret 639 627 !! True on success, false otherwise. 640 LOGICAL :: zforce 628 LOGICAL :: zforce 641 629 IF (LEN_TRIM(path) == 0) THEN 642 ret = .false. 630 ret = .false. 643 631 ELSE 644 632 zforce = .false. ; IF (PRESENT(forced)) zforce = forced … … 655 643 !! Get some informations about a path 656 644 !! 657 !! The method retrieves various informations about the input path using fstat C function. 645 !! The method retrieves various informations about the input path using fstat C function. 658 646 !! The type of path as returned in __type__ argument is can take the following values: 659 647 !! … … 666 654 INTEGER, INTENT(out), OPTIONAL :: type, & !! Optional type of path (see function documentation). 667 655 perm, & !! Optional permission of the path 668 nlnks, & !! Optional number of links to the path 656 nlnks, & !! Optional number of links to the path 669 657 uid, & !! Optional user id 670 658 gid !! Optional group id … … 674 662 ctime !! Optional creation time 675 663 LOGICAL :: ret !! True on success, false otherwise. 676 INTEGER :: ty,pe,ln,ud,gd 664 INTEGER :: ty,pe,ln,ud,gd 677 665 INTEGER(kind=8) :: fs 678 666 CHARACTER(len=:), ALLOCATABLE :: at,mt,ct … … 691 679 ret = INT(fstat_c(cstring(ADJUSTL(path)),p,l,t,u,g,f,ta,tm,tc)) == 0 692 680 IF (ret) THEN 693 pe=INT(p) ; ln=INT(l) ; ty=INT(t) ; ud=INT(u) ; gd=INT(g) 694 fs=INT(f,kind=8) 681 pe=INT(p) ; ln=INT(l) ; ty=INT(t) ; ud=INT(u) ; gd=INT(g) 682 fs=INT(f,kind=8) 695 683 at = fstring(ta) 696 684 mt = fstring(tm) 697 685 ct = fstring(tc) 698 686 ENDIF 699 IF (PRESENT(type)) type = ty 687 IF (PRESENT(type)) type = ty 700 688 IF (PRESENT(perm)) perm = pe 701 689 IF (PRESENT(nlnks)) nlnks = ln … … 713 701 !! Check if a path is a directory 714 702 !! 715 !! The method is just a wrapper of [[fsystem(module):fs_stat(function)]] to get only specific 703 !! The method is just a wrapper of [[fsystem(module):fs_stat(function)]] to get only specific 716 704 !! information about __path__ type. 717 705 CHARACTER(len=*), INTENT(in) :: path !! The path to check 718 LOGICAL :: ret !! .true. if the path is a directory, .false. otherwise. 706 LOGICAL :: ret !! .true. if the path is a directory, .false. otherwise. 719 707 INTEGER :: ty 720 708 ret = fs_stat(path,type=ty) 721 ret = ret.AND.(ty==2.or.ty==3) 709 ret = ret.AND.(ty==2.or.ty==3) 722 710 RETURN 723 711 END FUNCTION fs_isdir 724 712 725 713 FUNCTION fs_isfile(path) RESULT (ret) 726 !! Check if a path is a file 727 !! 728 !! The method is just a wrapper of [[fsystem(module):fs_stat(function)]] to get only specific 714 !! Check if a path is a file 715 !! 716 !! The method is just a wrapper of [[fsystem(module):fs_stat(function)]] to get only specific 729 717 !! information about __path__ type. 730 718 CHARACTER(len=*), INTENT(in) :: path !! The path to check 731 LOGICAL :: ret !! .true. if the path is a file, .false. otherwise. 719 LOGICAL :: ret !! .true. if the path is a file, .false. otherwise. 732 720 INTEGER :: ty 733 721 ret=fs_stat(path,type=ty) … … 737 725 738 726 FUNCTION fs_islink(path) RESULT (ret) 739 !! Check if a path is a link 740 !! 741 !! The method is just a wrapper of [[fsystem(module):fs_stat(function)]] to get only specific 727 !! Check if a path is a link 728 !! 729 !! The method is just a wrapper of [[fsystem(module):fs_stat(function)]] to get only specific 742 730 !! information about __path__ type. 743 731 CHARACTER(len=*), INTENT(in) :: path !! The path to check 744 LOGICAL :: ret !! .true. if the path is a link, .false. otherwise. 745 INTEGER :: ty 732 LOGICAL :: ret !! .true. if the path is a link, .false. otherwise. 733 INTEGER :: ty 746 734 ret=fs_stat(path,type=ty) 747 735 ret = ret.and.(ty==1.or.ty==3) … … 759 747 !! - 1 : Checks for EXECUTE permission 760 748 !! - 2 : Checks for WRITE permission 761 !! - 4 : Checks for READ permission 749 !! - 4 : Checks for READ permission 762 750 CHARACTER(len=*), INTENT(in) :: path !! Path to check 763 751 INTEGER, INTENT(in), OPTIONAL :: permission !! Optional permission to check … … 765 753 INTEGER(kind=C_INT) :: zp 766 754 IF (LEN_TRIM(path) == 0) THEN 767 ret = .false. 755 ret = .false. 768 756 ELSE 769 757 zp = 0 ; IF (PRESENT(permission)) zp = INT(permission,kind=C_INT) … … 777 765 !! Split given path into base,extension 778 766 !! 779 !! The __base__ of a path is conventionnally defined as all characters before the last dot of the path. 780 !! The extension (__ext__) of the path gathers consequently all characters from the last dot to the end 767 !! The __base__ of a path is conventionnally defined as all characters before the last dot of the path. 768 !! The extension (__ext__) of the path gathers consequently all characters from the last dot to the end 781 769 !! of the string. 782 770 !! @note 783 !! If the basename of the path begins by a dot then the path is assumed to be an hidden file (directory). 771 !! If the basename of the path begins by a dot then the path is assumed to be an hidden file (directory). 784 772 !! __ext__ will then be empty. 785 CHARACTER(len=*), INTENT(in) :: path !! Path to split 773 CHARACTER(len=*), INTENT(in) :: path !! Path to split 786 774 CHARACTER(len=:), INTENT(out), ALLOCATABLE :: base, & !! Output base of the path 787 775 ext !! Output extension of the path 788 LOGICAL, INTENT(in), OPTIONAL :: absolute !! .true. to return absolute path 789 LOGICAL :: ret !! .true. on success, .false. otherwise. 776 LOGICAL, INTENT(in), OPTIONAL :: absolute !! .true. to return absolute path 777 LOGICAL :: ret !! .true. on success, .false. otherwise. 790 778 LOGICAL :: zabs 791 779 INTEGER :: p 792 780 CHARACTER(len=:), ALLOCATABLE :: d,b,apath 793 base = "" ; ext = "" 781 base = "" ; ext = "" 794 782 ret = .false. 795 783 IF (LEN_TRIM(path) == 0) THEN … … 800 788 IF (zabs) THEN 801 789 apath = fs_realpath(path) ; IF (LEN_TRIM(apath) == 0) RETURN 802 ENDIF 790 ENDIF 803 791 d = fs_dirname(apath) ; IF (LEN_TRIM(d) == 0) RETURN 804 792 b = fs_basename(apath) ; IF (LEN_TRIM(b) == 0) RETURN … … 806 794 ! If dot is set as first char of basename : it's an hidden file 807 795 IF (p > 1) THEN 808 ext = b(p:) ; base = TRIM(d)//"/"//b(:p-1) 809 ELSE 810 base = TRIM(apath) 796 ext = b(p:) ; base = TRIM(d)//"/"//b(:p-1) 797 ELSE 798 base = TRIM(apath) 811 799 ENDIF 812 800 ret = .true. … … 815 803 816 804 FUNCTION fs_create(path, mode, type, permissive) RESULT(ret) 817 !! Create a directory/file 805 !! Create a directory/file 818 806 !! 819 807 !! The method creates the file/directory pointed by given __path__. … … 827 815 !! Unless __permissive__ is set to .true., the method will fails if intermediate 828 816 !! directories in the path do not exist. 829 CHARACTER(len=*), INTENT(in) :: path !! Path to create 817 CHARACTER(len=*), INTENT(in) :: path !! Path to create 830 818 INTEGER, INTENT(in), OPTIONAL :: mode !! Optional octal permisions to set 831 819 CHARACTER(len=1), INTENT(in), OPTIONAL :: type !! Optional type of path to create … … 833 821 LOGICAL :: ret !! True on success, false otherwise. 834 822 INTEGER :: zmd,zt,zp 835 CHARACTER(len=:), ALLOCATABLE :: b,e 823 CHARACTER(len=:), ALLOCATABLE :: b,e 836 824 ret = .false. 837 825 ! Checking for existence … … 839 827 RETURN 840 828 ELSE IF (fs_access(path)) THEN 841 RETURN 829 RETURN 842 830 ENDIF 843 831 ! Set type of path 844 832 IF (PRESENT(type)) THEN 845 833 IF (.NOT.(type(1:1)=="f".OR.type(1:1)=="d")) THEN 846 RETURN 834 RETURN 847 835 ELSE 848 836 zt=0 ; IF (type(1:1)=="f") zt = 1 … … 854 842 ! set permissions according to type 855 843 IF (zt == 0) THEN 856 zmd = oct_2_dec(777)-get_umask() 844 zmd = oct_2_dec(777)-get_umask() 857 845 ELSE 858 846 zmd = oct_2_dec(666) -get_umask() … … 874 862 FUNCTION fs_get_parent(path, n) RESULT(opath) 875 863 !! Get the nth parent of the given path 876 !! 877 !! The method first resolves the given path using [[fsystem(module):fs_realpath(function)]] 864 !! 865 !! The method first resolves the given path using [[fsystem(module):fs_realpath(function)]] 878 866 !! to get an absolute path. 879 !! @note 867 !! @note 880 868 !! If __n__ is greater than the maximum parent level of the path, "/" is returned. 881 869 CHARACTER(len=*), INTENT(in) :: path 882 870 !! Input path 883 INTEGER, INTENT(in), OPTIONAL :: n 871 INTEGER, INTENT(in), OPTIONAL :: n 884 872 !! The level of the parent to get 885 873 CHARACTER(len=:), ALLOCATABLE :: opath 886 !! The nth parent of the given path, or an empty string if the parent can not be computed 874 !! The nth parent of the given path, or an empty string if the parent can not be computed 887 875 CHARACTER(len=:), ALLOCATABLE :: zp 888 876 INTEGER :: i,mx,zl,mzl 889 opath = "" 877 opath = "" 890 878 zl = 1 ; IF (PRESENT(n)) zl = MAX(n,1) 891 879 IF (LEN_TRIM(path) == 0) THEN … … 900 888 mzl = 1 ; DO i=1,mx ; IF(zp(i:i) == '/') mzl=mzl+1 ; ENDDO 901 889 i=0 902 DO 890 DO 903 891 mx = INDEX(zp(1:mx),'/',.true.) ; i=i+1 904 IF (mx==0.OR.i>=zl.OR.i>=mzl) EXIT 892 IF (mx==0.OR.i>=zl.OR.i>=mzl) EXIT 905 893 mx = mx - 1 906 894 ENDDO 907 895 IF (mx >= 1) THEN 908 896 opath = zp(1:MAX(1,mx-1)) 909 ELSE 910 opath = "/" 897 ELSE 898 opath = "/" 911 899 ENDIF 912 900 RETURN … … 929 917 SUBROUTINE fs_usleep(usec) 930 918 !! Sleep for a given number of microseconds 931 !! @note 932 !! Currently if C usleep function failed, the system... does not sleep ! 919 !! @note 920 !! Currently if C usleep function failed, the system... does not sleep ! 933 921 INTEGER, INTENT(in) :: usec !! The number of microseconds to sleep for 934 INTEGER(kind=C_INT) :: ret 922 INTEGER(kind=C_INT) :: ret 935 923 ! usleep expects useconds_t (unsigned int) which is given here as a 4-bytes int 936 924 ret = usleep_c(INT(usec,kind=C_INT)) … … 979 967 LOGICAL :: zpeak 980 968 CHARACTER(len=2) :: zunits 981 INTEGER(kind=8) :: ztot,zava,zfre 969 INTEGER(kind=8) :: ztot,zava,zfre 982 970 983 971 zunits = 'B ' ; IF (PRESENT(units)) zunits = units 984 972 IF (zunits /= 'B' .AND. zunits /= 'KB' .AND. zunits /= 'MB' .AND. zunits /= 'GB') zunits = 'B ' 985 973 ret = INT(getSystemMemory_c(ztot,zava,zfre),kind=4) == 0 986 ztot = ztot * 1024 ; zava = zava * 1024 ; zfre = zfre * 1024 974 ztot = ztot * 1024 ; zava = zava * 1024 ; zfre = zfre * 1024 987 975 988 976 IF (PRESENT(total)) total = ztot … … 1014 1002 FUNCTION oct_2_dec(octal) RESULT(res) 1015 1003 !> Octal to decimal conversion 1016 !! 1004 !! 1017 1005 !! The method converts the octal number ranging from 0 to 777 in the decimal system. 1018 1006 !! @attention … … 1029 1017 ENDDO 1030 1018 res=d 1031 RETURN 1019 RETURN 1032 1020 END FUNCTION oct_2_dec 1033 1021 … … 1059 1047 !! Get octal number of string representation's permission 1060 1048 CHARACTER(len=3),INTENT(in) :: str !! The permission to convert 1061 INTEGER :: oct !! Octal value of the string permission on succes, -1 otherwise. 1049 INTEGER :: oct !! Octal value of the string permission on succes, -1 otherwise. 1062 1050 oct = -1 1063 1051 IF (LEN_TRIM(str) /= 3) RETURN 1064 1052 SELECT CASE(str) 1065 CASE("---") ; oct = 0 1053 CASE("---") ; oct = 0 1066 1054 CASE("--x") ; oct = 1 1067 1055 CASE("-w-") ; oct = 2 … … 1071 1059 CASE("rw-") ; oct = 6 1072 1060 CASE("rwx") ; oct = 7 1073 CASE DEFAULT 1061 CASE DEFAULT 1074 1062 oct = -1 ; RETURN 1075 END SELECT 1063 END SELECT 1076 1064 RETURN 1077 1065 END FUNCTION sp_2_op … … 1090 1078 CASE(6) ; str="rw-" 1091 1079 CASE(7) ; str="rwx" 1092 CASE DEFAULT 1080 CASE DEFAULT 1093 1081 str='ukn' ; RETURN 1094 END SELECT 1082 END SELECT 1095 1083 RETURN 1096 1084 END FUNCTION op_2_sp … … 1098 1086 FUNCTION str_perm(oct_perm) RESULT(ret) 1099 1087 !! Get the string representation of the given permission mask 1100 INTEGER, INTENT(in) :: oct_perm !! The octal representation of the permission 1088 INTEGER, INTENT(in) :: oct_perm !! The octal representation of the permission 1101 1089 CHARACTER(len=9) :: ret !! String representation of the octal number on succes, 'ukn' otherwise 1102 1090 INTEGER :: u,g,o 1103 IF (.NOT.chk_pm(oct_perm)) THEN 1091 IF (.NOT.chk_pm(oct_perm)) THEN 1104 1092 ret = "ukn" ; RETURN 1105 1093 ENDIF … … 1169 1157 1170 1158 SUBROUTINE chrono_start(this) 1171 !! Start the chrono. 1159 !! Start the chrono. 1172 1160 !! 1173 1161 !! @note … … 1180 1168 ENDIF 1181 1169 this%on_run = .true. 1182 END SUBROUTINE chrono_start 1170 END SUBROUTINE chrono_start 1183 1171 1184 1172 SUBROUTINE chrono_stop(this) … … 1197 1185 END SUBROUTINE chrono_reset 1198 1186 1199 SUBROUTINE chrono_get(this,cpu,clock,units) 1187 SUBROUTINE chrono_get(this,cpu,clock,units) 1200 1188 !! Get elapsed time since last call of start or reset methods. 1201 !! 1189 !! 1202 1190 !! The method computes the time elapsed in two ways : 1203 1191 !! 1204 1192 !! - If the [[fsystem(module):chrono(type)]] is not running, the method retruns 0. 1205 !! - Otherwise, elapsed time since the last call of 1193 !! - Otherwise, elapsed time since the last call of 1206 1194 !! [[chrono(type):start(bound)]] (or [[chrono(type):reset(bound)]]). 1207 1195 OBJECT(chrono), INTENT(in) :: this … … 1209 1197 REAL(kind=8), INTENT(out), OPTIONAL :: cpu 1210 1198 !! Elapsed cpu time in seconds by default (see units argument). 1211 REAL(kind=8), INTENT(out), OPTIONAL :: clock 1199 REAL(kind=8), INTENT(out), OPTIONAL :: clock 1212 1200 !! Elapsed system clock time in seconds by default (see units argument). 1213 1201 CHARACTER(len=2), INTENT(in), OPTIONAL :: units 1214 1202 !! A two characters wide string with the units to convert in. Units should 1215 !! be one of the following : 'ms', 's' (default), 'm', 'h' or 'd'. 1203 !! be one of the following : 'ms', 's' (default), 'm', 'h' or 'd'. 1216 1204 CHARACTER(len=2) :: zu 1217 1205 REAL(kind=8) :: cu, fact … … 1223 1211 ENDIF 1224 1212 IF (PRESENT(clock)) THEN 1225 CALL SYSTEM_CLOCK(ck,r,m) 1213 CALL SYSTEM_CLOCK(ck,r,m) 1226 1214 clock = c2t(ck,this%clock_start,r,m) 1227 1215 ENDIF … … 1231 1219 ENDIF 1232 1220 fact = 1d0 1233 zu = 's' 1221 zu = 's' 1234 1222 IF (PRESENT(units)) THEN 1235 1223 zu = units … … 1242 1230 END SELECT 1243 1231 ENDIF 1244 IF (PRESENT(cpu)) cpu = cpu / fact 1232 IF (PRESENT(cpu)) cpu = cpu / fact 1245 1233 IF (PRESENT(clock)) clock = clock / fact 1246 1234 END SUBROUTINE chrono_get … … 1249 1237 !! Get the real-time between two clock counts from system_clock. 1250 1238 INTEGER(kind=8), INTENT(in) :: e !! Final clock count 1251 INTEGER(kind=8), INTENT(in) :: i !! Initial clock count 1239 INTEGER(kind=8), INTENT(in) :: i !! Initial clock count 1252 1240 INTEGER(kind=8), INTENT(in) :: r !! Clock count rate 1253 1241 INTEGER(kind=8), INTENT(in) :: m !! Maximum Clock count value
Note: See TracChangeset
for help on using the changeset viewer.