Changeset 2 for strings_mod.F90
- Timestamp:
- Dec 8, 2021, 9:25:11 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
strings_mod.F90
r1 r2 4 4 5 5 PRIVATE 6 PUBLIC :: m odname, init_printout, msg, fmsg, get_in, lunout, prt_level6 PUBLIC :: maxlen, init_printout, msg, fmsg, get_in, lunout, prt_level 7 7 PUBLIC :: strLower, strHead, strStack, strClean, strIdx, strCount, strReplace 8 8 PUBLIC :: strUpper, strTail, strStackm, strReduce, strFind, strParse, cat, find … … 13 13 14 14 INTERFACE get_in; MODULE PROCEDURE getin_s, getin_i, getin_r, getin_l; END INTERFACE get_in 15 INTERFACE msg; MODULE PROCEDURE msg_1, msg_l1,msg_m; END INTERFACE msg16 INTERFACE fmsg; MODULE PROCEDURE fmsg_1, fmsg_l1,fmsg_m; END INTERFACE fmsg15 INTERFACE msg; MODULE PROCEDURE msg_1, msg_m; END INTERFACE msg 16 INTERFACE fmsg; MODULE PROCEDURE fmsg_1, fmsg_m; END INTERFACE fmsg 17 17 INTERFACE strHead; MODULE PROCEDURE strHead_1, strHead_m; END INTERFACE strHead 18 18 INTERFACE strTail; MODULE PROCEDURE strTail_1, strTail_m; END INTERFACE strTail … … 32 32 INTERFACE testFile; MODULE PROCEDURE testFile_1, testFile_m; END INTERFACE testFile 33 33 34 CHARACTER(LEN=256), SAVE :: modname = '' !--- Current subroutine name 35 INTEGER, SAVE :: lunout = 6 !--- Printing unit (default: 6, ie. on screen) 36 INTEGER, SAVE :: prt_level = 1 !--- Printing level (default: 1, ie. print all) 37 34 INTEGER, PARAMETER :: maxlen = 256 !--- Standard maximum length for strings 35 INTEGER, SAVE :: lunout = 6 !--- Printing unit (default: 6, ie. on screen) 36 INTEGER, SAVE :: prt_level = 1 !--- Printing level (default: 1, ie. print all) 38 37 39 38 CONTAINS … … 57 56 !============================================================================================================================== 58 57 SUBROUTINE getin_s(nam, val, def) 59 USE ioipsl_getin _mod, ONLY: getin58 USE ioipsl_getincom, ONLY: getin 60 59 CHARACTER(LEN=*), INTENT(IN) :: nam 61 60 CHARACTER(LEN=*), INTENT(INOUT) :: val … … 66 65 !============================================================================================================================== 67 66 SUBROUTINE getin_i(nam, val, def) 68 USE ioipsl_getin _mod, ONLY: getin67 USE ioipsl_getincom, ONLY: getin 69 68 CHARACTER(LEN=*), INTENT(IN) :: nam 70 69 INTEGER, INTENT(INOUT) :: val … … 75 74 !============================================================================================================================== 76 75 SUBROUTINE getin_r(nam, val, def) 77 USE ioipsl_getin _mod, ONLY: getin76 USE ioipsl_getincom, ONLY: getin 78 77 CHARACTER(LEN=*), INTENT(IN) :: nam 79 78 REAL, INTENT(INOUT) :: val … … 84 83 !============================================================================================================================== 85 84 SUBROUTINE getin_l(nam, val, def) 86 USE ioipsl_getin _mod, ONLY: getin85 USE ioipsl_getincom, ONLY: getin 87 86 CHARACTER(LEN=*), INTENT(IN) :: nam 88 87 LOGICAL, INTENT(INOUT) :: val … … 97 96 !=== Display one or several messages, one each line, starting with the current routine name "modname". 98 97 !============================================================================================================================== 99 SUBROUTINE msg_1(str, unit) 100 CHARACTER(LEN=*), INTENT(IN) :: str 101 INTEGER, OPTIONAL, INTENT(IN) :: unit 98 SUBROUTINE msg_1(str, modname, ll, unit) 99 !--- Display a simple message "str". Optional parameters: 100 ! * "modname": module name, displayed in front of the message (with ": " separator) if present. 101 ! * "ll": message trigger ; message is displayed only if ll==.TRUE. 102 ! * "unit": write unit (by default: "lunout") 103 CHARACTER(LEN=*), INTENT(IN) :: str 104 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: modname 105 LOGICAL, OPTIONAL, INTENT(IN) :: ll 106 INTEGER, OPTIONAL, INTENT(IN) :: unit 102 107 INTEGER :: unt 108 IF(PRESENT(ll)) THEN; IF(ll) RETURN; END IF 103 109 unt = lunout; IF(PRESENT(unit)) unt = unit 104 WRITE(unt,'(a)') TRIM(modname)//': '//str 110 IF(PRESENT(modname)) THEN 111 WRITE(unt,'(a)') TRIM(modname)//': '//str !--- Routine name provided 112 ELSE 113 WRITE(unt,'(a)') str !--- Simple message 114 END IF 105 115 END SUBROUTINE msg_1 106 116 !============================================================================================================================== 107 SUBROUTINE msg_l1(ll, str, unit) 108 LOGICAL, INTENT(IN) :: ll 109 CHARACTER(LEN=*), INTENT(IN) :: str 110 INTEGER, OPTIONAL, INTENT(IN) :: unit 111 INTEGER :: unt 112 IF(.NOT.ll) RETURN 113 unt = lunout; IF(PRESENT(unit)) unt = unit 114 WRITE(unt,'(a)') TRIM(modname)//': '//str 115 END SUBROUTINE msg_l1 116 !============================================================================================================================== 117 SUBROUTINE msg_m(str, unit, nmax) 118 CHARACTER(LEN=*), INTENT(IN) :: str(:) 119 INTEGER, OPTIONAL, INTENT(IN) :: unit 120 INTEGER, OPTIONAL, INTENT(IN) :: nmax 121 CHARACTER(LEN=256), ALLOCATABLE :: s(:) 117 SUBROUTINE msg_m(str, modname, ll, unit, nmax) 118 !--- Same as msg_1 with multiple strings that are stacked (separator: coma) on up to "nmax" full lines. 119 CHARACTER(LEN=*), INTENT(IN) :: str(:) 120 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: modname 121 LOGICAL, OPTIONAL, INTENT(IN) :: ll 122 INTEGER, OPTIONAL, INTENT(IN) :: unit 123 INTEGER, OPTIONAL, INTENT(IN) :: nmax 124 CHARACTER(LEN=maxlen), ALLOCATABLE :: s(:) 122 125 INTEGER :: unt, nmx, k 126 LOGICAL :: lerr 127 lerr = .TRUE.; IF(PRESENT(ll)) lerr = ll 123 128 unt = lunout ; IF(PRESENT(unit)) unt = unit 124 129 nmx = 128; IF(PRESENT(nmax)) nmx = nmax 125 130 s = strStackm(str, ', ', nmx) 126 DO k=1,SIZE(s); WRITE(unt,'(a)') TRIM(modname)//': '//TRIM(s(k)); END DO 131 IF(PRESENT(modname)) THEN 132 DO k=1,SIZE(s); CALL msg_1(s(k), modname, lerr, unt); END DO 133 ELSE 134 DO k=1,SIZE(s); CALL msg_1(s(k), ll=lerr, unit=unt); END DO 135 END IF 127 136 END SUBROUTINE msg_m 128 137 !============================================================================================================================== 129 LOGICAL FUNCTION fmsg_1(str, unit) RESULT(lerr) 130 CHARACTER(LEN=*), INTENT(IN) :: str 131 INTEGER, OPTIONAL, INTENT(IN) :: unit 138 LOGICAL FUNCTION fmsg_1(str, modname, ll, unit) RESULT(lerr) 139 CHARACTER(LEN=*), INTENT(IN) :: str 140 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: modname 141 LOGICAL, OPTIONAL, INTENT(IN) :: ll 142 INTEGER, OPTIONAL, INTENT(IN) :: unit 132 143 INTEGER :: unt 133 lerr = .TRUE. 144 lerr = .TRUE.; IF(PRESENT(ll)) lerr = ll 134 145 unt = lunout ; IF(PRESENT(unit)) unt = unit 135 CALL msg_1(str, unt) 146 IF(PRESENT(modname)) THEN 147 CALL msg_1(str, modname, lerr, unt) 148 ELSE 149 CALL msg_1(str, ll=lerr, unit=unt) 150 END IF 136 151 END FUNCTION fmsg_1 137 152 !============================================================================================================================== 138 LOGICAL FUNCTION fmsg_l1(li, str, unit) RESULT(lerr) 139 LOGICAL, INTENT(IN) :: li 140 CHARACTER(LEN=*), INTENT(IN) :: str 141 INTEGER, OPTIONAL, INTENT(IN) :: unit 142 INTEGER :: unt 143 lerr = li; IF(.NOT.lerr) RETURN 144 unt = lunout ; IF(PRESENT(unit)) unt = unit 145 CALL msg_l1(lerr, str, unt) 146 END FUNCTION fmsg_l1 147 !============================================================================================================================== 148 LOGICAL FUNCTION fmsg_m(str, unit, nmax) RESULT(lerr) 149 CHARACTER(LEN=*), INTENT(IN) :: str(:) 150 INTEGER, OPTIONAL, INTENT(IN) :: unit 151 INTEGER, OPTIONAL, INTENT(IN) :: nmax 153 LOGICAL FUNCTION fmsg_m(str, modname, ll, unit, nmax) RESULT(lerr) 154 CHARACTER(LEN=*), INTENT(IN) :: str(:) 155 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: modname 156 LOGICAL, OPTIONAL, INTENT(IN) :: ll 157 INTEGER, OPTIONAL, INTENT(IN) :: unit 158 INTEGER, OPTIONAL, INTENT(IN) :: nmax 152 159 INTEGER :: unt, nmx 153 lerr = .TRUE. 160 lerr = .TRUE.; IF(PRESENT(ll)) lerr = ll 154 161 unt = lunout ; IF(PRESENT(unit)) unt = unit 155 162 nmx = 128; IF(PRESENT(nmax)) nmx = nmax 156 CALL msg_m(str, unt, nmx) 163 IF(PRESENT(modname)) THEN 164 CALL msg_m(str, modname, lerr, unt, nmx) 165 ELSE 166 CALL msg_m(str, ll=lerr, unit=unt, nmax=nmx) 167 END IF 157 168 END FUNCTION fmsg_m 158 169 !============================================================================================================================== … … 162 173 !=== Lower/upper case conversion function. ==================================================================================== 163 174 !============================================================================================================================== 164 ELEMENTAL CHARACTER(LEN= 256) FUNCTION strLower(str) RESULT(out)175 ELEMENTAL CHARACTER(LEN=maxlen) FUNCTION strLower(str) RESULT(out) 165 176 CHARACTER(LEN=*), INTENT(IN) :: str 166 177 INTEGER :: k … … 171 182 END FUNCTION strLower 172 183 !============================================================================================================================== 173 ELEMENTAL CHARACTER(LEN= 256) FUNCTION strUpper(str) RESULT(out)184 ELEMENTAL CHARACTER(LEN=maxlen) FUNCTION strUpper(str) RESULT(out) 174 185 CHARACTER(LEN=*), INTENT(IN) :: str 175 186 INTEGER :: k … … 188 199 !=== * strHead(..,.TRUE.) = 'a_b' ${str%$sep*} ================ 189 200 !============================================================================================================================== 190 CHARACTER(LEN= 256) FUNCTION strHead_1(str,sep,lFirst) RESULT(out)201 CHARACTER(LEN=maxlen) FUNCTION strHead_1(str,sep,lFirst) RESULT(out) 191 202 CHARACTER(LEN=*), INTENT(IN) :: str 192 203 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: sep … … 203 214 !============================================================================================================================== 204 215 FUNCTION strHead_m(str,sep,lFirst) RESULT(out) 205 CHARACTER(LEN= 256),ALLOCATABLE :: out(:)216 CHARACTER(LEN=maxlen), ALLOCATABLE :: out(:) 206 217 CHARACTER(LEN=*), INTENT(IN) :: str(:) 207 218 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: sep … … 222 233 !=== * strHead(..,.TRUE.) = 'c' ${str##*$sep} ================ 223 234 !============================================================================================================================== 224 CHARACTER(LEN= 256) FUNCTION strTail_1(str,sep,lFirst) RESULT(out)235 CHARACTER(LEN=maxlen) FUNCTION strTail_1(str,sep,lFirst) RESULT(out) 225 236 CHARACTER(LEN=*), INTENT(IN) :: str 226 237 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: sep … … 237 248 !============================================================================================================================== 238 249 FUNCTION strTail_m(str,sep,lFirst) RESULT(out) 239 CHARACTER(LEN= 256),ALLOCATABLE :: out(:)250 CHARACTER(LEN=maxlen), ALLOCATABLE :: out(:) 240 251 CHARACTER(LEN=*), INTENT(IN) :: str(:) 241 252 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: sep … … 270 281 !============================================================================================================================== 271 282 FUNCTION strStackm(str, sep, nmax) RESULT(out) 272 CHARACTER(LEN= 256),ALLOCATABLE :: out(:)283 CHARACTER(LEN=maxlen), ALLOCATABLE :: out(:) 273 284 CHARACTER(LEN=*), INTENT(IN) :: str(:) 274 285 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: sep 275 286 INTEGER, OPTIONAL, INTENT(IN) :: nmax 276 CHARACTER(LEN= 256), ALLOCATABLE :: t(:)277 CHARACTER(LEN= 256) :: sp287 CHARACTER(LEN=maxlen), ALLOCATABLE :: t(:) 288 CHARACTER(LEN=maxlen) :: sp 278 289 INTEGER :: is, ns, no, mx, n 279 290 IF(SIZE(str) == 0) THEN; out = ['']; RETURN; END IF … … 328 339 CHARACTER(LEN=*), ALLOCATABLE, INTENT(INOUT) :: str1(:) 329 340 INTEGER, OPTIONAL, INTENT(OUT) :: nb 330 CHARACTER(LEN= 256), ALLOCATABLE :: s1(:)341 CHARACTER(LEN=maxlen), ALLOCATABLE :: s1(:) 331 342 INTEGER :: k, n, n1 332 343 IF(PRESENT(nb)) nb = 0 … … 342 353 CHARACTER(LEN=*), ALLOCATABLE, INTENT(INOUT) :: str1(:) 343 354 CHARACTER(LEN=*), INTENT(IN) :: str2(:) 344 CHARACTER(LEN= 256), ALLOCATABLE :: s1(:), s2(:)355 CHARACTER(LEN=maxlen), ALLOCATABLE :: s1(:), s2(:) 345 356 INTEGER :: k 346 357 IF(SIZE(str2)==0) RETURN … … 432 443 LOGICAL, OPTIONAL, INTENT(IN) :: lSc !--- Care about nbs with front sign or in scient. notation 433 444 434 INTEGER :: idx0!--- Used to display an identified non-numeric string435 INTEGER, ALLOCATABLE :: ii(:)436 LOGICAL :: ll, ls437 CHARACTER(LEN= 256):: d445 INTEGER :: idx0 !--- Used to display an identified non-numeric string 446 INTEGER, ALLOCATABLE :: ii(:) 447 LOGICAL :: ll, ls 448 CHARACTER(LEN=maxlen) :: d 438 449 ! modname = 'strIdx' 439 450 lerr = .FALSE. … … 545 556 DO 546 557 lerr = strIdx_prv(r, delimiter, ib, ie, jd, ll) 547 IF(fmsg( lerr,'"'//TRIM(r(ib:ie-1))//'" is not numeric')) RETURN558 IF(fmsg('"'//TRIM(r(ib:ie-1))//'" is not numeric', ll=lerr)) RETURN 548 559 IF(jd == 0) EXIT 549 560 ib = ie + LEN(delimiter(jd)) … … 560 571 !============================================================================================================================== 561 572 LOGICAL FUNCTION strParse_1(rawList, delimiter, keys, lSc, vals, n) RESULT(lerr) 562 CHARACTER(LEN=*), INTENT(IN) :: rawList, delimiter563 CHARACTER(LEN= 256), ALLOCATABLE, INTENT(OUT) :: keys(:)564 LOGICAL, OPTIONAL, INTENT(IN) :: lSc !--- Take care about numbers in scientific notation565 CHARACTER(LEN= 256), ALLOCATABLE, OPTIONAL, INTENT(OUT) :: vals(:)566 INTEGER, OPTIONAL, INTENT(OUT) :: n573 CHARACTER(LEN=*), INTENT(IN) :: rawList, delimiter 574 CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: keys(:) 575 LOGICAL, OPTIONAL, INTENT(IN) :: lSc !--- Take care about numbers in scientific notation 576 CHARACTER(LEN=maxlen), ALLOCATABLE, OPTIONAL, INTENT(OUT) :: vals(:) 577 INTEGER, OPTIONAL, INTENT(OUT) :: n 567 578 LOGICAL :: ll 568 579 ! modname = 'strParse' … … 574 585 !============================================================================================================================== 575 586 LOGICAL FUNCTION strParse_m(rawList, delimiter, keys, lSc, vals, n, id) RESULT(lerr) 576 CHARACTER(LEN=*), INTENT(IN) :: rawList, delimiter(:)577 CHARACTER(LEN= 256), ALLOCATABLE, INTENT(OUT) :: keys(:) !--- Parsed keys vector578 LOGICAL, OPTIONAL, INTENT(IN) :: lSc !--- Take care about numbers in scientific notation579 CHARACTER(LEN= 256), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: vals(:) !--- Values for <name>=<value> keys580 INTEGER, OPTIONAL, INTENT(OUT) :: n !--- Length of the parsed vector581 INTEGER, OPTIONAL, ALLOCATABLE, INTENT(OUT) :: id(:) !--- Indexes of the separators in "delimiter(:)" vector587 CHARACTER(LEN=*), INTENT(IN) :: rawList, delimiter(:) 588 CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: keys(:) !--- Parsed keys vector 589 LOGICAL, OPTIONAL, INTENT(IN) :: lSc !--- Take care about numbers in scientific notation 590 CHARACTER(LEN=maxlen), OPTIONAL, ALLOCATABLE, INTENT(OUT) :: vals(:) !--- Values for <name>=<value> keys 591 INTEGER, OPTIONAL, INTENT(OUT) :: n !--- Length of the parsed vector 592 INTEGER, OPTIONAL, ALLOCATABLE, INTENT(OUT) :: id(:) !--- Indexes of the separators in "delimiter(:)" vector 582 593 583 594 CHARACTER(LEN=1024) :: r … … 587 598 ! modname = 'strParse' 588 599 ll = .FALSE.; IF(PRESENT(lSc)) ll = lSc 589 IF(test(fmsg( strCount_1m(rawList, delimiter, nk, ll), "Couldn't parse list: non-numerical strings were found"),lerr)) RETURN600 IF(test(fmsg("Couldn't parse list: non-numerical strings were found", ll=strCount_1m(rawList, delimiter, nk, ll)),lerr)) RETURN 590 601 591 602 !--- FEW ALLOCATIONS … … 600 611 ib = 1 601 612 DO ik = 1, nk-1 602 IF(test(fmsg( strIdx_prv(r, delimiter, ib, ie, jd, ll),'Non-numeric values found'),lerr)) RETURN613 IF(test(fmsg('Non-numeric values found', ll=strIdx_prv(r, delimiter, ib, ie, jd, ll)),lerr)) RETURN 603 614 keys(ik) = r(ib:ie-1) 604 615 IF(PRESENT(vals)) CALL parseKeys(keys(ik), vals(ik)) !--- Parse a <key>=<val> pair … … 674 685 CHARACTER(LEN=*), TARGET, INTENT(IN) :: s0 675 686 CHARACTER(LEN=*), OPTIONAL, TARGET, INTENT(IN) :: s1, s2, s3, s4, s5, s6, s7, s8, s9 676 CHARACTER(LEN= 256), ALLOCATABLE :: out(:)677 CHARACTER(LEN= 256), POINTER :: s687 CHARACTER(LEN=maxlen), ALLOCATABLE :: out(:) 688 CHARACTER(LEN=maxlen), POINTER :: s 678 689 LOGICAL :: lv(10) 679 690 INTEGER :: iv … … 693 704 CHARACTER(LEN=*), TARGET, DIMENSION(:), INTENT(IN) :: s0 694 705 CHARACTER(LEN=*), OPTIONAL, TARGET, DIMENSION(:), INTENT(IN) :: s1, s2, s3, s4, s5, s6, s7, s8, s9 695 CHARACTER(LEN= 256), ALLOCATABLE :: out(:,:)696 CHARACTER(LEN= 256), POINTER :: s(:)706 CHARACTER(LEN=maxlen), ALLOCATABLE :: out(:,:) 707 CHARACTER(LEN=maxlen), POINTER :: s(:) 697 708 LOGICAL :: lv(10) 698 709 INTEGER :: nrow, ncol, iv, n … … 707 718 END SELECT 708 719 n = SIZE(s, DIM=1) 709 IF(n/=nrow) THEN; CALL msg( 'Can''t concatenate vectors of differing lengths',1); STOP; END IF720 IF(n/=nrow) THEN; CALL msg("Can't concatenate vectors of differing lengths"); STOP; END IF 710 721 out(:,iv) = s(:) 711 722 END DO … … 748 759 END SELECT 749 760 n = SIZE(i, DIM=1) 750 IF(n/=nrow) THEN; CALL msg( 'Can''t concatenate vectors of differing lengths',1); STOP; END IF761 IF(n/=nrow) THEN; CALL msg("Can't concatenate vectors of differing lengths"); STOP; END IF 751 762 out(:,iv) = i(:) 752 763 END DO … … 789 800 END SELECT 790 801 n = SIZE(r, DIM=1) 791 IF(n/=nrow) THEN; CALL msg( 'Can''t concatenate vectors of differing lengths',1); STOP; END IF802 IF(n/=nrow) THEN; CALL msg("Can't concatenate vectors of differing lengths"); STOP; END IF 792 803 out(:,iv) = r(:) 793 804 END DO … … 830 841 END SELECT 831 842 n = SIZE(d, DIM=1) 832 IF(n/=nrow) THEN; CALL msg( 'Can''t concatenate vectors of differing lengths',1); STOP; END IF843 IF(n/=nrow) THEN; CALL msg("Can't concatenate vectors of differing lengths"); STOP; END IF 833 844 out(:,iv) = d(:) 834 845 END DO … … 852 863 853 864 CHARACTER(LEN=2048) :: row 854 CHARACTER(LEN= 256) :: rFm, el855 CHARACTER(LEN= 256), ALLOCATABLE :: d(:,:)865 CHARACTER(LEN=maxlen) :: rFm, el 866 CHARACTER(LEN=maxlen), ALLOCATABLE :: d(:,:) 856 867 CHARACTER(LEN=1) :: s1, sp 857 868 INTEGER :: is, ii, ir, np, nrow, unt, ic … … 870 881 871 882 !--- CHECK ARGUMENTS COHERENCE 872 lerr = np /= SIZE(titles); IF(fmsg( lerr, 'string "pattern" length and titles list mismatch')) RETURN883 lerr = np /= SIZE(titles); IF(fmsg('string "pattern" length and titles list mismatch', ll=lerr)) RETURN 873 884 IF(ls) THEN; ns = SIZE(s, DIM=1); ncol = ncol + SIZE(s, DIM=2) 874 885 lerr = COUNT([(p(ic:ic)=='s', ic=1, np)]) /= SIZE(s, DIM=2) … … 880 891 lerr = COUNT([(p(ic:ic)=='r', ic=1, np)]) /= SIZE(r, DIM=2) 881 892 END IF 882 883 IF(fmsg(lerr, 'string "pattern" length and arguments number mismatch')) RETURN 884 lerr = ncol /= SIZE(titles); IF(fmsg(lerr, '"titles" length and arguments number mismatch')) RETURN 885 lerr = ls.AND.li.AND.ns/=ni; IF(fmsg(lerr, 'string and integer arguments lengths mismatch')) RETURN 886 lerr = ls.AND.lr.AND.ns/=nr; IF(fmsg(lerr, 'string and real arguments lengths mismatch')) RETURN 887 lerr = li.AND.lr.AND.ni/=nr; IF(fmsg(lerr, 'integer and real arguments lengths mismatch')) RETURN 893 IF(fmsg('string "pattern" length and arguments number mismatch', ll=lerr)) RETURN 894 lerr = ncol /= SIZE(titles); IF(fmsg('"titles" length and arguments number mismatch', ll=lerr)) RETURN 895 lerr = ls.AND.li.AND.ns/=ni; IF(fmsg('string and integer arguments lengths mismatch', ll=lerr)) RETURN 896 lerr = ls.AND.lr.AND.ns/=nr; IF(fmsg( 'string and real arguments lengths mismatch', ll=lerr)) RETURN 897 lerr = li.AND.lr.AND.ni/=nr; IF(fmsg( 'integer and real arguments lengths mismatch', ll=lerr)) RETURN 888 898 nrow = MAX(ns,ni,nr)+1 889 899 nmx = nrow; IF(PRESENT(nmax)) nmx = MIN(nmx,nmax+1) … … 912 922 END DO 913 923 nr = LEN_TRIM(row)-1 !--- Final separator removed 914 CALL msg(row(1:nr), un t)924 CALL msg(row(1:nr), unit=unt) 915 925 IF(ir /= 1) CYCLE !--- Titles are underlined 916 926 row=''; DO ic=1,ncol; row=TRIM(row)//REPEAT('-',n(ic))//'+'; END DO 917 CALL msg(row(1:LEN_TRIM(row)-1), un t)927 CALL msg(row(1:LEN_TRIM(row)-1), unit=unt) 918 928 END DO 919 929 … … 932 942 LOGICAL, OPTIONAL, INTENT(IN) :: llast !--- Last variable: no final ',' 933 943 934 CHARACTER(LEN= 256) :: rFm, el935 CHARACTER(LEN= 256), ALLOCATABLE :: d(:,:)936 CHARACTER(LEN=:), ALLOCATABLE :: sp, row944 CHARACTER(LEN=maxlen) :: rFm, el 945 CHARACTER(LEN=maxlen), ALLOCATABLE :: d(:,:) 946 CHARACTER(LEN=:), ALLOCATABLE :: sp, row 937 947 INTEGER :: is, ii, ir, nrow, ic 938 948 INTEGER :: ns, ni, nr, ncol, np … … 957 967 lerr = COUNT([(p(ic:ic)=='r', ic=1, np)]) /= SIZE(r, DIM=2) 958 968 END IF 959 IF(fmsg( lerr, 'string "pattern" length and arguments number mismatch')) RETURN960 lerr = ncol /= SIZE(titles); IF(fmsg( lerr, '"titles" length and arguments number mismatch')) RETURN961 lerr = ls.AND.li.AND.ns/=ni; IF(fmsg( lerr, 'string and integer arguments lengths mismatch')) RETURN962 lerr = ls.AND.lr.AND.ns/=nr; IF(fmsg( lerr, 'string and real arguments lengths mismatch')) RETURN963 lerr = li.AND.lr.AND.ni/=nr; IF(fmsg( lerr, 'integer and real arguments lengths mismatch')) RETURN969 IF(fmsg('string "pattern" length and arguments number mismatch', ll=lerr)) RETURN 970 lerr = ncol /= SIZE(titles); IF(fmsg('"titles" length and arguments number mismatch', ll=lerr)) RETURN 971 lerr = ls.AND.li.AND.ns/=ni; IF(fmsg('string and integer arguments lengths mismatch', ll=lerr)) RETURN 972 lerr = ls.AND.lr.AND.ns/=nr; IF(fmsg( 'string and real arguments lengths mismatch', ll=lerr)) RETURN 973 lerr = li.AND.lr.AND.ni/=nr; IF(fmsg( 'integer and real arguments lengths mismatch', ll=lerr)) RETURN 964 974 965 975 !--- Allocate the assembled quantities array … … 1012 1022 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: err_msg, nam(:), subn !--- Error message, variables and calling subroutine names 1013 1023 INTEGER, OPTIONAL, INTENT(IN) :: nmax, unit !--- Maximum number of lines to display (default: all) 1014 CHARACTER(LEN= 256),ALLOCATABLE :: ttl(:)1024 CHARACTER(LEN=maxlen), ALLOCATABLE :: ttl(:) 1015 1025 LOGICAL, ALLOCATABLE :: m(:) 1016 1026 INTEGER, ALLOCATABLE :: ki(:), kj(:) 1017 1027 INTEGER :: i, j, k, rk, rk1, ib, ie, itr, nm, unt, nmx, nv 1018 CHARACTER(LEN= 256):: mes, sub, fm='(f12.9)', v, s1019 CHARACTER(LEN= 256),ALLOCATABLE :: vnm(:)1028 CHARACTER(LEN=maxlen) :: mes, sub, fm='(f12.9)', v, s 1029 CHARACTER(LEN=maxlen), ALLOCATABLE :: vnm(:) 1020 1030 1021 1031 lerr = ANY(ll); IF(.NOT.lerr) RETURN !--- No outliers -> finished … … 1028 1038 1029 1039 rk = SIZE(n); nv = SIZE(vnm) 1030 IF(test(fmsg(nv /= 1 .AND. nv /= n(rk), 'In "'//TRIM(sub)//'": SIZE(nam) /= 1 or =last "n" element' , unt),lerr)) RETURN 1031 IF(test(fmsg(SIZE(a) /= SIZE(ll), 'In "'//TRIM(sub)//'": "ll" and "a" sizes mismatch' , unt),lerr)) RETURN 1032 IF(test(fmsg(SIZE(a) /= PRODUCT(n), 'In "'//TRIM(sub)//'": profile "n" does not match "a" and "ll"', unt),lerr)) RETURN 1033 1034 WRITE(unt,*)'Outliers detected by '//TRIM(sub)//': '//TRIM(mes) 1040 IF(test(fmsg('SIZE(nam) /= 1 and /= last "n" element', sub, nv /= 1 .AND. nv /= n(rk), unt),lerr)) RETURN 1041 IF(test(fmsg('ll" and "a" sizes mismatch', sub, SIZE(a) /= SIZE(ll), unt),lerr)) RETURN 1042 IF(test(fmsg('profile "n" does not match "a" and "ll', sub, SIZE(a) /= PRODUCT(n), unt),lerr)) RETURN 1043 CALL msg(mes, sub, unit=unt) 1035 1044 1036 1045 !--- SCALAR CASE: single value to display … … 1051 1060 IF(nv == 1) lerr = dispTable('sr', ttl, s=cat(PACK(nam,ll)), r=cat(PACK(a,ll)), rFmt=fm, nmax=nmax) 1052 1061 IF(nv /= 1) lerr = dispTable('ir', ['name ','value'], i=cat(PACK(ki,m)), r=cat(PACK(a,ll)), rFmt=fm, nmax=nmax) 1053 CALL msg( lerr,'In '//TRIM(sub)//": can't display outliers table", unt)1062 CALL msg("can't display outliers table", sub, lerr, unt) 1054 1063 RETURN 1055 1064 END IF … … 1068 1077 IF(rk==2) lerr = dispTable('ir', ttl, i=cat(PACK(ki,m)), r=cat(PACK(a(ib:ie),m)), rFmt=fm, nmax=nmax) 1069 1078 IF(rk==3) lerr = dispTable('iir', ttl, i=cat(PACK(ki,m),PACK(kj,m)), r=cat(PACK(a(ib:ie),m)), rFmt=fm, nmax=nmax) 1070 CALL msg( lerr,'In '//TRIM(sub)//": can't display outliers table", unt)1071 IF(lerr) THEN; CALL msg("Can't display outliers table"); RETURN; END IF1079 CALL msg("can't display outliers table", sub, lerr, unt) 1080 IF(lerr) RETURN 1072 1081 END DO 1073 1082 END FUNCTION dispOutliers_1 … … 1082 1091 INTEGER, OPTIONAL, INTENT(IN) :: nmax, unit !--- Maximum number of lines to display (default: all) 1083 1092 1084 CHARACTER(LEN= 256):: mes, sub, fm='(f12.9)', prf1085 CHARACTER(LEN= 256),ALLOCATABLE :: ttl(:), vnm(:)1093 CHARACTER(LEN=maxlen) :: mes, sub, fm='(f12.9)', prf 1094 CHARACTER(LEN=maxlen), ALLOCATABLE :: ttl(:), vnm(:) 1086 1095 LOGICAL, ALLOCATABLE :: m(:) 1087 1096 INTEGER, ALLOCATABLE :: ki(:), kj(:), kl(:) … … 1096 1105 nmx = SIZE(a); IF(PRESENT(nmax)) nmx = MIN(nmx,nmax)!--- Maximum number of lines to print 1097 1106 unt = lunout; IF(PRESENT(unit)) unt = unit !--- Unit to print messages 1098 lerr = SIZE(vnm) /= nv; IF(fmsg( lerr, 'In "dispOutlayers_2": SIZE(nam) /= SIZE(a,2)' ,unt)) RETURN1099 lerr = SIZE(a,1) /= SIZE(ll); IF(fmsg( lerr,'In '//TRIM(sub)//': "ll" and "a" sizes mismatch',unt)) RETURN1100 lerr = SIZE(a,1) /= PRODUCT(n); IF(fmsg( lerr,'In '//TRIM(sub)//': profile "n" does not match "a" and "ll"',unt)) RETURN1107 lerr = SIZE(vnm) /= nv; IF(fmsg('SIZE(nam) /= SIZE(a,2)', sub, lerr, unt)) RETURN 1108 lerr = SIZE(a,1) /= SIZE(ll); IF(fmsg('"ll" and "a" sizes mismatch', sub, lerr, unt)) RETURN 1109 lerr = SIZE(a,1) /= PRODUCT(n); IF(fmsg('profile "n" does not match "a" and "ll"', sub, lerr, unt)) RETURN 1101 1110 1102 1111 SELECT CASE(rk1) !--- Indices list … … 1116 1125 IF(rk == 3) lerr = dispTable(prf, ttl, i = cat(PACK(ki,ll),PACK(kj,ll),PACK(kl,ll)), & 1117 1126 r = val, rFmt=fm, nmax=nmax) 1118 CALL msg( lerr,'In '//TRIM(sub)//": can't display outliers table", unt)1127 CALL msg("can't display outliers table", sub, lerr, unt) 1119 1128 END FUNCTION dispOutliers_2 1120 1129 !============================================================================================================================== … … 1125 1134 !============================================================================================================================== 1126 1135 LOGICAL FUNCTION reduceExpr_1(str, val) RESULT(lerr) 1127 CHARACTER(LEN=*), INTENT(IN) :: str1128 CHARACTER(LEN= 256),INTENT(OUT) :: val1129 1130 CHARACTER(LEN= 256):: v1131 CHARACTER(LEN=1024) :: s, vv1136 CHARACTER(LEN=*), INTENT(IN) :: str 1137 CHARACTER(LEN=maxlen), INTENT(OUT) :: val 1138 1139 CHARACTER(LEN=maxlen) :: v 1140 CHARACTER(LEN=1024) :: s, vv 1132 1141 CHARACTER(LEN=1024), ALLOCATABLE :: vl(:) 1133 1142 INTEGER, ALLOCATABLE :: ip(:) … … 1141 1150 ll = strCount(s,')',nn) 1142 1151 lerr = nl /= nn 1143 IF(fmsg( lerr, 'Mismatching number of opening and closing parenthesis: '//TRIM(s))) RETURN1152 IF(fmsg('Mismatching number of opening and closing parenthesis: '//TRIM(s), ll=lerr)) RETURN 1144 1153 nl = 2*nl-1 1145 1154 … … 1175 1184 !============================================================================================================================== 1176 1185 LOGICAL FUNCTION reduceExpr_basic(str, val) RESULT(lerr) 1177 CHARACTER(LEN=*), INTENT(IN) :: str1178 CHARACTER(LEN=*), INTENT(OUT) :: val1179 DOUBLE PRECISION, ALLOCATABLE :: vl(:)1180 INTEGER, ALLOCATABLE :: id(:)1181 CHARACTER(LEN= 256), ALLOCATABLE :: ky(:)1182 CHARACTER(LEN=1), ALLOCATABLE :: op(:)1186 CHARACTER(LEN=*), INTENT(IN) :: str 1187 CHARACTER(LEN=*), INTENT(OUT) :: val 1188 DOUBLE PRECISION, ALLOCATABLE :: vl(:) 1189 INTEGER, ALLOCATABLE :: id(:) 1190 CHARACTER(LEN=maxlen), ALLOCATABLE :: ky(:) 1191 CHARACTER(LEN=1), ALLOCATABLE :: op(:) 1183 1192 1184 1193 CHARACTER(LEN=1024) :: s … … 1194 1203 vl = str2dble(ky) !--- Conversion to doubles 1195 1204 lerr = ANY(vl >= HUGE(1.d0)) 1196 IF(fmsg( lerr,'Some values are non-numeric in: '//TRIM(s))) RETURN!--- Non-numerical values found1205 IF(fmsg('Some values are non-numeric in: '//TRIM(s), ll=lerr)) RETURN !--- Non-numerical values found 1197 1206 DO io = 1, SIZE(op) !--- Loop on known operators (order matters !) 1198 1207 DO i = SIZE(id), 1, -1 !--- Loop on found operators … … 1218 1227 !============================================================================================================================== 1219 1228 FUNCTION reduceExpr_m(str, val) RESULT(lerr) 1220 LOGICAL, ALLOCATABLE :: lerr(:)1221 CHARACTER(LEN=*), INTENT(IN) :: str(:)1222 CHARACTER(LEN= 256), ALLOCATABLE, INTENT(OUT) :: val(:)1229 LOGICAL, ALLOCATABLE :: lerr(:) 1230 CHARACTER(LEN=*), INTENT(IN) :: str(:) 1231 CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: val(:) 1223 1232 INTEGER :: i 1224 1233 ALLOCATE(lerr(SIZE(str)),val(SIZE(str))) … … 1277 1286 END FUNCTION str2dble 1278 1287 !============================================================================================================================== 1279 ELEMENTAL CHARACTER(LEN= 256) FUNCTION bool2str(b) RESULT(out)1288 ELEMENTAL CHARACTER(LEN=maxlen) FUNCTION bool2str(b) RESULT(out) 1280 1289 LOGICAL, INTENT(IN) :: b 1281 1290 WRITE(out,*)b … … 1283 1292 END FUNCTION bool2str 1284 1293 !============================================================================================================================== 1285 ELEMENTAL CHARACTER(LEN= 256) FUNCTION int2str(i, nDigits) RESULT(out)1294 ELEMENTAL CHARACTER(LEN=maxlen) FUNCTION int2str(i, nDigits) RESULT(out) 1286 1295 INTEGER, INTENT(IN) :: i 1287 1296 INTEGER, OPTIONAL, INTENT(IN) :: nDigits … … 1292 1301 END FUNCTION int2str 1293 1302 !============================================================================================================================== 1294 ELEMENTAL CHARACTER(LEN= 256) FUNCTION real2str(r,fmt) RESULT(out)1303 ELEMENTAL CHARACTER(LEN=maxlen) FUNCTION real2str(r,fmt) RESULT(out) 1295 1304 REAL, INTENT(IN) :: r 1296 1305 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: fmt … … 1300 1309 END FUNCTION real2str 1301 1310 !============================================================================================================================== 1302 ELEMENTAL CHARACTER(LEN= 256) FUNCTION dble2str(d,fmt) RESULT(out)1311 ELEMENTAL CHARACTER(LEN=maxlen) FUNCTION dble2str(d,fmt) RESULT(out) 1303 1312 DOUBLE PRECISION, INTENT(IN) :: d 1304 1313 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: fmt … … 1367 1376 CHARACTER(LEN=*), INTENT(IN) :: message, items, reason 1368 1377 INTEGER, OPTIONAL, INTENT(IN) :: nmax 1369 CHARACTER(LEN= 256), ALLOCATABLE :: s(:)1378 CHARACTER(LEN=maxlen), ALLOCATABLE :: s(:) 1370 1379 INTEGER :: i, nmx 1371 1380 nmx = 256; IF(PRESENT(nmax)) nmx=nmax
Note: See TracChangeset
for help on using the changeset viewer.