# flibs/m_vstrings(n) 1.0 "flibs"

## NAME

flibs/m_vstrings - Processing strings

## TABLE OF CONTENTS

TABLE OF CONTENTS
SYNOPSIS
DESCRIPTION
OVERVIEW
Creating a string
Concatenate two strings
Modify the case
Pattern matching
Validating a string
Allocatable or pointer
Dynamic or static buffer
Design
Limitations
Preprocessing
History
METHODS
INTERFACE TO STANDARD FORTRAN
STATIC METHODS
TODO
COPYRIGHT

## SYNOPSIS

vstring_new (this ?args?)
vstring_new (this)
vstring_new (this,char_string)
vstring_new (this,vstring)
vstring_new (this,chararray)
vstring_new (this, ncount ?, vstring?)
vstring_free (this)
vstring_exists (this) result ( exists )
vstring_equals (this, stringb ?, nocase,length?) result (equals)
vstring_equals (this, string2 ?, nocase,length?) result (equals)
vstring_cast (this ?, args?)
vstring_cast (this , length , charstring)
vstring_cast (this , charstring)
vstring_cast (this , value)
vstring_cast (this , value)
vstring_cast (this , value)
vstring_length (this) result ( length )
vstring_concat (this,string2) result ( concat_string )
vstring_concat (this,string2) result ( concat_string )
vstring_append (this,string2)
vstring_append (this,string2)
vstring_map (this , map_old , map_new ?, nocase?) result ( stringmap )
vstring_replace (this , first , last ?, newstring?) result ( stringreplace )
vstring_compare (this,string2?, nocase , length?) result ( compare )
vstring_compare (this,string2?, nocase , length?) result ( compare )
vstring_trim (this ?, chars?) result ( trim_string )
vstring_trim (this ?, chars?) result ( trim_string )
vstring_trimleft (this ?, chars?) result ( trim_string )
vstring_trimleft (this ?, chars?) result ( trim_string )
vstring_trimright (this ?, chars?) result ( trim_string )
vstring_trimright (this ?, chars?) result ( trim_string )
vstring_first (this ?, string2 , first?) result ( firstIndex )
vstring_first (this ?, string2 , first?) result ( firstIndex )
vstring_last (this ?, string2 , last?) result ( lastIndex )
vstring_last (this ?, string2 , last?) result ( lastIndex )
vstring_range (this, first, last) result ( string_range )
vstring_index (this , charIndex ) result ( string_index )
vstring_toupper (this?, first??, last?) result ( new_upper )
vstring_tolower (this?, first??, last?) result ( new_lower )
vstring_totitle (this?, first??, last?) result ( new_title )
vstring_reverse (this) result ( new_reverse )
vstring_random (this) result ( new_random )
vstring_match (this , pattern ?, nocase?) result ( match )
vstring_match (this , pattern ?, nocase?) result ( match )
vstring_is (this , class ?, strict? ?, failindex?) result ( isinclass )
vstring_iachar (this) result ( new_iachar )
vstring_ichar (this) result ( new_ichar )
vstring_charindex (this , substring ?, back?) result ( charindex )
vstring_scan (this, substring?, back?) result ( charindex )
vstring_verify (this, substring?, back?) result ( charindex )
vstring_adjustl (this) result ( newstring )
vstring_adjustr (this) result ( newstring )
vstring_achar (i) result ( new_achar )
vstring_char (i) result ( new_achar )

## DESCRIPTION

The module m_vstring provides OO services to manage strings of dynamic length. The goal of the current component is to provide higher-level services that the standard fortran currently provides. The component provides methods which mimic the services available in the Tcl language. It provides string comparison, string search and string matching methods. See in test_m_vstring to see a complete example of the services provided.

## OVERVIEW

A vstring is an array of characters. The simplest way to create a vstring is with vstring_new from a "character(len=<something>)" string. The length of the vstring is computed dynamically, depending on the current number of characters, with vstring_length. In the following example, the length is 9.

        use m_vstring, only : &
          vstring_new, &
          vstring_free, &
          t_vstring, &
          vstring_length
        type ( t_vstring,) :: string1
        integer :: length
        call vstring_new ( string1 , "my string" )
        length = vstring_length (string1)
        call vstring_free( string1 )

### Creating a string

With vstring_new, one can also create a new vstring as a copy of an existing vstring. With vstring_new, one can also create a new vstring with an array of characters or with a repeated copy of an existing vstring. Destroy the vstring with vstring_free.

### Concatenate two strings

Two vstrings can be concatenated in two ways. The vstring_concat method returns a new vstring computed by the concatenation of the two strings. The vstring_append allows to add the characters of the 2nd vstring at the end of the current string. In the following example, the string3 is "my string is very interesting".

        call vstring_new ( string1 , "my string" )
        call vstring_new ( string2 , " is very interesting" )
        string3 = vstring_concat ( string1 , string2 )

### Modify the case

The user can modify the case of a vstring. The vstring_tolower creates a new vstring with lower case characters. The vstring_toupper creates a new vstring with upper case characters. The vstring_totitle creates a new vstring with the first letter in upper case and all the other characters to lower case. The user can know if two vstrings are equal with vstring_equals. Two vstrings can be compared with vstring_compare, which is based on the lexicographic order. One can transform one vstring into a new one using a map with vstring_map.

### Pattern matching

The vstring_match method provides string-matching services in the glob-style. It manages "*" pattern (which matches 0 or more characters), the "?" pattern (which matches exactly one character), escape sequences and character ranges. The following example show how to compare a file name against a pattern :

        call vstring_new ( string1 , "m_vstring.f90" )
        call vstring_new ( pattern , 'm_*.f90' )
        match = vstring_match ( string1 , pattern )

### Validating a string

The vstring_is method provides a way of validating data by computing whether the vstring is in a class of data, for example integer, real, digit, alphanumeric, etc... In the following example, the user can check whether the string read on standard input is an integer :

        read ( 5 , * ) charstring
        call vstring_new ( string1 , charstring )
        isinteger = call vstring_is ( string1 , "integer" )
        if ( .NOT. isinteger ) then
          ! Generate an error
        endif

If the character set under use is not in one the pre-defined classes of vstring_is, the user can directly call vstring_isincharset or vstring_isinasciirange, which are the basic blocks of vstring_is. Second string argument may be character string The design choice has been made to design the subroutines/functions so that their dummy arguments are generally only of type t_vstring. Another choice would have been to allways take as dummy arguments both t_vstring and "character (len=*)" strings, with module procedure interfaces to make them generic. The last choice ease the work of the client of the current component, which can use directly standard fortran constant strings (for example,

        equals = vstring_equals ( string1 , "toto" )

instead of

        type ( t_vstring ) :: string2
        call vstring_new ( string2 , "toto" )
        equals = vstring_equals ( string1 , string2 )
        call vstring_free ( string2 )

that is to say 5 lines instead of 1. The main drawback is that the number of interfaces is at least multiplied by 2, if not 4 or 8 when the number of string arguments is more than 2. This makes the unit tests multiplied by the same number, if one want to exercise all the possible interfaces. That way was chosen by the original iso_varying_string module and lead to a heavy component, with a large number of lines and a small number of features, because all the time was lost in the management of such an heavy module. The other drawback is that is breaks the object oriented design so that the "type bound" procedure of F2003 cannot be used. The current choice is to focus mainly on the services provided, not the ease of use. That allows to provide much more features than in the original component, but complicates a little more the use in the client code. The choice done here is that the first argument is allways of type vstring (and called "this"), while the second argument (if any), mays by either of type vstring or of type "character (len=*). That solution allows to keep both consistency and ease of use at the maximum possible level. Several methods are designed this way, for example, vstring_equals, vstring_compare, vstring_append, vstring_concat and others.

### Allocatable or pointer

Two implementation of m_vstring are provided, depending on the compiler used :

- the allocatable array of characters with the pre-processing macro _VSTRING_ALLOCATABLE,
- the pointer array of characters with the pre-processing macro _VSTRING_POINTER

If none of the macros are defined, the default implementation is _VSTRING_ALLOCATABLE. The two implementations provide exactly the same services. But the "allocatable" implementation allows to manage the vstring which are going out of the current scope so that the use of vstring_free is not necessary and memory leaks do not occur. Instead, with the pointer implementation, the call to vstring_free is strictly necessary (if not, memory is lost each time a new vstring is created). The current version of m_vstring has been tested with the following compilers and versions:

- Intel Visual Fortran 8 : tested with _VSTRING_ALLOCATABLE and _VSTRING_POINTER But the allocatable version allows to debug more easily.
- gfortran 2007/04/16 : tested with _VSTRING_POINTER (works fine, except for vstring_match)
- g95 May 3 2007 : tested with _VSTRING_POINTER, OK

### Dynamic or static buffer

The internal algorithms provided by m_vstrings are based on basic fortran character strings. In several situations, the dynamic vstring has to be converted into a basic fortran character buffer string, which size has to be given explicitely in the source code, with the len = <something> statement (in the character ( len = <something>) ). Two solutions are provided, and the user can define the pre-processing macro _VSTRING_STATIC_BUFFER to configure that :

- the first solution is to set the size of the buffer statically, to a constant integer value VSTRING_BUFFER_SIZE.
- the second solution is to compute the size of the buffer dynamicaly, with the fortran 90 len = vstring_length(this) statement,

If the _VSTRING_STATIC_BUFFER is defined, then character strings of constant size are used as buffers. If the _VSTRING_STATIC_BUFFER is not defined (which is the default), then character strings of dynamic size are used as buffers. The second solution is more efficient, because the strings are not oversized or undersized, depending on the real number of characters in the dynamic string. But the feature may not be provided by the compiler at hand. For example, problems with the dynamic length character string have been experienced with Intel Fortran 8.

### Design

This component has been designed with OO principles in mind. This is why the first argument of every method is named "this", which is the current object. If another string is required as a second argument, it may be either of type dynamic or as a character(len=*) type, to improve usability. This component is meant to evolve following the fortran 2003 standard and OO type-bound procedures.

### Limitations

- No regular expression algorithm is provided. But vstring_match allows to do string matching in glob-style.
- The vstring_match does not work with gfortran 2007/04/16 because of a limitation in gfortran for zero-size arrays
- the vstring_adjustl, vstring_adjustr, vstring_scan, vstring_adjustl, vstring_adjustr, vstring_is methods does not work with IVF8 because strings declared like this : character (len = vstring_length(this) :: character are not consistent strings, probably because of a bug in the implementation of len = pure function value in IVF8.
- Fortran does not allow to manage character encodings such as UTF8.

### Preprocessing

The following preprocessing macro must be considered :

- _VSTRING_STATIC_BUFFER : see the section "Dynamic or static buffer"
- _VSTRING_ALLOCATABLE or _VSTRING_POINTER : see the section "Allocatable or pointer"

### History

This module was originally based on the iso_varying_string.f90 module by Rich Townsend.

## METHODS

In the following definitions, the this argument has, depending on the method, one of the the following definitions :

type ( t_vstring ) , intent(inout) :: this

type ( t_vstring ) , intent(in) :: this

The "intent(in)" or "intent(inout)" declaration depends on the method and is what it is expected to be (if not, it is a bug).

vstring_new (this ?args?)
  Generic constructor. Creates the new vstring "this".
vstring_new (this)
  Creates a vstring with 0 characters and 0 length.
vstring_new (this,char_string)
  character(LEN=*), intent(in) :: char_string
  The new vstring is filled with the characters found in "char_string".
vstring_new (this,vstring)
  type ( t_vstring ) , intent(in) :: vstring
  The new vstring is filled with the characters found in the dynamic string "vstring".
vstring_new (this,chararray)
  character(len=1), dimension(:), intent(in) :: chararray
  The new vstring is filled with the characters found in the array of characters "chararray".
vstring_new (this, ncount ?, vstring?)
  integer, intent(in) :: ncount
  type ( t_vstring ) , intent(in), optional :: vstring
  Repeat the string ncount times and concatenate the result to create the new string. If not provided, the default string is the blank space. This can be considered as an implementation of "vstring_repeat".
vstring_free (this)
  Destructor.
  The use of the destructor is OPTIONAL. See the thread " New ISO_VARYING_STRING implementation (without memory leaks)" on comp.lang.fortran : "On most systems, memory is memory :-). However, there is a difference between how ALLOCATABLE variables and POINTER variables are handled. ALLOCATABLE variables are always deallocated automatically when thay go out of scope (unless they have the SAVE attribute). POINTER variables usually are not. The reason is that the program may have associated additional pointers, that aren't going out of scope, with the same target as the one that is."
vstring_exists (this) result ( exists )
  logical :: exists
  Returns .true. if the string is allocated.
vstring_equals (this, stringb ?, nocase,length?) result (equals)
  type ( t_vstring ) , intent(in) :: stringb
  logical , intent (in), optional :: nocase
  integer , intent (in), optional :: length
  logical :: equals
  Perform a character-by-character comparison of strings this and string2. Returns true if this and stringb are identical, or .false when not. If nocase is set to true, the case of the characters is not taken into account. The default behaviour is to take into account for case of characters. If length is specified, then only the first length characters are used in the comparison.
vstring_equals (this, string2 ?, nocase,length?) result (equals)
  character(len=*), intent(in) :: string2
  logical , intent (in), optional :: nocase
  integer , intent (in), optional :: length
  logical :: equals
  Same as previous but with string2 as a character string.
vstring_cast (this ?, args?)
  Convert a dynamic string into another fortran data type.
vstring_cast (this , length , charstring)
  integer, intent(in) :: length
  character ( LEN = length ) , intent(out) :: charstring
  Convert a dynamic string into a character string with fixed length. If the number of characters in the target charstring is not large enough, the target charstring is truncated, that is, contains only the first characters of the current dynamic string.
vstring_cast (this , charstring)
  character ( LEN = * ) , intent(out) :: charstring
  Convert a dynamic string into a character string with automatic length. If the number of characters in the target charstring is not large enough, the target charstring is truncated, that is, contains only the first characters of the current dynamic string.
vstring_cast (this , value)
  integer, intent(out) :: value
  Returns the integer stored in the current string.
vstring_cast (this , value)
  real, intent(out) :: value
  Returns the real stored in the current string.
vstring_cast (this , value)
  double precision, intent(out) :: value
  Returns the double precision stored in the current string.
vstring_length (this) result ( length )
  integer :: length
  Returns the length of the current dynamic string.
vstring_concat (this,string2) result ( concat_string )
  type ( t_vstring ) , intent(in) :: string2
  type ( t_vstring ) :: concat_string
  Returns a new dynamic string made by the concatenation of two dynamic strings.
vstring_concat (this,string2) result ( concat_string )
  character(len=*) , intent(in) :: string2
  type ( t_vstring ) :: concat_string
  Returns a new string made by the concatenation of the current dynamic string and the given character(len=*) string.
vstring_append (this,string2)
  type ( t_vstring ) , intent(in) :: string2
  Append the given string at the end of the current string. If the given string string2 is of length greater than zero, that means that the length of the current string will be greater after the call to vstring_append. Note : that method can be called as a convenient alternative to vstring_concat, when the concat is to be done "in place".
vstring_append (this,string2)
  character(len=*) , intent(in) :: string2
  Same as previous, but with a character(len=*) string2.
vstring_map (this , map_old , map_new ?, nocase?) result ( stringmap )
  type ( t_vstring ) , dimension( : ), intent(in) :: map_old
  type ( t_vstring ) , dimension( : ), intent(in) :: map_new
  logical, intent(in), optional :: nocase
  type(t_vstring) :: stringmap
  Replaces substrings in string based on the mapping defined by the couple (map_old , map_new). map_old and map_new are arrays of vstrings and are of the same size so that if imap is an index no greater than the size of map_old, map_old ( imap ) is the old string and map_new ( imap ) is the new string. Each instance of a key in the string will be replaced with its corresponding value. Both old and new strings may be multiple characters. If nocase is set to .true., then matching is done without regard to case differences. Replacement is done in an ordered manner, so the old string appearing first in the list will be checked first, and so on. The current string is only iterated over once, so earlier replacements will have no affect for later matches. For example,

        vstring_map 1abcaababcabababc [abc,ab,a,1] [1,2,3,0]

  will return the string 01321221. Note that if an earlier key is a prefix of a later one, it will completely mask the later one. So if the previous example is reordered like this,

        vstring_map 1abcaababcabababc [1,ab,a,abc] [0,2,3,1]

  it will return the string 02c322c222c.
vstring_replace (this , first , last ?, newstring?) result ( stringreplace )
  integer, intent(in) :: first
  integer, intent(in) :: last
  type ( t_vstring ) , intent(in), optional :: newstring
  type ( t_vstring ) :: stringreplace
  Removes a range of consecutive characters from string, starting with the character whose index is first and ending with the character whose index is last. An index of 1 refers to the first character of the string. If newstring is specified, then it is placed in the removed character range.
vstring_compare (this,string2?, nocase , length?) result ( compare )
  type ( t_vstring ) , intent(in) :: string2
  logical , intent (in), optional :: nocase
  integer , intent (in), optional :: length
  integer :: compare
  Perform a character-by-character comparison of strings this and string2. Returns -1, 0, or 1, depending on whether this is lexicographically less than, equal to, or greater than string2. If nocase is set to true, the case of the characters is not taken into account. The default behaviour is to take into account for case of characters. If length is specified, then only the first length characters are used in the comparison.
vstring_compare (this,string2?, nocase , length?) result ( compare )
  character (len=*) , intent(in) :: string2
  logical , intent (in), optional :: nocase
  integer , intent (in), optional :: length
  integer :: compare
  Same as previous, but with a character(len=*) string2.
vstring_trim (this ?, chars?) result ( trim_string )
  type ( t_vstring ) , intent(in), optional :: chars
  type ( t_vstring ) :: trim_string
  Returns a new string except that any leading or trailing characters from the set given by chars are removed. If chars is not specified then white space is removed (spaces, tabs, newlines, and carriage returns).
vstring_trim (this ?, chars?) result ( trim_string )
  character (len=*) , intent(in), optional :: chars
  type ( t_vstring ) :: trim_string
  Same as previous, but with a character(len=*) string "chars".
vstring_trimleft (this ?, chars?) result ( trim_string )
  type ( t_vstring ) , intent(in), optional :: chars
  type ( t_vstring ) :: trim_string
  Returns a new string except that any leading characters from the set given by chars are removed. If chars is not specified then white space is removed (spaces, tabs, newlines, and carriage returns).
vstring_trimleft (this ?, chars?) result ( trim_string )
  character (len=*) , intent(in), optional :: chars
  type ( t_vstring ) :: trim_string
  Same as previous, but with a character(len=*) string "chars".
vstring_trimright (this ?, chars?) result ( trim_string )
  type ( t_vstring ) , intent(in), optional :: chars
  type ( t_vstring ) :: trim_string
  Returns a value equal to string except that any trailing characters from the set given by chars are removed. If chars is not specified then white space is removed (spaces, tabs, newlines, and carriage returns).
vstring_trimright (this ?, chars?) result ( trim_string )
  character (len=*) , intent(in), optional :: chars
  type ( t_vstring ) :: trim_string
  Same as previous, but with a character(len=*) string "chars".
vstring_first (this ?, string2 , first?) result ( firstIndex )
  type ( t_vstring ) , intent(in) :: string2
  integer, intent(in), optional :: first
  integer :: firstIndex
  Search in the current string for a sequence of characters that exactly match the characters in string2. If found, return the index of the first character in the first such match within the current string. If not found, return 0. If first is specified, then the search is constrained to start with the character in the current string specified by the index.
vstring_first (this ?, string2 , first?) result ( firstIndex )
  character(len=*) , intent(in) :: string2
  integer, intent(in), optional :: first
  integer :: firstIndex
  Same as previous, but with a character(len=*) string "string2".
vstring_last (this ?, string2 , last?) result ( lastIndex )
  type ( t_vstring ) , intent(in) :: string2
  integer, intent(in), optional :: last
  integer :: lastIndex
  Search in the current string for a sequence of characters that exactly match the characters in string2. If found, return the index of the last character in the first such match within the current string. If not found, return 0. If last is specified, then the search is constrained to start with the character in the current string specified by the index.
vstring_last (this ?, string2 , last?) result ( lastIndex )
  character(len=*) , intent(in) :: string2
  integer, intent(in), optional :: last
  integer :: lastIndex
  Same as previous, but with a character(len=*) string "string2".
vstring_range (this, first, last) result ( string_range )
  integer, intent(in) :: first
  integer, intent(in) :: last
  type ( t_vstring ) :: string_range
  Returns a range of consecutive characters from string, starting with the character whose index is first and ending with the character whose index is last. An index of 1 refers to the first character of the string. If first is less than 1 then an error is generated. If last is greater than or equal to the length of the string then an error is generated. If first is greater than last then an error is generated.
vstring_index (this , charIndex ) result ( string_index )
  integer, intent(in) :: charIndex
  type ( t_vstring ) :: string_index
  Returns the charIndex'th character of the string argument. A charIndex of 1 corresponds to the first character of the string. If charIndex is less than 1 or greater than or equal to the length of the string then an error is generated.
vstring_toupper (this?, first??, last?) result ( new_upper )
  integer, intent(in) :: first
  integer, intent(in) :: last
  type ( t_vstring ) :: new_upper
  Returns a vstring except that all lower (or title) case letters have been converted to upper case. If first is specified, it refers to the first char index in the string to start modifying. If last is specified, it refers to the char index in the string to stop at (inclusive).
vstring_tolower (this?, first??, last?) result ( new_lower )
  integer, intent(in) :: first
  integer, intent(in) :: last
  type ( t_vstring ) :: new_lower
  Returns a vstring except that all upper (or title) case letters have been converted to lower case. If first is specified, it refers to the first char index in the string to start modifying. If last is specified, it refers to the char index in the string to stop at (inclusive).
vstring_totitle (this?, first??, last?) result ( new_title )
  integer, intent(in) :: first
  integer, intent(in) :: last
  type ( t_vstring ) :: new_title
  Returns a vstring except that the first character in string is converted to upper case, and the rest of the string is converted to lower case. If first is specified, it refers to the first char index in the string to start modifying. If last is specified, it refers to the char index in the string to stop at (inclusive).
vstring_reverse (this) result ( new_reverse )
  type ( t_vstring ) :: new_reverse
  Return a string that has all characters in reverse order.
vstring_random (this) result ( new_random )
  integer, intent(in) :: length
  type ( t_vstring ) :: new_random
  Fill a string with required length and randomized characters.
vstring_match (this , pattern ?, nocase?) result ( match )
  type ( t_vstring ) , intent(in) :: pattern
  logical , intent(in) , optional :: nocase
  logical :: match
  See if pattern matches string; return 1 if it does, 0 if it doesn't. If nocase is specified and true, then the pattern attempts to match against the string in a case insensitive manner. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern:
  - * Matches any sequence of characters in string, including a null string.
  - ? Matches any single character in string.
  - [chars] Matches any character in the set given by chars. If a sequence of the form x-y appears in chars, then any character between x and y, inclusive, will match. When used with -nocase, the characters of the range are converted to lower case first. Whereas {[A-z]} matches '_' when matching case-sensitively ('_' falls between the 'Z' and 'a'), with -nocase this is considered like {[A-Za-z]} (and probably what was meant in the first place).
  - \x Matches the single character x. This provides a way of avoiding the special interpretation of the characters *?[]\ in pattern.
  The following example is extracted from the unit tests provided with flibs. In the following example, "match" is true.

          type ( t_vstring ) :: string1
          logical :: match
          call vstring_new ( string1 , "m_vstring.f90" )
          match = vstring_match ( string1 , "m_*.f90" )
          call vstring_free ( string1 )

vstring_match (this , pattern ?, nocase?) result ( match )
  character(len=*) , intent(in) :: pattern
  logical , intent(in) , optional :: nocase
  logical :: match
  Same as previous, with character(len=*) as pattern.
vstring_is (this , class ?, strict? ?, failindex?) result ( isinclass )
  character(len=*) , intent(in) :: class
  logical, intent(in) , optional :: strict
  integer, intent(out) , optional :: failindex
  logical :: isinclass
  Returns .true. if string is a valid member of the specified character class, otherwise returns .false.. If strict is provided and .true., then an empty string returns .false.. If strict is provided and .false., or not provided, an empty string returns .true.. If failindex is provided, then if the function returns .false., the index in the string where the class was no longer valid will be stored in the variable failindex. The following character classes are recognized (the class name can be abbreviated):
  - alpha Any alphabet character, that is [a-zA-Z].
  - alnum Any alphabet or digit character, that is [a-zA-Z0-9].
  - ascii Any character with a value less than 128 (those that are in the 7-bit ascii range).
  - control Any control character. Control chars are in the ranges 00..1F and 7F..9F, that is from ascii #0 to #31 and from #127 to #159
  - digit Any digit character. Note that this includes characters outside of the [0-9] range.
  - false Any of the forms allowed where the logical is false.
  - graph Any printing character, except space that is from ascii #33 to #126.
  - integer Any of the valid forms for an ordinary integer in Fortran, with optional surrounding whitespace.
  - logical Any valid Fortran logical
  - lower Any lower case alphabet character, that is [a-z].
  - punct Any punctuation character, that is _,;:.?[](){}@"'
  - print Any printing character, including space that is from ascii #32 to #126.
  - real Any of the valid forms for a real in Fortran, with optional surrounding whitespace.
  - space Any space character, that is white space, tab, newline or carriage return.
  - true Any of the forms allowed where the logical is true.
  - upper Any upper case alphabet character, that is [A-Z].
  - xdigit Any hexadecimal digit character ([0-9A-Fa-f]).
  - wordchar Any word character. That is any alphanumeric character (upper case, lower case, or digit), or any connector punctuation characters (e.g. underscore).

## INTERFACE TO STANDARD FORTRAN

These methods or routines are simply an interface of standard fortran string processing routines.

vstring_iachar (this) result ( new_iachar )
  integer :: new_iachar
  Returns the code for the ASCII character in the character position of C. Example : If this is "@", then iachar is 64.
vstring_ichar (this) result ( new_ichar )
  integer :: new_ichar
  Returns the code for the character in the first character position of in the systemâ€™s native character set. This is an interface to the standard fortran.
vstring_charindex (this , substring ?, back?) result ( charindex )
  type ( t_vstring ) , intent(in) :: substring
  logical, intent(in), optional :: back
  integer :: charindex
  Returns the position of the start of the first occurrence of string substring as a sub-string in the current string, counting from one. If substring is not present in the current string, zero is returned. If the back argument is present and true, the return value is the start of the last occurrence rather than the first. Note: this is a simple interface to the standard fortran intrinsic "index".
vstring_scan (this, substring?, back?) result ( charindex )
  type ( t_vstring ) , intent(in) :: substring
  logical, intent(in), optional :: back
  integer :: charindex
  Returns the position of a character of the current string that is in set, or zero if there is no such character. If the logical back is absent or present with value false, the position of the leftmost such character is returned. If back is present with value true, the position of the rightmost such character is returned. Note: this is a simple interface to the standard fortran intrinsic "index".
vstring_verify (this, substring?, back?) result ( charindex )
  type ( t_vstring ) , intent(in) :: substring
  logical, intent(in), optional :: back
  integer :: charindex
  Returns the default integer value 0 if each character in the current string appears in set, or the position of a character of the current string that is not in set. If the logical back is absent or present with value false, the position of the left-most such character is returned. If back is present with value true, the position of the rightmost such character is returned. Note: this is a simple interface to the standard fortran intrinsic "verify".
vstring_adjustl (this) result ( newstring )
  type ( t_vstring ) :: newstring
  Adjusts left to return a string of the same length by removing all leading blanks and inserting the same number of trailing blanks. Note : this is a simple interface to the standard fortran intrinsic "adjustl".
vstring_adjustr (this) result ( newstring )
  type ( t_vstring ) :: newstring
  Adjusts right to return a string of the same length by removing all trailing blanks and inserting the same number of leading blanks. Note: this is a simple interface to the standard fortran intrinsic "adjustr".

## STATIC METHODS

vstring_achar (i) result ( new_achar )
  integer, intent (in) :: i
  type ( t_vstring ) :: new_achar
  Returns the character located at position I in the ASCII collating sequence. This is an interface to the standard fortran.
vstring_char (i) result ( new_achar )
  integer, intent (in) :: i
  type ( t_vstring ) :: new_achar
  Returns the character represented by the integer I. This is an interface to the standard fortran. Example : If i is 64, then char is "@".

## TODO

- Refactor the component and use datastructures/vectors.f90
- vstring_read Returns the vstring which is read on the given unit number, or on the standard input if no unit is given.
- vstring_write Writes the current vstring on the given unit number, or on the standard output if no unit is given.
- vstring_wordend Returns the index of the character just after the last one in the word containing character charIndex of string.
- vstring_wordstart Returns the index of the first character in the word containing character charIndex of string.

## COPYRIGHT

Copyright © 2008 Michael Baudin michael.baudin@gmail.com
Copyright © 2008 Arjen Markus arjenmarkus@sourceforge.net