diff --git a/docs/BOOK_M_strings.html b/docs/BOOK_M_strings.html index 8a8082bb..d2963658 100755 --- a/docs/BOOK_M_strings.html +++ b/docs/BOOK_M_strings.html @@ -4,7 +4,7 @@ - + + +
     is a resource-intensive routine. Once the end of
+     the string is found, it is probably best to keep track of it in
+     order to avoid repeated calls to len_white. Because they
+     might be more efficient, consider looking for vendor-supplied or
+     system-optimized equivalents. For example:
+
+        o lnblnk - Solaris f77
+        o len_trim - FORTRAN 90
+
+ + + +
      subroutine message(s)
+       character(len=*) :: s ! s is of variable length
+          lgth=len(s)        ! get total length of variable
+          ! explicitly specify a substring instead of just variable name
+          lastnb = len_white(s(:lgth))
+          write(*,*)'error:[',s(:lastnb),']'
+      end subroutine messages
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+ +
+

NAME

+

listout(3f) - [M_strings:NUMERIC] expand a list of numbers where negative numbers denote range ends (1 -10 means 1 thru 10) (LICENSE:PD)

+

SYNOPSIS

+

subroutine listout(icurve_lists,icurve_expanded,inums,ierr)

+
   integer,intent(in)    :: icurve_lists(:)
+   integer,intent(out)   :: icurve_expanded(:)
+   integer,intent(out)   :: inums
+   integer,intent(out)   :: ierr
+
+

DESCRIPTION

+

expand a list of whole numbers where negative numbers indicate a range. So [10,-20] would be expanded to [10,11,12,13,14,15,16,17,18,19,20].

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLE

+

Sample program:

+
    program demo_listout
+    use M_strings, only : listout
+    implicit none
+    integer,allocatable :: icurve_lists(:)
+    integer :: icurve_expanded(1000)
+    ! icurve_lists is input array
+    integer :: inums
+    ! icurve_expanded is output array
+    integer :: i
+    ! number of icurve_lists values on input,
+    ! number of icurve_expanded numbers on output
+    integer :: ierr
+       icurve_lists=[1, 20, -30, 101, 100, 99, 100, -120, 222, -200]
+       inums=size(icurve_lists)
+       call listout(icurve_lists,icurve_expanded,inums,ierr)
+       if(ierr == 0)then
+          write(*,'(i0)')(icurve_expanded(i),i=1,inums)
+       else
+          write(*,'(a,i0)')'error occurred in *listout* ',ierr
+          write(*,'(i0)')(icurve_expanded(i),i=1,inums)
+       endif
+    end program demo_listout
+
+

Results:

+
    > 1 20 21 22 23
+    > 24 25 26 27 28
+    > 29 30 101 100 99
+    > 100 101 102 103 104
+    > 105 106 107 108 109
+    > 110 111 112 113 114
+    > 115 116 117 118 119
+    > 120 222 221 220 219
+    > 218 217 216 215 214
+    > 213 212 211 210 209
+    > 208 207 206 205 204
+    > 203 202 201 200
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

longest_common_substring(3f) - [M_strings:COMPARE] function that returns the longest common substring of two strings.

+

SYNOPSIS

+

function longest_common_substring(a,b) result(match)

+
    character(len=*),intent(in)  :: a, b
+    character(len=:),allocatable :: match
+
+

DESCRIPTION

+

function that returns the longest common substring of two strings.

+

Note that substrings are consecutive characters within a string. This distinguishes them from subsequences, which is any sequence of characters within a string, even if there are extraneous characters in between them.

+

Hence, the longest common subsequence between "thisisatest" and "testing123testing" is "tsitest", whereas the longest common substring is just "test".

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLE

+

Sample program

+
   program demo_longest_common_substring
+   use M_strings, only : longest_common_substring
+   implicit none
+     call compare('testing123testingthing','thisis',             'thi')
+     call compare('testing',             'sting',              'sting')
+     call compare('thisisatest_stinger','testing123testingthing','sting')
+     call compare('thisisatest_stinger', 'thisis',            'thisis')
+     call compare('thisisatest',         'testing123testing',   'test')
+     call compare('thisisatest',      'thisisatest',     'thisisatest')
+   contains
+
+   subroutine compare(a,b,answer)
+   character(len=*),intent(in) :: a, b, answer
+   character(len=:),allocatable :: match
+   character(len=*),parameter :: g='(*(g0))'
+      match=longest_common_substring(a,b)
+      write(*,g) 'comparing "',a,'" and "',b,'"'
+      write(*,g) merge('(PASSED) "','(FAILED) "',answer == match), &
+      & match,'"; expected "',answer,'"'
+   end subroutine compare
+
+   end program demo_longest_common_substring
+
+

expected output

+
   comparing "testing123testingthing" and "thisis"
+   (PASSED) "thi"; expected "thi"
+   comparing "testing" and "sting"
+   (PASSED) "sting"; expected "sting"
+   comparing "thisisatest_stinger" and "testing123testingthing"
+   (PASSED) "sting"; expected "sting"
+   comparing "thisisatest_stinger" and "thisis"
+   (PASSED) "thisis"; expected "thisis"
+   comparing "thisisatest" and "testing123testing"
+   (PASSED) "test"; expected "test"
+   comparing "thisisatest" and "thisisatest"
+   (PASSED) "thisisatest"; expected "thisisatest"
+
+
+
+

NAME

+

lower(3f) - [M_strings:CASE] changes a string to lowercase over specified range (LICENSE:PD)

+

SYNOPSIS

+

elemental pure function lower(str,begin,end) result (string)

+
    character(*), intent(in) :: str
+    integer,optional         :: begin, end
+    character(len(str))      :: string  ! output string
+
+

DESCRIPTION

+

lower(string) returns a copy of the input string with all characters converted to miniscule over the specified range, assuming ASCII character sets are being used. If no range is specified the entire string is converted to miniscule.

+

OPTIONS

+ +

RESULTS

+ +

TRIVIA

+

The terms "uppercase" and "lowercase" date back to the early days of the mechanical printing press. Individual metal alloy casts of each needed letter, or punctuation symbol, were meticulously added to a press block, by hand, before rolling out copies of a page. These metal casts were stored and organized in wooden cases. The more often needed miniscule letters were placed closer to hand, in the lower cases of the work bench. The less often needed, capitalized, majuscule letters, ended up in the harder to reach upper cases.

+

EXAMPLE

+

Sample program:

+
      program demo_lower
+      use M_strings, only: lower
+      implicit none
+      character(len=:),allocatable  :: s
+         s=' ABCDEFG abcdefg '
+         write(*,*) 'mixed-case input string is ```.',s
+         write(*,*) 'lower-case output string is ```',lower(s)
+      end program demo_lower
+
+

Expected output

+
      mixed-case input string is ```. ABCDEFG abcdefg
+      lower-case output string is ``` abcdefg abcdefg
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

lpad(3f) - [M_strings:LENGTH] convert to a cropped string and then blank-pad on the left to requested length (LICENSE:PD)

+

SYNOPSIS

+

function lpad(valuein,length) result(strout)

+
    class*,intent(in)       :: valuein(..)
+    integer,intent(in)      :: length
+
+

DESCRIPTION

+

lpad(3f) converts a scalar value to a cropped string and then pads it on the left with spaces to at least the specified length. If the trimmed input is longer than the requested length the string is returned trimmed of leading and trailing spaces.

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLE

+

Sample Program:

+
     program demo_lpad
+      use M_strings, only : lpad
+      implicit none
+         write(*,'("[",a,"]")') lpad( 'my string', 20)
+         write(*,'("[",a,"]")') lpad( 'my string   ', 20)
+         write(*,'("[",a,"]")') lpad( '   my string', 20)
+         write(*,'("[",a,"]")') lpad( '   my string   ', 20)
+         write(*,'("[",a,"]")') lpad( valuein=42 , length=7)
+         write(*,'("[",a,"]")') lpad( valuein=1.0/9.0 , length=20)
+     end program demo_lpad
+
+

Results:

+
    > [           my string]
+    > [           my string]
+    > [           my string]
+    > [           my string]
+    > [     42]
+    > [         0.111111112]
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

matching_delimiter(3f) - [M_strings:QUOTES] find position of matching delimiter (LICENSE:PD)

+

SYNOPSIS

+

impure elemental subroutine matching_delimiter(str,ipos,imatch)

+
   character(len=*),intent(in)  :: str
+   integer,intent(in)           :: ipos
+   integer,intent(out)          :: imatch
+
+

DESCRIPTION

+

Sets imatch to the position in string of the delimiter matching the delimiter in position ipos. Allowable delimiters are (), [], {}, <>.

+

OPTIONS

+ +

EXAMPLE

+

Sample program:

+
   program demo_matching_delimiter
+      use M_strings, only : matching_delimiter
+      implicit none
+      character(len=128)  :: str
+      integer             :: imatch
+
+      str=' a [[[[b] and ] then ] finally ]'
+      write(*,*)'string=',str
+      call matching_delimiter(str,1,imatch)
+      write(*,*)'location=',imatch
+      call matching_delimiter(str,4,imatch)
+      write(*,*)'location=',imatch
+      call matching_delimiter(str,5,imatch)
+      write(*,*)'location=',imatch
+      call matching_delimiter(str,6,imatch)
+      write(*,*)'location=',imatch
+      call matching_delimiter(str,7,imatch)
+      write(*,*)'location=',imatch
+      call matching_delimiter(str,32,imatch)
+      write(*,*)'location=',imatch
+
+   end program demo_matching_delimiter
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

merge_str(3f) - [M_strings:LENGTH] pads strings to same length and then calls MERGE(3f) (LICENSE:PD)

+

SYNOPSIS

+

function merge_str(str1,str2,expr) result(strout)

+
    character(len=*),intent(in),optional :: str1
+    character(len=*),intent(in),optional :: str2
+    logical,intent(in)              :: expr
+    character(len=:),allocatable    :: strout
+
+

DESCRIPTION

+

merge_str(3f) pads the shorter of str1 and str2 to the longest length of str1 and str2 and then calls MERGE(padded_str1,padded_str2,expr). It trims trailing spaces off the result and returns the trimmed string. This makes it easier to call MERGE(3f) with strings, as MERGE(3f) requires the strings to be the same length.

+

NOTE: STR1 and STR2 are always required even though declared optional. this is so the call "STR_MERGE(A,B,present(A))" is a valid call. The parameters STR1 and STR2 when they are optional parameters can be passed to a procedure if the options are optional on the called procedure.

+

OPTIONS

+ +

RESULT

+ +

EXAMPLES

+

Sample Program:

+
    program demo_merge_str
+    use M_strings, only : merge_str
+    implicit none
+    character(len=:), allocatable :: answer
+       answer=merge_str('first string', &
+        & 'second string is longer',10 == 10)
+       write(*,'("[",a,"]")') answer
+       answer=merge_str('first string', &
+        & 'second string is longer',10 /= 10)
+       write(*,'("[",a,"]")') answer
+    end program demo_merge_str
+
+

Expected output

+
    [first string]
+    [second string is longer]
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

modif(3f) - [M_strings:EDITING] emulate the MODIFY command from the line editor XEDIT (LICENSE:PD)

+

SYNOPSIS

+

subroutine modif(cline,cmod)

+
    character(len=*) :: cline ! input string to change
+    ! directive provides directions on changing string
+    character(len=*) :: cmod
+
+

DESCRIPTION

+

MODIF(3f) Modifies the line currently pointed at using a directive that acts much like a line editor directive. Primarily used to create interactive utilities such as input history editors for interactive line-mode programs.

+

the modify directives are as follows-

+

DIRECTIVE EXPLANATION

+ +

Any other character replaces the character above it.

+

EXAMPLES

+

Example input/output:

+
   THE INPUT LINE```..... 10 THIS STRING  TO BE MORTIFD
+   THE DIRECTIVES LINE```        ^ IS THE#        D#  ^IE
+   ALTERED INPUT LINE```. 10 THIS IS THE STRING  TO BE MODIFIED
+
+

Sample program:

+
   program demo_modif
+   use M_strings, only : modif
+   implicit none
+   character(len=256)           :: line
+   integer                      :: ios
+   integer                      :: count
+   integer                      :: COMMAND_LINE_LENGTH
+   character(len=:),allocatable :: COMMAND_LINE
+      ! get command name length
+      call get_command_argument(0,length=count)
+      ! get command line length
+      call get_command(length=COMMAND_LINE_LENGTH)
+      ! allocate string big enough to hold command line
+      allocate(character(len=COMMAND_LINE_LENGTH+200) :: COMMAND_LINE)
+      ! get command line as a string
+      call get_command(command=COMMAND_LINE)
+      ! trim leading spaces just in case
+      COMMAND_LINE=adjustl(COMMAND_LINE)
+      ! remove command name
+      COMMAND_LINE=adjustl(COMMAND_LINE(COUNT+2:))
+      INFINITE: do
+         read(*,'(a)',iostat=ios)line
+         if(ios /= 0)exit
+         call modif(line,COMMAND_LINE)
+         write(*,'(a)')trim(line)
+      enddo INFINITE
+   end program demo_modif
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

msg(3f) - [M_strings:TYPE] converts any standard scalar type to a string (LICENSE:PD)

+

SYNOPSIS

+

function msg(g1,g2g3,g4,g5,g6,g7,g8,g9,sep)

+
     class(*),intent(in),optional  :: g1,g2,g3,g4,g5,g6,g7,g8,g9
+     character(len=*),intent(in),optional :: sep
+     character(len=:),allocatable :: msg
+
+

DESCRIPTION

+

msg(3f) builds a space-separated string from up to nine scalar values.

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLES

+

Sample program:

+
       program demo_msg
+       use M_strings, only : msg
+       implicit none
+       character(len=:),allocatable :: pr
+       character(len=:),allocatable :: frmt
+       integer                      :: biggest
+
+       pr=msg('HUGE(3f) integers',huge(0),&
+       & 'and real',huge(0.0),'and double',huge(0.0d0))
+       write(*,'(a)')pr
+       pr=msg('real            :',&
+        & huge(0.0),0.0,12345.6789,tiny(0.0) )
+       write(*,'(a)')pr
+       pr=msg('doubleprecision :',&
+        & huge(0.0d0),0.0d0,12345.6789d0,tiny(0.0d0) )
+       write(*,'(a)')pr
+       pr=msg('complex         :',&
+        & cmplx(huge(0.0),tiny(0.0)) )
+       write(*,'(a)')pr
+
+       ! create a format on the fly
+       biggest=huge(0)
+       ! +0 for gfortran-11 bug
+       frmt=msg('(*(i',int(log10(real(biggest)))+0,':,1x))',sep='')
+       write(*,*)'format=',frmt
+
+       ! although it will often work, using msg(3f) in an I/O statement
+       ! is not recommended
+       write(*,*)msg('program will now stop')
+
+       end program demo_msg
+
+

Output

+
      HUGE(3f) integers 2147483647 and real 3.40282347E+38
+      and double 1.7976931348623157E+308
+      real            : 3.40282347E+38 0.00000000
+      12345.6787 1.17549435E-38
+      doubleprecision : 1.7976931348623157E+308 0.0000000000000000
+      12345.678900000001 2.2250738585072014E-308
+      complex         : (3.40282347E+38,1.17549435E-38)
+       format=(*(i9:,1x))
+       program will now stop
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

M_strings(3f) - [M_strings::INTRO] Fortran string module

+

DESCRIPTION

+

The M_strings(3fm) module is a collection of Fortran procedures that supplement the built-in intrinsic string routines. Routines for parsing, tokenizing, changing case, substituting new strings for substrings, locating strings with simple wildcard expressions, removing tabs and line terminators and other string manipulations are included.

+

M_strings__oop(3fm) is a companion module that provides an OOP interface to the M_strings module.

+

SYNOPSIS

+

public entities:

+
     use M_strings,only : split, slice, sep, delim, chomp, strtok
+     use M_strings,only : split2020, find_field
+     use M_strings,only : substitute, change, modif, transliterate, &
+             & reverse, squeeze
+     use M_strings,only : replace, join
+     use M_strings,only : upper, lower, upper_quoted
+     use M_strings,only : rotate13, percent_encode
+     use M_strings,only : adjustc, compact, nospace, indent
+     use M_strings,only : crop, clip, unquote, quote, matching_delimiter
+     use M_strings,only : len_white, pad, lpad, cpad, rpad, zpad, &
+             & stretch, lenset, merge_str
+     use M_strings,only : switch, s2c, c2s
+     use M_strings,only : noesc, notabs, dilate, expand, visible
+     use M_strings,only : longest_common_substring
+     use M_strings,only : string_to_value, string_to_values, s2v, s2vs
+     use M_strings,only : int, real, dble, nint
+     use M_strings,only : atoi, atol, aton
+     use M_strings,only : value_to_string, v2s, msg
+     use M_strings,only : listout, getvals
+     use M_strings,only : glob, ends_with
+     use M_strings,only : paragraph
+     use M_strings,only : base, decodebase, codebase, base2
+     use M_strings,only : isalnum, isalpha, iscntrl, isdigit
+     use M_strings,only : isgraph, islower, isprint, ispunct
+     use M_strings,only : isspace, isupper, isascii, isblank, isxdigit
+     use M_strings,only : isnumber
+     use M_strings,only : fortran_name
+     use M_strings,only : describe
+     use M_strings,only : edit_distance
+     use M_strings,only : bundle
+
+

TOKENS

+ +

CONTRIBUTIONS

+ +

EDITING

+ +

CASE

+ +

STRING LENGTH AND PADDING

+ +

WHITE SPACE

+ +

See Also: squeeze

+

QUOTES

+ +

CHARACTER ARRAY VERSUS STRING

+ +

NONALPHA

+ +

NUMERIC STRINGS

+ +

CHARACTER TESTS

+ + + + + + + +

BASE CONVERSION

+ +

MISCELLANEOUS

+ +

INTRINSICS

+

The M_strings(3fm) module supplements and works in combination with the Fortran built-in intrinsics. Stand-alone Fortran lets you access the characters in a string using ranges much like they are character arrays, assignment, comparisons with standard operators, supports dynamically allocatable strings and supports concatenation using the // operator, as well as a number of intrinsic string routines:

+
       adjustl             Left adjust a string
+       adjustr             Right adjust a string
+       index               Position of a substring within a string
+       repeat              Repeated string concatenation
+       scan                Scan a string for the presence of a set
+                           of characters
+       trim                Remove trailing blank characters of a string
+       verify              Scan a string for the absence of a set of
+                           characters
+       len                 It returns the length of a character string
+       achar               converts an integer into a character
+       iachar              converts a character into an integer
+       len_trim            finds length of string with trailing spaces
+                           ignored
+       new_line            Newline character
+       selected_char_kind  Choose character kind
+       lge                 Lexical greater than or equal
+       lgt                 Lexical greater than
+       lle                 Lexical less than or equal
+       llt                 Lexical less than
+
+

OOPS INTERFACE

+

The M_strings__oop(3fm) module (included with the M_strings(3fm) module) provides an OOP (Object-Oriented Programming) interface to the M_strings(3fm) module.

+

SEE ALSO

+

There are additional routines in other GPF modules for working with expressions (M_calculator), time strings (M_time), random strings (M_random, M_uuid), lists (M_list), and interfacing with the C regular expression library (M_regex).

+

EXAMPLES

+

Each of the procedures includes an [example](example/) program in the corresponding man(1) page for the function.

+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

M_strings__oop(3f) - [M_strings::INTRO::OOPS] OOP Fortran string module

+

SYNOPSIS

+

use M_strings__oop

+

DESCRIPTION

+

The M_strings(3fm) module is a collection of Fortran procedures that supplement the built-in intrinsic string routines. Routines for parsing, tokenizing, changing case, substituting new strings for substrings, locating strings with simple wildcard expressions, removing tabs and line terminators and other string manipulations are included.

+

M_strings__oop(3fm) is a companion module that provides an OOP interface to the M_strings module.

+

SEE ALSO

+

There are additional routines in other GPF modules for working with expressions (M_calculator), time strings (M_time), random strings (M_random, M_uuid), lists (M_list), and interfacing with the C regular expression library (M_regex).

+

EXAMPLES

+

Each of the procedural functions in M_strings(3fm) includes an example program in the corresponding man(1) page for the function. The object-oriented interface does not have individual man(1) pages, but is instead demonstrated using the following example program:

+
    program demo_M_strings__oop
+    !
+    ! This is an example using the object-oriented class/type model
+    ! defined in M_strings__oop
+    !
+    ! This is essentially the same functionality as the procedures
+    ! combined with several Fortran intrinsics and overloaded operators
+    !
+    use M_strings__oop,only : string, p
+    implicit none
+    TYPE(string) :: str1, str2, str3, str4
+
+      write(*,*)'Call methods of type(STRING)'
+
+      ! define TYPE(STRING) with constructor
+      str2=string('   This  is  a  String!       ')
+      str4=string(' a  String ')
+
+      write(*,101)'str2%str is ```............. ', &
+       & str2%str                      ! print string member of type
+      write(*,202)'len ```..................... ', &
+       & str2%len()                    ! same as intrinsic LEN()
+      write(*,202)'len_trim ```................ ', &
+       & str2%len_trim()               ! same as intrinsic LEN_TRIM()
+      write(*,202)'index("is")```.............. ', &
+       & str2%index("is")              ! same as intrinsic INDEX()
+      write(*,202)'index("is",back=.T.) ```.... ', &
+       & str2%index("is",back=.TRUE.)  ! same as intrinsic INDEX()
+      write(*,101)'upper ```................... ', &
+       & p(str2%upper())               ! call upper()
+      write(*,101)'lower ```................... ', &
+       & p(str2%lower())               ! call lower()
+      write(*,101)'reverse ```................. ', &
+       & p(str2%reverse())             ! call reverse()
+      write(*,101)'adjustl ```................. ', &
+       & p(str2%adjustl())             ! same as intrinsic ADJUSTL()
+      write(*,101)'adjustr ```................. ', &
+       & p(str2%adjustr())             ! same as intrinsic ADJUSTR()
+      write(*,101)'adjustc ```................. ', &
+       & p(str2%adjustc())             ! center string in current string length
+      write(*,101)'adjustc(40) ```............. ', &
+       & p(str2%adjustc(40))           ! center string in string length of NN
+      write(*,101)'lenset(40) ```.............. ', &
+       & p(str2%lenset(40))            ! call pad() to force minimal string length
+      write(*,101)'trim ```.................... ', &
+       & p(str2%trim())                ! same as intrinsic TRIM()
+      write(*,101)'crop ```.................... ', &
+       & p(str2%crop())                ! trim leading and trailing spaces
+      write(*,101)'substitute("This","Here") .. ', &
+       & p(str2%substitute("This","Here")) ! call SUBSTITUTE()
+      write(*,101)'compact ```................. ', &
+       & p(str2%compact())                 ! call COMPACT()
+      write(*,101)'compact("") ```............. ', &
+       & p(str2%compact(""))
+      write(*,101)'compact(":") ```............ ', &
+       & p(str2%compact(":"))
+      ! calls M_strings procedure TRANSLITERATE()
+      write(*,101)'transliterate("aei","VWX") . ', &
+       & p(str2%transliterate("aei","VWX"))
+      write(*,101)'transliterate("aeiou"," ") . ', &
+       & p(str2%transliterate("aeiou"," "))
+      write(*,101)'transliterate("aeiou","") .. ', &
+       & p(str2%transliterate("aeiou",""))
+      write(*,101)'transliterate(" aeiou","") . ', &
+       & p(str2%transliterate(" aeiou",""))
+      write(*,404)'chars ```................. . ', &
+       & str4%chars()                   ! call SWITCH()
+
+      str2%str='\t\tSome tabs\t   x\bX '
+      write(*,101)'str2%str ```................ ',str2%str
+      write(*,101)'expand ```.................. ', &
+       & p(str2%expand())
+      str2=str2%expand()
+      write(*,101)'notabs ```.................. ', &
+       & p(str2%notabs())               ! calls NOTABS()
+      write(*,101)'noesc ```................... ', &
+       & p(str2%noesc())                ! calls NOESC()
+
+      write(*,*)repeat('=',68)
+      write(*,*)'Casting to numeric variables'
+      str3=string('   12.345678901234567e1        ')
+      write(*,101)'str3%str ```................ ',str3%str
+      ! calls to M_strings procedure STRING_TO_VALUE()
+      write(*,*)'int  ```.................... ', str3%int()
+      write(*,*)'nint ```.................... ', str3%nint()
+      write(*,*)'real ```.................... ', str3%real()
+      write(*,*)'dble ```.................... ', str3%dble()
+
+      write(*,*)repeat('=',68)
+      write(*,*)'Matching simple globbing patterns'
+      str3=string('   12.345678901234567e1        ')
+      str3=string('Four score and seven years ago')
+      write(*,101)'str3%str ```................ ',str3%str
+      ! %match calls M_strings procedure GLOB
+      write(*,*)'match("Fo*") ```............ ', str3%match("Fo*")
+      write(*,*)'match("and") ```............ ', str3%match("and")
+      write(*,*)'match("*and*") ```.......... ', str3%match("*and*")
+
+      101 format(1x,a,"[",a,"]")
+      202 format(1x,a,i0)
+      303 format(1x,*(l3))
+      404 format(1x,a,*("[",a1,"]":))
+
+      write(*,*)repeat('=',68)
+      write(*,*)'OVERLOADED OPERATORS (add and subtract,return TYPE(STRING))'
+      str1%str='123.456'
+      str2%str='AaBbCcDdEeFfGgHhIi AaBbCcDdEeFfGgHhIi'
+      write(*,101)'str1%str ```................ ',str1%str
+      write(*,101)'str2%str ```................ ',str2%str
+      write(*,*)'str1 + str2 ```............. ',p(str1 + str2)
+      ! a string that looks like a numeric value can have a value added
+      write(*,*)'str1 + 20000 ```............ ',p(str1 +20000)
+      write(*,*)'str1 - 20.0 ```............. ',p(str1 -20.0)
+      write(*,*)'str2 - "Aa" (removes ALL) .. ',p(str2 - 'Aa')
+
+      write(*,*)repeat('=',68)
+      write(*,*)'OVERLOADED OPERATORS (multiply,return TYPE(STRING))'
+      str1%str='AaBbCcDdEeFfGgHhIi'
+      write(*,101)'str1%str ```................ ',str1%str
+      write(*,*)'str1 * 2 ```................ ',p(str1 * 2)
+
+      write(*,*)repeat('=',68)
+      write(*,*)'OVERLOADED OPERATORS (//,return TYPE(STRING))'
+      str1%str='String one:'
+      str2%str='String two:'
+      write(*,101)'str1%str ```................ ',str1%str
+      write(*,101)'str2%str ```................ ',str2%str
+      write(*,*)'str1 // str2 ```............. ',p(str1 // str2)
+      ! numeric values are converted to strings
+      write(*,*)'str1 // 20000 ```............ ',p(str1 // 20000)
+      write(*,*)'str1 // 20.0 ```............. ',p(str1 // 20.0)
+
+      write(*,*)repeat('=',68)
+      write(*,*)'OVERLOADED OPERATORS (logical comparisons,return logical)'
+      ! NOTE: comparisons are performed on the character variable members
+      !       of the type(string)
+      str1%str='abcdefghij'
+      str2%str='klmnopqrst'
+      write(*,101)'str1%str ```................ ',str1%str
+      write(*,101)'str2%str ```................ ',str2%str
+      write(*,*)': EQ LT GT LE GE NE'
+      write(*,*)'compare str1 to str1'
+      write(*,303)str1 == str1  ,str1 < str1  ,str1 > str1  ,str1 <= str1 &
+                 & ,str1 >= str1  ,str1 /= str1
+      write(*,*)'compare str1 to str2'
+      write(*,303)str1 == str2  ,str1 < str2  ,str1 > str2  ,str1 <= str2 &
+                 & ,str1 >= str2  ,str1 /= str2
+      write(*,*)'compare str2 to str1'
+      write(*,303)str2 == str1  ,str2 < str1  ,str2 > str1  ,str2 <= str1 &
+                 & ,str2 >= str1  ,str2 /= str1
+
+      write(*,*)repeat('=',68)
+
+    end program demo_M_strings__oop
+
+

Expected output

+
  exercise the M_STRING_OOP module interface
+  ===================================================================
+  Call methods of type(STRING)
+  ===================================================================
+  str2%str is ```............. [   This  is  a  String!             ]
+  len ```..................... 36
+  len_trim ```................ 23
+  index("is")```.............. 6
+  index("is",back=.T.) ```.... 10
+  upper ```................... [   THIS  IS  A  STRING!             ]
+  lower ```................... [   this  is  a  string!             ]
+  reverse ```................. [             !gnirtS  a  si  sihT   ]
+  adjustl ```................. [This  is  a  String!                ]
+  adjustr ```................. [                This  is  a  String!]
+  adjustc ```................. [        This  is  a  String!        ]
+  adjustc(40) ```............. [              This  is  a  String!      ]
+  lenset(40) ```.............. [   This  is  a  String!                 ]
+  trim ```.................... [   This  is  a  String!]
+  crop ```.................... [This  is  a  String!]
+  substitute("This","Here") .. [   Here  is  a  String!             ]
+  compact ```................. [This is a String!]
+  compact("") ```............. [ThisisaString!]
+  compact(":") ```............ [This:is:a:String!]
+  transliterate("aei","VWX") . [   ThXs  Xs  V  StrXng!             ]
+  transliterate("aeiou"," ") . [   Th s   s     Str ng!             ]
+  transliterate("aeiou","") .. [   Ths  s    Strng!                 ]
+  transliterate(" aeiou","") . [ThssStrng!                          ]
+  chars ```................. . [ ][a][ ][s][t][r][i][n][g][ ]
+  ===================================================================
+  str2%str ```................ [\t\tSome tabs\t   x\bX ]
+  expand ```.................. [         Some tabs          x   X]
+  notabs ```.................. [                Some tabs          x    X]
+  noesc ```................... [  Some tabs    x X]
+  ===================================================================
+  Casting to numeric variables
+  str3%str ```................ [   12.345678901234567e1        ]
+  int  ```....................          123
+  real ```....................    123.456787
+  dble ```....................    123.45678901234567
+  ===================================================================
+  Matching simple globbing patterns
+  str3%str ```................ [Four score and seven years ago]
+  match("Fo*") ```............  T
+  match("and") ```............  F
+  match("*and*") ```..........  T
+  ====================================================================
+  OVERLOADED OPERATORS (add and subtract, return TYPE(STRING))
+  str1%str ```............... [123.456]
+  str2%str ```............... [AaBbCcDdEeFfGgHhIi AaBbCcDdEeFfGgHhIi]
+  str1 + str2 ```............ 123.456 AaBbCcDdEeFfGgHhIi AaBbCcDdEeFfGgHhIi
+  str1 + 20000 ```........... 20123.455999999998
+  str1 - 20.0 ```............ -103.456
+  str2 - "Aa" (removes ALL) . BbCcDdEeFfGgHhIi BbCcDdEeFfGgHhIi
+  ===================================================================
+  OVERLOADED OPERATORS (multiply, return TYPE(STRING))
+  str1%str ```................ [AaBbCcDdEeFfGgHhIi]
+  str1 * 2 ```................ AaBbCcDdEeFfGgHhIiAaBbCcDdEeFfGgHhIi
+  ===================================================================
+  OVERLOADED OPERATORS (//, return TYPE(STRING))
+  str1%str ```................ [String one:]
+  str2%str ```................ [String two:]
+  str1 // str2 ```............ String one:String two:
+  str1 // 20000 ```........... String one:20000
+  str1 // 20.0 ```............ String one:20.0
+  ===================================================================
+  OVERLOADED OPERATORS (logical comparisons, return logical)
+  str1%str ```................ [abcdefghij]
+  str2%str ```................ [klmnopqrst]
+  : EQ LT GT LE GE NE
+  compare str1 to str1
+  :  T  F  F  T  T  F
+  compare str1 to str2
+  :  F  T  F  T  F  T
+  compare str2 to str1
+  :  F  F  T  F  T  T
+  ===================================================================
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

nint(3f) - [M_strings:TYPE] overloads NINT(3f) so it can handle character arguments (LICENSE:PD)

+

SYNOPSIS

+

impure elemental function nint(string)

+
    character(len=*) :: string
+    integer          :: nint
+
+

DESCRIPTION

+

nint(3f) returns an integer when given a numeric representation of a numeric value. This overloads the NINT(3f) intrinsic so that CHARACTER arguments assumed to represent a numeric value may be input.

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLE

+

Sample program:

+
     program demo_nint
+     use,intrinsic :: iso_fortran_env, only : int8, int16, int32, int64
+     use M_strings, only: nint
+     implicit none
+     character(len=*),parameter :: g='(*(g0,1x))'
+        write(*,g)nint('100'),nint('20.4')
+        write(*,g)'intrinsic nint(3f) still works',nint(20.4)
+        write(*,g)'elemental',&
+        & nint([character(len=23) :: '10','20.3','20.5','20.6'])
+     end program demo_nint
+
+

Results:

+
    > 100 20
+    > intrinsic nint(3f) still works 20
+    > elemental 10 20 21 21
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

noesc(3f) - [M_strings:NONALPHA] convert non-printable characters to a space (LICENSE:PD)

+

SYNOPSIS

+

elemental function noesc(INSTR)

+
    character(len=*),intent(in) :: INSTR
+    character(len=len(instr))   :: noesc
+
+

DESCRIPTION

+

Convert non-printable characters to a space.

+

EXAMPLES

+

Sample Program:

+
   program demo_noesc
+
+    use M_strings, only : noesc
+    implicit none
+    character(len=128) :: ascii
+    character(len=128) :: cleared
+    integer            :: i
+    ! fill variable with base ASCII character set
+    do i=1,128
+       ascii(i:i)=char(i-1)
+    enddo
+    cleared=noesc(ascii)
+    write(*,*)'characters and their ADE (ASCII Decimal Equivalent)'
+    call ade(ascii)
+    write(*,*)'Cleared of non-printable characters'
+    call ade(cleared)
+    write(*,*)'Cleared string:'
+    write(*,*)cleared
+    contains
+      subroutine ade(string)
+      implicit none
+      ! the string to print
+      character(len=*),intent(in) :: string
+      ! number of characters in string to print
+      integer :: lgth
+      ! counter used to step thru string
+      integer :: i
+         ! get trimmed length of input string
+         lgth=len_trim(string(:len(string)))
+
+         ! replace lower unprintable characters with spaces
+         write(*,101)(merge(string(i:i),' ',&
+         & iachar(string(i:i)) >= 32        &
+         & .and.                            &
+         & iachar(string(i:i)) <= 126)      &
+         & ,i=1,lgth)
+
+         ! print ADE value of character underneath it
+         write(*,202)     (iachar(string(i:i))/100,    i=1,lgth)
+         write(*,202)(mod( iachar(string(i:i)),100)/10,i=1,lgth)
+         write(*,202)(mod((iachar(string(i:i))),10),   i=1,lgth)
+      ! format for printing string characters
+      101   format(*(a1:))
+      ! format for printing ADE values
+      202   format(*(i1:))
+      end subroutine ade
+    end program demo_noesc
+
+   Expected output
+
+   The string is printed with the ADE value vertically beneath.
+   The original string has all the ADEs from 000 to 127. After
+   NOESC(3f) is called on the string all the "non-printable"
+   characters are replaced with a space (ADE of 032).
+
+

characters and their ADE (ASCII Decimal Equivalent)

+
   >                                 !"#$%&'()*+,-./0123456789
+   :;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
+   >0000000000000000000000000000000000000000000000000000000000
+   0000000000000000000000000000000000000000001111111111111111111111111111
+   >00000000001111111111222222222233333333334444444444555555555566666666
+   667777777777888888888899999999990000000000111111111122222222
+   >012345678901234567890123456789012345678901234567890123456789012345678
+   90123456789012345678901234567890123456789012345678901234567
+
+

Cleared of non-printable characters

+
   >                                 !"#$%&'()*+,-./0123456789
+   :;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
+   >0000000000000000000000000000000000000000000000000000000000
+   000000000000000000000000000000000000000000111111111111111111111111111
+   >3333333333333333333333333333333333333333444444444455555555
+   556666666666777777777788888888889999999999000000000011111111112222222
+   >2222222222222222222222222222222223456789012345678901234567
+   890123456789012345678901234567890123456789012345678901234567890123456
+
+

Cleared string:

+
   >                                  !"#$%&'()*+,-./0123456789:;<=>?@
+   ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

nospace(3f) - [M_strings:WHITESPACE] remove all whitespace from input string (LICENSE:PD)

+

SYNOPSIS

+

function nospace(str) - remove all whitespace from input string

+
    character(len=*),intent(in)          :: str
+    character(len=:),allocatable         :: nospace
+
+

DESCRIPTION

+

nospace(3f) removes space, tab, carriage return, new line, vertical tab, formfeed and null characters (called "whitespace"). The output is returned trimmed.

+

EXAMPLES

+

Sample program:

+
    program demo_nospace
+    use M_strings, only: nospace
+    implicit none
+    character(len=:),allocatable  :: s
+       s='  This     is      a     test  '
+       write(*,*) 'original input string is ```.',s
+       write(*,*) 'processed output string is ```',nospace(s)
+       if(nospace(s) == 'Thisisatest')then
+          write(*,*)'nospace test passed'
+       else
+          write(*,*)'nospace test error'
+       endif
+    end program demo_nospace
+
+

Expected output

+
    original input string is ```.  This     is      a     test
+    processed output string is ```Thisisatest
+    nospace test passed
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

notabs(3f) - [M_strings:NONALPHA] expand tab characters (LICENSE:PD)

+

SYNOPSIS

+

subroutine notabs(INSTR,OUTSTR,lgth)

+
    character(len=*),intent=(in)  :: INSTR
+    character(len=*),intent=(out) :: OUTSTR
+    integer,intent=(out)          :: lgth
+
+

DESCRIPTION

+

NOTABS() converts tabs in INSTR to spaces in OUTSTR while maintaining columns. It assumes a tab is set every 8 characters. Trailing spaces are removed.

+

In addition, trailing carriage returns and line feeds are removed (they are usually a problem created by going to and from MSWindows).

+

What are some reasons for removing tab characters from an input line? Some Fortran compilers have problems with tabs, as tabs are not part of the Fortran character set. Some editors and printers will have problems with tabs. It is often useful to expand tabs in input files to simplify further processing such as tokenizing an input line.

+

OPTIONS

+ +

RESULTS

+ +

EXAMPLES

+

Sample program:

+
   program demo_notabs
+
+   !  test filter to remove tabs and trailing white space from input
+   !  on files up to 1024 characters wide
+   use M_strings, only : notabs
+   character(len=1024) :: in,out
+   integer             :: ios,iout
+      do
+         read(*,'(A)',iostat=ios)in
+         if(ios /= 0) exit
+         call notabs(in,out,iout)
+         write(*,'(a)')out(:iout)
+      enddo
+   end program demo_notabs
+
+

SEE ALSO

+

GNU/Unix commands expand(1) and unexpand(1)

+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

pad(3f) - [M_strings:LENGTH] return string padded to at least specified length (LICENSE:PD)

+

SYNOPSIS

+

function pad(str,length,pattern,right,clip) result(strout)

+
   character(len=*)                           :: str
+   integer,intent(in)                         :: length
+   character(len=max(length,len(trim(line)))) :: strout
+   character(len=*),intent(in),optional       :: pattern
+   logical,intent(in),optional                :: right
+   logical,intent(in),optional                :: clip
+
+

DESCRIPTION

+

pad(3f) pads a string with a pattern to at least the specified length. If the trimmed input string is longer than the requested length the trimmed string is returned.

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLE

+

Sample Program:

+
   program demo_pad
+    use M_strings, only : pad
+    implicit none
+    character(len=10)            :: string='abcdefghij'
+    character(len=:),allocatable :: answer
+    integer                      :: i
+    character(len=*),parameter   :: g='(*(g0))'
+       answer=pad(string,5)
+       write(*,'("[",a,"]")') answer
+       answer=pad(string,20)
+       write(*,'("[",a,"]")') answer
+       i=30
+       write(*,g)
+       write(*,'(1x,a,1x,i0)') &
+        & pad('CHAPTER 1 : The beginning ',i,'.'), 1   , &
+        & pad('CHAPTER 2 : The end ',i,'.'),       1234, &
+        & pad('APPENDIX ',i,'.'),                  1235
+       write(*,*)
+       write(*,'(1x,a,i7)') &
+        & pad('CHAPTER 1 : The beginning ',i,'.'), 1   , &
+        & pad('CHAPTER 2 : The end ',i,'.'),       1234, &
+        & pad('APPENDIX ',i,'.'),                  1235
+
+        write(*,g)pad('12',5,'0',right=.false.)
+
+        write(*,g)pad('12345 ',30,'_',right=.false.)
+        write(*,g)pad('12345 ',30,'_',right=.false.,clip=.true.)
+        write(*,g)pad('12345 ',7,'_',right=.false.)
+        write(*,g)pad('12345 ',7,'_',right=.false.,clip=.true.)
+        write(*,g)pad('12345 ',6,'_',right=.false.)
+        write(*,g)pad('12345 ',6,'_',right=.false.,clip=.true.)
+        write(*,g)pad('12345 ',5,'_',right=.false.)
+        write(*,g)pad('12345 ',5,'_',right=.false.,clip=.true.)
+        write(*,g)pad('12345 ',4,'_',right=.false.)
+        write(*,g)pad('12345 ',4,'_',right=.false.,clip=.true.)
+   end program demo_pad
+
+

Results:

+

> [abcdefghij]

+ +

SEE ALSO

+

adjustl(3f), adjustr(3f), repeat(3f), trim(3f), len_trim(3f), len(3f)

+

adjustc(3f), stretch(3f), lpad(3f), rpad(3f), cpad(3f), zpad(3f), lenset(3f)

+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

paragraph(3f) - [M_strings:TOKENS] break a long line into a paragraph (LICENSE:PD)

+

SYNOPSIS

+

function paragraph(source_string,length)

+
   character(len=*),intent(in)       :: source_string
+   integer,intent(in)                :: length
+   character(allocatable(len=length)    :: paragraph(:)
+
+

DESCRIPTION

+

paragraph(3f) breaks a long line into a simple paragraph of specified line length.

+

Given a long string break it on spaces into an array such that no variable is longer than the specified length. Individual words longer than LENGTH will be placed in variables by themselves.

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLE

+

sample program

+
   program demo_paragraph
+   use M_strings, only : paragraph
+   implicit none
+   character(len=:),allocatable :: paragrph(:)
+   character(len=*),parameter    :: string= '&
+    &one two three four five &
+    &six seven eight &
+    &nine ten eleven twelve &
+    &thirteen fourteen fifteen sixteen &
+    &seventeen'
+
+   write(*,*)'LEN=',len(string)
+   write(*,*)'INPUT:'
+   write(*,*)string
+
+   paragrph=paragraph(string,40)
+   write(*,*)'LEN=',len(paragrph),' SIZE=',size(paragrph)
+   write(*,*)'OUTPUT:'
+   write(*,'(a)')paragrph
+
+   write(*,'(a)')paragraph(string,0)
+   write(*,'(3x,a)')paragraph(string,47)
+
+   end program demo_paragraph
+
+

Results:

+
    LEN=         106
+    INPUT:
+    one two three four five six seven eight nine ten eleven twelve
+    thirteen fourteen fifteen sixteen seventeen
+    LEN=          40  SIZE=           3
+    OUTPUT:
+
+

one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen

+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

percent_encode(3f) - [M_strings:ENCODE] percent-encode strings and character arrays (LICENSE:PD)

+

SYNOPSIS

+

function percent_encode(text)

+
     character(len=1),intent(in)  :: text(:)
+     character(len=;),allocatable :: percent_encode
+
+

or

+

function percent_encode(text)

+
     character(len=*),intent(in)  :: text
+     character(len=;),allocatable :: percent_encode
+
+

DESCRIPTION

+

This function percent-encodes ASCII strings or ASCII character arrays. "Reserved" characters are encoded.

+

URI containing spaces or most other non-alphanumeric characters must be encoded using percent encoding (aka. URL encoding).

+

The characters allowed in a URI are either reserved or unreserved (or a percent character as part of a percent-encoding). Reserved characters are those characters that sometimes have special meaning, while unreserved characters have no such meaning. Using percent-encoding, characters which otherwise would not be allowed are represented using allowed characters. The sets of reserved and unreserved characters and the circumstances under which certain reserved characters have special meaning have changed slightly with each revision of specifications that govern URIs and URI schemes.

+

According to RFC 3986, the characters in a URL have to be taken from a defined set of unreserved and reserved ASCII characters. Any other characters are not allowed in a URL.

+

The unreserved characters can be encoded, but should not be. The unreserved characters are:

+
      > ABCDEFGHIJKLMNOPQRSTUVWXYZ
+      > abcdefghijklmnopqrstuvwxyz
+      > 0123456789-_.~
+
+

The reserved characters have to be encoded only under certain circumstances. The reserved characters are:

+
      >  * ' ( ) ; : @ & = + $ , / ? % # [ ]
+
+

OPTIONS

+ +

RETURNS

+ +

EXAMPLES

+

Sample program:

+
   program demo_percent_encode
+   use M_strings, only : percent_encode
+   use, intrinsic :: iso_fortran_env, only : stdout=>output_unit
+   implicit none
+      write(*,*)percent_encode('[this is a string]')
+   end program demo_percent_encode
+
+

Results:

+
 >  %5Bthis%20is%20a%20string%5D
+
+

AUTHOR

+

John S. Urban

+
+
+

NAME

+

quote(3f) - [M_strings:QUOTES] add quotes to string as if written with list-directed output (LICENSE:PD)

+

SYNOPSIS

+

function quote(str,mode,clip) result (quoted_str)

+
   character(len=*),intent(in)          :: str
+   character(len=*),optional,intent(in) :: mode
+   logical,optional,intent(in)          :: clip
+   character(len=:),allocatable         :: quoted_str
+
+

DESCRIPTION

+

Add quotes to a CHARACTER variable as if it was written using list-directed output. This is particularly useful for processing strings to add to CSV files.

+

OPTIONS

+ + + +
            DOUBLE   default. replace quote with double quotes
+            ESCAPE   replace quotes with backslash-quote instead of
+                     double quotes
+
+ +

RESULT

+ +

EXAMPLE

+

Sample program:

+
   program demo_quote
+   use M_strings, only : quote
+   implicit none
+   integer                      :: i
+   character(len=*),parameter   :: f='(*(g0))'
+   character(len=:),allocatable :: str
+   character(len=80),parameter  :: data(3)=[character(len=80)::&
+      'test string',&
+      'quote="',&
+      '"word1" "word2"']
+      do i=1,size(data)
+         ! the original string
+         write(*,'(a)')'ORIGINAL      '//trim(data(i))
+
+         ! the string processed by quote(3f)
+         str=quote(data(i))
+         write(*,'(a)')'QUOTED        '//str
+
+         ! write the string list-directed to compare the results
+         write(*,f,advance='no') 'LIST DIRECTED'
+         ! default is often NONE or APOSTROPHE
+         write(*,*,delim='quote') trim(data(i))
+      enddo
+   end program demo_quote
+
+

Results:

+
 > ORIGINAL      test string
+ > QUOTED        "test string"
+ > LIST DIRECTED "test string"
+ > ORIGINAL      quote="
+ > QUOTED        "quote="""
+ > LIST DIRECTED "quote="""
+ > ORIGINAL      "word1" "word2"
+ > QUOTED        """word1"" ""word2"""
+ > LIST DIRECTED """word1"" ""word2"""
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

real(3f) - [M_strings:TYPE] overloads REAL(3f) so it can handle character arguments (LICENSE:PD)

+

SYNOPSIS

+

impure elemental function real(string)

+
    character(len=*) :: string
+    integer          :: real
+
+

DESCRIPTION

+

real(3f) returns a REAL value when given a numeric representation of a numeric value. This overloads the REAL(3f) intrinsic so that CHARACTER arguments assumed to represent a numeric value may be input.

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLE

+

Sample program:

+
     program demo_real
+     use M_strings, only: real
+     implicit none
+     write(*,*)real('100'),real('20.4')
+     write(*,*)'real still works',real(20)
+     write(*,*)'elemental',&
+     & real([character(len=23) :: '10','20.3','20.5','20.6'])
+     end program demo_real
+
+

Results:

+
     >    100.000000       20.3999996
+     >  real still works   20.0000000
+     >  elemental   10.0000000  20.2999992  20.5000000  20.6000004
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

replace(3f) - [M_strings:EDITING] function replaces one substring for another in string (LICENSE:PD)

+

SYNOPSIS

+

syntax:

+
     function replace(targetline,old,new,cmd,&
+      & occurrence, &
+      & repeat, &
+      & ignorecase, &
+      & ierr) result (newline)
+     character(len=*)                       :: targetline
+     character(len=*),intent(in),optional   :: old
+     character(len=*),intent(in),optional   :: new
+     character(len=*),intent(in),optional   :: cmd
+     integer,intent(in),optional            :: occurrence
+     integer,intent(in),optional            :: repeat
+     logical,intent(in),optional            :: ignorecase
+     integer,intent(out),optional           :: ierr
+     character(len=:),allocatable           :: newline
+
+

DESCRIPTION

+

Replace one substring for another in string. Either CMD or OLD and NEW must be specified.

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLES

+

Sample Program:

+
   program demo_replace
+   use M_strings, only : replace
+   implicit none
+   character(len=:),allocatable :: line
+
+   write(*,*)replace('Xis is Xe string','X','th')
+   write(*,*)replace('Xis is xe string','x','th',ignorecase=.true.)
+   write(*,*)replace('Xis is xe string','X','th',ignorecase=.false.)
+
+   ! a null old substring means "at beginning of line"
+   write(*,*) replace('my line of text','','BEFORE:')
+
+   ! a null new string deletes occurrences of the old substring
+   write(*,*) replace('I wonder i ii iii','i','')
+
+   ! Examples of the use of RANGE
+
+   line=replace('aaaaaaaaa','a','A',occurrence=1,repeat=1)
+   write(*,*)'replace first a with A ['//line//']'
+
+   line=replace('aaaaaaaaa','a','A',occurrence=3,repeat=3)
+   write(*,*)'replace a with A for 3rd to 5th occurrence ['//line//']'
+
+   line=replace('ababababa','a','',occurrence=3,repeat=3)
+   write(*,*)'replace a with null instances 3 to 5 ['//line//']'
+
+   line=replace( &
+    & 'a b ab baaa aaaa aa aa a a a aa aaaaaa',&
+    & 'aa','CCCC',occurrence=-1,repeat=1)
+   write(*,*)'replace lastaa with CCCC ['//line//']'
+
+   write(*,*)replace('myf90stuff.f90.f90','f90','for',occurrence=-1,repeat=1)
+   write(*,*)replace('myf90stuff.f90.f90','f90','for',occurrence=-2,repeat=2)
+
+   end program demo_replace
+
+

Results:

+
    this is the string
+    this is the string
+    this is xe string
+    BEFORE:my line of text
+    I wonder
+    replace first a with A [Aaaaaaaaa]
+    replace a with A for 3rd to 5th occurrence [aaAAAaaaa]
+    replace a with null instances 3 to 5 [ababbb]
+    replace lastaa with CCCC [a b ab baaa aaaa aa aa a a a aa aaaaCCCC]
+    myf90stuff.f90.for
+    myforstuff.for.f90
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

reverse(3f) - [M_strings:EDITING] Return a string reversed (LICENSE:PD)

+

SYNOPSIS

+

elemental pure function reverse(str) result (string)

+
    character(*), intent(in) :: str
+    character(len(str))      :: string
+
+

DESCRIPTION

+

reverse(string) returns a copy of the input string with all characters reversed from right to left.

+

EXAMPLE

+

Sample program:

+
      program demo_reverse
+      use M_strings, only: reverse
+      implicit none
+      character(len=:),allocatable  :: s
+         write(*,*)'REVERSE STRINGS:',reverse('Madam, I''m Adam')
+         s='abcdefghijklmnopqrstuvwxyz'
+         write(*,*) 'original input string is ```.',s
+         write(*,*) 'reversed output string is ```',reverse(s)
+      end program demo_reverse
+
+

Results:

+
     >  REVERSE STRINGS:madA m'I ,madaM
+     >  original input string is ```.abcdefghijklmnopqrstuvwxyz
+     >  reversed output string is ```zyxwvutsrqponmlkjihgfedcba
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

rotate13(3f) - [M_strings:ENCODE] apply trivial ROT13 encryption to a string (LICENSE:PD)

+

SYNOPSIS

+

rotate13(input) result(output)

+
    character(len=*),intent(in) :: input
+    character(len=len(input))   :: output
+
+

DESCRIPTION

+

ROT13 ("rotate by 13 places", sometimes hyphenated ROT-13) is a simple letter substitution cipher that replaces a letter with the 13th letter after it in the alphabet; wrapping around if necessary.

+

The transformation can be done using a lookup table, such as the following:

+
      Input  ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+      Output NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm
+
+

ROT13 is used in online forums as a means of hiding spoilers, punchlines, puzzle solutions, and offensive materials from the casual glance. ROT13 has inspired a variety of letter and word games on-line, and is frequently mentioned in newsgroup conversations.

+

The algorithm provides virtually no cryptographic security, and is often cited as a canonical example of weak encryption.

+

ROT13 is a special case of the Caesar cipher which was developed in ancient Rome.

+

ALGORITHM

+

Applying ROT13 to a piece of text merely requires examining its alphabetic characters and replacing each one by the letter 13 places further along in the alphabet, wrapping back to the beginning if necessary. A becomes N, B becomes O, and so on up to M, which becomes Z, then the sequence continues at the beginning of the alphabet: N becomes A, O becomes B, and so on to Z, which becomes M. Only those letters which occur in the English alphabet are affected; numbers, symbols, whitespace, and all other characters are left unchanged.

+

SAME ALGORITHM FOR ENCODING AND DECODING

+

Because there are 26 letters in the English alphabet and 26 = 2 x 13, the ROT13 function is its own inverse: so the same action can be used for encoding and decoding. In other words, two successive applications of ROT13 restore the original text (in mathematics, this is sometimes called an involution; in cryptography, a reciprocal cipher).

+

TRIVIAL SECURITY

+

The use of a constant shift means that the encryption effectively has no key, and decryption requires no more knowledge than the fact that ROT13 is in use. Even without this knowledge, the algorithm is easily broken through frequency analysis.

+

In encrypted normal English-language text of any significant size, ROT13 is recognizable from some letter/word patterns. The words "n", "V" (capitalized only), and "gur" (ROT13 for "a", "I", and "the"), and words ending in "yl" ("ly") are examples.

+

REFERENCES

+

Wikipedia, the free encyclopedia

+

EXAMPLE

+

Sample program

+
   program demo_rotate13
+   use M_strings, only : rotate13
+   implicit none
+   character(len=256) :: line
+   integer            :: ios
+   do
+      read(*,'(a)',iostat=ios)line
+      if(ios /= 0)exit
+      write(*,'(a)')rotate13(line)
+   enddo
+   end program demo_rotate13
+
+

Sample usage:

+
   demo_rotate13
+   United we stand, divided we fall.
+   Havgrq jr fgnaq, qvivqrq jr snyy.
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

rpad(3f) - [M_strings:LENGTH] convert to a string and pad on the right to requested length (LICENSE:PD)

+

SYNOPSIS

+

function rpad(valuein,length) result(strout)

+
    class*,intent(in)       :: valuein(..)
+    integer,intent(in)      :: length
+
+

DESCRIPTION

+

rpad(3f) converts a scalar intrinsic value to a string and then pads it on the right with spaces to at least the specified length. If the trimmed input string is longer than the requested length the string is returned trimmed of leading and trailing spaces.

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLE

+

Sample Program:

+
     program demo_rpad
+      use M_strings, only : rpad
+      implicit none
+         write(*,'("[",a,"]")') rpad( 'my string', 20)
+         write(*,'("[",a,"]")') rpad( 'my string   ', 20)
+         write(*,'("[",a,"]")') rpad( '   my string', 20)
+         write(*,'("[",a,"]")') rpad( '   my string   ', 20)
+         write(*,'("[",a,"]")') rpad( valuein=42 , length=7)
+         write(*,'("[",a,"]")') rpad( valuein=1.0/9.0 , length=20)
+     end program demo_rpad
+
+

Results:

+
     > [my string           ]
+     > [my string           ]
+     > [my string           ]
+     > [my string           ]
+     > [42     ]
+     > [0.111111112         ]
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

s2c(3f) - [M_strings:ARRAY] convert character variable to array of characters with last element set to null (LICENSE:PD)

+

SYNOPSIS

+

function s2c(string)

+
    character(len=*),intent=(in)  :: string
+    character(len=1),allocatable  :: s2c(:)
+
+

DESCRIPTION

+

Given a character variable convert it to an array of single-character character variables with the last element set to a null character. This is generally used to pass character variables to C procedures.

+

EXAMPLES

+

character(len=3),allocatable :: array(:)

+ +

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

s2v(3f) - [M_strings:TYPE] function returns doubleprecision numeric value from a string (LICENSE:PD)

+

SYNOPSIS

+

function s2v(string[,ierr][,onerr])

+
    character(len=*)             :: string
+    doubleprecision              :: s2v
+    integer,intent(out),optional :: ierr
+    class(*),intent(in),optional :: onerr
+
+

DESCRIPTION

+

This function converts a string to a DOUBLEPRECISION numeric value.

+

The intrinsics INT(3f), REAL(3f), and DBLE(3f) are also extended to take CHARACTER variables. The KIND= keyword is not supported on the extensions.

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLE

+

Sample Program:

+
   program demo_s2v
+
+    use M_strings, only: s2v, int, real, dble
+    implicit none
+    character(len=8)              :: s=' 10.345 '
+    integer                       :: i
+    character(len=14),allocatable :: strings(:)
+    doubleprecision               :: dv
+    integer                       :: errnum
+
+    ! different strings representing INTEGER, REAL, and DOUBLEPRECISION
+    strings=[&
+    &' 10.345       ',&
+    &'+10           ',&
+    &'    -3        ',&
+    &'    -4.94e-2  ',&
+    &'0.1           ',&
+    &'12345.678910d0',&
+    &'              ',& ! Note: will return zero without an error message
+    &'1 2 1 2 1 . 0 ',& ! Note: spaces will be ignored
+    &'WHAT?         ']  ! Note: error messages will appear, zero returned
+
+    ! a numeric value is returned,
+    ! so it can be used in numeric expression
+    write(*,*) '1/2 value of string is ',s2v(s)/2.0d0
+    write(*,*)
+    write(*,*)' STRING            VALUE                    ERROR_NUMBER'
+    do i=1,size(strings)
+       ! Note: not a good idea to use s2v(3f) in a WRITE(3f) statement,
+       ! as it does I/O when errors occur, so called on a separate line
+       dv=s2v(strings(i),errnum)
+       write(*,*) strings(i)//'=',dv,errnum
+    enddo
+    write(*,*)"Extended intrinsics"
+    write(*,*)'given inputs:',s,strings(:8)
+    write(*,*)'INT(3f):',int(s),int(strings(:8))
+    write(*,*)'REAL(3f):',real(s),real(strings(:8))
+    write(*,*)'DBLE(3f):',dble(s),dble(strings(:8))
+    write(*,*)"That's all folks!"
+
+    end program demo_s2v
+
+   Expected output
+
+    >1/2 value of string is    5.1725000000000003
+    >
+    > STRING            VALUE                    ERROR_NUMBER
+    > 10.345       =   10.345000000000001                0
+    >+10           =   10.000000000000000                0
+    >    -3        =  -3.0000000000000000                0
+    >    -4.94e-2  =  -4.9399999999999999E-002           0
+    >0.1           =  0.10000000000000001                0
+    >12345.678910d0=   12345.678910000001                0
+    >              =   0.0000000000000000                0
+    >1 2 1 2 1 . 0 =   12121.000000000000                0
+    >*a2d* - cannot produce number from string [WHAT?]
+    >*a2d* - [Bad value during floating point read]
+    >WHAT?         =   0.0000000000000000             5010
+    >Extended intrinsics
+    >given inputs: 10.345 10.345 +10 -3 -4.94e-2 0.1
+    12345.678910d0 1 2 1 2 1 . 0
+    >INT(3f): 10 10 10 -3 0 0 12345 0 12121
+    >REAL(3f): 10.3450003 10.3450003 10.0000000 -3.00000000
+    -4.94000018E-02
+    >          0.100000001 12345.6787 0.00000000 12121.0000
+    >DBLE(3f): 10.345000000000001 10.345000000000001
+    10.000000000000000
+    >          -3.0000000000000000 -4.9399999999999999E-002
+    0.10000000000000001
+    >          12345.678910000001 0.0000000000000000
+    12121.000000000000
+    >That's all folks!
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

s2vs(3f) - [M_strings:TYPE] given a string representing numbers return a numeric array (LICENSE:PD)

+

SYNOPSIS

+

function s2vs(line[,delim])

+
       character(len=*) :: line
+       doubleprecision,allocatable :: s2vs(:)
+
+

DESCRIPTION

+

The function S2VS(3f) takes a string representing a series of numbers and converts it to a numeric doubleprecision array. The string values may be delimited by spaces, semi-colons, and commas by default.

+

OPTIONS

+ +

RESULTS

+ +

EXAMPLE

+

Sample Program:

+
     program demo_s2vs
+     use M_strings, only : s2vs
+     implicit none
+     character(len=80) :: s=' 10 20e3;3.45 -400.3e-2;1234; 5678 '
+     real,allocatable :: values(:)
+     integer,allocatable :: ivalues(:)
+     integer :: ii
+
+     values=s2vs(s)
+     ivalues=int(s2vs(s))
+     call reportit()
+
+     contains
+       subroutine reportit()
+         write(*,*)'S2VS:'
+         write(*,*)'input string```..........',&
+          & trim(s)
+         write(*,*)'number of values found```',&
+          & size(values)
+         write(*,*)'values```................',&
+          & (values(ii),ii=1,size(values))
+         write(*,'(*(g0,1x))')'ivalues```...............',&
+          & (ivalues(ii),ii=1,size(values))
+       end subroutine reportit
+     end program demo_s2vs
+
+

Expected output

+
    S2VS:
+    input string```.......... 10 20e3;3.45 -400.3e-2;1234; 5678
+    number of values found```           6
+    values```................   10.0000000 20000.0000 3.45000005
+    -4.00299978 1234.00000 5678.00000
+
+

ivalues```............... 10 20000 3 -4 1234 5678

+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

sep(3f) - [M_strings:TOKENS] function to parse string into an array using specified delimiters (LICENSE:PD)

+

SYNOPSIS

+

function sep(input_line,delimiters,nulls)

+
    character(len=*),intent(in)              :: input_line
+    character(len=*),optional,intent(in)     :: delimiters
+    character(len=*),optional,intent(in)     :: nulls
+    character(len=:),allocatable             :: sep(:)
+
+

DESCRIPTION

+

sep(3f) parses a string using specified delimiter characters and store tokens into an allocatable array

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLES

+

Sample program:

+
   program demo_sep
+   use M_strings, only: sep
+   character(len=*),parameter :: fo='(/,a,*(/,"[",g0,"]":,","))'
+   character(len=*),parameter :: line=&
+   '  aBcdef   ghijklmnop qrstuvwxyz  1:|:2     333|333 a B cc    '
+      write(*,'(a)') 'INPUT LINE:['//LINE//']'
+      write(*,fo) 'typical call:',sep(line)
+      write(*,fo) 'delimiters ":|":',sep(line,':|')
+      write(*,fo) 'count null fields ":|":',sep(line,':|','return')
+   end program demo_sep
+
+

Output

+
   INPUT LINE:[  aBcdef   ghijklmnop qrstuvwxyz  1:|:2     333|333 a B cc    ]
+
+   typical call:
+   [cc        ],
+   [B         ],
+   [a         ],
+   [333|333   ],
+   [1:|:2     ],
+   [qrstuvwxyz],
+   [ghijklmnop],
+   [aBcdef    ]
+
+   delimiters ":|":
+   [333 a B cc                         ],
+   [2     333                          ],
+   [  aBcdef   ghijklmnop qrstuvwxyz  1]
+
+   count null fields ":|":
+   [333 a B cc                         ],
+   [2     333                          ],
+   [                                   ],
+   [                                   ],
+   [  aBcdef   ghijklmnop qrstuvwxyz  1]
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

slice(3f) - [M_strings:TOKENS] parse string into an array using specified delimiters (LICENSE:PD)

+

SYNOPSIS

+

subroutine slice(input_line,ibegin,iend,delimiters,nulls)

+
    character(len=*),intent(in)              :: input_line
+    integer,allocatable,intent(out)          :: ibegin(:),iend(:)
+    character(len=*),optional,intent(in)     :: delimiters
+    character(len=*),optional,intent(in)     :: nulls
+
+

DESCRIPTION

+

slice(3f) parses a string using specified delimiter characters and store token beginning and ending positions into allocatable arrays

+

OPTIONS

+ +

EXAMPLES

+

Sample program:

+
    program demo_slice
+    use M_strings, only: slice
+    implicit none
+    integer :: i
+    character(len=*),parameter     :: &
+    & line='  aBcdef   ghijklmnop qrstuvwxyz  1:|:2     333|333 a B cc    '
+    integer,allocatable :: ibegin(:), iend(:) ! output arrays of positions
+    character(len=*),parameter :: title='(80("="),t1,a)'
+       write(*,*)'INPUT LINE:['//line//']'
+       !
+       write(*,title)'typical call: '
+       call slice(line,ibegin,iend)
+       call printme()
+       !
+       write(*,title)'custom list of delimiters=":|" : '
+       call slice(line,ibegin,iend,delimiters=':|',nulls='ignore')
+       call printme()
+       !
+       write(*,title)'delimiters=":|", and count null fields: '
+       call slice(line,ibegin,iend,delimiters=':|',nulls='return')
+       call printme()
+       !
+       write(*,title)'default delimiters and return null fields: '
+       call slice(line,ibegin,iend,delimiters='',nulls='return')
+       call printme()
+    contains
+    subroutine printme()
+       write(*,'((*(:/,3x,"[",g0,"]")))')&
+               & (line(ibegin(i):iend(i)),i=1,size(ibegin))
+       write(*,'(*(g0,1x))')'SIZE:',size(ibegin)
+    end subroutine printme
+    end program demo_slice
+
+

Results:

+
 > INPUT LINE:
+ > [  aBcdef   ghijklmnop qrstuvwxyz  1:|:2     333|333 a B cc    ]
+ > typical call: ========================================================
+ >
+ >    [aBcdef]
+ >    [ghijklmnop]
+ >    [qrstuvwxyz]
+ >    [1:|:2]
+ >    [333|333]
+ >    [a]
+ >    [B]
+ >    [cc]
+ > SIZE: 8
+ > custom list of delimiters=":|" : =====================================
+ >
+ >    [  aBcdef   ghijklmnop qrstuvwxyz  1]
+ >    [2     333]
+ >    [333 a B cc    ]
+ > SIZE: 3
+ > delimiters=":|", and count null fields: ==============================
+ >
+ >    [  aBcdef   ghijklmnop qrstuvwxyz  1]
+ >    []
+ >    []
+ >    [2     333]
+ >    [333 a B cc    ]
+ > SIZE: 5
+ > default delimiters and return null fields: ===========================
+ >
+ >    []
+ >    []
+ >    [aBcdef]
+ >    []
+ >    []
+ >    [ghijklmnop]
+ >    [qrstuvwxyz]
+ >    []
+ >    [1:|:2]
+ >    []
+ >    []
+ >    []
+ >    []
+ >    [333|333]
+ >    [a]
+ >    [B]
+ >    [cc]
+ >    []
+ >    []
+ >    []
+ > SIZE: 20
+
+

======================================================================

+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

split2020(3f) - [M_strings:TOKENS] parse a string into tokens using proposed f2023 method (LICENSE:PD)

+

SYNOPSIS

+

TOKEN form

+
   subroutine split2020 (string, set, tokens, separator)
+   character(len=*),intent(in) :: string
+   character(len=*),intent(in) :: set
+   character(len=:),allocatable,intent(out) :: tokens(:)
+   character(len=1),allocatable,intent(out),optional :: separator(:)
+
+

BOUNDS ARRAY form

+
   subroutine split2020 (string, set, first, last)
+   character(len=*),intent(in) :: string
+   character(len=*),intent(in) :: set
+   integer,allocatable,intent(out) :: first(:)
+   integer,allocatable,intent(out) :: last(:)
+
+

STEP THROUGH BY POSITION form

+
   subroutine split2020 (string, set, pos [, back])
+   character(len=*),intent(in) :: string
+   character(len=*),intent(in) :: set
+   integer,intent(inout)       :: pos
+   logical,intent(in),optional :: back
+
+

DESCRIPTION

+

Parse a string into tokens. STRING, SET, TOKENS and SEPARATOR must all be of the same CHARACTER kind type parameter.

+

OPTIONS

+ +

EXAMPLES

+

Sample of uses

+
   program demo_sort2020
+   use M_strings, only : split2020
+   implicit none
+   character(len=*),parameter :: gen='(*("[",g0,"]":,","))'
+
+    ! Execution of TOKEN form
+    block
+      character (len=:), allocatable :: string
+      character (len=:), allocatable :: tokens(:)
+      character (len=*),parameter :: set = " ,"
+      string = 'first,second,third'
+      call split2020(string, set, tokens )
+      write(*,gen)tokens
+
+    ! assigns the value ['first ','second','third ' ]
+    ! to TOKENS.
+    endblock
+
+    ! Execution of BOUNDS form
+
+    block
+      character (len=:), allocatable :: string
+      character (len=*),parameter :: set = " ,"
+      integer, allocatable        :: first(:), last(:)
+      string =    'first,second,,forth'
+      call split2020 (string, set, first, last)
+      write(*,gen)first
+      write(*,gen)last
+
+    ! will assign the value [ 1, 7, 14, 15 ] to FIRST,
+    ! and the value [ 5, 12, 13, 19 ] to LAST.
+    endblock
+
+    ! Execution of STEP form
+    block
+      character (len=:), allocatable :: string
+      character (len=*),parameter :: set = " ,"
+      integer :: p, ibegin, iend
+      string = " one,   last  example  "
+      do while (p < len(string))
+        ibegin = p + 1
+        call split2020 (string, set, p)
+        iend=p-1
+        if(iend > ibegin)then
+           print '(t3,a,1x,i0,1x,i0)', string (ibegin:iend),ibegin,iend
+        endif
+      enddo
+    endblock
+   end program demo_sort2020
+
+

Results:

+
   [first ],[second],[third ]
+   [1],[7],[14],[15]
+   [5],[12],[13],[19]
+     one 2 4
+     last 9 12
+     example 15 21
+
+     > ??? option to skip adjacent delimiters (not return null tokens)
+     >     common with whitespace
+     > ??? quoted strings, especially CSV both " and ', Fortran adjacent
+     >     is insert versus other rules
+     > ??? escape character like \\ .
+     > ??? multi-character delimiters like \\n, \\t,
+     > ??? regular expression separator
+
+

AUTHOR

+

Milan Curcic, "milancurcic@hey.com"

+

LICENSE

+

MIT

+

VERSION

+

version 0.1.0, copyright 2020, Milan Curcic

+
+
+

NAME

+

split(3f) - [M_strings:TOKENS] parse string into an array using specified delimiters (LICENSE:PD)

+

SYNOPSIS

+

subroutine split(input_line,array,delimiters,order,nulls)

+
    character(len=*),intent(in)              :: input_line
+    character(len=:),allocatable,intent(out) :: array(:)
+    character(len=*),optional,intent(in)     :: delimiters
+    character(len=*),optional,intent(in)     :: order
+    character(len=*),optional,intent(in)     :: nulls
+
+

DESCRIPTION

+

SPLIT(3f) parses a string using specified delimiter characters and store tokens into an allocatable array

+

OPTIONS

+ +

EXAMPLES

+

Sample program:

+
   program demo_split
+   use M_strings, only: split
+   implicit none
+   integer :: i
+   character(len=*),parameter :: title='(80("="),t1,a)'
+   character(len=*),parameter     :: line=&
+   '  aBcdef   ghijklmnop qrstuvwxyz  1:|:2     333|333 a B cc    '
+   character(len=:),allocatable :: array(:) ! output array of tokens
+      write(*,*)'INPUT LINE:['//line//']'
+      !
+      write(*,title)'typical call: '
+      call split(line,array)
+      call printme()
+      !
+      write(*,title)'custom delimiters=":|" : '
+      call split(line,array,delimiters=':|',&
+      & order='sequential',nulls='ignore')
+      call printme()
+      !
+      write(*,title)&
+      'delimiters=":|",reverse array order and count null fields:'
+      call split(line,array,delimiters=':|',&
+      & order='reverse',nulls='return')
+      call printme()
+      !
+      write(*,title)&
+      'default delimiters, reverse array order and return null fields:'
+      call split(line,array,delimiters='',&
+      & order='reverse',nulls='return')
+      call printme()
+   contains
+   subroutine printme()
+      write(*,'(i0," ==> ",a)')(i,trim(array(i)),i=1,size(array))
+      write(*,*)'SIZE:',size(array)
+   end subroutine printme
+   end program demo_split
+
+

Results:

+
 > INPUT LINE:
+ > [  aBcdef   ghijklmnop qrstuvwxyz  1:|:2     333|333 a B cc    ]
+ > typical call: ========================================================
+ > 1 ==> aBcdef
+ > 2 ==> ghijklmnop
+ > 3 ==> qrstuvwxyz
+ > 4 ==> 1:|:2
+ > 5 ==> 333|333
+ > 6 ==> a
+ > 7 ==> B
+ > 8 ==> cc
+ >  SIZE:           8
+ > custom delimiters=":|" : =============================================
+ > 1 ==>   aBcdef   ghijklmnop qrstuvwxyz  1
+ > 2 ==> 2     333
+ > 3 ==> 333 a B cc
+ >  SIZE:           3
+ > delimiters=":|",reverse array order and count null fields:============
+ > 1 ==> 333 a B cc
+ > 2 ==> 2     333
+ > 3 ==>
+ > 4 ==>
+ > 5 ==>   aBcdef   ghijklmnop qrstuvwxyz  1
+ >  SIZE:           5
+ > default delimiters, reverse array order and return null fields:=======
+ > 1 ==>
+ > 2 ==>
+ > 3 ==>
+ > 4 ==> cc
+ > 5 ==> B
+ > 6 ==> a
+ > 7 ==> 333|333
+ > 8 ==>
+ > 9 ==>
+ > 10 ==>
+ > 11 ==>
+ > 12 ==> 1:|:2
+ > 13 ==>
+ > 14 ==> qrstuvwxyz
+ > 15 ==> ghijklmnop
+ > 16 ==>
+ > 17 ==>
+ > 18 ==> aBcdef
+ > 19 ==>
+ > 20 ==>
+ >  SIZE:          20
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

squeeze(3f) - [M_strings:EDITING] delete adjacent duplicate occurrences of a character from a string (LICENSE:PD)

+

SYNOPSIS

+

function squeeze(STR,CHAR) result (OUTSTR)

+
    character(len=*),intent(in)          :: STR
+    character(len=*),intent(in),optional :: CHAR
+    character(len=len(str))              :: OUTSTR
+
+

DESCRIPTION

+

squeeze(3f) reduces adjacent duplicates of the specified character to a single character

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLES

+

Sample Program:

+
   program demo_squeeze
+   use M_strings, only : squeeze
+   implicit none
+   character(len=:),allocatable :: strings(:)
+
+   strings=[ character(len=72) :: &
+   &'', &
+   &'"If I were two-faced,&
+   &would I be wearing this one?" --- Abraham Lincoln',  &
+   &'..1111111111111111111&
+   &111111111111111111111111111111111111111111117777888', &
+   &'I never give ''em hell,&
+   &I just tell the truth, and they think it''s hell.',&
+   &'                                                  &
+   & --- Harry S Truman'    &
+   &]
+      call printme( trim(strings(1)), ' ' )
+      call printme( strings(2:4),     ['-','7','.'] )
+      call printme( strings(5),       [' ','-','r'] )
+   contains
+   impure elemental subroutine printme(str,chr)
+   character(len=*),intent(in) :: str
+   character(len=1),intent(in) :: chr
+   character(len=:),allocatable :: answer
+      write(*,'(a)')repeat('=',11)
+      write(*,'("IN:   <<<",g0,">>>")')str
+      answer=squeeze(str,chr)
+      write(*,'("OUT:  <<<",g0,">>>")')answer
+      write(*,'("LENS: ",*(g0,1x))')"from",len(str),"to",len(answer), &
+              & "for a change of",len(str)-len(answer)
+      write(*,'("CHAR: ",g0)')chr
+   end subroutine printme
+   end program demo_squeeze
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

stretch(3f) - [M_strings:LENGTH] return string padded to at least specified length (LICENSE:PD)

+

SYNOPSIS

+

function stretch(str,length,pattern,suffix) result(strout)

+
    character(len=*),intent(in)         :: str
+    integer,intent(in)                  :: length
+    character(len=*)intent(in),optional :: pattern
+    character(len=*)intent(in),optional :: suffix
+    character(len=:),allocatable        :: strout
+
+

DESCRIPTION

+

stretch(3f) pads a string with spaces to at least the specified length. If the trimmed input string is longer than the requested length the original string is returned trimmed of trailing spaces.

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLE

+

Sample Program:

+
  program demo_stretch
+   use M_strings, only : stretch
+   implicit none
+   character(len=10)            :: string='abcdefghij'
+   character(len=:),allocatable :: answer
+   integer                      :: i
+      answer=stretch(string,5)
+      write(*,'("[",a,"]")') answer
+      answer=stretch(string,20)
+      write(*,'("[",a,"]")') answer
+      i=30
+      write(*,*)
+      write(*,'(1x,a,i0)') &
+       & stretch('CHAPTER 1 : The beginning ',i,'.'), 1    ,&
+       & stretch('CHAPTER 2 : The end ',i,'.'),       1234 ,&
+       & stretch('APPENDIX ',i,'.'),                  1235
+      write(*,*)
+      write(*,'(1x,a,i7)') &
+       & stretch('CHAPTER 1 : The beginning ',i,'.'), 1    ,&
+       & stretch('CHAPTER 2 : The end ',i,'.'),       1234 ,&
+       & stretch('APPENDIX ',i,'.'),                  1235
+      write(*,*)
+      write(*,*) &
+       & stretch('CHAPTER 1 : The beginning ',i,suffix=': '), 1
+      write(*,*) &
+       & stretch('CHAPTER 2 : The end ',i,suffix=': '),1234
+      write(*,*) &
+       & stretch('APPENDIX ',i,suffix=': '),           1235
+  end program demo_stretch
+
+  Results:
+
+   [abcdefghij]
+   [abcdefghij          ]
+
+    CHAPTER 1 : The beginning ```.1
+    CHAPTER 2 : The end ```.......1234
+    APPENDIX ```..................1235
+
+    CHAPTER 1 : The beginning ```.      1
+    CHAPTER 2 : The end ```.......   1234
+    APPENDIX ```..................   1235
+
+    CHAPTER 1 : The beginning     :            1
+    CHAPTER 2 : The end           :         1234
+    APPENDIX                      :         1235
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

string_to_value(3f) - [M_strings:TYPE] subroutine returns numeric value from string (LICENSE:PD)

+

SYNOPSIS

+

subroutine string_to_value(chars,valu,ierr)

+
    character(len=*),intent(in)              :: chars   ! input string
+    integer|real|doubleprecision,intent(out) :: valu
+    integer,intent(out)                      :: ierr
+
+

DESCRIPTION

+

Returns a numeric value from a numeric character string.

+

Works with any g-format input, including integer, real, and exponential. If the input string begins with "B", "Z", or "O" and otherwise represents a positive whole number it is assumed to be a binary, hexadecimal, or octal value. If the string contains commas they are removed. If the string is of the form NN:MMM``` or NN#MMM then NN is assumed to be the base of the whole number.

+

If an error occurs in the READ, IOSTAT is returned in IERR and value is set to zero. if no error occurs, IERR=0.

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLE

+

Sample Program:

+
   program demo_string_to_value
+    use M_strings, only: string_to_value
+    implicit none
+    real :: value
+    integer :: ierr
+    character(len=80) :: string
+       string=' -40.5e-2 '
+       call string_to_value(string,value,ierr)
+       write(*,*) 'value of string ['//trim(string)//'] is ',value
+   end program demo_string_to_value
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

string_to_values(3f) - [M_strings:TYPE] read a string representing numbers into a numeric array (LICENSE:PD)

+

SYNOPSIS

+

subroutine string_to_values(line,iread,values,inums,delims,ierr)

+
       character(len=*) :: line
+       integer          :: iread
+       real             :: values(*)
+       integer          :: inums
+       character(len=*) :: delims
+       integer          :: ierr
+
+

DESCRIPTION

+

This routine can take a string representing a series of numbers and convert it to a numeric array and return how many numbers were found.

+

OPTIONS

+ +

RESULTS

+ +

EXAMPLE

+

Sample Program:

+
     program demo_string_to_values
+      use M_strings, only : string_to_values
+      implicit none
+      character(len=80)  :: s=' 10 20e3;3.45 -400.3e-2;1234; 5678 '
+      integer,parameter  :: isz=10
+      real               :: array(isz)
+      integer            :: inums, ierr, ii
+
+      call string_to_values(s,10,array,inums,' ;',ierr)
+      call reportit()
+
+      call string_to_values('10;2.3;3.1416',isz,array,inums,' ;',ierr)
+      call reportit()
+
+      contains
+         subroutine reportit()
+            write(*,*)'string_to_values:'
+            write(*,*)'input string```..........',trim(s)
+            write(*,*)'number of values found```',inums
+            write(*,*)'values```................',(array(ii),ii=1,inums)
+         end subroutine reportit
+     end program demo_string_to_values
+
+

Expected output

+
    string_to_values:
+    input string```.......... 10 20e3;3.45 -400.3e-2;1234; 5678
+    number of values found```           6
+    values```................   10.0000000  20000.0000  3.45000005
+    -4.00299978  1234.00000  5678.00000
+    string_to_values:
+    input string```.......... 10 20e3;3.45 -400.3e-2;1234; 5678
+    number of values found```           3
+    values```................   10.0000000  2.29999995  3.14159989
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

strtok(3f) - [M_strings:TOKENS] Tokenize a string (LICENSE:PD)

+

SYNOPSIS

+

function strtok(source_string,itoken,token_start,token_end,delimiters) result(strtok_status)

+
  ! returned value
+  logical                      :: strtok_status
+  ! string to tokenize
+  character(len=*),intent(in)  :: source_string
+  ! token count since started
+  integer,intent(inout)        :: itoken
+  ! beginning of token
+  integer,intent(out)          :: token_start
+  ! end of token
+  integer,intent(inout)        :: token_end
+  ! list of separator characters
+  character(len=*),intent(in)  :: delimiters
+
+

DESCRIPTION

+

The STRTOK(3f) function is used to isolate sequential tokens in a string, SOURCE_STRING. These tokens are delimited in the string by at least one of the characters in DELIMITERS. The first time that STRTOK(3f) is called, ITOKEN should be specified as zero. Subsequent calls, wishing to obtain further tokens from the same string,

+ +

This routine assumes no other calls are made to it using any other input string while it is processing an input line.

+

OPTIONS

+ +

RETURN

+ +

EXAMPLES

+

Sample program:

+
    program demo_strtok
+    use M_strings, only : strtok
+    implicit none
+    character(len=264)          :: inline
+    character(len=*),parameter  :: delimiters=' ;,'
+    integer                     :: ios, itoken, ibegin, iend
+       do ! read lines from stdin until end-of-file or error
+          read (unit=*,fmt="(a)",iostat=ios) inline
+          if(ios /= 0)stop
+          ! must set ITOKEN=0 before looping on strtok(3f)
+          ! on a new string.
+          itoken=0
+          do while &
+          &( strtok(inline,itoken,ibegin,iend,delimiters) )
+             print *, itoken,&
+             & 'TOKEN=['//(inline(ibegin:iend))//']',ibegin,iend
+          enddo
+       enddo
+    end program demo_strtok
+
+    sample input file
+
+     this is a test of strtok; A:B :;,C;;
+
+    sample output file
+
+    1  TOKEN=[this]    2   5
+    2  TOKEN=[is]      7   8
+    3  TOKEN=[a]       10  10
+    4  TOKEN=[test]    12  15
+    5  TOKEN=[of]      17  18
+    6  TOKEN=[strtok]  20  25
+    7  TOKEN=[A:B]     28  30
+    8  TOKEN=[:]       32  32
+    9  TOKEN=[C]       35  35
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

substitute(3f) - [M_strings:EDITING] subroutine globally substitutes one substring for another in string (LICENSE:PD)

+

SYNOPSIS

+

subroutine substitute(targetline,old,new,ierr,start,end)

+
    character(len=*)              :: targetline
+    character(len=*),intent(in)   :: old
+    character(len=*),intent(in)   :: new
+    integer,intent(out),optional  :: ierr
+    integer,intent(in),optional   :: start
+    integer,intent(in),optional   :: end
+
+

DESCRIPTION

+

Globally substitute one substring for another in string.

+

OPTIONS

+ +

EXAMPLES

+

Sample Program:

+
   program demo_substitute
+   use M_strings, only : substitute
+   implicit none
+   ! must be long enough to hold changed line
+   character(len=80) :: targetline
+
+   targetline='this is the input string'
+   write(*,*)'ORIGINAL    : '//trim(targetline)
+
+   ! changes the input to 'THis is THe input string'
+   call substitute(targetline,'th','TH')
+   write(*,*)'th => TH    : '//trim(targetline)
+
+   ! a null old substring means "at beginning of line"
+   ! changes the input to 'BEFORE:this is the input string'
+   call substitute(targetline,'','BEFORE:')
+   write(*,*)'"" => BEFORE: '//trim(targetline)
+
+   ! a null new string deletes occurrences of the old substring
+   ! changes the input to 'ths s the nput strng'
+   call substitute(targetline,'i','')
+   write(*,*)'i => ""     : '//trim(targetline)
+
+   end program demo_substitute
+
+

Expected output

+
    ORIGINAL    : this is the input string
+    th => TH    : THis is THe input string
+    "" => BEFORE: BEFORE:THis is THe input string
+    i => ""     : BEFORE:THs s THe nput strng
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

switch(3f) - [M_strings:ARRAY] converts between CHARACTER scalar and array of single characters (LICENSE:PD)

+

SYNOPSIS

+

pure function switch(array) result (string)

+
    character(len=1),intent(in) :: array(:)
+    character(len=SIZE(array))  :: string
+
+     or
+
+

pure function switch(string) result (array)

+
    character(len=*),intent(in) :: string
+    character(len=1)            :: array(len(string))
+
+

DESCRIPTION

+

SWITCH(3f): generic function that switches CHARACTER string to an array of single characters or an array of single characters to a CHARACTER string. Useful in passing strings to C. New Fortran features may supersede these routines.

+

EXAMPLES

+

Sample program:

+
   program demo_switch
+   use M_strings, only : switch, isalpha, islower, nospace
+   character(len=*),parameter :: &
+   & dashes='-----------------------------------'
+   character(len=*),parameter :: string='This is a string'
+   character(len=1024)        :: line
+
+   ! First, examples of standard Fortran features
+   ! returns array [F,T,T,T,T,T]
+   write(*,*)['A','=','=','=','=','='] == '='
+   ! this would return T
+   write(*,*)all(['=','=','=','=','=','='] == '=')
+   ! this would return F
+   write(*,*)all(['A','=','=','=','=','='] == '=')
+
+   ! so to test if the string DASHES is all dashes
+   ! using SWITCH(3f) is
+   if(all(switch(dashes) == '-'))then
+      write(*,*)'DASHES is all dashes'
+   endif
+
+   ! so to test is a string is all letters
+   ! isalpha(3f) returns .true. only if character is a letter
+   ! false because dashes are not a letter
+   write(*,*) all(isalpha(switch(dashes)))
+   ! false because of spaces
+   write(*,*) all(isalpha(switch(string)))
+   ! true because removed whitespace
+   write(*,*) all(isalpha(switch(nospace(string))))
+
+   ! to see if a string is all uppercase
+   ! show the string
+   write(*,*) string
+   ! converted to character array
+   write(*,'(1x,*("[",a,"]":))') switch(string)
+   write(*,'(*(l3))') islower(switch(string))
+
+   ! we need a string that is all letters
+   line=nospace(string)
+   write(*,*)'LINE=',trim(line)
+   ! all true except first character
+   write(*,*) islower(switch(nospace(string)))
+   ! should be false
+   write(*,*) all(islower(switch(nospace(string))))
+   ! should be true
+   write(*,*) all(islower(switch(nospace(string(2:)))))
+
+   end program demo_switch
+
+

Expected output

+

F T T T T T

+

T

+

F

+

DASHES is all dashes

+

F

+

F

+

T

+

This is a string [T][h][i][s][ ][i][s][ ][a][ ][s][t][r][i][n][g]

+

F T T T F T T F T F T T T T T T

+

LINE=Thisisastring

+

F T T T T T T T T T T T T

+

F

+

T

+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

transliterate(3f) - [M_strings:EDITING] replace characters from old set with new set (LICENSE:PD)

+

SYNOPSIS

+

pure function transliterate(instr,old_set,new_set) result(outstr)

+
    character(len=*),intent(in)  :: instr
+    character(len=*),intent(in)  :: old_set
+    character(len=*),intent(in)  :: new_set
+    character(len=len(instr))    :: outstr
+
+

DESCRIPTION

+

Translate, squeeze, and/or delete characters from the input string.

+

OPTIONS

+ + + +
            Each character in the input string that matches a character
+            in the old set is replaced.
+
+ + + +
            If the new_set is the empty set the matched characters
+            are deleted.
+
+            If the new_set is shorter than the old set the last character
+            in the new set is used to replace the remaining characters
+            in the new set.
+
+

RETURNS

+ +

EXAMPLES

+

Sample Program:

+
   program demo_transliterate
+
+    use M_strings, only : transliterate
+    implicit none
+    character(len=80)   :: STRING
+
+    STRING='aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ'
+    write(*,'(a)') STRING
+
+    ! convert a string to uppercase:
+    write(*,*) TRANSLITERATE(STRING, &
+    & 'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')
+
+    ! change all miniscule letters to a colon (":"):
+    write(*,*) TRANSLITERATE(STRING, &
+    & 'abcdefghijklmnopqrstuvwxyz',':')
+
+    ! delete all miniscule letters
+    write(*,*) TRANSLITERATE(STRING, &
+    & 'abcdefghijklmnopqrstuvwxyz','')
+
+   end program demo_transliterate
+
+   Expected output
+
+    > aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ
+    > AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ
+    > :A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z
+    > ABCDEFGHIJKLMNOPQRSTUVWXYZ
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

unquote(3f) - [M_strings:QUOTES] remove quotes from string as if read with list-directed input (LICENSE:PD)

+

SYNOPSIS

+

function unquote(quoted_str,esc) result (unquoted_str)

+
   character(len=*),intent(in)          :: quoted_str
+   character(len=1),optional,intent(in) :: esc
+   character(len=:),allocatable         :: unquoted_str
+
+

DESCRIPTION

+

Remove quotes from a CHARACTER variable as if it was read using list-directed input. This is particularly useful for processing tokens read from input such as CSV files.

+

Fortran can now read using list-directed input from an internal file, which should handle quoted strings, but list-directed input does not support escape characters, which UNQUOTE(3f) does.

+

OPTIONS

+ +

RESULT

+ +

EXAMPLE

+

Sample program:

+
   program demo_unquote
+      use M_strings, only : unquote
+      implicit none
+      character(len=128)           :: quoted_str
+      character(len=:),allocatable :: unquoted_str
+      character(len=1),parameter   :: esc='\'
+      character(len=1024)          :: msg
+      integer                      :: ios
+      character(len=1024)          :: dummy
+      do
+         write(*,'(a)',advance='no')'Enter test string:'
+         read(*,'(a)',iostat=ios,iomsg=msg)quoted_str
+         if(ios /= 0)then
+            write(*,*)trim(msg)
+            exit
+         endif
+
+         ! the original string
+         write(*,'(a)')'QUOTED       ['//trim(quoted_str)//']'
+
+         ! the string processed by unquote(3f)
+         unquoted_str=unquote(trim(quoted_str),esc)
+         write(*,'(a)')'UNQUOTED     ['//unquoted_str//']'
+
+         ! read the string list-directed to compare the results
+         read(quoted_str,*,iostat=ios,iomsg=msg)dummy
+         if(ios /= 0)then
+            write(*,*)trim(msg)
+         else
+            write(*,'(a)')'LIST DIRECTED['//trim(dummy)//']'
+         endif
+      enddo
+   end program demo_unquote
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

upper(3f) - [M_strings:CASE] changes a string to uppercase (LICENSE:PD)

+

SYNOPSIS

+

elemental pure function upper(str,begin,end) result (string)

+
    character(*), intent(in)    :: str
+    integer,optional,intent(in) :: begin,end
+    character(len(str))         :: string  ! output string
+
+

DESCRIPTION

+

upper(string) returns a copy of the input string with all characters converted in the optionally specified range to uppercase, assuming ASCII character sets are being used. If no range is specified the entire string is converted to uppercase.

+

OPTIONS

+ +

RESULTS

+ +

TRIVIA

+

The terms "uppercase" and "lowercase" date back to the early days of the mechanical printing press. Individual metal alloy casts of each needed letter, or punctuation symbol, were meticulously added to a press block, by hand, before rolling out copies of a page. These metal casts were stored and organized in wooden cases. The more often needed miniscule letters were placed closer to hand, in the lower cases of the work bench. The less often needed, capitalized, majuscule letters, ended up in the harder to reach upper cases.

+

EXAMPLE

+

Sample program:

+
    program demo_upper
+    use M_strings, only: upper
+    implicit none
+    character(len=:),allocatable  :: s
+       s=' ABCDEFG abcdefg '
+       write(*,*) 'mixed-case input string is ```.',s
+       write(*,*) 'upper-case output string is ```',upper(s)
+       write(*,*) 'make first character uppercase  ``` ',&
+       & upper('this is a sentence.',1,1)
+       write(*,'(1x,a,*(a:,"+"))') 'UPPER(3f) is elemental ==>',&
+       & upper(["abc","def","ghi"])
+    end program demo_upper
+
+

Expected output

+
    mixed-case input string is ```. ABCDEFG abcdefg
+    upper-case output string is ``` ABCDEFG ABCDEFG
+    make first character uppercase  ``` This is a sentence.
+    UPPER(3f) is elemental ==>ABC+DEF+GHI
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

upper_quoted(3f) - [M_strings:CASE] elemental function converts string to uppercase skipping strings quoted per Fortran syntax rules (LICENSE:PD)

+

SYNOPSIS

+

elemental pure function upper_quoted(str) result (string)

+
    character(*), intent(in)    :: str
+    character(len(str))         :: string  ! output string
+
+

DESCRIPTION

+

upper_quoted(string) returns a copy of the input string with all not-quoted characters converted to uppercase, assuming ASCII character sets are being used. The quoting rules are the same as for Fortran source. Either a single or double quote starts a quoted string, and a quote character of the same type is doubled when it appears internally in the quoted string. If a double quote quotes the string single quotes may appear in the quoted string as single characters, and vice-versa for single quotes.

+

OPTIONS

+ +

RESULTS

+ +

EXAMPLE

+

Sample program:

+
    program demo_upper_quoted
+    use M_strings, only: upper_quoted
+    implicit none
+    character(len=:),allocatable  :: s
+    s=' ABCDEFG abcdefg "Double-Quoted" ''Single-Quoted'' "with ""&
+       & Quote" everything else'
+       write(*,*) 'mixed-case input string is ```.',s
+       write(*,*) 'upper-case output string is ```',upper_quoted(s)
+       write(*,'(1x,a,*(a:,"+"))') 'upper_quoted(3f) is elemental ==>', &
+       & upper_quoted(["abc","def","ghi"])
+    end program demo_upper_quoted
+
+

Expected output:

+
    mixed-case input string is ```. ABCDEFG abcdefg "Double-Quoted"
+    'Single-Quoted' "with "" Quote" everything else
+    upper-case output string is ``` ABCDEFG ABCDEFG "Double-Quoted"
+    'Single-Quoted' "with "" Quote" EVERYTHING ELSE
+    upper_quoted(3f) is elemental ==>ABC+DEF+GHI
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

v2s(3f) - [M_strings:TYPE] return numeric string from a numeric value (LICENSE:PD)

+

SYNOPSIS

+

function v2s(value) result(outstr)

+
       integer|real|doubleprecision|logical,intent(in ) :: value
+       character(len=:),allocatable :: outstr
+       character(len=*),optional,intent(in) :: fmt
+
+

DESCRIPTION

+

v2s(3f) returns a representation of a numeric value as a string when given a numeric value of type REAL, DOUBLEPRECISION, INTEGER or LOGICAL. It creates the strings using internal WRITE() statements. Trailing zeros are removed from non-zero values, and the string is left-justified.

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLE

+

Sample Program:

+
   program demo_v2s
+   use M_strings, only: v2s
+   write(*,*) 'The value of 3.0/4.0 is ['//v2s(3.0/4.0)//']'
+   write(*,*) 'The value of 1234    is ['//v2s(1234)//']'
+   write(*,*) 'The value of 0d0     is ['//v2s(0d0)//']'
+   write(*,*) 'The value of .false. is ['//v2s(.false.)//']'
+   write(*,*) 'The value of .true. is  ['//v2s(.true.)//']'
+   end program demo_v2s
+
+

Expected output

+
    The value of 3.0/4.0 is [0.75]
+    The value of 1234    is [1234]
+    The value of 0d0     is [0]
+    The value of .false. is [F]
+    The value of .true. is  [T]
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

value_to_string(3f) - [M_strings:TYPE] return numeric string from a numeric value (LICENSE:PD)

+

SYNOPSIS

+

subroutine value_to_string(value,chars[,lgth,ierr,fmt,trimz])

+
    character(len=*) :: chars  ! minimum of 23 characters required
+    !--------
+    ! VALUE may be any <em>one</em> of the following types:
+    doubleprecision,intent(in)               :: value
+    real,intent(in)                          :: value
+    integer,intent(in)                       :: value
+    logical,intent(in)                       :: value
+    !--------
+    character(len=*),intent(out)             :: chars
+    integer,intent(out),optional             :: lgth
+    integer,optional                         :: ierr
+    character(len=*),intent(in),optional     :: fmt
+    logical,intent(in)                       :: trimz
+
+

DESCRIPTION

+

value_to_string(3f) returns a numeric representation of a numeric value in a string given a numeric value of type REAL, DOUBLEPRECISION, INTEGER or LOGICAL. It creates the string using internal writes. It then removes trailing zeros from non-zero values, and left-justifies the string.

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLE

+

Sample program:

+
     program demo_value_to_string
+     use M_strings, only: value_to_string
+     implicit none
+     character(len=80) :: string
+     integer           :: lgth
+        call value_to_string(3.0/4.0,string,lgth)
+        write(*,*) 'The value is [',string(:lgth),']'
+
+        call value_to_string(3.0/4.0,string,lgth,fmt='')
+        write(*,*) 'The value is [',string(:lgth),']'
+
+        call value_to_string&
+        &(3.0/4.0,string,lgth,fmt='("THE VALUE IS ",g0)')
+        write(*,*) 'The value is [',string(:lgth),']'
+
+        call value_to_string(1234,string,lgth)
+        write(*,*) 'The value is [',string(:lgth),']'
+
+        call value_to_string(1.0d0/3.0d0,string,lgth)
+        write(*,*) 'The value is [',string(:lgth),']'
+
+     end program demo_value_to_string
+
+

Expected output

+
    The value is [0.75]
+    The value is [      0.7500000000]
+    The value is [THE VALUE IS .750000000]
+    The value is [1234]
+    The value is [0.33333333333333331]
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

visible(3f) - [M_strings:NONALPHA] expand a string to control and meta-control representations (LICENSE:PD)

+

SYNOPSIS

+

function visible(input) result(output)

+
    character(len=*),intent(in)           :: input
+    character(len=:),allocatable          :: output
+
+

DESCRIPTION

+

visible(3f) expands characters to commonly used sequences used to represent the characters as control sequences or meta-control sequences.

+

EXAMPLES

+

Sample Program:

+
    program demo_visible
+    use M_strings, only : visible
+    integer :: i
+       do i=0,255
+          write(*,'(i0,1x,a)')i,visible(char(i))
+       enddo
+    end program demo_visible
+
+

BUGS

+

The expansion is not reversible, as input sequences such as "M-" or "^a" will look like expanded sequences.

+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+
+

NAME

+

zpad(3f) - [M_strings:LENGTH] pad a string on the left with zeros to specified length (LICENSE:PD)

+

SYNOPSIS

+

function zpad(valuein,length) result(strout)

+
    class*,intent(in)           :: valuein(..)
+    integer,intent(in),optional :: length
+
+

DESCRIPTION

+

zpad(3f) crops the input string (or integer, which will be converted to a string) and then pads it on the left with zeros to the specified length.

+

Note that if the trimmed input string is already as long or longer than the requested length the trimmed original string is returned.

+

For strings representing unsigned numbers this is basically an alias for

+
       strout=pad(str,length,'0',clip=.true.,right=.false.)
+
+

For integers the same is often done with internal WRITE(3f) statements such as

+
       write(strout,'(i5.5)')ivalue
+
+

but unlike internal I/O the function call can be used in expressions or passed as a procedure argument.

+

OPTIONS

+ +

RETURNS

+ +

EXAMPLE

+

Sample Program:

+
     program demo_zpad
+      use M_strings, only : zpad
+      implicit none
+      character(len=*),parameter :: boxed='("[",a,"]",*(g0,1x))'
+      integer :: lun, i
+         print boxed, zpad( '111', 5),'basic use'
+         print boxed, zpad( valuein=42 , length=7),'by argument name'
+         print boxed, zpad( '  34567  ', 7),'cropped before padding'
+         print boxed, zpad( '123456789', 5),'input longer than length'
+         print boxed, zpad( '  +34567  ', 7),'starts with plus sign'
+         print boxed, zpad( '  -34567  ', 7),'starts with minus sign'
+         print boxed, zpad(1234),'some integers instead of strings'
+         print boxed, zpad(-1234)
+         print boxed, zpad(1234,8)
+         print boxed, zpad(-1234,8)
+         print boxed, zpad(''),'a null gets you nothing'
+         print boxed, zpad('0'),'but blanks are used for default length'
+         print boxed, zpad('0    ')
+         print boxed, zpad('     ')
+         print *, 'input value may be an array:'
+         print '("[",a,"]")', zpad([1,10,100,1000,10000,100000],8)
+
+         ! example usage:
+         ! open output_00085.dat
+         i=85
+         open(newunit=lun,file='output_'//zpad(i,5)//'.dat')
+         close(unit=lun,status='delete')
+
+     end program demo_zpad
+
+

Results:

+
    > [00111]basic use
+    > [0000042]by argument name
+    > [0034567]cropped before padding
+    > [123456789]input longer than length
+    > [+0034567]starts with plus sign
+    > [-0034567]starts with minus sign
+    > [1234]some integers instead of strings
+    > [-1234]
+    > [00001234]
+    > [-00001234]
+    > []a null gets you nothing
+    > [0]but blanks are used for default length
+    > [00000]
+    > [00000]
+    >  input value may be an array:
+    > [00000001]
+    > [00000010]
+    > [00000100]
+    > [00001000]
+    > [00010000]
+    > [00100000]
+
+

AUTHOR

+

John S. Urban

+

LICENSE

+

Public Domain

+
+ + diff --git a/docs/adjustc.3m_strings.html b/docs/adjustc.3m_strings.html index 1b3a8011..6f339ec4 100755 --- a/docs/adjustc.3m_strings.html +++ b/docs/adjustc.3m_strings.html @@ -176,7 +176,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 adjustc (3m_strings) May 12, 2024
Generated by manServer 1.08 from dd0c11bb-9e27-4568-8549-5664a048e942 using man macros. +
Nemo Release 3.1 adjustc (3m_strings) June 09, 2024
Generated by manServer 1.08 from a5517f68-ab16-47f4-b750-7b29bd348fd6 using man macros.

diff --git a/docs/aton.3m_strings.html b/docs/aton.3m_strings.html index c51cc3a1..9c090a88 100644 --- a/docs/aton.3m_strings.html +++ b/docs/aton.3m_strings.html @@ -187,7 +187,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 aton (3m_strings) May 12, 2024
Generated by manServer 1.08 from f3f21548-5f07-4895-b588-761b68293214 using man macros. +
Nemo Release 3.1 aton (3m_strings) June 09, 2024
Generated by manServer 1.08 from f8af44cf-eee5-42ea-b088-716dc725fe6b using man macros.

diff --git a/docs/base.3m_strings.html b/docs/base.3m_strings.html index 02364b7f..995702f3 100755 --- a/docs/base.3m_strings.html +++ b/docs/base.3m_strings.html @@ -171,7 +171,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 base (3m_strings) May 12, 2024
Generated by manServer 1.08 from c88ed589-8b40-4d1b-9f62-04c08f70d90d using man macros. +
Nemo Release 3.1 base (3m_strings) June 09, 2024
Generated by manServer 1.08 from 21cdca38-2aa0-423f-ade6-906e9b3450ae using man macros.

diff --git a/docs/base2.3m_strings.html b/docs/base2.3m_strings.html index 0b3bd645..c52e38e9 100755 --- a/docs/base2.3m_strings.html +++ b/docs/base2.3m_strings.html @@ -168,7 +168,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 base2 (3m_strings) May 12, 2024
Generated by manServer 1.08 from 9af8cbd9-8cc0-4b6d-b6a1-1cd4fdb43a10 using man macros. +
Nemo Release 3.1 base2 (3m_strings) June 09, 2024
Generated by manServer 1.08 from 7be550ad-797b-4f54-8b4a-b7e30dbf6b4d using man macros.

diff --git a/docs/bundle.3m_strings.html b/docs/bundle.3m_strings.html index 7976fafd..ef601972 100644 --- a/docs/bundle.3m_strings.html +++ b/docs/bundle.3m_strings.html @@ -166,7 +166,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 bundle (3m_strings) May 12, 2024
Generated by manServer 1.08 from bf0b4776-d696-446e-be5e-de8a092aa05a using man macros. +
Nemo Release 3.1 bundle (3m_strings) June 09, 2024
Generated by manServer 1.08 from ce83860e-d2d2-4ba2-a7ae-fe78881b1e27 using man macros.

diff --git a/docs/c2s.3m_strings.html b/docs/c2s.3m_strings.html index 7a26c319..9e908ca4 100755 --- a/docs/c2s.3m_strings.html +++ b/docs/c2s.3m_strings.html @@ -143,7 +143,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 c2s (3m_strings) May 12, 2024
Generated by manServer 1.08 from a4fc345c-c12f-4e8d-9516-0ca74f4c9623 using man macros. +
Nemo Release 3.1 c2s (3m_strings) June 09, 2024
Generated by manServer 1.08 from 19a8cbc6-feb5-49e6-ac9c-78ae9d59140d using man macros.

diff --git a/docs/change.3m_strings.html b/docs/change.3m_strings.html index ad395a34..db20cb61 100755 --- a/docs/change.3m_strings.html +++ b/docs/change.3m_strings.html @@ -199,7 +199,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 change (3m_strings) May 12, 2024
Generated by manServer 1.08 from d9921493-2f2b-4c87-bb94-85896dd55f0d using man macros. +
Nemo Release 3.1 change (3m_strings) June 09, 2024
Generated by manServer 1.08 from 6b7b5b0e-3ee7-4e33-86c8-cbbdf9607369 using man macros.

diff --git a/docs/chomp.3m_strings.html b/docs/chomp.3m_strings.html index 5d38e916..2eff8be5 100755 --- a/docs/chomp.3m_strings.html +++ b/docs/chomp.3m_strings.html @@ -205,7 +205,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 chomp (3m_strings) May 12, 2024
Generated by manServer 1.08 from 71ad966b-8eee-46a2-802d-514bf4175c54 using man macros. +
Nemo Release 3.1 chomp (3m_strings) June 09, 2024
Generated by manServer 1.08 from 9560a654-5588-40a1-a66a-0786698aded6 using man macros.

diff --git a/docs/clip.3m_strings.html b/docs/clip.3m_strings.html index d0c33eb4..213f1567 100755 --- a/docs/clip.3m_strings.html +++ b/docs/clip.3m_strings.html @@ -159,7 +159,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 clip (3m_strings) May 12, 2024
Generated by manServer 1.08 from d7d54118-752f-4873-a953-dac2fdbe0155 using man macros. +
Nemo Release 3.1 clip (3m_strings) June 09, 2024
Generated by manServer 1.08 from bc4a4939-6275-4c01-a45f-16114db32c1d using man macros.

diff --git a/docs/codebase.3m_strings.html b/docs/codebase.3m_strings.html index 94653296..2c00092a 100755 --- a/docs/codebase.3m_strings.html +++ b/docs/codebase.3m_strings.html @@ -146,7 +146,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 codebase (3m_strings) May 12, 2024
Generated by manServer 1.08 from 27806d20-05e1-41c8-9bf2-63557455cdb0 using man macros. +
Nemo Release 3.1 codebase (3m_strings) June 09, 2024
Generated by manServer 1.08 from 14b44feb-85d6-4262-bea0-981e952716d9 using man macros.

diff --git a/docs/compact.3m_strings.html b/docs/compact.3m_strings.html index 6f2b8034..a8690891 100755 --- a/docs/compact.3m_strings.html +++ b/docs/compact.3m_strings.html @@ -180,7 +180,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 compact (3m_strings) May 12, 2024
Generated by manServer 1.08 from 9b0a42a5-90cc-4338-950f-86dfdc1588bc using man macros. +
Nemo Release 3.1 compact (3m_strings) June 09, 2024
Generated by manServer 1.08 from 4ebb1128-bcd1-4e56-8f09-72232269da2a using man macros.

diff --git a/docs/cpad.3m_strings.html b/docs/cpad.3m_strings.html index 7205d4b7..47a52cb0 100644 --- a/docs/cpad.3m_strings.html +++ b/docs/cpad.3m_strings.html @@ -170,7 +170,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 cpad (3m_strings) May 12, 2024
Generated by manServer 1.08 from e6ac94aa-d2d8-4ab9-a82b-ef051fe88aa7 using man macros. +
Nemo Release 3.1 cpad (3m_strings) June 09, 2024
Generated by manServer 1.08 from b4e44601-0567-4a4e-8db3-a299321ec288 using man macros.

diff --git a/docs/crop.3m_strings.html b/docs/crop.3m_strings.html index ad73f910..83d2a532 100755 --- a/docs/crop.3m_strings.html +++ b/docs/crop.3m_strings.html @@ -163,7 +163,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 crop (3m_strings) May 12, 2024
Generated by manServer 1.08 from 43cef32e-1c25-4777-958f-94ac41c97304 using man macros. +
Nemo Release 3.1 crop (3m_strings) June 09, 2024
Generated by manServer 1.08 from f62bd971-c69f-4859-bb6b-97cf7d4897db using man macros.

diff --git a/docs/dble.3m_strings.html b/docs/dble.3m_strings.html index 1204caad..1115abdd 100644 --- a/docs/dble.3m_strings.html +++ b/docs/dble.3m_strings.html @@ -164,7 +164,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 dble (3m_strings) May 12, 2024
Generated by manServer 1.08 from 1f4d2499-9cc2-44bc-b2bb-04ed9d74d299 using man macros. +
Nemo Release 3.1 dble (3m_strings) June 09, 2024
Generated by manServer 1.08 from eccaf23c-e7e1-43ce-a6a4-77ffec6c0362 using man macros.

diff --git a/docs/decodebase.3m_strings.html b/docs/decodebase.3m_strings.html index 4b39c662..0ff735de 100755 --- a/docs/decodebase.3m_strings.html +++ b/docs/decodebase.3m_strings.html @@ -186,7 +186,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 decodebase (3m_strings) May 12, 2024
Generated by manServer 1.08 from 5e0f865a-20fb-46f9-9955-9a86c5d24810 using man macros. +
Nemo Release 3.1 decodebase (3m_strings) June 09, 2024
Generated by manServer 1.08 from f07dc1da-955e-4c9b-af16-28cb4cec8535 using man macros.

diff --git a/docs/delim.3m_strings.html b/docs/delim.3m_strings.html index db781f1f..a9d5a06b 100755 --- a/docs/delim.3m_strings.html +++ b/docs/delim.3m_strings.html @@ -276,7 +276,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 delim (3m_strings) May 12, 2024
Generated by manServer 1.08 from 9deed356-a940-4800-9c96-bd3498dbc4f7 using man macros. +
Nemo Release 3.1 delim (3m_strings) June 09, 2024
Generated by manServer 1.08 from dd4ccf2f-55a2-4236-8666-f68bdc338b2b using man macros.

diff --git a/docs/describe.3m_strings.html b/docs/describe.3m_strings.html index 437c608b..e2255b25 100755 --- a/docs/describe.3m_strings.html +++ b/docs/describe.3m_strings.html @@ -262,7 +262,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 describe (3m_strings) May 12, 2024
Generated by manServer 1.08 from 8da90f5a-ad95-4e74-b23d-72d96d374037 using man macros. +
Nemo Release 3.1 describe (3m_strings) June 09, 2024
Generated by manServer 1.08 from af5f4b43-4ff0-4759-81f5-b1326d2ad434 using man macros.

diff --git a/docs/dilate.3m_strings.html b/docs/dilate.3m_strings.html index c0928309..5836f125 100755 --- a/docs/dilate.3m_strings.html +++ b/docs/dilate.3m_strings.html @@ -173,7 +173,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 dilate (3m_strings) May 12, 2024
Generated by manServer 1.08 from 1221e61b-302d-4d8c-b7a7-2b69287971ff using man macros. +
Nemo Release 3.1 dilate (3m_strings) June 09, 2024
Generated by manServer 1.08 from 988da3b2-cbd3-43dd-adeb-b04b03a9b91c using man macros.

diff --git a/docs/edit_distance.3m_strings.html b/docs/edit_distance.3m_strings.html index ac3d6cdb..d94dd967 100755 --- a/docs/edit_distance.3m_strings.html +++ b/docs/edit_distance.3m_strings.html @@ -148,7 +148,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 edit_distance (3m_strings) May 12, 2024
Generated by manServer 1.08 from 9a1836aa-e26e-48ba-b31a-ccc4d6f6aa59 using man macros. +
Nemo Release 3.1 edit_distance (3m_strings) June 09, 2024
Generated by manServer 1.08 from deda9af5-3379-4f03-92a7-525b86cb1dbb using man macros.

diff --git a/docs/ends_with.3m_strings.html b/docs/ends_with.3m_strings.html index 8694829a..ba450742 100755 --- a/docs/ends_with.3m_strings.html +++ b/docs/ends_with.3m_strings.html @@ -194,7 +194,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 ends_with (3m_strings) May 12, 2024
Generated by manServer 1.08 from 9a00d4c4-6eaa-4332-9e6c-bf3b33f1a4f4 using man macros. +
Nemo Release 3.1 ends_with (3m_strings) June 09, 2024
Generated by manServer 1.08 from dc1837cb-e7ac-4deb-a53a-b03fe2631cfc using man macros.

diff --git a/docs/expand.3m_strings.html b/docs/expand.3m_strings.html index cf69d5cb..641ba42a 100755 --- a/docs/expand.3m_strings.html +++ b/docs/expand.3m_strings.html @@ -93,64 +93,23 @@

DESCRIPTION

sequences or control characters. By default ...

Escape sequences -

- - - - - - - - - - - - - - - -
-\ -backslash -
-a -alert (BEL) -- g is an alias for a -
-b -backspace -
-c -suppress further output -
-e -escape -
-f -form feed -
-n -new line -
-r -carriage return -
-t -horizontal tab -
-v -vertical tab -
-oNNN -byte with octal value NNN (3 digits) -
-dNNN -byte with decimal value NNN (3 digits) -
-xHH -byte with hexadecimal value HH (2 digits) -- h is an alias for x -

+

+      \      backslash
+      a      alert (BEL) -- g is an alias for a
+      b      backspace
+      c      suppress further output
+      e      escape
+      f      form feed
+      n      new line
+      r      carriage return
+      t      horizontal tab
+      v      vertical tab
+      oNNN   byte with octal value NNN (3 digits)
+      dNNN   byte with decimal value NNN (3 digits)
+      xHH    byte with hexadecimal value HH (2 digits) -- h is an alias for x
+

+

The default escape character is the backslash, but this may be changed using the optional parameter ESCAPE. @@ -178,14 +137,18 @@

EXAMPLES

Results (with nonprintable characters shown visible): -> ^[[H^[[2J -> ^IABC^Iabc -> ^IA^G -> -> ONE -> TWO -> THREE -> \ +

+

+    > ^[[H^[[2J
+    > ^IABC^Iabc
+    > ^IA^G
+    >
+    > ONE
+    > TWO
+    > THREE
+    > \
+

+

@@ -204,7 +167,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 expand (3m_strings) May 12, 2024
Generated by
manServer 1.08 from ae3a59e1-ca67-4062-b7db-37d387ac85f0 using man macros. +
Nemo Release 3.1 expand (3m_strings) June 09, 2024
Generated by manServer 1.08 from eb3ce537-b458-486c-887d-993bae27b1d4 using man macros.

diff --git a/docs/find_field.3m_strings.html b/docs/find_field.3m_strings.html index 01f8dfd6..47ab117a 100644 --- a/docs/find_field.3m_strings.html +++ b/docs/find_field.3m_strings.html @@ -120,10 +120,7 @@

DESCRIPTION

information is in the argument descriptions. Note that most of the arguments are optional.

-

-       from comp.lang.fortran @ Richard Maine
-

-

+from comp.lang.fortran @ Richard Maine @@ -211,32 +208,35 @@

EXAMPLES

write(*,’(*(g0))’)repeat(’=’,70)

end program demo_find_field +

-‘‘‘ Results: -‘‘‘text -> [a,b,[ccc,ddd],and more] -> <> -> <a> -> <b> -> <> -> <ccc> -> <ddd> -> <> -> <and more> -> <> -> ====================================================================== -> [a,b,[ccc,ddd],and more] -> <>2 [ -> <a>4 , -> <b>6 , -> <>7 [ -> <ccc>11 , -> <ddd>15 ] -> <>16 , -> <and>20 -> <more>257 ] -> ====================================================================== +

+

+    > [a,b,[ccc,ddd],and more]
+    > <>
+    > <a>
+    > <b>
+    > <>
+    > <ccc>
+    > <ddd>
+    > <>
+    > <and more>
+    > <>
+    > ==================================================================
+    > [a,b,[ccc,ddd],and more]
+    > <>2 [
+    > <a>4 ,
+    > <b>6 ,
+    > <>7 [
+    > <ccc>11 ,
+    > <ddd>15 ]
+    > <>16 ,
+    > <and>20
+    > <more>257 ]
+    > ==================================================================
+

+

@@ -271,7 +271,7 @@

VERSION

Minor editing to conform to inclusion in the string procedure module


-
Nemo Release 3.1 find_field (3m_strings) May 12, 2024
Generated by
manServer 1.08 from 1c19e76d-ed06-41a0-8ca3-f0df32f1865a using man macros. +
Nemo Release 3.1 find_field (3m_strings) June 09, 2024
Generated by manServer 1.08 from e92cf7cd-2437-48db-918c-3fa450edc5e8 using man macros.

diff --git a/docs/fortran_name.3m_strings.html b/docs/fortran_name.3m_strings.html index 40fa8eaa..b70bbeca 100755 --- a/docs/fortran_name.3m_strings.html +++ b/docs/fortran_name.3m_strings.html @@ -161,7 +161,7 @@

EXAMPLE


-
Nemo Release 3.1 fortran_name (3m_strings) May 12, 2024
Generated by manServer 1.08 from 5a5d4f6f-2709-4951-b012-601760a80cc1 using man macros. +
Nemo Release 3.1 fortran_name (3m_strings) June 09, 2024
Generated by manServer 1.08 from 56704ee2-15a4-4aeb-8d31-d4141360b6e9 using man macros.

diff --git a/docs/getvals.3m_strings.html b/docs/getvals.3m_strings.html index ff5616bf..7085a5ab 100755 --- a/docs/getvals.3m_strings.html +++ b/docs/getvals.3m_strings.html @@ -234,7 +234,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 getvals (3m_strings) May 12, 2024
Generated by manServer 1.08 from 821642e0-bc6a-48df-b141-b9d1e884d182 using man macros. +
Nemo Release 3.1 getvals (3m_strings) June 09, 2024
Generated by manServer 1.08 from 82a1e7bf-8f43-48af-b2f1-4fd97a1e6d82 using man macros.

diff --git a/docs/glob.3m_strings.html b/docs/glob.3m_strings.html index 33d6aafd..3bd67e78 100755 --- a/docs/glob.3m_strings.html +++ b/docs/glob.3m_strings.html @@ -393,7 +393,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 glob (3m_strings) May 12, 2024
Generated by manServer 1.08 from 77224937-6269-46ae-848a-13fe6b0e4756 using man macros. +
Nemo Release 3.1 glob (3m_strings) June 09, 2024
Generated by manServer 1.08 from 6018b54b-00f4-4159-be67-a48f19d5b0d2 using man macros.

diff --git a/docs/indent.3m_strings.html b/docs/indent.3m_strings.html index 114fa326..2f347bc8 100755 --- a/docs/indent.3m_strings.html +++ b/docs/indent.3m_strings.html @@ -116,20 +116,13 @@

EXAMPLES

Results: -

- - - - -
-3 -a b c -0a b c -
-6 -a b c -
+

+

+     > 3   a b c
+     > 0a b c
+     > 6      a b c
+

+

@@ -148,7 +141,7 @@

LICENSE

Public Domain


-
Nemo Release 3.1 indent (3m_strings) May 12, 2024
Generated by
manServer 1.08 from b94b7630-70c4-4de1-bd70-72949cc837e8 using man macros. +
Nemo Release 3.1 indent (3m_strings) June 09, 2024
Generated by manServer 1.08 from 4c302168-0164-4115-90ce-f8aa4883fc4e using man macros.

diff --git a/docs/index.html b/docs/index.html index 8a8082bb..d2963658 100755 --- a/docs/index.html +++ b/docs/index.html @@ -4,7 +4,7 @@ - +