From JLS@liverpool.ac.uk Mon Mar  9 14:37:38 1992
Received: from danpost2.uni-c.dk by dkuug.dk via EUnet with SMTP (5.64+/8+bit/IDA-1.2.8)
	id AA20669; Mon, 9 Mar 92 14:37:38 +0100
Received: from vm.uni-c.dk by danpost2.uni-c.dk (5.65/1.34)
	id AA16864; Mon, 9 Mar 92 13:36:27 GMT
Message-Id: <9203091336.AA16864@danpost2.uni-c.dk>
Received: from vm.uni-c.dk by vm.uni-c.dk (IBM VM SMTP V2R1) with BSMTP id 0657;
   Mon, 09 Mar 92 14:37:48 DNT
Received: from UKACRL.BITNET by vm.uni-c.dk (Mailer R2.07) with BSMTP id 6499;
 Mon, 09 Mar 92 14:37:42 DNT
Received: from RL.IB by UKACRL.BITNET (Mailer R2.07) with BSMTP id 4717; Mon,
 09 Mar 92 13:33:47 GMT
Received: from RL.IB by UK.AC.RL.IB (Mailer R2.07) with BSMTP id 5139; Mon, 09
          Mar 92 13:33:37 GMT
Via:      UK.AC.LIV.IBM;  9 MAR 92 13:32:04 GMT
Received: from JLS@UK.AC.LIVERPOOL by MAILER(4.2.a);  9 Mar 1992 13:30:00 GM
Date:     Mon, 09 Mar 92 13:29:00 GMT
From: Lawrie Schonfelder <JLS@liverpool.ac.uk>
Subject:  is1539_1 a
To: SC22/WG5 members <SC22WG5@dkuug.dk>
X-Charset: ASCII
X-Char-Esc: 29

           International Standards Organization



             Varying Length Character Strings

                            in

                          Fortran




                      ISO/IEC 1539-1
       {collateral standard to ISO/IEC 1539 : 1991}

                 {Draft Produced 8-Mar-92}
Contents


Foreword. . . . . . . . . . . . . . . . . . . . . . . .  iv

Introduction. . . . . . . . . . . . . . . . . . . . . .   v

Section 1 : Scope . . . . . . . . . . . . . . . . . . .   1
   1.1 Normative References . . . . . . . . . . . . . .   2

Section 2 : Requirements. . . . . . . . . . . . . . . .   3
   2.1 The Name of the Module . . . . . . . . . . . . .   3
   2.2 The Type . . . . . . . . . . . . . . . . . . . .   4
   2.3 Extended Meanings for Intrinsic Operators. . . .   4
       2.3.1 Assignment . . . . . . . . . . . . . . . .   5
       2.3.2 Concatenation. . . . . . . . . . . . . . .   5
       2.3.3 Comparisons. . . . . . . . . . . . . . . .   5
   2.4 Extended Meanings for Generic Intrinsic
       Procedures . . . . . . . . . . . . . . . . . . .   5
       2.4.1 The LEN Procedure. . . . . . . . . . . . .   6
       2.4.2 The CHAR Procedure . . . . . . . . . . . .   6
       2.4.3 The ICHAR Procedure. . . . . . . . . . . .   6
       2.4.4 The IACHAR Procedure . . . . . . . . . . .   6
       2.4.5 The TRIM procedure . . . . . . . . . . . .   7
       2.4.6 The LEN_TRIM procedure . . . . . . . . . .   7
       2.4.7 The ADJUSTL procedure. . . . . . . . . . .   7
       2.4.8 The ADJUSTR procedure. . . . . . . . . . .   8
       2.4.9 The REPEAT procedure . . . . . . . . . . .   8
       2.4.10 Comparison Procedures . . . . . . . . . .   8
       2.4.11 The INDEX procedure . . . . . . . . . . .   9
       2.4.12 The SCAN procedure. . . . . . . . . . . .  10
       2.4.13 The VERIFY procedure. . . . . . . . . . .  10
   2.5 Additional Generic Procedure for Type
       Conversion . . . . . . . . . . . . . . . . . . .  10
       2.5.1 The VAR_STR procedure. . . . . . . . . . .  11
   2.6 Additional Generic Procedures for
       Input/Output . . . . . . . . . . . . . . . . . .  11
       2.6.1 The READ_STRING procedure. . . . . . . . .  11
       2.6.2 The WRITE_STRING procedure . . . . . . . .  12
       2.6.3 The WRITE_LINE procedure . . . . . . . . .  13
   2.7 Additional Generic Procedures for Substring
       Manipulation . . . . . . . . . . . . . . . . . .  13
       2.7.1 The INSERT procedure . . . . . . . . . . .  14
       2.7.2 The REPLACE procedure. . . . . . . . . . .  14
       2.7.3 The REMOVE procedure . . . . . . . . . . .  15
       2.7.4 The EXTRACT procedure. . . . . . . . . . .  15

Annex A . . . . . . . . . . . . . . . . . . . . . . . .  17
   MODULE ISO_VARYING_STRING. . . . . . . . . . . . . .  17

Annex B . . . . . . . . . . . . . . . . . . . . . . . .  67
   PROGRAM word_count . . . . . . . . . . . . . . . . .  67
   PROGRAM vocabulary_word_count. . . . . . . . . . . .  68
Foreword

[This page to be provided by ISO CS]
Introduction

   This International Standard has been prepared by ISO/IEC
JTC1/SC22/WG5, the technical working group for the Fortran language.
This International Standard is a collateral standard to ISO/IEC 1539 : 1991,
which defines the latest revision of the Fortran language. This revised
language is informally known as Fortran 90.

   This International Standard defines the interface and semantics for a
Fortran 90 module which provides facilities for the manipulation of
character strings of arbitrary and dynamic length.  The annex A includes a
possible implementation in Fortran 90 of a module that conforms to this
International Standard.  It should be noted, however, that this is purely for
purposes of demonstrating the feasibility and portability of the standard.
The actual code shown in this annex is not intended in any way to prescribe
the method of implementation.
Section 1 : Scope

   This International Standard defines facilities for use in Fortran for the
manipulation of character strings of dynamically variable and arbitrary
length.  The Fortran language for which this International Standard provides
a collateral standard is that defined by

   -   ISO/IEC 1539 : 1991  "Programming Language Fortran"

   This International Standard prescribes the name of a Fortran module,
the name of the derived data type to be used to represent such strings, the
interfaces for the procedures and operators that must be provided to
manipulate objects of this type, and the semantics that are required for each
of the entities made accessible by this module.

   This International Standard does not prescribe the details of any
implementation. Neither the method used to represent the data entities of
the defined type nor the algorithms used to implement the procedures or
operators whose interfaces are defined by this International Standard are
prescribed.  A conformant implementation may use any representation and
any algorithms, subject only to the requirement that the publicly accessible
names and interfaces conform to this International Standard,  and that the
semantics are as required by this International Standard and those of
ISO/IEC 1539 : 1991.

   It should be noted that a processor is not required to implement this
International Standard in order to be a standard conforming Fortran
processor, but if a processor implements facilities for manipulating varying
length character strings, it is recommended that this be done in a manner
that is conformant with this International Standard.

   A module, written in standard conforming Fortran, is included in
Annex A.  This module illustrates one way in which a standard conforming
module could be written.  This module is both conformant with the
requirements of this International Standard and, because it is written in
standard conforming Fortran, it provides a portable implementation of the
required facilities.
   This module is included for information only and is not intended to
constrain implementations in any way.  This module is a demonstration that
at least one implementation, in standard conforming and hence portable
Fortran, is possible.

   It should be noted that this International Standard defines facilities for
dynamically varying length strings of characters of default kind only.
Throughout this International Standard all references to intrinsic type
CHARACTER
should be read as meaning characters of default kind.  Similar facilities
could be defined for non-default kind characters by a separate module for
each such character kind.

   This International Standard has been designed, as far as is practicable,
to provide for varying length character strings the facilities that are
available
for intrinsic fixed length character strings.  All the intrinsic operations and
functions which apply to fixed length character strings have extended
meanings defined by this International Standard for varying length character
strings.  Also a small number of additional facilities are defined that are
appropriate because of the essential differences between the intrinsic type
and the varying length derived data type.

   This International Standard is meant to define a set of fundamental
facilities for varying length character strings which should be sufficient to
allow most of the basic string operations to be easily programmed.


1.1 Normative References

   -   ISO/IEC 1539 : 1991  "Programming Language Fortran"
   -   ISO/IEC  646 : 1983  "Character Coding"Section 2 : Requirements


2.1 The Name of the Module

   The name of the module shall be
       ISO_VARYING_STRING
   Programs shall be able to access the facilities defined by this
   International Standard by the inclusion of USE statements of the form
       USE ISO_VARYING_STRING
   Rationale: This name is chosen both to indicate in a mnemonic way the
   nature of the module and to identify the fact that this is an ISO
   standard module.


2.2 The Type

   The type shall have the name
       VARYING_STRING
   Entities of this type shall represent values which are strings of
   characters of default kind.  These character strings may be of any non-
   negative length and this length may vary dynamically during the
   execution of a program.  There shall be no arbitrary upper length limit
   other than that imposed by the size of the processor and the complexity
   of the programs it is able to process. The characters representing the
   value of the string have positions 1,2,...,N, where N is the length of the
   string. The internal structure of the type shall be PRIVATE to the module.
   Rationale: This name is chosen both to indicate in a mnemonic way the
   nature of the type and to reduce the probability of a user creating a
   type name conflict with other derived type names that might be
   employed in a program.  The use of a type whose internal structure is
   PRIVATE is to permit different implementations to employ different
   representations if they so choose without direct impact on standard
   conforming programs.


2.3 Extended Meanings for Intrinsic Operators

   The meanings for the intrinsic operators of:
       assignment     =
       concatenation  //
       comparisons==, /=, <, <=, >=, >
   shall be extended to accept any combination of operands of
   type(VARYING_STRING) and type CHARACTER. Note that, the equivalent comparison
   operator forms, .EQ., .NE., .LT., .LE., .GE., .GT., also have their meanings
   extended in this manner.

   2.3.1 Assignment: An assignment of the form
           var = expr
       shall be defined for the following type combinations:
           VARYING_STRING = VARYING_STRING
           VARYING_STRING = CHARACTER
                CHARACTER = VARYING_STRING
       Action: The characters that are the value of the expression expr
       become the value of the variable var. In the first two cases, the
       length of the variable becomes that of the expression. In the third
       case, the rules of intrinsic assignment to a Fortran character
       variable apply.  Namely, if the expression string is longer than the
       declared length of the character variable, only the left-most
       characters are assigned. If the character variable is longer than that
       of the string expression, it is padded on the right with blanks.

   2.3.2 Concatenation: The concatenation operation
           string_a // string_b
       shall be defined for the following type combinations:
           VARYING_STRING // VARYING_STRING
           VARYING_STRING // CHARACTER
                CHARACTER // VARYING_STRING
       Action: The result is of type(VARYING_STRING) and its value is a new
string
       whose characters are the same as those produced by concatenating
       the two argument character strings in the order given.  The values
       of the operands are unchanged by the operation.

   2.3.3 Comparisons: Comparisons of the form
           string_a .OP. string_b
       where .OP. represents any of the operators ==, /=, <, <=, >=, > shall be
       defined for the following type combinations:
           VARYING_STRING .OP. VARYING_STRING
           VARYING_STRING .OP. CHARACTER
                CHARACTER .OP. VARYING_STRING
       Note that, the equivalent operator forms .EQ., .NE., .LT., .LE., .GE.,
.GT.
       also have their meanings extended in this manner.
       Action: The result is of type default LOGICAL and its value is true if
       string_a stands in the indicated relation to string_b.  The collating
       sequence used for the inequality comparisons is that defined by the
       processor for characters of default kind.  If string_a and string_b are
of
       different length, the comparison is done as if the shorter string
       were padded on the right with blanks.  The values of the operands
       are unchanged by the operation.


2.4 Extended Meanings for Generic Intrinsic Procedures

   The generic intrinsic procedures LEN, CHAR, ICHAR, IACHAR, TRIM, LEN_TRIM,
ADJUSTL,
ADJUSTR, REPEAT, LLT, LLE, LGE, LGT, INDEX, SCAN, and VERIFY shall have their
meanings
extended to include the appropriate argument type combinations involving
type(VARYING_STRING) and CHARACTER.

   2.4.1 The LEN Procedure: The generic function reference of the form
           LEN(string)
       shall be added, where the argument string is of type(VARYING_STRING).
       Action: The result is of type default INTEGER and has the value of the
       current length of the string. The argument is unchanged by the
       procedure.

   2.4.2 The CHAR Procedure: The generic function references of the form

           CHAR(string)
           CHAR(string,length)
       shall be added, where the argument string is of type(VARYING_STRING) and
       the argument length is of type default INTEGER.
       Action: The result is of type default CHARACTER.  In the first case, the
       result has the value of the characters of string, and the same length.
       In the second case, the result has the length specified by the
       argument length. If string is longer than length, the result is truncated
       on the right. If string is shorter than length, the result is padded on
       the right with blanks.  If length is less than one, the result is of zero
       length. The arguments are unchanged by the procedure.

   2.4.3 The ICHAR Procedure: The generic function reference of the form
           ICHAR(c)
       shall be added, where the argument c is of type(VARYING_STRING) and of
       a length exactly one.
       Action: The result is of type default INTEGER and has the value of the
       position of the character c in the processor defined collating
       sequence for default characters. The argument is unchanged by the
       procedure.

   2.4.4 The IACHAR Procedure: The generic function reference of the
   form
           IACHAR(c)
       shall be added, where the argument c is of type(VARYING_STRING) and of
       a length exactly one.
       Action: The result is of type default INTEGER and has the value of the
       position of the character c in the collating sequence for default
       characters defined by the International Standard,
       ISO/IEC 646 : 1983. If the character c is not defined in the
       standard set the result is processor dependent. The argument is
       unchanged by the procedure.

   2.4.5 The TRIM procedure: The generic function reference of the form
           TRIM(string)
       shall be added, where the argument string is of type(VARYING_STRING).
       Action: The result is of type(VARYING_STRING). The result value is the
       string produced by removing any trailing blanks from the
       argument. If the argument string contains only blank characters or
       is of zero-length, the result is a zero-length string. The argument
       is unchanged by the procedure.

   2.4.6 The LEN_TRIM procedure: The generic function reference of the
   form
           LEN_TRIM(string)
       shall be added, where the argument string is of type(VARYING_STRING).
       Action: The result is of type default INTEGER. The result value is the
       position of the last non-blank character in string. If the argument
       string contains only blank characters or is of zero-length, the result
       is zero.  The argument is unchanged by the procedure.

   2.4.7 The ADJUSTL procedure: The generic function reference of the
   form
           ADJUSTL(string)
       shall be added, where the argument string is of type(VARYING_STRING).
       Action: The result is of type(VARYING_STRING).  The result value contains
       the same characters as the argument shifted cyclically to the left
       until the first character is non-blank. The result is identical to the
       argument if the first character of string is non-blank, string contains
       only blank characters or is of zero length.  The argument is
       unchanged by the procedure.

   2.4.8 The ADJUSTR procedure: The generic function reference of the
   form
           ADJUSTR(string)
       shall be added, where the argument string is of type(VARYING_STRING).
       Action: The result is of type(VARYING_STRING).  The result value contains
       the same characters as the argument shifted cyclically to the right
       until the last character is non-blank.  The result is identical to the
       argument if the last character of string is non-blank, string contains
       only blank characters or is of zero length.  The argument is
       unchanged by the procedure.

   2.4.9 The REPEAT procedure: The generic function reference of the
   form
           REPEAT(string,ncopies)
       shall be added, where the arguments string and ncopies are of
       type(VARYING_STRING) and type default INTEGER, respectively.
       Action: The result is of type(VARYING_STRING). The result value is the
       string produced by repeated concatenation of the argument string,
       producing a string containing ncopies copies of string. A negative value
       for ncopies is not permitted. If ncopies is zero, the result is of
       zero-length. The arguments are unchanged by the procedure.

   2.4.10 Comparison Procedures: The set of generic function references
   of the form
           Lop(string_a,string_b)
       shall be added, where op stands for one of:
           LT -   less than
           LE -   less than or equal to
           GE -   greater than or equal to
           GT -   greater than
       and the arguments string_a and string_b are of one of the type
       combinations:
           VARYING_STRING and VARYING_STRING,
           VARYING_STRING and CHARACTER, or
                CHARACTER and VARYING_STRING.
       Action: The result in each case is of type default LOGICAL and is true
       if string_a stands in the indicated relationship to string_b, and is
false
       otherwise.  The collating sequence used to establish the ordering
       of characters for these procedures is that of the International
       Standard, ISO 646 : 1983.  If string_a and string_b are of different
       length, the comparison is done as if the shorter string were padded
       on the right with blanks. If either argument contains a character
       not defined by the standard, the result is processor dependent.
       The arguments are unchanged by the procedure.

   2.4.11 The INDEX procedure: The generic function reference of the
   form
           INDEX(string,substring,back)
       shall be added, where the optional argument back is of type default
       LOGICAL and the arguments string and substring are of one of the type
       combinations:
           VARYING_STRING and VARYING_STRING,
           VARYING_STRING and CHARACTER, or
                CHARACTER and VARYING_STRING.
       Action: The result in each case is of type default INTEGER. The result
       value is the starting position in string of substring. If substring
occurs
       more than once in string, the result is for the first occurrence
       encountered. If substring is not found in string, the value zero is
       returned.  The search is done in the forward direction if the
       argument back is absent or present with value .FALSE., and in the
       backward direction if back is present with the value .TRUE.. If the
       length of substring is zero, the result is LEN(string) + 1 when back is
present
       with the value .TRUE. and one otherwise. If LEN(string) is less than
       LEN(substring), the result is zero. The arguments are unchanged by the
       procedure.

   2.4.12 The SCAN procedure: The generic reference of the form
           SCAN(string,set,back)
       shall be added, where the optional argument back is of type default
       LOGICAL and the arguments string and set are of one of the type
       combinations:
           VARYING_STRING and VARYING_STRING,
           VARYING_STRING and CHARACTER, or
                CHARACTER and VARYING_STRING.
       Action: The result in each case is of type default INTEGER. The result
       value is the first position in string that contains a character that is
       also contained in the argument set.  If none of the characters in set
       are found in string, the value zero is returned.  The search is
       performed in the forward direction if the argument back is absent or
       present with value .FALSE., and in the backward direction if back is
       present with the value .TRUE.. If either the string or the set is of zero
       length, the result is zero. The arguments are unchanged by the
       procedure.

   2.4.13 The VERIFY procedure: The generic reference of the form
           VERIFY(string,set,back)
       shall be added, where the optional argument back is of type default
       LOGICAL and the string and set arguments are of one of the type
       combinations:
           VARYING_STRING and VARYING_STRING,
           VARYING_STRING and CHARACTER, or
                CHARACTER and VARYING_STRING.
       Action: The result in each case is of type default INTEGER. The result
       value is the first position in string that contains a character that is
       not contained in the argument set.  If string contains only characters
       from set or is of zero-length, the value zero is returned.  The search
       is done in the forward direction if the argument back is absent or
       present with value .FALSE., and in the backward direction if back is
       present with the value .TRUE.. If set is of zero length, the result is
       LEN(string) if back is present with the value .FALSE., and is one
otherwise.
       The arguments are unchanged by the procedure.


2.5 Additional Generic Procedure for Type Conversion

   An additional generic procedure shall be added to convert intrinsic
fixed length character values into varying length string values.

   2.5.1 The VAR_STR procedure: The generic reference of the form
           VAR_STR(char)
       shall be provided, where the argument char is of type default CHARACTER
       and may be of any length.
       Action: The result is of type(VARYING_STRING) and its value is the same
       string of characters as the argument. The argument is unchanged
       by the procedure.


2.6 Additional Generic Procedures for Input/Output

   The following additional generic procedures shall be provided to
   support input and output of varying string values with formatted
   sequential files.

       READ_STRING    -   input part or all of a record into a string
       WRITE_STRING       -  append a string to an output record
       WRITE_LINE         -  append a string to an output record
                             and end the record

   2.6.1 The READ_STRING procedure: The generic subroutine references
   of the forms
           CALL READ_STRING(string,maxlen,iostat)
           CALL READ_STRING(unit,string,maxlen,iostat)
           CALL READ_STRING(string,set,maxlen,iostat)
           CALL READ_STRING(unit,string,set,maxlen,iostat)
       shall be provided. The arguments unit, maxlen, and iostat are of type
       default INTEGER.  Both maxlen and iostat are optional, and maxlen is an
       INTENT(IN) argument and iostat is an INTENT(OUT) argument.  The argument
       string is of type(VARYING_STRING).  The argument set is either of type
default
       CHARACTER or of type(VARYING_STRING).
       Action: The argument unit specifies the input unit to be used. It
       must be connected to a formatted file for sequential read access.
       If the argument unit is omitted, the default input unit is used. The
       argument string must be a variable into which characters may be
       put. The READ_STRING procedure causes characters from the connected
       file, starting with the next character in the current record if there
       is a current record or the first character of the next record if not,
       to be read and stored in the variable string. The end of record
       always terminates the input but input may be terminated before
       this.  If maxlen is present, its value indicates the maximum number of
       characters that will be read. If maxlen is less than or equal to zero, no
       characters will be input and string will be set to zero length. If maxlen
       is absent, a maximum of HUGE(1) is used. If the argument set is
       provided, this specifies a set of characters the occurrence of any of
       which will terminate the input.  This terminal character, although
       read from the input file, will not be included in the result string.
       The file position after the data transfer is complete is after the last
       character that was read.  If the transfer was terminated by the end
       of record being reached, the file is positioned after the record just
       read. If present, the argument iostat is used to return the status
       resulting from the data transfer.  A zero value is returned if a valid
       read operation occurs, a positive value if an error is caused, and a
       negative value if an end-of-file condition occurs. If iostat is absent
       and anything other than a valid read operation occurs, the program
       execution is terminated.

   2.6.2 The WRITE_STRING procedure: The generic subroutine
   references of the forms
           CALL WRITE_STRING(string,iostat)
           CALL WRITE_STRING(unit,string,iostat)
       shall be provided. The arguments unit and iostat are of type default
       INTEGER and iostat is  an optional INTENT(OUT) argument. The argument
       string may be either of type(VARYING_STRING) or type default CHARACTER.
       Action: The argument unit specifies the output unit to be used. If
       the argument unit is omitted, the default output unit is used. The
       output unit must be connected to a formatted file for sequential
       write access.  The argument string must be an expression whose
       characters are to be written to the output unit.  The WRITE_STRING
       procedure causes the characters of the string to be appended to the
       current record, if there is a current record, or to the start of the
       next record if there is no current record. The last character
       transferred becomes the last character of the current record, which
       is the last record of the file. If present, the argument iostat is used
       to return the status resulting from the data transfer.  A zero value
       is returned if a valid write operation occurs, and a positive value
       if an error is caused. If iostat is absent and anything other than a
       valid write operation occurs, the program execution is terminated.

   2.6.3 The WRITE_LINE procedure: The generic subroutine references
   of the forms
           CALL WRITE_LINE(string,iostat)
           CALL WRITE_LINE(unit,string,iostat)
       shall be provided. The arguments unit and iostat are of type default
       INTEGER and iostat is an optional INTENT(OUT) argument. The argument
       string may be either of type(VARYING_STRING) or type default CHARACTER.
       Action: The argument unit specifies the output unit to be used. If
       the argument unit is omitted, the default output unit is used. The
       output unit must be connected to a formatted file for sequential
       write access. The argument string must be an expression whose
       characters are to be written to the output unit. The WRITE_LINE
       procedure causes the characters of the string to be appended to the
       current record, if there is a current record, or to the start of the
       next record if there is no current record. Following completion of
       the data transfer, the file is positioned after the record just written,
       which becomes the previous and last record of the file. If present,
       the argument iostat is used to return the status resulting from the
       data transfer. A zero value is returned if a valid write operation
       occurs, and a positive value if an error is caused. If iostat is absent
       and anything other than a valid write operation occurs, the
       program execution is terminated.


2.7 Additional Generic Procedures for Substring
Manipulation

   The following additional generic procedures shall be provided to
support the manipulation of substrings of varying length strings.

       INSERT         -   insert a substring into a string
       REPLACE    -   replace a substring in a string
       REMOVE         -   remove a section of a string

       EXTRACT    -   extract a section from a string

   2.7.1 The INSERT procedure: The generic function reference of the
   form
           INSERT(string,start,substring)
       shall be provided, where the argument start is of type default INTEGER,
       and the arguments string and substring of type(VARYING_STRING) or type
       default CHARACTER, in any combination.
       Action: The result is of type(VARYING_STRING). The result value is a copy
       of the characters of the argument string modified by the following
       actions. The characters of substring are inserted into the copy of string
       before the character at the character position start. The remainder
       of the result string is shifted to the right and enlarged as necessary.
       If start is greater than LEN(string), substring is simply appended to the
       copy of string. If start is less than or equal to one, substring is
inserted
       before the first character of the copy string. The length of the
       result is LEN(string) + LEN(substring). The arguments are unchanged by
the
       procedure.

   2.7.2 The REPLACE procedure: The generic function references of the
   forms
           REPLACE(string,start,substring)
           REPLACE(string,start,finish,substring)
           REPLACE(string,target,substring,every,back)
       shall be provided, where the arguments start and finish are of type
       default INTEGER, the arguments every and back are both optional and
       both of type default LOGICAL, and the arguments string, substring and
       target are either of type(VARYING_STRING) or type default CHARACTER, in
any
       combination.
       Action: The result is of type(VARYING_STRING). The result value is a copy
       of the characters of the argument string modified by one of the
       following actions.
           a) For the version with the argument start but without the
           argument finish. The characters of the argument substring are
           inserted into the copy of string before the character at the
           character position start, replacing the following LEN(substring)
           characters. The result string is enlarged if necessary. If start is
           greater than LEN(string), substring is simply appended to the copy
           string. If start is less than or equal to one, substring replaces
           characters in the copy string starting at character position one.
           b) For the version with the argument finish. The characters in
           the copy of string between positions start and finish, including
           those at start and finish, are deleted and the characters of the
           argument substring inserted in their place. If start is less than 1,
           the value 1 is used. If finish is greater than LEN(string), the value
           LEN(string) is used. If finish is less than start, the characters of
           substring are inserted before the character at start and no
           characters are deleted. The length of the result string is
           adjusted as necessary.
           c) For the versions with the argument target. The copy of string
           is searched for an occurrence of target. The search is done in
           the backward direction if the argument back is present with the
           value .TRUE., but in the forward direction otherwise. If target is
           found, it is replaced by substring. If every is present with the
value
           .TRUE., the search and replace is continued from the first
           character following target until all occurrences of target in the
           copy string are replaced, otherwise only the first occurrence of
           target is replaced. The argument target must not have a zero
           length.
       In all cases the arguments are unchanged by the procedure.

   2.7.3 The REMOVE procedure: The generic function reference of the
   form
           REMOVE(string,start,finish)
       shall be provided, where the argument string is of type(VARYING_STRING)
or
       of type default CHARACTER, and the arguments start and finish are both of
       type default INTEGER and both optional.
       Action: The result is of type(VARYING_STRING). The result value is a copy
       of the characters of string modified by the following actions. The
       characters between start and finish, inclusive, are removed from the
       copy string, reducing it in size as required. If start is absent or less
       than 1, then the value 1 is used. If finish is absent or greater than
       LEN(string), the value LEN(string) is used. If finish is less than start,
the
       characters of string are delivered unchanged as the result. The
       arguments are unchanged by the procedure.

   2.7.4 The EXTRACT procedure: The generic function reference of the
   form
           EXTRACT(string,start,finish)
       shall be provided, where the argument string is of type(VARYING_STRING)
or
       type CHARACTER, and the arguments start and finish are both of type
       default INTEGER and both optional.
       Action: The result has type(VARYING_STRING) and its value is a copy of
the
       characters in string between start and finish, inclusive. If start is
absent
       or less than 1, the value 1 is used. If finish is absent or greater than
       LEN(string), the value LEN(string) is used. If start is greater than
finish a
       zero length string is returned. The arguments are unchanged by the
       procedure.
  Annex A
(Informative)

   The following module is written in Fortran 90, conformant with the
language as specified in the standard ISO/IEC 1539 : 1991.  It is intended
to be a portable implementation of a module conformant with this
International Standard. It is not intended to be prescriptive of how facilities
consistent with this International Standard should be provided. This module
is intended primarily to demonstrate that portable facilities consistent with
the interfaces and semantics required by this International Standard could
be provided within the confines of the Fortran language. It is also included
as a guide for users of processors which do not have supplier provided
facilities implementing this International Standard.

   It should be noted that while every care has been taken by the technical
working group to ensure that this module is a correct implementation of this
International Standard in valid Fortran code, no guarantee is given or
implied that this code will produce correct results, or even that it will
execute on any particular processor.


MODULE ISO_VARYING_STRING

! Written by J.L.Schonfelder
! Incorporating suggestions by C.Tanasescu, C.Weber, J.Wagener and W.Walter,
! and corrections due to L.Moss, M.Cohen, P.Griffiths, B.T.Smith
! and many other members of the committee ISO/IEC JTC1/SC22/WG5

! Version produced (5-Mar-92)

!-----------------------------------------------------------------------------!
! This module defines the interface and one possible implementation for a     !
! dynamic length character string facility in Fortran 90. The Fortran 90      !
! language is defined by the standard ISO/IEC 1539 : 1991.                    !
! The publicly accessible interface defined by this module is conformant      !
! with the collateral standard, ISO/IEC 1539-1 : 1993.                        !
! The detailed implementation may be considered as an informal definition of  !
! the required semantics, and may also be used as a guide to the production   !
! of a portable implementation.                                               !
! N.B. Although every care has been taken to produce valid Fortran code in    !
!      construction of this module no guarantee is given or implied that this !
!      code will work correctly without error on any specific processor.      !
!-----------------------------------------------------------------------------!

PRIVATE

!-----------------------------------------------------------------------------!
! By default all entities declared or defined in this module are private to   !
! the module. Only those entities declared explicitly as being public are     !
! accessible to programs using the module. In particular, the procedures and  !
! operators defined herein are made accessible via their generic identifiers  !
! only; their specific names are private.                                     !
!-----------------------------------------------------------------------------!

TYPE VARYING_STRING
 PRIVATE
 CHARACTER,DIMENSION(:),POINTER :: chars
ENDTYPE VARYING_STRING

!-----------------------------------------------------------------------------!
! The representation chosen for this definition of the module is of a string  !
! type consisting of a single component that is a pointer to a rank one array !
! of characters.                                                              !
! Note: this Module is defined only for characters of default kind. A similar !
! module could be defined for non-default characters if these are supported   !
! on a processor by adding a KIND parameter to the component in the type      !
! definition, and to all delarations of objects of CHARACTER type.            !
!-----------------------------------------------------------------------------!

CHARACTER,PARAMETER :: blank = " "
INTEGER,PARAMETER   :: ichar0 = ICHAR("0")

!----- GENERIC PROCEDURE INTERFACE DEFINITIONS -------------------------------!

!----- LEN interface ---------------------------------------------------------!
INTERFACE LEN
  MODULE PROCEDURE len_s   ! length of string
ENDINTERFACE

!----- Conversion procedure interfaces ---------------------------------------!
INTERFACE VAR_STR
  MODULE PROCEDURE c_to_s   ! character to string
ENDINTERFACE

INTERFACE CHAR
  MODULE PROCEDURE s_to_c, &   ! string to character
                   s_to_fix_c  ! string to specified length character
ENDINTERFACE

!----- ASSIGNMENT interfaces -------------------------------------------------!
INTERFACE ASSIGNMENT(=)
  MODULE PROCEDURE s_ass_s, &   ! string    = string
                   c_ass_s, &   ! character = string
                   s_ass_c      ! string    = character
ENDINTERFACE

!----- Concatenation operator interfaces -------------------------------------!
INTERFACE OPERATOR(//)
  MODULE PROCEDURE s_concat_s, &  ! string//string
                   s_concat_c, &  ! string//character
                   c_concat_s     ! character//string
ENDINTERFACE

!----- Repeated Concatenation interfaces -------------------------------------!
INTERFACE REPEAT
  MODULE PROCEDURE repeat_s
ENDINTERFACE

!------ Equality comparison operator interfaces-------------------------------!
INTERFACE OPERATOR(==)
  MODULE PROCEDURE s_eq_s, &  ! string==string
                   s_eq_c, &  ! string==character
                   c_eq_s     ! character==string
ENDINTERFACE

!----- not-equality comparison operator interfaces ---------------------------!
INTERFACE OPERATOR(/=)
  MODULE PROCEDURE s_ne_s, &  ! string/=string
                   s_ne_c, &  ! string/=character
                   c_ne_s     ! character/=string
ENDINTERFACE

!----- less-than comparison operator interfaces ------------------------------!
INTERFACE OPERATOR(<)
  MODULE PROCEDURE s_lt_s, &  ! string<string
                   s_lt_c, &  ! string<character
                   c_lt_s     ! character<string
ENDINTERFACE

!----- less-than-or-equal comparison operator interfaces ---------------------!
INTERFACE OPERATOR(<=)
  MODULE PROCEDURE s_le_s, &  ! string<=string
                   s_le_c, &  ! string<=character
                   c_le_s     ! character<=string
ENDINTERFACE

!----- greater-than-or-equal comparison operator interfaces ------------------!
INTERFACE OPERATOR(>=)
  MODULE PROCEDURE s_ge_s, &  ! string>=string
                   s_ge_c, &  ! string>=character
                   c_ge_s     ! character>=string
ENDINTERFACE

!----- greater-than comparison operator interfaces ---------------------------!
INTERFACE OPERATOR(>)
  MODULE PROCEDURE s_gt_s, &  ! string>string
                   s_gt_c, &  ! string>character
                   c_gt_s     ! character>string
ENDINTERFACE

!----- LLT procedure interfaces ----------------------------------------------!
INTERFACE LLT
  MODULE PROCEDURE s_llt_s, &  ! LLT(string,string)
                   s_llt_c, &  ! LLT(string,character)
                   c_llt_s     ! LLT(character,string)
ENDINTERFACE

!----- LLE procedure interfaces ----------------------------------------------!
INTERFACE LLE
  MODULE PROCEDURE s_lle_s, &  ! LLE(string,string)
                   s_lle_c, &  ! LLE(string,character)
                   c_lle_s     ! LLE(character,string)
ENDINTERFACE

!----- LGE procedure interfaces ----------------------------------------------!
INTERFACE LGE
  MODULE PROCEDURE s_lge_s, &  ! LGE(string,string)
                   s_lge_c, &  ! LGE(string,character)
                   c_lge_s     ! LGE(character,string)
ENDINTERFACE

!----- LGT procedure interfaces ----------------------------------------------!
INTERFACE LGT
  MODULE PROCEDURE s_lgt_s, &  ! LGT(string,string)
                   s_lgt_c, &  ! LGT(string,character)
                   c_lgt_s     ! LGT(character,string)
ENDINTERFACE

!----- Input function interface ---------------------------------------------!
INTERFACE READ_STRING
  MODULE PROCEDURE get_d_eor, &    ! default unit, EoR termination
                   get_u_eor, &    ! specified unit, EoR termination
                   get_d_tset_s, & ! default unit, string set termination
                   get_u_tset_s, & ! specified unit, string set termination
                   get_d_tset_c, & ! default unit, char set termination
                   get_u_tset_c    ! specified unit, char set termination
ENDINTERFACE

!----- Output procedure interfaces -------------------------------------------!
INTERFACE WRITE_STRING
  MODULE PROCEDURE put_d_s, & ! string to default unit
                   put_u_s, & ! string to specified unit
                   put_d_c, & ! char to default unit
                   put_u_c    ! char to specified unit
ENDINTERFACE

INTERFACE WRITE_LINE
  MODULE PROCEDURE putline_d_s, & ! string to default unit
                   putline_u_s, & ! string to specified unit
                   putline_d_c, & ! char to default unit
                   putline_u_c    ! char to specified unit
ENDINTERFACE

!----- Insert procedure interfaces -------------------------------------------!
INTERFACE INSERT
  MODULE PROCEDURE insert_ss, & ! string in string
                   insert_sc, & ! char in string
                   insert_cs, & ! string in char
                   insert_cc    ! char in char
ENDINTERFACE

!----- Replace procedure interfaces ------------------------------------------!
INTERFACE REPLACE
  MODULE PROCEDURE replace_ss, &   ! string by string, at specified
                   replace_sc, &   ! string by char  , starting
                   replace_cs, &   ! char by string  , point
                   replace_cc, &   ! char by char
                   replace_ss_sf,& ! string by string, between
                   replace_sc_sf,& ! string by char  , specified
                   replace_cs_sf,& ! char by string  , starting and
                   replace_cc_sf,& ! char by char    , finishing points
                   replace_sss, &  ! in string replace string by string
                   replace_ssc, &  ! in string replace string by char
                   replace_scs, &  ! in string replace char by string
                   replace_scc, &  ! in string replace char by char
                   replace_css, &  ! in char replace string by string
                   replace_csc, &  ! in char replace string by char
                   replace_ccs, &  ! in char replace char by string
                   replace_ccc     ! in char replace char by char
ENDINTERFACE

!----- Remove procedure interface --------------------------------------------!
INTERFACE REMOVE
  MODULE PROCEDURE remove_s, & ! characters from string, between start
                   remove_c    ! characters from char  , and finish
ENDINTERFACE

!----- Extract procedure interface -------------------------------------------!
INTERFACE EXTRACT
  MODULE PROCEDURE extract_s, & ! from string extract string, between start
                   extract_c    ! from char   extract string, and finish
ENDINTERFACE

!----- Index procedure interfaces --------------------------------------------!
INTERFACE INDEX
  MODULE PROCEDURE index_ss, index_sc, index_cs
ENDINTERFACE

!----- Scan procedure interfaces ---------------------------------------------!
INTERFACE SCAN
  MODULE PROCEDURE scan_ss, scan_sc, scan_cs
ENDINTERFACE

!----- Verify procedure interfaces -------------------------------------------!
INTERFACE VERIFY
  MODULE PROCEDURE verify_ss, verify_sc, verify_cs
ENDINTERFACE

INTERFACE LEN_TRIM
  MODULE PROCEDURE len_trim_s
ENDINTERFACE

INTERFACE TRIM
  MODULE PROCEDURE trim_s
ENDINTERFACE

INTERFACE IACHAR
  MODULE PROCEDURE iachar_s
ENDINTERFACE

INTERFACE ICHAR
  MODULE PROCEDURE ichar_s
ENDINTERFACE

INTERFACE ADJUSTL
  MODULE PROCEDURE adjustl_s
ENDINTERFACE

INTERFACE ADJUSTR
  MODULE PROCEDURE adjustr_s
ENDINTERFACE

!----- specification of publically accessible entities -----------------------!
PUBLIC ::
VARYING_STRING,VAR_STR,CHAR,LEN,READ_STRING,WRITE_STRING,WRITE_LINE,INSERT,REPLA
CE,REMOVE, &
          REPEAT,EXTRACT,INDEX,SCAN,VERIFY,LLT,LLE,LGE,LGT,ASSIGNMENT(=),    &
          OPERATOR(//),OPERATOR(==),OPERATOR(/=),OPERATOR(<),OPERATOR(<=),   &
          OPERATOR(>=),OPERATOR(>),LEN_TRIM,TRIM,IACHAR,ICHAR,ADJUSTL,ADJUSTR

CONTAINS

!----- LEN Procedure ---------------------------------------------------------!
 FUNCTION len_s(string)
  type(VARYING_STRING),INTENT(IN) :: string
  INTEGER                         :: len_s
  ! returns the length of the string argument or zero if there is no current
  ! string value
  IF(.NOT.ASSOCIATED(string%chars))THEN
    len_s = 0
  ELSE
    len_s = SIZE(string%chars)
  ENDIF
 ENDFUNCTION len_s

!----- Conversion Procedures ------------------------------------------------!
 FUNCTION c_to_s(chr)
  type(VARYING_STRING)        :: c_to_s
  CHARACTER(LEN=*),INTENT(IN) :: chr
  ! returns the string consisting of the characters char
  INTEGER                     :: lc
  lc=LEN(chr)
  ALLOCATE(c_to_s%chars(1:lc))
  DO i=1,lc
    c_to_s%chars(i) = chr(i:i)
  ENDDO
 ENDFUNCTION c_to_s

 FUNCTION s_to_c(string)
  type(VARYING_STRING),INTENT(IN)   :: string
  CHARACTER(LEN=SIZE(string%chars)) :: s_to_c
  ! returns the characters of string as an automatically sized character
  INTEGER                           :: lc
  lc=SIZE(string%chars)
  DO i=1,lc
    s_to_c(i:i) = string%chars(i)
  ENDDO
 ENDFUNCTION s_to_c

 FUNCTION s_to_fix_c(string,length)
  type(VARYING_STRING),INTENT(IN) :: string
  INTEGER,INTENT(IN)              :: length
  CHARACTER(LEN=length)           :: s_to_fix_c
  ! returns the character of fixed length, length, containing the characters
  ! of string either padded with blanks or truncated on the right to fit
  INTEGER                         :: lc
  lc=MIN(SIZE(string%chars),length)
  DO i=1,lc
    s_to_fix_c(i:i) = string%chars(i)
  ENDDO
  IF(lc < length)THEN  ! result longer than string padding needed
    s_to_fix_c(lc+1:length) = blank
  ENDIF
 ENDFUNCTION s_to_fix_c

!----- ASSIGNMENT Procedures -------------------------------------------------!
 SUBROUTINE s_ass_s(var,expr)
  type(VARYING_STRING),INTENT(OUT) :: var
  type(VARYING_STRING),INTENT(IN)  :: expr
  !  assign a string value to a string variable overriding default assignement
  !  reallocates string variable to size of string value and copies characters
  IF(ASSOCIATED(var%chars))DEALLOCATE(var%chars)
  ALLOCATE(var%chars(1:LEN(expr)))
  var%chars = expr%chars
 ENDSUBROUTINE s_ass_s

 SUBROUTINE c_ass_s(var,expr)
  CHARACTER(LEN=*),INTENT(OUT)    :: var
  type(VARYING_STRING),INTENT(IN) :: expr
  ! assign a string value to a character variable
  ! if the string is longer than the character truncate the string on the right
  ! if the string is shorter the character is blank padded on the right
  INTEGER                         :: lc,ls
  lc = LEN(var); ls = MIN(LEN(expr),lc)
  DO i = 1,ls
   var(i:i) = expr%chars(i)
  ENDDO
  DO i = ls+1,lc
