international standards organization varying ... - fortran · 4 iso/iec 1539 : 1991, which defines...
TRANSCRIPT
International Standards Organization
Varying Length Character Strings
in
Fortran
ISO/IEC 1539-2{auxiliary standard to ISO/IEC 1539 : 1991}
{Second Committee Draft Produced 26-Jul-93}
CD version 2 ISO/IEC 1539-2 : 1993 (E)
Contents
Foreword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vi
Section 1 : Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1 Normative References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Section 2 : Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.1 The Name of the Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32.2 The Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32.3 Extended Meanings for Intrinsic Operators . . . . . . . . . . . . . . . . . . . . 3
2.3.1 Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32.3.2 Concatenation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.3.3 Comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.4 Extended Meanings for Generic Intrinsic Procedures . . . . . . . . . . . . 42.4.1 The LEN Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.4.2 The CHAR Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.4.3 The ICHAR Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.4.4 The IACHAR Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.4.5 The TRIM procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.4.6 The LEN_TRIM procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.4.7 The ADJUSTL procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.4.8 The ADJUSTR procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.4.9 The REPEAT procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.4.10 Comparison Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.4.11 The INDEX procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82.4.12 The SCAN procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82.4.13 The VERIFY procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.5 Additional Generic Procedure for Type Conversion . . . . . . . . . . . . . 92.5.1 The VAR_STR procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.6 Additional Generic Procedures for Input/Output . . . . . . . . . . . . . . . . 92.6.1 The GET procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.6.2 The PUT procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112.6.3 The PUT_LINE procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.7 Additional Generic Procedures for Substring Manipulation . . . . . . 122.7.1 The INSERT procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.7.2 The REPLACE procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.7.3 The REMOVE procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.7.4 The EXTRACT procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142.7.5 The SPLIT procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Annex A . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15MODULE ISO_VARYING_STRING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
iii
ISO/IEC 1539-2 : 1993 (E) CD version 2
Annex B . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65PROGRAM word_count . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65PROGRAM vocabulary_word_count . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
iv
CD version 2 ISO/IEC 1539-2 : 1993 (E)
Foreword
[This page to be provided by ISO CS]
v
ISO/IEC 1539-2 : 1993 (E) CD version 2
Introduction1
This International Standard has been prepared by ISO/IEC JTC1/SC22/WG5, the technical working2group for the Fortran language. This International Standard is an auxiliary standard to3ISO/IEC 1539 : 1991, which defines the latest revision of the Fortran language, and is the first part4of the multipart Fortran family of standards; this International Standard is the second part. The revised5language defined by the above standard is informally known as Fortran 90.6
This International Standard defines the interface and semantics for a module which provides facilities7for the manipulation of character strings of arbitrary and dynamically variable length. The annex A8includes a possible implementation in Fortran 90 of a module that conforms to this International9Standard. It should be noted, however, that this is purely for purposes of demonstrating the feasibility10and portability of the standard. The actual code shown in this annex is not intended in any way to11prescribe the method of implementation, nor is there any implication that this is in any way an optimal12portable implementation. The module is merely a fairly straight forward demonstration that a portable13implementation is possible.14
vi
CD version 2 ISO/IEC 1539-2 : 1993 (E)
Section 1 : Scope1
This International Standard defines facilities for use in Fortran for the manipulation of character strings2of dynamically variable length. This International Standard provides an auxiliary standard for the3Fortran language informally known as Fortran 90. The standard defining this revision of the Fortran4language is5
- ISO/IEC 1539 : 1991 "Programming Language Fortran"6
This International Standard is an auxiliary standard to that defining Fortran 90 in that it defines7additional facilities to those defined intrinsically in the primary language standard. However, a8processor conforming to the Fortran 90 standard is not required to also conform to this International9Standard. Nevertheless, conformance to to this International Standard assumes conformance to the10primary Fortran 90 standard.11
This International Standard prescribes the name of a Fortran module, the name of the derived data type12to be used to represent varying-length strings, the interfaces for the procedures and operators that must13be provided to manipulate objects of this type, and the semantics that are required for each of the14entities made accessible by this module.15
This International Standard does not prescribe the details of any implementation. Neither the method16used to represent the data entities of the defined type nor the algorithms used to implement the17procedures or operators whose interfaces are defined by this International Standard are prescribed. A18conformant implementation may use any representation and any algorithms, subject only to the19requirement that the publicly accessible names and interfaces conform to this International Standard,20and that the semantics are as required by this International Standard and those of ISO/IEC 1539 : 1991.21
It should be noted that a processor is not required to implement this International Standard in order to22be a standard conforming Fortran processor, but if a processor implements facilities for manipulating23varying length character strings, it is recommended that this be done in a manner that is conformant24with this International Standard. A processor conforming to this International Standard may extend25the facilities provided for the manipulation of varying length character strings as long as such26extensions do not conflict with those defined in this International Standard.27
A module, written in standard conforming Fortran, is included in Annex A. This module illustrates28one way in which a standard conforming module could be written. This module is both conformant29with the requirements of this International Standard and, because it is written in standard conforming30Fortran, it provides a portable implementation of the required facilities.31
This module is included for information only and is not intended to constrain implementations in any32way. This module is a demonstration that at least one implementation, in standard conforming and33hence portable Fortran, is possible.34
It should be noted that this International Standard defines facilities for dynamically varying length35strings of characters of default kind only. Throughout this International Standard all references to36intrinsic type CHARACTER should be read as meaning characters of default kind. Similar facilities could37be defined for non-default kind characters by a separate, if similar, module for each such character38kind.39
1
ISO/IEC 1539-2 : 1993 (E) CD version 2
This International Standard has been designed, as far as is reasonable, to provide for varying length1character strings the facilities that are available for intrinsic fixed length character strings. All the2intrinsic operations and functions which apply to fixed length character strings have extended meanings3defined by this International Standard for varying length character strings. Also a small number of4additional facilities are defined that are appropriate because of the essential differences between the5intrinsic type and the varying length derived data type.6
1.1 Normative References7
- ISO/IEC 1539 : 1991 "Programming Language Fortran"8- ISO/IEC 646 : 1983 "Character Coding"9
2
CD version 2 ISO/IEC 1539-2 : 1993 (E)
Section 2 : Requirements1
2.1 The Name of the Module2
The name of the module shall be3ISO_VARYING_STRING4
Programs shall be able to access the facilities defined by this International Standard by the inclusion5of USE statements of the form6
USE ISO_VARYING_STRING7
2.2 The Type8
The type shall have the name9VARYING_STRING10
Entities of this type shall represent values which are strings of characters of default kind. These11character strings may be of any non-negative length and this length may vary dynamically during the12execution of a program. There shall be no arbitrary upper length limit other than that imposed by the13size of the processor and the complexity of the programs it is able to process. The characters14representing the value of the string have positions 1,2,...,N, where N is the length of the string. The15internal structure of the type shall be PRIVATE to the module.16
2.3 Extended Meanings for Intrinsic Operators17
The meanings for the intrinsic operators of:18assignment =19concatenation //20comparisons ==, /=, <, <=, >=, >21
shall be extended to accept any combination of scalar operands of type VARYING_STRING and type22CHARACTER. Note that, the equivalent comparison operator forms, .EQ., .NE., .LT., .LE., .GE.,23.GT., also have their meanings extended in this manner.24
2.3.1 Assignment: An assignment of the form25var = expr26
shall be defined for scalars with the following type combinations:27VARYING_STRING = VARYING_STRING28VARYING_STRING = CHARACTER29
CHARACTER = VARYING_STRING30Action: The characters that are the value of the expression expr become the value of the31variable var. There are two cases:32Case(i) : Where the variable is of type VARYING_STRING, the length of the33
variable becomes that of the expression.34Case(ii) : Where the variable is of type CHARACTER, the rules of intrinsic35
assignment to a Fortran character variable apply. Namely, if the36expression string is longer than the declared length of the character37variable, only the left-most characters are assigned. If the character38variable is longer than that of the string expression, it is padded on the39right with blanks.40
3
ISO/IEC 1539-2 : 1993 (E) CD version 2
2.3.2 Concatenation: The concatenation operation1string_a // string_b2
shall be defined for scalars with the following type combinations:3VARYING_STRING // VARYING_STRING4VARYING_STRING // CHARACTER5
CHARACTER // VARYING_STRING6The values of the operands are unchanged by the operation.7Result Type: VARYING_STRING8Result Value: The result value is a new string whose characters are the same as those9produced by concatenating the operand character strings in the order given.10
2.3.3 Comparisons: Comparisons of the form11string_a .OP. string_b12
where .OP. represents any of the operators ==, /=, <, <=, >=, > shall be defined for13scalar operands with the following type combinations:14
VARYING_STRING .OP. VARYING_STRING15VARYING_STRING .OP. CHARACTER16
CHARACTER .OP. VARYING_STRING17The values of the operands are unchanged by the operation.18Note that, the equivalent operator forms .EQ., .NE., .LT., .LE., .GE., .GT. also19have their meanings extended in this manner.20Result Type: default LOGICAL.21Result Value: The result value is true if string_a stands in the indicated relation to22string_b. The collating sequence used for the inequality comparisons is that defined by23the processor for characters of default kind. If string_a and string_b are of different24lengths, the comparison is done as if the shorter string were padded on the right with25blanks.26
2.4 Extended Meanings for Generic Intrinsic Procedures27
The generic intrinsic procedures LEN, CHAR, ICHAR, IACHAR, TRIM, LEN_TRIM, ADJUSTL, ADJUSTR,28REPEAT, LLT, LLE, LGE, LGT, INDEX, SCAN, and VERIFY shall have their meanings extended to29include the appropriate scalar argument type combinations involving VARYING_STRING and CHARACTER.30
2.4.1 The LEN Procedure: The generic function reference of the form31LEN(string)32
shall be added.33Description: Returns the length of a character string.34Class: Transformational function.35Argument: string is a scalar of type VARYING_STRING. The argument is unchanged by36the procedure.37Result Type: default INTEGER.38Result Value: The result value is the number of characters in string.39
4
CD version 2 ISO/IEC 1539-2 : 1993 (E)
2.4.2 The CHAR Procedure: The generic function references of the form1CHAR(string)2CHAR(string,length)3
shall be added.4Description: Converts a varying string value to default character.5Class: Transformational function.6Arguments:7string - is of type VARYING_STRING8length - is of type default INTEGER.9The arguments must be scalars and are unchanged by the procedure.10Result Type: default CHARACTER.11Result Value:12Case(i) : If length is absent, the result has the value of the characters of13
string, and the same length.14Case(ii) : If length is present, the result has the length specified by the15
argument length. If string is longer than length, the result is16truncated on the right. If string is shorter than length, the result is17padded on the right with blanks. If length is less than one, the result18is of zero length.19
2.4.3 The ICHAR Procedure: The generic function reference of the form20ICHAR(c)21
shall be added.22Description: Position of a character in the processor collating sequence.23Class: Transformational function.24Argument: c is a scalar of type VARYING_STRING and of length exactly one. The25argument is unchanged by the procedure.26Result Type: default INTEGER.27Result Value: The result value is the position of the character c in the processor defined28collating sequence for default characters.29
2.4.4 The IACHAR Procedure: The generic function reference of the form30IACHAR(c)31
shall be added.32Description: Position of a character in the collating sequence defined by the standard33ISO 646 : 1983.34Class: Transformational function.35Argument: c is a scalar of type VARYING_STRING and of length exactly one. The36argument is unchanged by the procedure.37Result Type: default INTEGER.38Result Value: The result value is the position of the character c in the collating sequence39defined by the standard ISO 646 : 1983 for default characters. If the character c is not40defined in the standard set, the result is processor dependent.41
2.4.5 The TRIM procedure: The generic function reference of the form42TRIM(string)43
shall be added.44Description: Remove trailing blanks from a string.45Class: Transformational Function.46Argument: string is a scalar of type VARYING_STRING. The argument is unchanged by47the procedure.48
5
ISO/IEC 1539-2 : 1993 (E) CD version 2
Result Type: VARYING_STRING.1Result Value: The result value is the string produced by removing any trailing blanks2from the argument. If the argument string contains only blank characters or is of zero3length, the result is a zero-length string.4
2.4.6 The LEN_TRIM procedure: The generic function reference of the form5LEN_TRIM(string)6
shall be added.7Description: Length of a string not counting any trailing blanks.8Class: Transformational function.9Argument: string is a scalar of type VARYING_STRING. The argument is unchanged by10the procedure.11Result Type: default INTEGER.12Result Value: The result value is the position of the last non-blank character in string.13If the argument string contains only blank characters or is of zero length, the result is14zero.15
2.4.7 The ADJUSTL procedure: The generic function reference of the form16ADJUSTL(string)17
shall be added.18Description: Adjusts to the left, removing any leading blanks and inserting trailing blanks.19Class: Transformational function.20Argument: string is a scalar of type VARYING_STRING. The argument is unchanged by21the procedure.22Result Type: VARYING_STRING.23Result Value: The result value contains the same characters as the argument shifted24cyclically to the left until the first character is non-blank. The result is identical to the25argument if the first character of string is non-blank, string contains only blank26characters or is of zero length.27
2.4.8 The ADJUSTR procedure: The generic function reference of the form28ADJUSTR(string)29
shall be added.30Description: Adjusts to the right, removing any trailing blanks and inserting leading31blanks.32Class: Transformational function.33Argument: string is a scalar of type VARYING_STRING. The argument is unchanged by34the procedure.35Result Type: VARYING_STRING.36Result Value: The result value contains the same characters as the argument shifted37cyclically to the right until the last character is non-blank. The result is identical to the38argument if the last character of string is non-blank, string contains only blank39characters or is of zero length.40
6
CD version 2 ISO/IEC 1539-2 : 1993 (E)
2.4.9 The REPEAT procedure: The generic function reference of the form1REPEAT(string,ncopies)2
shall be added.3Description: Concatenate several copies of a string.4Class: Transformational function.5Arguments:6string - is a scalar of type VARYING_STRING,7ncopies - is a scalar of type default INTEGER.8The value of ncopies must not be negative. The arguments are unchanged by the9procedure.10Result Type: VARYING_STRING.11Result Value: The result value is the string produced by repeated concatenation of the12argument string, producing a string containing ncopies copies of string. A negative13value for ncopies is not permitted. If ncopies is zero, the result is of zero length.14
2.4.10 Comparison Procedures: The set of generic function references of the form15Lop(string_a,string_b)16
shall be added, where op stands for one of:17LT - less than18LE - less than or equal to19GE - greater than or equal to20GT - greater than21
Description: Compares the lexical ordering of two strings based on the ISO 646 : 198322collating sequence.23Class: Transformational function.24Arguments: string_a and string_b are scalars of one of the type combinations:25
VARYING_STRING and VARYING_STRING,26VARYING_STRING and CHARACTER, or27
CHARACTER and VARYING_STRING.28The arguments are unchanged by the procedure.29Result Type: default LOGICAL.30Result Value: The result value is true if string_a stands in the indicated relationship to31string_b, and is false otherwise. The collating sequence used to establish the ordering32of characters for these procedures is that of the International Standard, ISO 646 : 1983.33If string_a and string_b are of different length, the comparison is done as if the shorter34string were padded on the right with blanks. If either argument contains a character not35defined by the standard, the result value is processor dependent.36
7
ISO/IEC 1539-2 : 1993 (E) CD version 2
2.4.11 The INDEX procedure: The generic function reference of the form1INDEX(string,substring,back)2
shall be added.3Description: Returns an integer which is the starting position of a substring within a4string.5Class: Transformational function.6Arguments. string and substring are scalars of one of the type combinations:7
VARYING_STRING and VARYING_STRING,8CHARACTER and VARYING_STRING, or9
VARYING_STRING and CHARACTER.10back - is a scalar of type default LOGICAL and is OPTIONAL.11Result type: default INTEGER.12Result value:13Case(i) : If back is absent or is present with the value false, the result is the14
minimum positive value of I such that,15EXTRACT(string,I,I+LEN(substring)-1)==substring,16or zero if there is no such value. Zero is returned if17LEN(string)<LEN(substring), and one is returned if18LEN(substring)=0.19
Case(ii) : If back is present with the value true, the result is the maximum value20of I less than or equal to LEN(string)-LEN(substring)+1 such that21EXTRACT(string,I:I+LEN(substring)-1)==substring,22or zero if there is no such value. Zero is returned if23LEN(string)<LEN(substring), and LEN(string)+1 is returned if24LEN(substring)=0.25
2.4.12 The SCAN procedure: The generic function reference of the form26SCAN(string,set,back)27
shall be added.28Description: Scan a string for any one of the characters in a set of characters.29Class: Transformational function.30Arguments: string and set are scalars of one of the type combinations:31
VARYING_STRING and VARYING_STRING,32VARYING_STRING and CHARACTER, or33
CHARACTER and VARYING_STRING.34back - is a scalar of type default LOGICAL and is OPTIONAL.35The arguments are unchanged by the procedure.36Result Type: default INTEGER.37Result Value:38Case(i) : If back is absent or is present with the value false and if string39
contains at least one character that is in set, the value of the result is40the position of the leftmost character of string that is in set.41
Case(ii) : If back is present with the value true and if string contains at least42one character that is in set, the value of the result is the position of43the rightmost character of string that is in set.44
Case(iii) : The value of the result is zero if no character of string is in set or45if the length of either string or set is zero.46
8
CD version 2 ISO/IEC 1539-2 : 1993 (E)
2.4.13 The VERIFY procedure: The generic function reference of the form1VERIFY(string,set,back)2
shall be added.3Description: Verify that a string contains only characters from a given set by scanning4for any character not in the set.5Class: Transformational function.6Arguments: string and set are scalars of one of the type combinations:7
VARYING_STRING and VARYING_STRING,8VARYING_STRING and CHARACTER, or9
CHARACTER and VARYING_STRING.10back - is a scalar of type default LOGICAL and is OPTIONAL.11The arguments are unchanged by the procedure.12Result Type: default INTEGER.13Result Value:14Case(i) : If back is absent or is present with the value false and if string15
contains at least one character that is not in set, the value of the result16is the position of the leftmost character of string that is not in set.17
Case(ii) : If back is present with the value true and if string contains at least18one character that is not in set, the value of the result is the position19of the rightmost character of string that is not in set.20
Case(iii) : The value of the result is zero if each character of string is in set or21if the length of string is zero.22
2.5 Additional Generic Procedure for Type Conversion23
An additional generic procedure shall be added to convert scalar intrinsic fixed-length character values24into scalar varying-length string values.25
2.5.1 The VAR_STR procedure: The generic function reference of the form26VAR_STR(char)27
shall be provided.28Description: Converts an intrinsic fixed-length character value into the equivalent29varying-length string value.30Class: Transformational function.31Argument: char is a scalar of type default CHARACTER and may be of any length. The32argument is unchanged by the procedure.33Result Type: VARYING_STRING.34Result Value: The result value is the same string of characters as the argument.35
2.6 Additional Generic Procedures for Input/Output36
The following additional generic procedures shall be provided to support input and output of37varying-length string values with formatted sequential files.38
GET - input part or all of a record into a string39PUT - append a string to an output record40PUT_LINE - append a string to an output record and end the record41
9
ISO/IEC 1539-2 : 1993 (E) CD version 2
2.6.1 The GET procedure: The generic subroutine references of the forms1CALL GET(string,maxlen,iostat)2CALL GET(unit,string,maxlen,iostat)3CALL GET(string,set,maxlen,iostat)4CALL GET(unit,string,set,maxlen,iostat)5
shall be provided.6Description: Input characters from an external file into a string.7Class: Subroutine.8Arguments:9string - is of type VARYING_STRING,10maxlen - is of type default INTEGER and is OPTIONAL,11unit - is of type default INTEGER,12set - is either of type VARYING_STRING or of type CHARACTER13iostat - is of type default INTEGER and is OPTIONAL.14All arguments are scalar. The argument unit specifies the input unit to be used. It must15be connected to a formatted file for sequential read access. If the argument unit is16omitted, the default input unit is used.17Action: The GET procedure causes characters from the connected file, starting with the18next character in the current record if there is a current record or the first character of the19next record if not, to be read and stored in the variable string. The end of record always20terminates the input but input may be terminated before this. If maxlen is present, its21value indicates the maximum number of characters that will be read. If maxlen is less than22or equal to zero, no characters will be read and string will be set to zero length. If23maxlen is absent, a maximum of HUGE(1) is used. If the argument set is provided, this24specifies a set of characters the occurrence of any of which will terminate the input. This25terminal character, although read from the input file, will not be included in the result26string. The file position after the data transfer is complete is after the last character that27was read. If the transfer was terminated by the end of record being reached, the file is28positioned after the record just read. If present, the argument iostat is used to return the29status resulting from the data transfer. A zero value is returned if a valid read operation30occurs, a positive value if an error is caused, and a negative value if an end-of-file31condition occurs. If iostat is absent and anything other than a valid read operation32occurs, the program execution is terminated.33
10
CD version 2 ISO/IEC 1539-2 : 1993 (E)
2.6.2 The PUT procedure: The generic subroutine references of the forms1CALL PUT(string,iostat)2CALL PUT(unit,string,iostat)3
shall be provided.4Description: Output a string to an external file.5Class: Subroutine.6Argument:7string - is either type VARYING_STRING or type CHARACTER,8unit - is type default INTEGER,9iostat - is type default INTEGER and is OPTIONAL.10All arguments are scalar. The argument unit specifies the output unit to be used. It must11be connected to a formatted file for sequential write access. If the argument unit is12omitted, the default output unit is used.13Action: The PUT procedure causes the characters of string to be appended to the current14record, if there is a current record, or to the start of the next record if there is no current15record. The last character transferred becomes the last character of the current record,16which is the last record of the file. If present, the argument iostat is used to return the17status resulting from the data transfer. A zero value is returned if a valid write operation18occurs, and a positive value if an error occurs. If iostat is absent and anything other than19a valid write operation occurs, the program execution is terminated.20
2.6.3 The PUT_LINE procedure: The generic subroutine references of the forms21CALL PUT_LINE(string,iostat)22CALL PUT_LINE(unit,string,iostat)23
shall be provided.24Description: Output a string to an external file and end the record.25Class: Subroutine.26Argument:27string - is either type VARYING_STRING or type CHARACTER28unit - is type default INTEGER29iostat - is type default INTEGER and is OPTIONAL.30All arguments are scalar. The argument unit specifies the output unit to be used. It must31be connected to a formatted file for sequential write access. If the argument unit is32omitted, the default output unit is used.33Action: The PUT_LINE procedure causes the characters of string to be appended to the34current record, if there is a current record, or to the start of the next record if there is no35current record. Following completion of the data transfer, the file is positioned after the36record just written, which becomes the previous and last record of the file. If present, the37argument iostat is used to return the status resulting from the data transfer. A zero value38is returned if a valid write operation occurs, and a positive value if an error occurs. If39iostat is absent and anything other than a valid write operation occurs, the program40execution is terminated.41
11
ISO/IEC 1539-2 : 1993 (E) CD version 2
2.7 Additional Generic Procedures for Substring Manipulation1
The following additional generic procedures shall be provided to support the manipulation of scalar2substrings of scalar varying-length strings.3
INSERT - insert a substring into a string4REPLACE - replace a substring in a string5REMOVE - remove a section of a string6EXTRACT - extract a section from a string7SPLIT - split a string into two at the occurrence of a separator8
2.7.1 The INSERT procedure: The generic function reference of the form9INSERT(string,start,substring)10
shall be provided.11Description: Insert a substring into a string at a specified position.12Class: Transformational function.13Arguments:14string - is either type VARYING_STRING or type default CHARACTER,15start - is type default INTEGER,16substring - is either type VARYING_STRING or type default CHARACTER.17All arguments must be scalars. The arguments are unchanged by the procedure.18Result Type: VARYING_STRING.19Result Value: The result value is a copy of the characters of the argument string with20the characters of substring inserted into the copy of string before the character at the21character position start. The remainder of the result string is shifted to the right and22enlarged as necessary. If start is greater than LEN(string), the value LEN(string)+123is used for start and the substring is appended to the copy of string. If start is less24than one, the value one is used for start and the substring is inserted before the first25character of the copy of the string. The length of the result is LEN(string) +26LEN(substring).27
2.7.2 The REPLACE procedure: The generic function references of the forms28REPLACE(string,start,substring)29REPLACE(string,start,finish,substring)30REPLACE(string,target,substring,every,back)31
shall be provided.32Description: Replaces a subset of the characters in a string by a given substring. The33subset may be specified either by position or by content.34Class: Transformational function.35Arguments:36string - is either type VARYING_STRING or type default CHARACTER,37start - is type default INTEGER,38finish - is type default INTEGER,39substring - is either type VARYING_STRING or type default CHARACTER,40target - is either type VARYING_STRING or type default CHARACTER,41every - is type default LOGICAL, and is OPTIONAL,42back - is type default LOGICAL, and is OPTIONAL.43All arguments are scalar and are unchanged by the procedure. The argument target must44not be of zero length. In all cases the arguments are unchanged by the procedure.45Result Type: VARYING_STRING.46
12
CD version 2 ISO/IEC 1539-2 : 1993 (E)
Result Value: The result value is a copy of the characters in string modified as per one1of the cases below.2Case(i) : For a reference of the form3
REPLACE(string,start,substring)4the characters of the argument substring are inserted in the copy of5string beginning with the character at the character position start.6The characters in positions from7
start to MIN(start+LEN(substring)-1,LEN(string))8are deleted. The result string is enlarged if necessary. If start is9greater than LEN(string), the value LEN(string)+1 is used for start10and substring is appended to the copy of string. If start is less than11one, the value one is used for start.12
Case(ii) : For a reference of the form13REPLACE(string,start,finish,substring)14
the characters in the copy of string between positions start and15finish, including those at start and finish, are deleted and replaced16by the characters of substring. If start is less than one, the value17one is used for start. If finish is greater than LEN(string), the18value LEN(string) is used for finish. If finish is less than start,19the characters of substring are inserted before the character at start20and no characters are deleted. The length of the result string is21adjusted as necessary.22
Case(iii) : For a reference of the form23REPLACE(string,target,substring,every,back)24
the copy of string is searched for occurrences of target. The search25is done in the backward direction if the argument back is present with26the value true, but in the forward direction otherwise. If target is27found, it is replaced by substring. If every is present with the value28true, the search and replace is continued from the character following29target in the search direction specified until all occurrences of target30in the copy string are replaced; otherwise only the first occurrence of31target is replaced.32
2.7.3 The REMOVE procedure: The generic function reference of the form33REMOVE(string,start,finish)34
shall be provided.35Description: Removes a specified substring from a string.36Class: Transformational function.37Arguments:38string - is either type VARYING_STRING or type default CHARACTER,39start - is type default INTEGER, and is OPTIONAL,40finish - is type default INTEGER, and is OPTIONAL.41All arguments must be scalars. The arguments are unchanged by the procedure.42Result Type: VARYING_STRING.43Result Value: The result value is a copy of the characters of string with the characters44between start and finish, inclusive, removed. If start is absent or less than one, the45value one is used for start. If finish is absent or greater than LEN(string), the value46LEN(string) is used for finish. If finish is less than start, the characters of string47are delivered unchanged as the result.48
13
ISO/IEC 1539-2 : 1993 (E) CD version 2
2.7.4 The EXTRACT procedure: The generic function reference of the form1EXTRACT(string,start,finish)2
shall be provided.3Description: Extracts a specified substring from a string.4Class: Transformational function.5Arguments:6string - is either type VARYING_STRING or type default CHARACTER,7start - is type default INTEGER, and is OPTIONAL,8finish - is type default INTEGER, and is OPTIONAL.9All arguments must be scalars. The arguments are unchanged by the procedure.10Result Type: VARYING_STRING.11Result Value: The result value is a copy of the characters of the argument string12between start and finish, inclusive. If start is absent or less than one, the value one13is used for start. If finish is absent or greater than LEN(string), the value14LEN(string) is used for finish. If finish is less than start, the result is a zero-length15string.16
2.7.5 The SPLIT procedure: The generic subroutine reference of the form17CALL SPLIT(string,word,set,separator,back)18
shall be provided.19Description: Splits a string into a two substrings with the substrings separated by the20occurence of a character from a specified separator set.21Class: Subroutine.22Arguments:23string - is type VARYING_STRING,24word - is type VARYING_STRING,25set - is either type VARYING_STRING or type default CHARACTER,26separator - is type VARYING_STRING, and is OPTIONAL,27back - is type default LOGICAL, and is OPTIONAL,28All arguments are scalar.29Action: The effect of the procedure is to divide the string at the first occurence of a30character that is a member of those included in set. The string is searched in the31forward direction unless back is present with the value true, in which case the search is32in the backward direction. The characters passed over in the search are returned in the33argument word and the remainder of the string, not including the separator character is34returned in the argument string. If no character from set is found, the whole string is35returned in word and string is returned as zero-length. If the argument separator is36present, the actual character found which separates the word from the remainder of the37string is returned in separator. The effect of the procedure is such that, on return,38either39
word//separator//string40is the same as the initial string for a forward search, or41
string//separator//word42is the same as the initial string for a backward search.43
14
CD version 2 ISO/IEC 1539-2 : 1993 (E)
Annex A1
(Informative)2
The following module is written in Fortran 90, conformant with the language as specified in the3standard ISO/IEC 1539 : 1991. It is intended to be a portable implementation of a module conformant4with this International Standard. It is not intended to be prescriptive of how facilities consistent with5this International Standard should be provided. This module is intended primarily to demonstrate that6portable facilities consistent with the interfaces and semantics required by this International Standard7could be provided within the confines of the Fortran language. It is also included as a guide for users8of processors which do not have supplier-provided facilities implementing this International Standard.9
It should be noted that while every care has been taken by the technical working group to ensure10that this module is a correct implementation of this International Standard in valid Fortran code, no11guarantee is given or implied that this code will produce correct results, or even that it will execute12on any particular processor. Neither is there any implication that this illustrative module is in any way13an optimal implementation of this standard; it is merely one fairly straight forward portable module14that is known to provide a functionally conformant implementation on a few processors.15
MODULE ISO_VARYING_STRING1617
! Written by J.L.Schonfelder18! Incorporating suggestions by C.Tanasescu, C.Weber, J.Wagener and W.Walter,19! and corrections due to L.Moss, M.Cohen, P.Griffiths, B.T.Smith20! and many other members of the committee ISO/IEC JTC1/SC22/WG521
! Version produced (20-Jul-93)22
!-----------------------------------------------------------------------------!23! This module defines the interface and one possible implementation for a !24! dynamic length character string facility in Fortran 90. The Fortran 90 !25! language is defined by the standard ISO/IEC 1539 : 1991. !26! The publicly accessible interface defined by this module is conformant !27! with the auxilliary standard, ISO/IEC 1539-1 : 1993. !28! The detailed implementation may be considered as an informal definition of !29! the required semantics, and may also be used as a guide to the production !30! of a portable implementation. !31! N.B. Although every care has been taken to produce valid Fortran code in !32! construction of this module no guarantee is given or implied that this !33! code will work correctly without error on any specific processor, nor !34! is this implementation intended to be in any way optimal either in use !35! of storage or CPU cycles. !36!-----------------------------------------------------------------------------!37
38PRIVATE39
40!-----------------------------------------------------------------------------!41! By default all entities declared or defined in this module are private to !42! the module. Only those entities declared explicitly as being public are !43! accessible to programs using the module. In particular, the procedures and !44! operators defined herein are made accessible via their generic identifiers !45! only; their specific names are private. !46!-----------------------------------------------------------------------------!47
48TYPE VARYING_STRING49PRIVATE50CHARACTER,DIMENSION(:),POINTER :: chars51
ENDTYPE VARYING_STRING5253
!-----------------------------------------------------------------------------!54! The representation chosen for this definition of the module is of a string !55! type consisting of a single component that is a pointer to a rank one array !56! of characters. !57
15
ISO/IEC 1539-2 : 1993 (E) CD version 2
! Note: this Module is defined only for characters of default kind. A similar !1! module could be defined for non-default characters if these are supported !2! on a processor by adding a KIND parameter to the component in the type !3! definition, and to all delarations of objects of CHARACTER type. !4!-----------------------------------------------------------------------------!5
6CHARACTER,PARAMETER :: blank = " "7
8!----- GENERIC PROCEDURE INTERFACE DEFINITIONS -------------------------------!9
10!----- LEN interface ---------------------------------------------------------!11INTERFACE LEN12
MODULE PROCEDURE len_s ! length of string13ENDINTERFACE14
15!----- Conversion procedure interfaces ---------------------------------------!16INTERFACE VAR_STR17
MODULE PROCEDURE c_to_s ! character to string18ENDINTERFACE19
20INTERFACE CHAR21
MODULE PROCEDURE s_to_c, & ! string to character22s_to_fix_c ! string to specified length character23
ENDINTERFACE2425
!----- ASSIGNMENT interfaces -------------------------------------------------!26INTERFACE ASSIGNMENT(=)27
MODULE PROCEDURE s_ass_s, & ! string = string28c_ass_s, & ! character = string29s_ass_c ! string = character30
ENDINTERFACE3132
!----- Concatenation operator interfaces -------------------------------------!33INTERFACE OPERATOR(//)34
MODULE PROCEDURE s_concat_s, & ! string//string35s_concat_c, & ! string//character36c_concat_s ! character//string37
ENDINTERFACE3839
!----- Repeated Concatenation interfaces -------------------------------------!40INTERFACE REPEAT41
MODULE PROCEDURE repeat_s42ENDINTERFACE43
44!------ Equality comparison operator interfaces-------------------------------!45INTERFACE OPERATOR(==)46
MODULE PROCEDURE s_eq_s, & ! string==string47s_eq_c, & ! string==character48c_eq_s ! character==string49
ENDINTERFACE5051
!----- not-equality comparison operator interfaces ---------------------------!52INTERFACE OPERATOR(/=)53
MODULE PROCEDURE s_ne_s, & ! string/=string54s_ne_c, & ! string/=character55c_ne_s ! character/=string56
ENDINTERFACE5758
!----- less-than comparison operator interfaces ------------------------------!59INTERFACE OPERATOR(<)60
MODULE PROCEDURE s_lt_s, & ! string<string61s_lt_c, & ! string<character62c_lt_s ! character<string63
ENDINTERFACE6465
!----- less-than-or-equal comparison operator interfaces ---------------------!66INTERFACE OPERATOR(<=)67
MODULE PROCEDURE s_le_s, & ! string<=string68s_le_c, & ! string<=character69c_le_s ! character<=string70
ENDINTERFACE7172
16
CD version 2 ISO/IEC 1539-2 : 1993 (E)
!----- greater-than-or-equal comparison operator interfaces ------------------!1INTERFACE OPERATOR(>=)2
MODULE PROCEDURE s_ge_s, & ! string>=string3s_ge_c, & ! string>=character4c_ge_s ! character>=string5
ENDINTERFACE67
!----- greater-than comparison operator interfaces ---------------------------!8INTERFACE OPERATOR(>)9MODULE PROCEDURE s_gt_s, & ! string>string10
s_gt_c, & ! string>character11c_gt_s ! character>string12
ENDINTERFACE1314
!----- LLT procedure interfaces ----------------------------------------------!15INTERFACE LLT16
MODULE PROCEDURE s_llt_s, & ! LLT(string,string)17s_llt_c, & ! LLT(string,character)18c_llt_s ! LLT(character,string)19
ENDINTERFACE2021
!----- LLE procedure interfaces ----------------------------------------------!22INTERFACE LLE23
MODULE PROCEDURE s_lle_s, & ! LLE(string,string)24s_lle_c, & ! LLE(string,character)25c_lle_s ! LLE(character,string)26
ENDINTERFACE2728
!----- LGE procedure interfaces ----------------------------------------------!29INTERFACE LGE30
MODULE PROCEDURE s_lge_s, & ! LGE(string,string)31s_lge_c, & ! LGE(string,character)32c_lge_s ! LGE(character,string)33
ENDINTERFACE3435
!----- LGT procedure interfaces ----------------------------------------------!36INTERFACE LGT37
MODULE PROCEDURE s_lgt_s, & ! LGT(string,string)38s_lgt_c, & ! LGT(string,character)39c_lgt_s ! LGT(character,string)40
ENDINTERFACE4142
!----- Input function interface ---------------------------------------------!43INTERFACE GET44
MODULE PROCEDURE get_d_eor, & ! default unit, EoR termination45get_u_eor, & ! specified unit, EoR termination46get_d_tset_s, & ! default unit, string set termination47get_u_tset_s, & ! specified unit, string set termination48get_d_tset_c, & ! default unit, char set termination49get_u_tset_c ! specified unit, char set termination50
ENDINTERFACE5152
!----- Output procedure interfaces -------------------------------------------!53INTERFACE PUT54
MODULE PROCEDURE put_d_s, & ! string to default unit55put_u_s, & ! string to specified unit56put_d_c, & ! char to default unit57put_u_c ! char to specified unit58
ENDINTERFACE5960
INTERFACE PUT_LINE61MODULE PROCEDURE putline_d_s, & ! string to default unit62
putline_u_s, & ! string to specified unit63putline_d_c, & ! char to default unit64putline_u_c ! char to specified unit65
ENDINTERFACE6667
!----- Insert procedure interfaces -------------------------------------------!68INTERFACE INSERT69
MODULE PROCEDURE insert_ss, & ! string in string70insert_sc, & ! char in string71insert_cs, & ! string in char72
17
ISO/IEC 1539-2 : 1993 (E) CD version 2
insert_cc ! char in char1ENDINTERFACE2
!----- Replace procedure interfaces ------------------------------------------!3INTERFACE REPLACE4MODULE PROCEDURE replace_ss, & ! string by string, at specified5
replace_sc, & ! string by char , starting6replace_cs, & ! char by string , point7replace_cc, & ! char by char8replace_ss_sf,& ! string by string, between9replace_sc_sf,& ! string by char , specified10replace_cs_sf,& ! char by string , starting and11replace_cc_sf,& ! char by char , finishing points12replace_sss, & ! in string replace string by string13replace_ssc, & ! in string replace string by char14replace_scs, & ! in string replace char by string15replace_scc, & ! in string replace char by char16replace_css, & ! in char replace string by string17replace_csc, & ! in char replace string by char18replace_ccs, & ! in char replace char by string19replace_ccc ! in char replace char by char20
ENDINTERFACE21
!----- Remove procedure interface --------------------------------------------!22INTERFACE REMOVE23
MODULE PROCEDURE remove_s, & ! characters from string, between start24remove_c ! characters from char , and finish25
ENDINTERFACE2627
!----- Extract procedure interface -------------------------------------------!28INTERFACE EXTRACT29
MODULE PROCEDURE extract_s, & ! from string extract string, between start30extract_c ! from char extract string, and finish31
ENDINTERFACE3233
!----- Split procedure interface ---------------------------------------------!34INTERFACE SPLIT35
MODULE PROCEDURE split_s, & ! split string at first occurance of36split_c ! character in set37
ENDINTERFACE38
!----- Index procedure interfaces --------------------------------------------!39INTERFACE INDEX40
MODULE PROCEDURE index_ss, index_sc, index_cs41ENDINTERFACE42
43!----- Scan procedure interfaces ---------------------------------------------!44INTERFACE SCAN45
MODULE PROCEDURE scan_ss, scan_sc, scan_cs46ENDINTERFACE47
48!----- Verify procedure interfaces -------------------------------------------!49INTERFACE VERIFY50
MODULE PROCEDURE verify_ss, verify_sc, verify_cs51ENDINTERFACE52
53!----- Interfaces for remaining intrinsic function overloads -----------------!54INTERFACE LEN_TRIM55
MODULE PROCEDURE len_trim_s56ENDINTERFACE57
58INTERFACE TRIM59
MODULE PROCEDURE trim_s60ENDINTERFACE61
62INTERFACE IACHAR63
MODULE PROCEDURE iachar_s64ENDINTERFACE65
66INTERFACE ICHAR67
MODULE PROCEDURE ichar_s68ENDINTERFACE69
18
CD version 2 ISO/IEC 1539-2 : 1993 (E)
1INTERFACE ADJUSTL2MODULE PROCEDURE adjustl_s3
ENDINTERFACE45
INTERFACE ADJUSTR6MODULE PROCEDURE adjustr_s7
ENDINTERFACE89
!----- specification of publically accessible entities -----------------------!10PUBLIC :: VARYING_STRING,VAR_STR,CHAR,LEN,GET,PUT,PUT_LINE,INSERT,REPLACE, &11
SPLIT,REMOVE,REPEAT,EXTRACT,INDEX,SCAN,VERIFY,LLT,LLE,LGE,LGT, &12ASSIGNMENT(=),OPERATOR(//),OPERATOR(==),OPERATOR(/=),OPERATOR(<), &13OPERATOR(<=),OPERATOR(>=),OPERATOR(>),LEN_TRIM,TRIM,IACHAR,ICHAR, &14ADJUSTL,ADJUSTR15
16CONTAINS17
18!----- LEN Procedure ---------------------------------------------------------!19FUNCTION len_s(string)20type(VARYING_STRING),INTENT(IN) :: string21INTEGER :: len_s22! returns the length of the string argument or zero if there is no current23! string value24IF(.NOT.ASSOCIATED(string%chars))THEN25
len_s = 026ELSE27
len_s = SIZE(string%chars)28ENDIF29ENDFUNCTION len_s30
31!----- Conversion Procedures ------------------------------------------------!32FUNCTION c_to_s(chr)33type(VARYING_STRING) :: c_to_s34CHARACTER(LEN=*),INTENT(IN) :: chr35! returns the string consisting of the characters char36INTEGER :: lc37lc=LEN(chr)38ALLOCATE(c_to_s%chars(1:lc))39DO i=1,lc40
c_to_s%chars(i) = chr(i:i)41ENDDO42ENDFUNCTION c_to_s43
44FUNCTION s_to_c(string)45type(VARYING_STRING),INTENT(IN) :: string46CHARACTER(LEN=SIZE(string%chars)) :: s_to_c47! returns the characters of string as an automatically sized character48INTEGER :: lc49lc=SIZE(string%chars)50DO i=1,lc51
s_to_c(i:i) = string%chars(i)52ENDDO53ENDFUNCTION s_to_c54
55FUNCTION s_to_fix_c(string,length)56type(VARYING_STRING),INTENT(IN) :: string57INTEGER,INTENT(IN) :: length58CHARACTER(LEN=length) :: s_to_fix_c59! returns the character of fixed length, length, containing the characters60! of string either padded with blanks or truncated on the right to fit61INTEGER :: lc62lc=MIN(SIZE(string%chars),length)63DO i=1,lc64
s_to_fix_c(i:i) = string%chars(i)65ENDDO66IF(lc < length)THEN ! result longer than string padding needed67
s_to_fix_c(lc+1:length) = blank68ENDIF69ENDFUNCTION s_to_fix_c70
!----- ASSIGNMENT Procedures -------------------------------------------------!71
19
ISO/IEC 1539-2 : 1993 (E) CD version 2
SUBROUTINE s_ass_s(var,expr)1type(VARYING_STRING),INTENT(OUT) :: var2type(VARYING_STRING),INTENT(IN) :: expr3! assign a string value to a string variable overriding default assignement4! reallocates string variable to size of string value and copies characters5ALLOCATE(var%chars(1:LEN(expr)))6var%chars = expr%chars7
ENDSUBROUTINE s_ass_s89
SUBROUTINE c_ass_s(var,expr)10CHARACTER(LEN=*),INTENT(OUT) :: var11type(VARYING_STRING),INTENT(IN) :: expr12! assign a string value to a character variable13! if the string is longer than the character truncate the string on the right14! if the string is shorter the character is blank padded on the right15INTEGER :: lc,ls16lc = LEN(var); ls = MIN(LEN(expr),lc)17DO i = 1,ls18var(i:i) = expr%chars(i)19
ENDDO20DO i = ls+1,lc21var(i:i) = blank22
ENDDO23ENDSUBROUTINE c_ass_s24
25SUBROUTINE s_ass_c(var,expr)26type(VARYING_STRING),INTENT(OUT) :: var27CHARACTER(LEN=*),INTENT(IN) :: expr28! assign a character value to a string variable29! disassociates the string variable from its current value, allocates new30! space to hold the characters and copies them from the character value31! into this space.32INTEGER :: lc33lc = LEN(expr)34ALLOCATE(var%chars(1:lc))35DO i = 1,lc36
var%chars(i) = expr(i:i)37ENDDO38ENDSUBROUTINE s_ass_c39
40!----- Concatenation operator procedures ------------------------------------!41FUNCTION s_concat_s(string_a,string_b) ! string//string42type(VARYING_STRING),INTENT(IN) :: string_a,string_b43type(VARYING_STRING) :: s_concat_s44INTEGER :: la,lb45la = LEN(string_a); lb = LEN(string_b)46ALLOCATE(s_concat_s%chars(1:la+lb))47s_concat_s%chars(1:la) = string_a%chars48s_concat_s%chars(1+la:la+lb) = string_b%chars49ENDFUNCTION s_concat_s50
51FUNCTION s_concat_c(string_a,string_b) ! string//character52type(VARYING_STRING),INTENT(IN) :: string_a53CHARACTER(LEN=*),INTENT(IN) :: string_b54type(VARYING_STRING) :: s_concat_c55INTEGER :: la,lb56la = LEN(string_a); lb = LEN(string_b)57ALLOCATE(s_concat_c%chars(1:la+lb))58s_concat_c%chars(1:la) = string_a%chars59DO i = 1,lb60
s_concat_c%chars(la+i) = string_b(i:i)61ENDDO62ENDFUNCTION s_concat_c63
64FUNCTION c_concat_s(string_a,string_b) ! character//string65CHARACTER(LEN=*),INTENT(IN) :: string_a66type(VARYING_STRING),INTENT(IN) :: string_b67type(VARYING_STRING) :: c_concat_s68INTEGER :: la,lb69la = LEN(string_a); lb = LEN(string_b)70ALLOCATE(c_concat_s%chars(1:la+lb))71DO i = 1,la72
20
CD version 2 ISO/IEC 1539-2 : 1993 (E)
c_concat_s%chars(i) = string_a(i:i)1ENDDO2c_concat_s%chars(1+la:la+lb) = string_b%chars3
ENDFUNCTION c_concat_s45
!----- Reapeated concatenation procedures -----------------------------------!6FUNCTION repeat_s(string,ncopies)7type(VARYING_STRING),INTENT(IN) :: string8INTEGER,INTENT(IN) :: ncopies9type(VARYING_STRING) :: repeat_s10! Returns a string produced by the concatenation of ncopies of the11! argument string12INTEGER :: lr,ls13IF (ncopies < 0) THEN14
WRITE(*,*) " Negative ncopies requested in REPEAT"15STOP16
ENDIF17ls = LEN(string); lr = ls*ncopies18ALLOCATE(repeat_s%chars(1:lr))19DO i = 1,ncopies20
repeat_s%chars(1+(i-1)*ls:i*ls) = string%chars21ENDDO22
ENDFUNCTION repeat_s2324
!------ Equality comparison operators ----------------------------------------!25FUNCTION s_eq_s(string_a,string_b) ! string==string26type(VARYING_STRING),INTENT(IN) :: string_a,string_b27LOGICAL :: s_eq_s28INTEGER :: la,lb29la = LEN(string_a); lb = LEN(string_b)30IF (la > lb) THEN31
s_eq_s = ALL(string_a%chars(1:lb) == string_b%chars) .AND. &32ALL(string_a%chars(lb+1:la) == blank)33
ELSEIF (la < lb) THEN34s_eq_s = ALL(string_a%chars == string_b%chars(1:la)) .AND. &35
ALL(blank == string_b%chars(la+1:lb))36ELSE37
s_eq_s = ALL(string_a%chars == string_b%chars)38ENDIF39ENDFUNCTION s_eq_s40
FUNCTION s_eq_c(string_a,string_b) ! string==character41type(VARYING_STRING),INTENT(IN) :: string_a42CHARACTER(LEN=*),INTENT(IN) :: string_b43LOGICAL :: s_eq_c44INTEGER :: la,lb,ls45la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)46DO i = 1,ls47
IF( string_a%chars(i) /= string_b(i:i) )THEN48s_eq_c = .FALSE.; RETURN49
ENDIF50ENDDO51IF( la > lb .AND. ANY( string_a%chars(lb+1:la) /= blank ) )THEN52
s_eq_c = .FALSE.; RETURN53ELSEIF( la < lb .AND. blank /= string_b(la+1:lb) )THEN54
s_eq_c = .FALSE.; RETURN55ENDIF56s_eq_c = .TRUE.57ENDFUNCTION s_eq_c58
59FUNCTION c_eq_s(string_a,string_b) ! character==string60CHARACTER(LEN=*),INTENT(IN) :: string_a61type(VARYING_STRING),INTENT(IN) :: string_b62LOGICAL :: c_eq_s63INTEGER :: la,lb,ls64la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)65DO i = 1,ls66
IF( string_a(i:i) /= string_b%chars(i) )THEN67c_eq_s = .FALSE.; RETURN68
ENDIF69ENDDO70IF( la > lb .AND. string_a(lb+1:la) /= blank )THEN71
21
ISO/IEC 1539-2 : 1993 (E) CD version 2
c_eq_s = .FALSE.; RETURN1ELSEIF( la < lb .AND. ANY( blank /= string_b%chars(la+1:lb) ) )THEN2
c_eq_s = .FALSE.; RETURN3ENDIF4c_eq_s = .TRUE.5
ENDFUNCTION c_eq_s67
!------ Non-equality operators -----------------------------------------------!8FUNCTION s_ne_s(string_a,string_b) ! string/=string9type(VARYING_STRING),INTENT(IN) :: string_a,string_b10LOGICAL :: s_ne_s11INTEGER :: la,lb12la = LEN(string_a); lb = LEN(string_b)13IF (la > lb) THEN14
s_ne_s = ANY(string_a%chars(1:lb) /= string_b%chars) .OR. &15ANY(string_a%chars(lb+1:la) /= blank)16
ELSEIF (la < lb) THEN17s_ne_s = ANY(string_a%chars /= string_b%chars(1:la)) .OR. &18
ANY(blank /= string_b%chars(la+1:lb))19ELSE20
s_ne_s = ANY(string_a%chars /= string_b%chars)21ENDIF22ENDFUNCTION s_ne_s23
24FUNCTION s_ne_c(string_a,string_b) ! string/=character25type(VARYING_STRING),INTENT(IN) :: string_a26CHARACTER(LEN=*),INTENT(IN) :: string_b27LOGICAL :: s_ne_c28INTEGER :: la,lb,ls29la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)30DO i = 1,ls31
IF( string_a%chars(i) /= string_b(i:i) )THEN32s_ne_c = .TRUE.; RETURN33
ENDIF34ENDDO35IF( la > lb .AND. ANY( string_a%chars(lb+1:la) /= blank ) )THEN36
s_ne_c = .TRUE.; RETURN37ELSEIF( la < lb .AND. blank /= string_b(la+1:lb) )THEN38
s_ne_c = .TRUE.; RETURN39ENDIF40s_ne_c = .FALSE.41ENDFUNCTION s_ne_c42
43FUNCTION c_ne_s(string_a,string_b) ! character/=string44CHARACTER(LEN=*),INTENT(IN) :: string_a45type(VARYING_STRING),INTENT(IN) :: string_b46LOGICAL :: c_ne_s47INTEGER :: la,lb,ls48la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)49DO i = 1,ls50
IF( string_a(i:i) /= string_b%chars(i) )THEN51c_ne_s = .TRUE.; RETURN52
ENDIF53ENDDO54IF( la > lb .AND. string_a(lb+1:la) /= blank )THEN55
c_ne_s = .TRUE.; RETURN56ELSEIF( la < lb .AND. ANY( blank /= string_b%chars(la+1:lb) ) )THEN57
c_ne_s = .TRUE.; RETURN58ENDIF59c_ne_s = .FALSE.60ENDFUNCTION c_ne_s61
62!------ Less-than operators --------------------------------------------------!63FUNCTION s_lt_s(string_a,string_b) ! string<string64type(VARYING_STRING),INTENT(IN) :: string_a,string_b65LOGICAL :: s_lt_s66INTEGER :: ls,la,lb67la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)68DO i = 1,ls69
IF( string_a%chars(i) < string_b%chars(i) )THEN70s_lt_s = .TRUE.; RETURN71
ELSEIF( string_a%chars(i) > string_b%chars(i) )THEN72
22
CD version 2 ISO/IEC 1539-2 : 1993 (E)
s_lt_s = .FALSE.; RETURN1ENDIF2
ENDDO3IF( la < lb )THEN4
DO i = la+1,lb5IF( blank < string_b%chars(i) )THEN6s_lt_s = .TRUE.; RETURN7
ELSEIF( blank > string_b%chars(i) )THEN8s_lt_s = .FALSE.; RETURN9
ENDIF10ENDDO11
ELSEIF( la > lb )THEN12DO i = lb+1,la13IF( string_a%chars(i) < blank )THEN14
s_lt_s = .TRUE.; RETURN15ELSEIF( string_a%chars(i) > blank )THEN16
s_lt_s = .FALSE.; RETURN17ENDIF18
ENDDO19ENDIF20s_lt_s = .FALSE.21
ENDFUNCTION s_lt_s2223
FUNCTION s_lt_c(string_a,string_b) ! string<character24type(VARYING_STRING),INTENT(IN) :: string_a25CHARACTER(LEN=*),INTENT(IN) :: string_b26LOGICAL :: s_lt_c27INTEGER :: ls,la,lb28la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)29DO i = 1,ls30
IF( string_a%chars(i) < string_b(i:i) )THEN31s_lt_c = .TRUE.; RETURN32
ELSEIF( string_a%chars(i) > string_b(i:i) )THEN33s_lt_c = .FALSE.; RETURN34
ENDIF35ENDDO36IF( la < lb )THEN37
IF( blank < string_b(la+1:lb) )THEN38s_lt_c = .TRUE.; RETURN39
ELSEIF( blank > string_b(la+1:lb) )THEN40s_lt_c = .FALSE.; RETURN41
ENDIF42ELSEIF( la > lb )THEN43
DO i = lb+1,la44IF( string_a%chars(i) < blank )THEN45
s_lt_c = .TRUE.; RETURN46ELSEIF( string_a%chars(i) > blank )THEN47
s_lt_c = .FALSE.; RETURN48ENDIF49
ENDDO50ENDIF51s_lt_c = .FALSE.52ENDFUNCTION s_lt_c53
54FUNCTION c_lt_s(string_a,string_b) ! character<string55CHARACTER(LEN=*),INTENT(IN) :: string_a56type(VARYING_STRING),INTENT(IN) :: string_b57LOGICAL :: c_lt_s58INTEGER :: ls,la,lb59la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)60DO i = 1,ls61
IF( string_a(i:i) < string_b%chars(i) )THEN62c_lt_s = .TRUE.; RETURN63
ELSEIF( string_a(i:i) > string_b%chars(i) )THEN64c_lt_s = .FALSE.; RETURN65
ENDIF66ENDDO67IF( la < lb )THEN68
DO i = la+1,lb69IF( blank < string_b%chars(i) )THEN70
c_lt_s = .TRUE.; RETURN71ELSEIF( blank > string_b%chars(i) )THEN72
23
ISO/IEC 1539-2 : 1993 (E) CD version 2
c_lt_s = .FALSE.; RETURN1ENDIF2
ENDDO3ELSEIF( la > lb )THEN4
IF( string_a(lb+1:la) < blank )THEN5c_lt_s = .TRUE.; RETURN6
ELSEIF( string_a(lb+1:la) > blank )THEN7c_lt_s = .FALSE.; RETURN8
ENDIF9ENDIF10c_lt_s = .FALSE.11ENDFUNCTION c_lt_s12
!------ Less-than-or-equal-to operators --------------------------------------!13FUNCTION s_le_s(string_a,string_b) ! string<=string14type(VARYING_STRING),INTENT(IN) :: string_a,string_b15LOGICAL :: s_le_s16INTEGER :: ls,la,lb17la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)18DO i = 1,ls19
IF( string_a%chars(i) < string_b%chars(i) )THEN20s_le_s = .TRUE.; RETURN21
ELSEIF( string_a%chars(i) > string_b%chars(i) )THEN22s_le_s = .FALSE.; RETURN23
ENDIF24ENDDO25IF( la < lb )THEN26
DO i = la+1,lb27IF( blank < string_b%chars(i) )THEN28
s_le_s = .TRUE.; RETURN29ELSEIF( blank > string_b%chars(i) )THEN30
s_le_s = .FALSE.; RETURN31ENDIF32
ENDDO33ELSEIF( la > lb )THEN34
DO i = lb+1,la35IF( string_a%chars(i) < blank )THEN36
s_le_s = .TRUE.; RETURN37ELSEIF( string_a%chars(i) > blank )THEN38
s_le_s = .FALSE.; RETURN39ENDIF40
ENDDO41ENDIF42s_le_s = .TRUE.43ENDFUNCTION s_le_s44
45FUNCTION s_le_c(string_a,string_b) ! string<=character46type(VARYING_STRING),INTENT(IN) :: string_a47CHARACTER(LEN=*),INTENT(IN) :: string_b48LOGICAL :: s_le_c49INTEGER :: ls,la,lb50la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)51DO i = 1,ls52
IF( string_a%chars(i) < string_b(i:i) )THEN53s_le_c = .TRUE.; RETURN54
ELSEIF( string_a%chars(i) > string_b(i:i) )THEN55s_le_c = .FALSE.; RETURN56
ENDIF57ENDDO58IF( la < lb )THEN59
IF( blank < string_b(la+1:lb) )THEN60s_le_c = .TRUE.; RETURN61
ELSEIF( blank > string_b(la+1:lb) )THEN62s_le_c = .FALSE.; RETURN63
ENDIF64ELSEIF( la > lb )THEN65
DO i = lb+1,la66IF( string_a%chars(i) < blank )THEN67
s_le_c = .TRUE.; RETURN68ELSEIF( string_a%chars(i) > blank )THEN69
s_le_c = .FALSE.; RETURN70ENDIF71
24
CD version 2 ISO/IEC 1539-2 : 1993 (E)
ENDDO1ENDIF2s_le_c = .TRUE.3
ENDFUNCTION s_le_c45
FUNCTION c_le_s(string_a,string_b) ! character<=string6CHARACTER(LEN=*),INTENT(IN) :: string_a7type(VARYING_STRING),INTENT(IN) :: string_b8LOGICAL :: c_le_s9INTEGER :: ls,la,lb10la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)11DO i = 1,ls12
IF( string_a(i:i) < string_b%chars(i) )THEN13c_le_s = .TRUE.; RETURN14
ELSEIF( string_a(i:i) > string_b%chars(i) )THEN15c_le_s = .FALSE.; RETURN16
ENDIF17ENDDO18IF( la < lb )THEN19
DO i = la+1,lb20IF( blank < string_b%chars(i) )THEN21
c_le_s = .TRUE.; RETURN22ELSEIF( blank > string_b%chars(i) )THEN23
c_le_s = .FALSE.; RETURN24ENDIF25
ENDDO26ELSEIF( la > lb )THEN27
IF( string_a(lb+1:la) < blank )THEN28c_le_s = .TRUE.; RETURN29
ELSEIF( string_a(lb+1:la) > blank )THEN30c_le_s = .FALSE.; RETURN31
ENDIF32ENDIF33c_le_s = .TRUE.34ENDFUNCTION c_le_s35
36!------ Greater-than-or-equal-to operators -----------------------------------!37FUNCTION s_ge_s(string_a,string_b) ! string>=string38type(VARYING_STRING),INTENT(IN) :: string_a,string_b39LOGICAL :: s_ge_s40INTEGER :: ls,la,lb41la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)42DO i = 1,ls43
IF( string_a%chars(i) > string_b%chars(i) )THEN44s_ge_s = .TRUE.; RETURN45
ELSEIF( string_a%chars(i) < string_b%chars(i) )THEN46s_ge_s = .FALSE.; RETURN47
ENDIF48ENDDO49IF( la < lb )THEN50
DO i = la+1,lb51IF( blank > string_b%chars(i) )THEN52
s_ge_s = .TRUE.; RETURN53ELSEIF( blank < string_b%chars(i) )THEN54
s_ge_s = .FALSE.; RETURN55ENDIF56
ENDDO57ELSEIF( la > lb )THEN58
DO i = lb+1,la59IF( string_a%chars(i) > blank )THEN60
s_ge_s = .TRUE.; RETURN61ELSEIF( string_a%chars(i) < blank )THEN62
s_ge_s = .FALSE.; RETURN63ENDIF64
ENDDO65ENDIF66s_ge_s = .TRUE.67ENDFUNCTION s_ge_s68
69FUNCTION s_ge_c(string_a,string_b) ! string>=character70type(VARYING_STRING),INTENT(IN) :: string_a71CHARACTER(LEN=*),INTENT(IN) :: string_b72
25
ISO/IEC 1539-2 : 1993 (E) CD version 2
LOGICAL :: s_ge_c1INTEGER :: ls,la,lb2la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)3DO i = 1,ls4
IF( string_a%chars(i) > string_b(i:i) )THEN5s_ge_c = .TRUE.; RETURN6
ELSEIF( string_a%chars(i) < string_b(i:i) )THEN7s_ge_c = .FALSE.; RETURN8
ENDIF9ENDDO10IF( la < lb )THEN11
IF( blank > string_b(la+1:lb) )THEN12s_ge_c = .TRUE.; RETURN13
ELSEIF( blank < string_b(la+1:lb) )THEN14s_ge_c = .FALSE.; RETURN15
ENDIF16ELSEIF( la > lb )THEN17
DO i = lb+1,la18IF( string_a%chars(i) > blank )THEN19
s_ge_c = .TRUE.; RETURN20ELSEIF( string_a%chars(i) < blank )THEN21
s_ge_c = .FALSE.; RETURN22ENDIF23
ENDDO24ENDIF25s_ge_c = .TRUE.26ENDFUNCTION s_ge_c27
28FUNCTION c_ge_s(string_a,string_b) ! character>=string29CHARACTER(LEN=*),INTENT(IN) :: string_a30type(VARYING_STRING),INTENT(IN) :: string_b31LOGICAL :: c_ge_s32INTEGER :: ls,la,lb33la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)34DO i = 1,ls35
IF( string_a(i:i) > string_b%chars(i) )THEN36c_ge_s = .TRUE.; RETURN37
ELSEIF( string_a(i:i) < string_b%chars(i) )THEN38c_ge_s = .FALSE.; RETURN39
ENDIF40ENDDO41IF( la < lb )THEN42
DO i = la+1,lb43IF( blank > string_b%chars(i) )THEN44
c_ge_s = .TRUE.; RETURN45ELSEIF( blank < string_b%chars(i) )THEN46
c_ge_s = .FALSE.; RETURN47ENDIF48
ENDDO49ELSEIF( la > lb )THEN50
IF( string_a(lb+1:la) > blank )THEN51c_ge_s = .TRUE.; RETURN52
ELSEIF( string_a(lb+1:la) < blank )THEN53c_ge_s = .FALSE.; RETURN54
ENDIF55ENDIF56c_ge_s = .TRUE.57ENDFUNCTION c_ge_s58
59!------ Greater-than operators -----------------------------------------------!60FUNCTION s_gt_s(string_a,string_b) ! string>string61type(VARYING_STRING),INTENT(IN) :: string_a,string_b62LOGICAL :: s_gt_s63INTEGER :: ls,la,lb64la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)65DO i = 1,ls66
IF( string_a%chars(i) > string_b%chars(i) )THEN67s_gt_s = .TRUE.; RETURN68
ELSEIF( string_a%chars(i) < string_b%chars(i) )THEN69s_gt_s = .FALSE.; RETURN70
ENDIF71ENDDO72
26
CD version 2 ISO/IEC 1539-2 : 1993 (E)
IF( la < lb )THEN1DO i = la+1,lb2
IF( blank > string_b%chars(i) )THEN3s_gt_s = .TRUE.; RETURN4
ELSEIF( blank < string_b%chars(i) )THEN5s_gt_s = .FALSE.; RETURN6
ENDIF7ENDDO8
ELSEIF( la > lb )THEN9DO i = lb+1,la10IF( string_a%chars(i) > blank )THEN11
s_gt_s = .TRUE.; RETURN12ELSEIF( string_a%chars(i) < blank )THEN13
s_gt_s = .FALSE.; RETURN14ENDIF15
ENDDO16ENDIF17s_gt_s = .FALSE.18ENDFUNCTION s_gt_s19
20FUNCTION s_gt_c(string_a,string_b) ! string>character21type(VARYING_STRING),INTENT(IN) :: string_a22CHARACTER(LEN=*),INTENT(IN) :: string_b23LOGICAL :: s_gt_c24INTEGER :: ls,la,lb25la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)26DO i = 1,ls27
IF( string_a%chars(i) > string_b(i:i) )THEN28s_gt_c = .TRUE.; RETURN29
ELSEIF( string_a%chars(i) < string_b(i:i) )THEN30s_gt_c = .FALSE.; RETURN31
ENDIF32ENDDO33IF( la < lb )THEN34
IF( blank > string_b(la+1:lb) )THEN35s_gt_c = .TRUE.; RETURN36
ELSEIF( blank < string_b(la+1:lb) )THEN37s_gt_c = .FALSE.; RETURN38
ENDIF39ELSEIF( la > lb )THEN40
DO i = lb+1,la41IF( string_a%chars(i) > blank )THEN42
s_gt_c = .TRUE.; RETURN43ELSEIF( string_a%chars(i) < blank )THEN44
s_gt_c = .FALSE.; RETURN45ENDIF46
ENDDO47ENDIF48s_gt_c = .FALSE.49ENDFUNCTION s_gt_c50
51FUNCTION c_gt_s(string_a,string_b) ! character>string52CHARACTER(LEN=*),INTENT(IN) :: string_a53type(VARYING_STRING),INTENT(IN) :: string_b54LOGICAL :: c_gt_s55INTEGER :: ls,la,lb56la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)57DO i = 1,ls58
IF( string_a(i:i) > string_b%chars(i) )THEN59c_gt_s = .TRUE.; RETURN60
ELSEIF( string_a(i:i) < string_b%chars(i) )THEN61c_gt_s = .FALSE.; RETURN62
ENDIF63ENDDO64IF( la < lb )THEN65
DO i = la+1,lb66IF( blank > string_b%chars(i) )THEN67
c_gt_s = .TRUE.; RETURN68ELSEIF( blank < string_b%chars(i) )THEN69
c_gt_s = .FALSE.; RETURN70ENDIF71
ENDDO72
27
ISO/IEC 1539-2 : 1993 (E) CD version 2
ELSEIF( la > lb )THEN1IF( string_a(lb+1:la) > blank )THEN2
c_gt_s = .TRUE.; RETURN3ELSEIF( string_a(lb+1:la) < blank )THEN4
c_gt_s = .FALSE.; RETURN5ENDIF6
ENDIF7c_gt_s = .FALSE.8
ENDFUNCTION c_gt_s910
!----- LLT procedures -------------------------------------------------------!11FUNCTION s_llt_s(string_a,string_b) ! string_a<string_b ISO-646 ordering12type(VARYING_STRING),INTENT(IN) :: string_a,string_b13LOGICAL :: s_llt_s14! Returns TRUE if string_a preceeds string_b in the ISO 646 collating15! sequence. Otherwise the result is FALSE. The result is FALSE if both16! string_a and string_b are zero length.17INTEGER :: ls,la,lb18la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)19DO i = 1,ls20
IF( LLT(string_a%chars(i),string_b%chars(i)) )THEN21s_llt_s = .TRUE.; RETURN22
ELSEIF( LGT(string_a%chars(i),string_b%chars(i)) )THEN23s_llt_s = .FALSE.; RETURN24
ENDIF25ENDDO26IF( la < lb )THEN27
DO i = la+1,lb28IF( LLT(blank,string_b%chars(i)) )THEN29
s_llt_s = .TRUE.; RETURN30ELSEIF( LGT(blank,string_b%chars(i)) )THEN31
s_llt_s = .FALSE.; RETURN32ENDIF33
ENDDO34ELSEIF( la > lb )THEN35
DO i = lb+1,la36IF( LLT(string_a%chars(i),blank) )THEN37
s_llt_s = .TRUE.; RETURN38ELSEIF( LGT(string_a%chars(i),blank) )THEN39
s_llt_s = .FALSE.; RETURN40ENDIF41
ENDDO42ENDIF43s_llt_s = .FALSE.44
ENDFUNCTION s_llt_s4546
FUNCTION s_llt_c(string_a,string_b)47type(VARYING_STRING),INTENT(IN) :: string_a48CHARACTER(LEN=*),INTENT(IN) :: string_b49LOGICAL :: s_llt_c50INTEGER :: ls,la,lb51la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)52DO i = 1,ls53
IF( LLT(string_a%chars(i),string_b(i:i)) )THEN54s_llt_c = .TRUE.; RETURN55
ELSEIF( LGT(string_a%chars(i),string_b(i:i)) )THEN56s_llt_c = .FALSE.; RETURN57
ENDIF58ENDDO59IF( la < lb )THEN60
IF( LLT(blank,string_b(la+1:lb)) )THEN61s_llt_c = .TRUE.; RETURN62
ELSEIF( LGT(blank,string_b(la+1:lb)) )THEN63s_llt_c = .FALSE.; RETURN64
ENDIF65ELSEIF( la > lb )THEN66
DO i = lb+1,la67IF( LLT(string_a%chars(i),blank) )THEN68
s_llt_c = .TRUE.; RETURN69ELSEIF( LGT(string_a%chars(i),blank) )THEN70
s_llt_c = .FALSE.; RETURN71ENDIF72
28
CD version 2 ISO/IEC 1539-2 : 1993 (E)
ENDDO1ENDIF2s_llt_c = .FALSE.3
ENDFUNCTION s_llt_c45
FUNCTION c_llt_s(string_a,string_b) ! string_a,string_b ISO-646 ordering6CHARACTER(LEN=*),INTENT(IN) :: string_a7type(VARYING_STRING),INTENT(IN) :: string_b8LOGICAL :: c_llt_s9INTEGER :: ls,la,lb10la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)11DO i = 1,ls12
IF( LLT(string_a(i:i),string_b%chars(i)) )THEN13c_llt_s = .TRUE.; RETURN14
ELSEIF( LGT(string_a(i:i),string_b%chars(i)) )THEN15c_llt_s = .FALSE.; RETURN16
ENDIF17ENDDO18IF( la < lb )THEN19
DO i = la+1,lb20IF( LLT(blank,string_b%chars(i)) )THEN21
c_llt_s = .TRUE.; RETURN22ELSEIF( LGT(blank,string_b%chars(i)) )THEN23
c_llt_s = .FALSE.; RETURN24ENDIF25
ENDDO26ELSEIF( la > lb )THEN27
IF( LLT(string_a(lb+1:la),blank) )THEN28c_llt_s = .TRUE.; RETURN29
ELSEIF( LGT(string_a(lb+1:la),blank) )THEN30c_llt_s = .FALSE.; RETURN31
ENDIF32ENDIF33c_llt_s = .FALSE.34
ENDFUNCTION c_llt_s3536
!----- LLE procedures -------------------------------------------------------!37FUNCTION s_lle_s(string_a,string_b) ! string_a<=string_b ISO-646 ordering38type(VARYING_STRING),INTENT(IN) :: string_a,string_b39LOGICAL :: s_lle_s40! Returns TRUE if strings are equal or if string_a preceeds string_b in the41! ISO 646 collating sequence. Otherwise the result is FALSE.42INTEGER :: ls,la,lb43la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)44DO i = 1,ls45
IF( LLT(string_a%chars(i),string_b%chars(i)) )THEN46s_lle_s = .TRUE.; RETURN47
ELSEIF( LGT(string_a%chars(i),string_b%chars(i)) )THEN48s_lle_s = .FALSE.; RETURN49
ENDIF50ENDDO51IF( la < lb )THEN52
DO i = la+1,lb53IF( LLT(blank,string_b%chars(i)) )THEN54
s_lle_s = .TRUE.; RETURN55ELSEIF( LGT(blank,string_b%chars(i)) )THEN56
s_lle_s = .FALSE.; RETURN57ENDIF58
ENDDO59ELSEIF( la > lb )THEN60
DO i = lb+1,la61IF( LLT(string_a%chars(i),blank) )THEN62
s_lle_s = .TRUE.; RETURN63ELSEIF( LGT(string_a%chars(i),blank) )THEN64
s_lle_s = .FALSE.; RETURN65ENDIF66
ENDDO67ENDIF68s_lle_s = .TRUE.69
ENDFUNCTION s_lle_s7071
FUNCTION s_lle_c(string_a,string_b) ! strung_a<=string_b ISO-646 ordering72
29
ISO/IEC 1539-2 : 1993 (E) CD version 2
type(VARYING_STRING),INTENT(IN) :: string_a1CHARACTER(LEN=*),INTENT(IN) :: string_b2LOGICAL :: s_lle_c3INTEGER :: ls,la,lb4la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)5DO i = 1,ls6IF( LLT(string_a%chars(i),string_b(i:i)) )THEN7
s_lle_c = .TRUE.; RETURN8ELSEIF( LGT(string_a%chars(i),string_b(i:i)) )THEN9
s_lle_c = .FALSE.; RETURN10ENDIF11
ENDDO12IF( la < lb )THEN13
IF( LLT(blank,string_b(la+1:lb)) )THEN14s_lle_c = .TRUE.; RETURN15
ELSEIF( LGT(blank,string_b(la+1:lb)) )THEN16s_lle_c = .FALSE.; RETURN17
ENDIF18ELSEIF( la > lb )THEN19
DO i = lb+1,la20IF( LLT(string_a%chars(i),blank) )THEN21
s_lle_c = .TRUE.; RETURN22ELSEIF( LGT(string_a%chars(i),blank) )THEN23
s_lle_c = .FALSE.; RETURN24ENDIF25
ENDDO26ENDIF27s_lle_c = .TRUE.28
ENDFUNCTION s_lle_c2930
FUNCTION c_lle_s(string_a,string_b) ! string_a<=string_b ISO-646 ordering31CHARACTER(LEN=*),INTENT(IN) :: string_a32type(VARYING_STRING),INTENT(IN) :: string_b33LOGICAL :: c_lle_s34INTEGER :: ls,la,lb35la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)36DO i = 1,ls37
IF( LLT(string_a(i:i),string_b%chars(i)) )THEN38c_lle_s = .TRUE.; RETURN39
ELSEIF( LGT(string_a(i:i),string_b%chars(i)) )THEN40c_lle_s = .FALSE.; RETURN41
ENDIF42ENDDO43IF( la < lb )THEN44
DO i = la+1,lb45IF( LLT(blank,string_b%chars(i)) )THEN46
c_lle_s = .TRUE.; RETURN47ELSEIF( LGT(blank,string_b%chars(i)) )THEN48
c_lle_s = .FALSE.; RETURN49ENDIF50
ENDDO51ELSEIF( la > lb )THEN52
IF( LLT(string_a(lb+1:la),blank) )THEN53c_lle_s = .TRUE.; RETURN54
ELSEIF( LGT(string_a(lb+1:la),blank) )THEN55c_lle_s = .FALSE.; RETURN56
ENDIF57ENDIF58c_lle_s = .TRUE.59
ENDFUNCTION c_lle_s6061
!----- LGE procedures -------------------------------------------------------!62FUNCTION s_lge_s(string_a,string_b) ! string_a>=string_b ISO-646 ordering63type(VARYING_STRING),INTENT(IN) :: string_a,string_b64LOGICAL :: s_lge_s65! Returns TRUE if strings are equal or if string_a follows string_b in the66! ISO 646 collating sequence. Otherwise the result is FALSE.67INTEGER :: ls,la,lb68la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)69DO i = 1,ls70
IF( LGT(string_a%chars(i),string_b%chars(i)) )THEN71s_lge_s = .TRUE.; RETURN72
30
CD version 2 ISO/IEC 1539-2 : 1993 (E)
ELSEIF( LLT(string_a%chars(i),string_b%chars(i)) )THEN1s_lge_s = .FALSE.; RETURN2
ENDIF3ENDDO4IF( la < lb )THEN5
DO i = la+1,lb6IF( LGT(blank,string_b%chars(i)) )THEN7s_lge_s = .TRUE.; RETURN8
ELSEIF( LLT(blank,string_b%chars(i)) )THEN9s_lge_s = .FALSE.; RETURN10
ENDIF11ENDDO12
ELSEIF( la > lb )THEN13DO i = lb+1,la14IF( LGT(string_a%chars(i),blank) )THEN15
s_lge_s = .TRUE.; RETURN16ELSEIF( LLT(string_a%chars(i),blank) )THEN17
s_lge_s = .FALSE.; RETURN18ENDIF19
ENDDO20ENDIF21s_lge_s = .TRUE.22
ENDFUNCTION s_lge_s2324
FUNCTION s_lge_c(string_a,string_b) ! string_a>=string_b ISO-646 ordering25type(VARYING_STRING),INTENT(IN) :: string_a26CHARACTER(LEN=*),INTENT(IN) :: string_b27LOGICAL :: s_lge_c28INTEGER :: ls,la,lb29la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)30DO i = 1,ls31
IF( LGT(string_a%chars(i),string_b(i:i)) )THEN32s_lge_c = .TRUE.; RETURN33
ELSEIF( LLT(string_a%chars(i),string_b(i:i)) )THEN34s_lge_c = .FALSE.; RETURN35
ENDIF36ENDDO37IF( la < lb )THEN38
IF( LGT(blank,string_b(la+1:lb)) )THEN39s_lge_c = .TRUE.; RETURN40
ELSEIF( LLT(blank,string_b(la+1:lb)) )THEN41s_lge_c = .FALSE.; RETURN42
ENDIF43ELSEIF( la > lb )THEN44
DO i = lb+1,la45IF( LGT(string_a%chars(i),blank) )THEN46
s_lge_c = .TRUE.; RETURN47ELSEIF( LLT(string_a%chars(i),blank) )THEN48
s_lge_c = .FALSE.; RETURN49ENDIF50
ENDDO51ENDIF52s_lge_c = .TRUE.53
ENDFUNCTION s_lge_c5455
FUNCTION c_lge_s(string_a,string_b) ! string_a>=string_b ISO-646 ordering56CHARACTER(LEN=*),INTENT(IN) :: string_a57type(VARYING_STRING),INTENT(IN) :: string_b58LOGICAL :: c_lge_s59INTEGER :: ls,la,lb60la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)61DO i = 1,ls62
IF( LGT(string_a(i:i),string_b%chars(i)) )THEN63c_lge_s = .TRUE.; RETURN64
ELSEIF( LLT(string_a(i:i),string_b%chars(i)) )THEN65c_lge_s = .FALSE.; RETURN66
ENDIF67ENDDO68IF( la < lb )THEN69
DO i = la+1,lb70IF( LGT(blank,string_b%chars(i)) )THEN71
c_lge_s = .TRUE.; RETURN72
31
ISO/IEC 1539-2 : 1993 (E) CD version 2
ELSEIF( LLT(blank,string_b%chars(i)) )THEN1c_lge_s = .FALSE.; RETURN2
ENDIF3ENDDO4
ELSEIF( la > lb )THEN5IF( LGT(string_a(lb+1:la),blank) )THEN6
c_lge_s = .TRUE.; RETURN7ELSEIF( LLT(string_a(lb+1:la),blank) )THEN8
c_lge_s = .FALSE.; RETURN9ENDIF10
ENDIF11c_lge_s = .TRUE.12
ENDFUNCTION c_lge_s13
!----- LGT procedures -------------------------------------------------------!14FUNCTION s_lgt_s(string_a,string_b) ! string_a>string_b ISO-646 ordering15type(VARYING_STRING),INTENT(IN) :: string_a,string_b16LOGICAL :: s_lgt_s17! Returns TRUE if string_a follows string_b in the ISO 646 collating sequence.18! Otherwise the result is FALSE. The result is FALSE if both string_a and19! string_b are zero length.20INTEGER :: ls,la,lb21la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)22DO i = 1,ls23
IF( LGT(string_a%chars(i),string_b%chars(i)) )THEN24s_lgt_s = .TRUE.; RETURN25
ELSEIF( LLT(string_a%chars(i),string_b%chars(i)) )THEN26s_lgt_s = .FALSE.; RETURN27
ENDIF28ENDDO29IF( la < lb )THEN30
DO i = la+1,lb31IF( LGT(blank,string_b%chars(i)) )THEN32
s_lgt_s = .TRUE.; RETURN33ELSEIF( LLT(blank,string_b%chars(i)) )THEN34
s_lgt_s = .FALSE.; RETURN35ENDIF36
ENDDO37ELSEIF( la > lb )THEN38
DO i = lb+1,la39IF( LGT(string_a%chars(i),blank) )THEN40
s_lgt_s = .TRUE.; RETURN41ELSEIF( LLT(string_a%chars(i),blank) )THEN42
s_lgt_s = .FALSE.; RETURN43ENDIF44
ENDDO45ENDIF46s_lgt_s = .FALSE.47
ENDFUNCTION s_lgt_s4849
FUNCTION s_lgt_c(string_a,string_b) ! string_a>string_b ISO-646 ordering50type(VARYING_STRING),INTENT(IN) :: string_a51CHARACTER(LEN=*),INTENT(IN) :: string_b52LOGICAL :: s_lgt_c53INTEGER :: ls,la,lb54la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)55DO i = 1,ls56
IF( LGT(string_a%chars(i),string_b(i:i)) )THEN57s_lgt_c = .TRUE.; RETURN58
ELSEIF( LLT(string_a%chars(i),string_b(i:i)) )THEN59s_lgt_c = .FALSE.; RETURN60
ENDIF61ENDDO62IF( la < lb )THEN63
IF( LGT(blank,string_b(la+1:lb)) )THEN64s_lgt_c = .TRUE.; RETURN65
ELSEIF( LLT(blank,string_b(la+1:lb)) )THEN66s_lgt_c = .FALSE.; RETURN67
ENDIF68ELSEIF( la > lb )THEN69
DO i = lb+1,la70IF( LGT(string_a%chars(i),blank) )THEN71
32
CD version 2 ISO/IEC 1539-2 : 1993 (E)
s_lgt_c = .TRUE.; RETURN1ELSEIF( LLT(string_a%chars(i),blank) )THEN2s_lgt_c = .FALSE.; RETURN3
ENDIF4ENDDO5
ENDIF6s_lgt_c = .FALSE.7
ENDFUNCTION s_lgt_c89
FUNCTION c_lgt_s(string_a,string_b) ! string_a>string_b ISO-646 ordering10CHARACTER(LEN=*),INTENT(IN) :: string_a11type(VARYING_STRING),INTENT(IN) :: string_b12LOGICAL :: c_lgt_s13INTEGER :: ls,la,lb14la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)15DO i = 1,ls16
IF( LGT(string_a(i:i),string_b%chars(i)) )THEN17c_lgt_s = .TRUE.; RETURN18
ELSEIF( LLT(string_a(i:i),string_b%chars(i)) )THEN19c_lgt_s = .FALSE.; RETURN20
ENDIF21ENDDO22IF( la < lb )THEN23
DO i = la+1,lb24IF( LGT(blank,string_b%chars(i)) )THEN25
c_lgt_s = .TRUE.; RETURN26ELSEIF( LLT(blank,string_b%chars(i)) )THEN27
c_lgt_s = .FALSE.; RETURN28ENDIF29
ENDDO30ELSEIF( la > lb )THEN31
IF( LGT(string_a(lb+1:la),blank) )THEN32c_lgt_s = .TRUE.; RETURN33
ELSEIF( LLT(string_a(lb+1:la),blank) )THEN34c_lgt_s = .FALSE.; RETURN35
ENDIF36ENDIF37c_lgt_s = .FALSE.38
ENDFUNCTION c_lgt_s394041
!----- Input string procedure -----------------------------------------------!42SUBROUTINE get_d_eor(string,maxlen,iostat)43type(VARYING_STRING),INTENT(OUT) :: string44
! the string variable to be filled with45! characters read from the46! file connected to the default unit47
INTEGER,INTENT(IN),OPTIONAL :: maxlen48! if present indicates the maximum49! number of characters that will be50! read from the file51
INTEGER,INTENT(OUT),OPTIONAL :: iostat52! if present used to return the status53! of the data transfer54! if absent errors cause termination55
! reads string from the default unit starting at next character in the file56! and terminating at the end of record or after maxlen characters.57CHARACTER(LEN=80) :: buffer58INTEGER :: ist,nch,toread,nb59IF(PRESENT(maxlen))THEN60toread=maxlen61
ELSE62toread=HUGE(1)63
ENDIF64string = "" ! clears return string65DO ! repeatedly read buffer and add to string until EoR66
! or maxlen reached67IF(toread <= 0)EXIT68nb=MIN(80,toread)69READ(*,FMT=’(A)’,ADVANCE=’NO’,EOR=9999,SIZE=nch,IOSTAT=ist) buffer(1:nb)70IF( ist /= 0 )THEN71
IF(PRESENT(iostat)) THEN72
33
ISO/IEC 1539-2 : 1993 (E) CD version 2
iostat=ist1RETURN2
ELSE3WRITE(*,*) " Error No.",ist, &4
" during READ_STRING of varying string on default unit"5STOP6
ENDIF7ENDIF8string = string //buffer(1:nb)9toread = toread - nb10
ENDDO11IF(PRESENT(iostat)) iostat = 012RETURN139999 string = string //buffer(1:nch)14IF(PRESENT(iostat)) iostat = ist15
ENDSUBROUTINE get_d_eor1617
SUBROUTINE get_u_eor(unit,string,maxlen,iostat)18INTEGER,INTENT(IN) :: unit19
! identifies the input unit which must be20! connected for sequential formatted read21
type(VARYING_STRING),INTENT(OUT) :: string22! the string variable to be filled with23! characters read from the24! file connected to the unit25
INTEGER,INTENT(IN),OPTIONAL :: maxlen26! if present indicates the maximum27! number of characters that will be28! read from the file29
INTEGER,INTENT(OUT),OPTIONAL :: iostat30! if present used to return the status31! of the data transfer32! if absent errors cause termination33
! reads string from unit starting at next character in the file and34! terminating at the end of record or after maxlen characters.35CHARACTER(LEN=80) :: buffer36INTEGER :: ist,nch,toread,nb37IF(PRESENT(maxlen))THEN38toread=maxlen39
ELSE40toread=HUGE(1)41
ENDIF42string="" ! clears return string43DO ! repeatedly read buffer and add to string until EoR44
! or maxlen reached45IF(toread <= 0)EXIT46nb=MIN(80,toread)47READ(unit,FMT=’(A)’,ADVANCE=’NO’,EOR=9999,SIZE=nch,IOSTAT=ist) buffer(1:nb)48IF( ist /= 0 )THEN49
IF(PRESENT(iostat)) THEN50iostat=ist51RETURN52
ELSE53WRITE(*,*) " Error No.",ist, &54
" during READ_STRING of varying string on UNIT ",unit55STOP56
ENDIF57ENDIF58string = string //buffer(1:nb)59toread = toread - nb60
ENDDO61IF(PRESENT(iostat)) iostat = 062RETURN639999 string = string //buffer(1:nch)64IF(PRESENT(iostat)) iostat = ist65
ENDSUBROUTINE get_u_eor66
SUBROUTINE get_d_tset_s(string,set,maxlen,iostat)67type(VARYING_STRING),INTENT(OUT) :: string68
! the string variable to be filled with69! characters read from the70! file connected to the default unit71
34
CD version 2 ISO/IEC 1539-2 : 1993 (E)
type(VARYING_STRING),INTENT(IN) :: set1! the set of characters which if found in2! the input terminate the read3
INTEGER,INTENT(IN),OPTIONAL :: maxlen4! if present indicates the maximum5! number of characters that will be6! read from the file7
INTEGER,INTENT(OUT),OPTIONAL :: iostat8! if present used to return the status9! of the data transfer10! if absent errors cause termination11
! reads string from the default unit starting at next character in the file and12! terminating at the end of record, occurance of a character in set,13! or after reading maxlen characters.14CHARACTER :: buffer ! characters must be read one at a time to detect15
! first terminator character in set16INTEGER :: ist,toread,lenset17ist=018lenset = LEN(set)19IF(PRESENT(maxlen))THEN20
toread=maxlen21ELSE22
toread=HUGE(1)23ENDIF24string = "" ! clears return string25DO ! repeatedly read buffer and add to string until EoR26
! or maxlen reached27IF(toread <= 0)EXIT28READ(*,FMT=’(A)’,ADVANCE=’NO’,EOR=9999,IOSTAT=ist) buffer29IF( ist /= 0 )THEN30
IF(PRESENT(iostat)) THEN31iostat=ist32RETURN33
ELSE34WRITE(*,*) " Error No.",ist, &35
" during READ_STRING of varying string on default unit"36STOP37
ENDIF38ENDIF39! check for occurance of set character in buffer40
DO j = 1,lenset41IF(buffer == set%chars(j)) GOTO 999942
ENDDO43string = string//buffer44toread = toread - 145
ENDDO46IF(PRESENT(iostat)) iostat = ist47RETURN489999 string = string//buffer49IF(PRESENT(iostat)) iostat = ist50
ENDSUBROUTINE get_d_tset_s51
SUBROUTINE get_u_tset_s(unit,string,set,maxlen,iostat)52INTEGER,INTENT(IN) :: unit53
! identifies the input unit which must be54! connected for sequential formatted read55
type(VARYING_STRING),INTENT(OUT) :: string56! the string variable to be filled with57! characters read from the58! file connected to the unit59
type(VARYING_STRING),INTENT(IN) :: set60! the set of characters which if found in61! the input terminate the read62
INTEGER,INTENT(IN),OPTIONAL :: maxlen63! if present indicates the maximum64! number of characters that will be65! read from the file66
INTEGER,INTENT(OUT),OPTIONAL :: iostat67! if present used to return the status68! of the data transfer69! if absent errors cause termination70
! reads string from unit starting at next character in the file and71
35
ISO/IEC 1539-2 : 1993 (E) CD version 2
! terminating at the end of record, occurance of a character in set,1! or after reading maxlen characters.2CHARACTER :: buffer ! characters must be read one at a time to detect3
! first terminator character in set4INTEGER :: ist,toread,lenset5ist=06lenset = LEN(set)7IF(PRESENT(maxlen))THEN8
toread=maxlen9ELSE10
toread=HUGE(1)11ENDIF12string = "" ! clears return string13DO ! repeatedly read buffer and add to string until EoR14
! or maxlen reached15IF(toread <= 0)EXIT16READ(unit,FMT=’(A)’,ADVANCE=’NO’,EOR=9999,IOSTAT=ist) buffer17IF( ist /= 0 )THEN18
IF(PRESENT(iostat)) THEN19iostat=ist20RETURN21
ELSE22WRITE(*,*) " Error No.",ist, &23
" during READ_STRING of varying string on unit ",unit24STOP25
ENDIF26ENDIF27! check for occurance of set character in buffer28
DO j = 1,lenset29IF(buffer == set%chars(j)) GOTO 999930
ENDDO31string = string//buffer32toread = toread - 133
ENDDO34IF(PRESENT(iostat)) iostat = ist35RETURN369999 string = string//buffer37IF(PRESENT(iostat)) iostat = ist38
ENDSUBROUTINE get_u_tset_s39
SUBROUTINE get_d_tset_c(string,set,maxlen,iostat)40type(VARYING_STRING),INTENT(OUT) :: string41
! the string variable to be filled with42! characters read from the43! file connected to the default unit44
CHARACTER(LEN=*),INTENT(IN) :: set45! the set of characters which if found in46! the input terminate the read47
INTEGER,INTENT(IN),OPTIONAL :: maxlen48! if present indicates the maximum49! number of characters that will be50! read from the file51
INTEGER,INTENT(OUT),OPTIONAL :: iostat52! if present used to return the status53! of the data transfer54! if absent errors cause termination55
! reads string from the default unit starting at next character in the file and56! terminating at the end of record, occurance of a character in set,57! or after reading maxlen characters.58CHARACTER :: buffer ! characters must be read one at a time to detect59
! first terminator character in set60INTEGER :: ist,toread,lenset61ist=062lenset = LEN(set)63IF(PRESENT(maxlen))THEN64
toread=maxlen65ELSE66
toread=HUGE(1)67ENDIF68string = "" ! clears return string69DO ! repeatedly read buffer and add to string until EoR70
! or maxlen reached71
36
CD version 2 ISO/IEC 1539-2 : 1993 (E)
IF(toread <= 0)EXIT1READ(*,FMT=’(A)’,ADVANCE=’NO’,EOR=9999,IOSTAT=ist) buffer2IF( ist /= 0 )THEN3
IF(PRESENT(iostat)) THEN4iostat=ist5RETURN6
ELSE7WRITE(*,*) " Error No.",ist, &8
" during READ_STRING of varying string on default unit"9STOP10
ENDIF11ENDIF12! check for occurance of set character in buffer13
DO j = 1,lenset14IF(buffer == set(j:j)) GOTO 999915
ENDDO16string = string//buffer17toread = toread - 118
ENDDO19IF(PRESENT(iostat)) iostat = ist20RETURN219999 string = string//buffer22IF(PRESENT(iostat)) iostat = ist23
ENDSUBROUTINE get_d_tset_c24
SUBROUTINE get_u_tset_c(unit,string,set,maxlen,iostat)25INTEGER,INTENT(IN) :: unit26
! identifies the input unit which must be27! connected for sequential formatted read28
type(VARYING_STRING),INTENT(OUT) :: string29! the string variable to be filled with30! characters read from the31! file connected to the unit32
CHARACTER(LEN=*),INTENT(IN) :: set33! the set of characters which if found in34! the input terminate the read35
INTEGER,INTENT(IN),OPTIONAL :: maxlen36! if present indicates the maximum37! number of characters that will be38! read from the file39
INTEGER,INTENT(OUT),OPTIONAL :: iostat40! if present used to return the status41! of the data transfer42! if absent errors cause termination43
! reads string from unit starting at next character in the file and44! terminating at the end of record, occurance of a character in set,45! or after reading maxlen characters.46CHARACTER :: buffer ! characters must be read one at a time to detect47
! first terminator character in set48INTEGER :: ist,toread,lenset49ist=050lenset = LEN(set)51IF(PRESENT(maxlen))THEN52
toread=maxlen53ELSE54
toread=HUGE(1)55ENDIF56string = "" ! clears return string57DO ! repeatedly read buffer and add to string until EoR58
! or maxlen reached59IF(toread <= 0)EXIT60READ(unit,FMT=’(A)’,ADVANCE=’NO’,EOR=9999,IOSTAT=ist) buffer61IF( ist /= 0 )THEN62
IF(PRESENT(iostat)) THEN63iostat=ist64RETURN65
ELSE66WRITE(*,*) " Error No.",ist, &67
" during READ_STRING of varying string on unit ",unit68STOP69
ENDIF70ENDIF71
37
ISO/IEC 1539-2 : 1993 (E) CD version 2
! check for occurance of set character in buffer1DO j = 1,lenset2IF(buffer == set(j:j)) GOTO 99993
ENDDO4string = string//buffer5toread = toread - 16
ENDDO7IF(PRESENT(iostat)) iostat = ist8RETURN99999 string = string//buffer10IF(PRESENT(iostat)) iostat = ist11
ENDSUBROUTINE get_u_tset_c12
!----- Output string procedures ----------------------------------------------!13SUBROUTINE put_d_s(string,iostat)14type(VARYING_STRING),INTENT(IN) :: string15
! the string variable to be appended to16! the current record or to the start of17! the next record if there is no18! current record19! uses the default unit20
INTEGER,INTENT(OUT),OPTIONAL :: iostat21! if present used to return the status22! of the data transfer23! if absent errors cause termination24
INTEGER :: ist25WRITE(*,FMT=’(A)’,ADVANCE=’NO’,IOSTAT=ist) CHAR(string)26IF( ist /= 0 )THEN27
IF(PRESENT(iostat))THEN28iostat = ist29RETURN30
ELSE31WRITE(*,*) " Error No.",ist, &32
" during WRITE_STRING of varying string on default unit"33STOP34
ENDIF35ENDIF36IF(PRESENT(iostat)) iostat=037
ENDSUBROUTINE put_d_s38
SUBROUTINE put_u_s(unit,string,iostat)39INTEGER,INTENT(IN) :: unit40
! identifies the output unit which must41! be connected for sequential formatted42! write43
type(VARYING_STRING),INTENT(IN) :: string44! the string variable to be appended to45! the current record or to the start of46! the next record if there is no47! current record48
INTEGER,INTENT(OUT),OPTIONAL :: iostat49! if present used to return the status50! of the data transfer51! if absent errors cause termination52
WRITE(unit,FMT=’(A)’,ADVANCE=’NO’,IOSTAT=ist) CHAR(string)53IF( ist /= 0 )THEN54IF(PRESENT(iostat))THEN55iostat = ist56RETURN57
ELSE58WRITE(*,*) " Error No.",ist, &59
" during WRITE_STRING of varying string on UNIT ",unit60STOP61
ENDIF62ENDIF63
IF(PRESENT(iostat)) iostat=064ENDSUBROUTINE put_u_s65
66SUBROUTINE put_d_c(string,iostat)67CHARACTER(LEN=*),INTENT(IN) :: string68
! the character variable to be appended to69! the current record or to the start of70
38
CD version 2 ISO/IEC 1539-2 : 1993 (E)
! the next record if there is no1! current record2! uses the default unit3
INTEGER,INTENT(OUT),OPTIONAL :: iostat4! if present used to return the status5! of the data transfer6! if absent errors cause termination7
INTEGER :: ist8WRITE(*,FMT=’(A)’,ADVANCE=’NO’,IOSTAT=ist) string9IF( ist /= 0 )THEN10IF(PRESENT(iostat))THEN11iostat = ist12RETURN13
ELSE14WRITE(*,*) " Error No.",ist, &15
" during WRITE_STRING of character on default unit"16STOP17
ENDIF18ENDIF19IF(PRESENT(iostat)) iostat=020
ENDSUBROUTINE put_d_c21
SUBROUTINE put_u_c(unit,string,iostat)22INTEGER,INTENT(IN) :: unit23
! identifies the output unit which must24! be connected for sequential formatted25! write26
CHARACTER(LEN=*),INTENT(IN) :: string27! the character variable to be appended to28! the current record or to the start of29! the next record if there is no30! current record31
INTEGER,INTENT(OUT),OPTIONAL :: iostat32! if present used to return the status33! of the data transfer34! if absent errors cause termination35
INTEGER :: ist36WRITE(unit,FMT=’(A)’,ADVANCE=’NO’,IOSTAT=ist) string37IF( ist /= 0 )THEN38IF(PRESENT(iostat))THEN39iostat = ist40RETURN41
ELSE42WRITE(*,*) " Error No.",ist," during WRITE_STRING of character on UNIT ",unit43STOP44
ENDIF45ENDIF46IF(PRESENT(iostat)) iostat=047
ENDSUBROUTINE put_u_c48
SUBROUTINE putline_d_s(string,iostat)49type(VARYING_STRING),INTENT(IN) :: string50
! the string variable to be appended to51! the current record or to the start of52! the next record if there is no53! current record54! uses the default unit55
INTEGER,INTENT(OUT),OPTIONAL :: iostat56! if present used to return the status57! of the data transfer58! if absent errors cause termination59
! appends the string to the current record and then ends the record60! leaves the file positioned after the record just completed which then61! becomes the previous and last record in the file.62INTEGER :: ist63WRITE(*,FMT=’(A,/)’,ADVANCE=’NO’,IOSTAT=ist) CHAR(string)64IF( ist /= 0 )THEN65IF(PRESENT(iostat))THEN66iostat = ist; RETURN67
ELSE68WRITE(*,*) " Error No.",ist, &69
" during WRITE_LINE of varying string on default unit"70
39
ISO/IEC 1539-2 : 1993 (E) CD version 2
STOP1ENDIF2
ENDIF3IF(PRESENT(iostat)) iostat=04
ENDSUBROUTINE putline_d_s56
SUBROUTINE putline_u_s(unit,string,iostat)7INTEGER,INTENT(IN) :: unit8
! identifies the output unit which must9! be connected for sequential formatted10! write11
type(VARYING_STRING),INTENT(IN) :: string12! the string variable to be appended to13! the current record or to the start of14! the next record if there is no15! current record16
INTEGER,INTENT(OUT),OPTIONAL :: iostat17! if present used to return the status18! of the data transfer19! if absent errors cause termination20
! appends the string to the current record and then ends the record21! leaves the file positioned after the record just completed which then22! becomes the previous and last record in the file.23INTEGER :: ist24WRITE(unit,FMT=’(A,/)’,ADVANCE=’NO’,IOSTAT=ist) CHAR(string)25IF( ist /= 0 )THEN26IF(PRESENT(iostat))THEN27iostat = ist; RETURN28
ELSE29WRITE(*,*) " Error No.",ist, &30
" during WRITE_LINE of varying string on UNIT",unit31STOP32
ENDIF33ENDIF34
IF(PRESENT(iostat)) iostat=035ENDSUBROUTINE putline_u_s36
SUBROUTINE putline_d_c(string,iostat)37CHARACTER(LEN=*),INTENT(IN) :: string38
! the character variable to be appended to39! the current record or to the start of40! the next record if there is no41! current record42! uses the default unit43
INTEGER,INTENT(OUT),OPTIONAL :: iostat44! if present used to return the status45! of the data transfer46! if absent errors cause termination47
! appends the string to the current record and then ends the record48! leaves the file positioned after the record just completed which then49! becomes the previous and last record in the file.50INTEGER :: ist51WRITE(*,FMT=’(A,/)’,ADVANCE=’NO’,IOSTAT=ist) string52IF(PRESENT(iostat))THEN53iostat = ist54RETURN55ELSEIF( ist /= 0 )THEN56WRITE(*,*) " Error No.",ist, &57
" during WRITE_LINE of character on default unit"58STOP59ENDIF60
ENDSUBROUTINE putline_d_c6162
SUBROUTINE putline_u_c(unit,string,iostat)63INTEGER,INTENT(IN) :: unit64
! identifies the output unit which must65! be connected for sequential formatted66! write67
CHARACTER(LEN=*),INTENT(IN) :: string68! the character variable to be appended to69! the current record or to the start of70! the next record if there is no71
40
CD version 2 ISO/IEC 1539-2 : 1993 (E)
! current record1INTEGER,INTENT(OUT),OPTIONAL :: iostat2
! if present used to return the status3! of the data transfer4! if absent errors cause termination5
! appends the string to the current record and then ends the record6! leaves the file positioned after the record just completed which then7! becomes the previous and last record in the file.8INTEGER :: ist9WRITE(unit,FMT=’(A,/)’,ADVANCE=’NO’,IOSTAT=ist) string10IF(PRESENT(iostat))THEN11iostat = ist12RETURN13ELSEIF( ist /= 0 )THEN14WRITE(*,*) " Error No.",ist, &15
" during WRITE_LINE of character on UNIT",unit16STOP17ENDIF18
ENDSUBROUTINE putline_u_c1920
!----- Insert procedures ----------------------------------------------------!21FUNCTION insert_ss(string,start,substring)22type(VARYING_STRING) :: insert_ss23type(VARYING_STRING),INTENT(IN) :: string24INTEGER,INTENT(IN) :: start25type(VARYING_STRING),INTENT(IN) :: substring26! calculates result string by inserting the substring into string27! beginning at position start pushing the remainder of the string28! to the right and enlarging it accordingly,29! if start is greater than LEN(string) the substring is simply appended30! to string by concatenation. if start is less than 131! substring is inserted before string, ie. start is treated as if it were 132CHARACTER,POINTER,DIMENSION(:) :: work33INTEGER :: ip,is,lsub,ls34lsub = LEN(substring); ls = LEN(string)35is = MAX(start,1)36ip = MIN(ls+1,is)37ALLOCATE(work(1:lsub+ls))38work(1:ip-1) = string%chars(1:ip-1)39work(ip:ip+lsub-1) =substring%chars40work(ip+lsub:lsub+ls) = string%chars(ip:ls)41insert_ss%chars => work42ENDFUNCTION insert_ss43
44FUNCTION insert_sc(string,start,substring)45type(VARYING_STRING) :: insert_sc46type(VARYING_STRING),INTENT(IN) :: string47INTEGER,INTENT(IN) :: start48CHARACTER(LEN=*),INTENT(IN) :: substring49! calculates result string by inserting the substring into string50! beginning at position start pushing the remainder of the string51! to the right and enlarging it accordingly,52! if start is greater than LEN(string) the substring is simply appended53! to string by concatenation. if start is less than 154! substring is inserted before string, ie. start is treated as if it were 155CHARACTER,POINTER,DIMENSION(:) :: work56INTEGER :: ip,is,lsub,ls57lsub = LEN(substring); ls = LEN(string)58is = MAX(start,1)59ip = MIN(ls+1,is)60ALLOCATE(work(1:lsub+ls))61work(1:ip-1) = string%chars(1:ip-1)62DO i = 1,lsub63work(ip-1+i) = substring(i:i)64
ENDDO65work(ip+lsub:lsub+ls) = string%chars(ip:ls)66insert_sc%chars => work67ENDFUNCTION insert_sc68
FUNCTION insert_cs(string,start,substring)69type(VARYING_STRING) :: insert_cs70CHARACTER(LEN=*),INTENT(IN) :: string71
41
ISO/IEC 1539-2 : 1993 (E) CD version 2
INTEGER,INTENT(IN) :: start1type(VARYING_STRING),INTENT(IN) :: substring2! calculates result string by inserting the substring into string3! beginning at position start pushing the remainder of the string4! to the right and enlarging it accordingly,5! if start is greater than LEN(string) the substring is simply appended6! to string by concatenation. if start is less than 17! substring is inserted before string, ie. start is treated as if it were 18CHARACTER,POINTER,DIMENSION(:) :: work9INTEGER :: ip,is,lsub,ls10lsub = LEN(substring); ls = LEN(string)11is = MAX(start,1)12ip = MIN(ls+1,is)13ALLOCATE(work(1:lsub+ls))14DO i=1,ip-115
work(i) = string(i:i)16ENDDO17work(ip:ip+lsub-1) =substring%chars18DO i=ip,ls19
work(i+lsub) = string(i:i)20ENDDO21insert_cs%chars => work22ENDFUNCTION insert_cs23
24FUNCTION insert_cc(string,start,substring)25type(VARYING_STRING) :: insert_cc26CHARACTER(LEN=*),INTENT(IN) :: string27INTEGER,INTENT(IN) :: start28CHARACTER(LEN=*),INTENT(IN) :: substring29! calculates result string by inserting the substring into string30! beginning at position start pushing the remainder of the string31! to the right and enlarging it accordingly,32! if start is greater than LEN(string) the substring is simply appended33! to string by concatenation. if start is less than 134! substring is inserted before string, ie. start is treated as if it were 135CHARACTER,POINTER,DIMENSION(:) :: work36INTEGER :: ip,is,lsub,ls37lsub = LEN(substring); ls = LEN(string)38is = MAX(start,1)39ip = MIN(ls+1,is)40ALLOCATE(work(1:lsub+ls))41DO i=1,ip-142
work(i) = string(i:i)43ENDDO44DO i = 1,lsub45work(ip-1+i) = substring(i:i)46
ENDDO47DO i=ip,ls48
work(i+lsub) = string(i:i)49ENDDO50insert_cc%chars => work51ENDFUNCTION insert_cc52
!----- Replace procedures ---------------------------------------------------!53FUNCTION replace_ss(string,start,substring)54type(VARYING_STRING) :: replace_ss55type(VARYING_STRING),INTENT(IN) :: string56INTEGER,INTENT(IN) :: start57type(VARYING_STRING),INTENT(IN) :: substring58! calculates the result string by the following actions:59! inserts the substring into string beginning at position60! start replacing the following LEN(substring) characters of the string61! and enlarging string if necessary. if start is greater than LEN(string)62! substring is simply appended to string by concatenation. If start is less63! than 1, substring replaces characters in string starting at 164CHARACTER,POINTER,DIMENSION(:) :: work65INTEGER :: ip,is,nw,lsub,ls66lsub = LEN(substring); ls = LEN(string)67is = MAX(start,1)68ip = MIN(ls+1,is)69nw = MAX(ls,ip+lsub-1)70ALLOCATE(work(1:nw))71
42
CD version 2 ISO/IEC 1539-2 : 1993 (E)
work(1:ip-1) = string%chars(1:ip-1)1work(ip:ip+lsub-1) = substring%chars2work(ip+lsub:nw) = string%chars(ip+lsub:ls)3replace_ss%chars => work4ENDFUNCTION replace_ss5
6FUNCTION replace_ss_sf(string,start,finish,substring)7type(VARYING_STRING) :: replace_ss_sf8type(VARYING_STRING),INTENT(IN) :: string9INTEGER,INTENT(IN) :: start,finish10type(VARYING_STRING),INTENT(IN) :: substring11! calculates the result string by the following actions:12! inserts the substring into string beginning at position13! start replacing the following finish-start+1 characters of the string14! and enlarging or shrinking the string if necessary.15! If start is greater than LEN(string) substring is simply appended to string16! by concatenation. If start is less than 1, start = 1 is used17! If finish is greater than LEN(string), finish = LEN(string) is used18! If finish is less than start, substring is inserted before start19CHARACTER,POINTER,DIMENSION(:) :: work20INTEGER :: ip,is,if,nw,lsub,ls21lsub = LEN(substring); ls = LEN(string)22is = MAX(start,1)23ip = MIN(ls+1,is)24if = MAX(ip-1,MIN(finish,ls))25nw = lsub + ls - if+ip-126ALLOCATE(work(1:nw))27work(1:ip-1) = string%chars(1:ip-1)28work(ip:ip+lsub-1) = substring%chars29work(ip+lsub:nw) = string%chars(if+1:ls)30replace_ss_sf%chars => work31
ENDFUNCTION replace_ss_sf32
FUNCTION replace_sc(string,start,substring)33type(VARYING_STRING) :: replace_sc34type(VARYING_STRING),INTENT(IN) :: string35INTEGER,INTENT(IN) :: start36CHARACTER(LEN=*),INTENT(IN) :: substring37! calculates the result string by the following actions:38! inserts the characters from substring into string beginning at position39! start replacing the following LEN(substring) characters of the string40! and enlarging string if necessary. If start is greater than LEN(string)41! substring is simply appended to string by concatenation. If start is less42! than 1, substring replaces characters in string starting at 143CHARACTER,POINTER,DIMENSION(:) :: work44INTEGER :: ip,is,nw,lsub,ls45lsub = LEN(substring); ls = LEN(string)46is = MAX(start,1)47ip = MIN(ls+1,is)48nw = MAX(ls,ip+lsub-1)49ALLOCATE(work(1:nw))50work(1:ip-1) = string%chars(1:ip-1)51DO i = 1,lsub52
work(ip-1+i) = substring(i:i)53ENDDO54work(ip+lsub:nw) = string%chars(ip+lsub:ls)55replace_sc%chars => work56
ENDFUNCTION replace_sc5758
FUNCTION replace_sc_sf(string,start,finish,substring)59type(VARYING_STRING) :: replace_sc_sf60type(VARYING_STRING),INTENT(IN) :: string61INTEGER,INTENT(IN) :: start,finish62CHARACTER(LEN=*),INTENT(IN) :: substring63! calculates the result string by the following actions:64! inserts the substring into string beginning at position65! start replacing the following finish-start+1 characters of the string66! and enlarging or shrinking the string if necessary.67! If start is greater than LEN(string) substring is simply appended to string68! by concatenation. If start is less than 1, start = 1 is used69! If finish is greater than LEN(string), finish = LEN(string) is used70! If finish is less than start, substring is inserted before start71
43
ISO/IEC 1539-2 : 1993 (E) CD version 2
CHARACTER,POINTER,DIMENSION(:) :: work1INTEGER :: ip,is,if,nw,lsub,ls2lsub = LEN(substring); ls = LEN(string)3is = MAX(start,1)4ip = MIN(ls+1,is)5if = MAX(ip-1,MIN(finish,ls))6nw = lsub + ls - if+ip-17ALLOCATE(work(1:nw))8work(1:ip-1) = string%chars(1:ip-1)9DO i = 1,lsub10
work(ip-1+i) = substring(i:i)11ENDDO12work(ip+lsub:nw) = string%chars(if+1:ls)13replace_sc_sf%chars => work14
ENDFUNCTION replace_sc_sf15
FUNCTION replace_cs(string,start,substring)16type(VARYING_STRING) :: replace_cs17CHARACTER(LEN=*),INTENT(IN) :: string18INTEGER,INTENT(IN) :: start19type(VARYING_STRING),INTENT(IN) :: substring20! calculates the result string by the following actions:21! inserts the substring into string beginning at position22! start replacing the following LEN(substring) characters of the string23! and enlarging string if necessary. if start is greater than LEN(string)24! substring is simply appended to string by concatenation. If start is less25! than 1, substring replaces characters in string starting at 126CHARACTER,POINTER,DIMENSION(:) :: work27INTEGER :: ip,is,nw,lsub,ls28lsub = LEN(substring); ls = LEN(string)29is = MAX(start,1)30ip = MIN(ls+1,is)31nw = MAX(ls,ip+lsub-1)32ALLOCATE(work(1:nw))33DO i=1,ip-134
work(i) = string(i:i)35ENDDO36work(ip:ip+lsub-1) = substring%chars37DO i=ip+lsub,nw38
work(i) = string(i:i)39ENDDO40replace_cs%chars => work41
ENDFUNCTION replace_cs4243
FUNCTION replace_cs_sf(string,start,finish,substring)44type(VARYING_STRING) :: replace_cs_sf45CHARACTER(LEN=*),INTENT(IN) :: string46INTEGER,INTENT(IN) :: start,finish47type(VARYING_STRING),INTENT(IN) :: substring48! calculates the result string by the following actions:49! inserts the substring into string beginning at position50! start replacing the following finish-start+1 characters of the string51! and enlarging or shrinking the string if necessary.52! If start is greater than LEN(string) substring is simply appended to string53! by concatenation. If start is less than 1, start = 1 is used54! If finish is greater than LEN(string), finish = LEN(string) is used55! If finish is less than start, substring is inserted before start56CHARACTER,POINTER,DIMENSION(:) :: work57INTEGER :: ip,is,if,nw,lsub,ls58lsub = LEN(substring); ls = LEN(string)59is = MAX(start,1)60ip = MIN(ls+1,is)61if = MAX(ip-1,MIN(finish,ls))62nw = lsub + ls - if+ip-163ALLOCATE(work(1:nw))64DO i=1,ip-165
work(i) = string(i:i)66ENDDO67work(ip:ip+lsub-1) = substring%chars68DO i=1,nw-ip-lsub+169
work(i+ip+lsub-1) = string(if+i:if+i)70ENDDO71
44
CD version 2 ISO/IEC 1539-2 : 1993 (E)
replace_cs_sf%chars => work1ENDFUNCTION replace_cs_sf2
FUNCTION replace_cc(string,start,substring)3type(VARYING_STRING) :: replace_cc4CHARACTER(LEN=*),INTENT(IN) :: string5INTEGER,INTENT(IN) :: start6CHARACTER(LEN=*),INTENT(IN) :: substring7! calculates the result string by the following actions:8! inserts the characters from substring into string beginning at position9! start replacing the following LEN(substring) characters of the string10! and enlarging string if necessary. If start is greater than LEN(string)11! substring is simply appended to string by concatenation. If start is less12! than 1, substring replaces characters in string starting at 113CHARACTER,POINTER,DIMENSION(:) :: work14INTEGER :: ip,is,nw,lsub,ls15lsub = LEN(substring); ls = LEN(string)16is = MAX(start,1)17ip = MIN(ls+1,is)18nw = MAX(ls,ip+lsub-1)19ALLOCATE(work(1:nw))20DO i=1,ip-121
work(i) = string(i:i)22ENDDO23DO i=1,lsub24
work(ip-1+i) = substring(i:i)25ENDDO26DO i=ip+lsub,nw27
work(i) = string(i:i)28ENDDO29replace_cc%chars => work30
ENDFUNCTION replace_cc3132
FUNCTION replace_cc_sf(string,start,finish,substring)33type(VARYING_STRING) :: replace_cc_sf34CHARACTER(LEN=*),INTENT(IN) :: string35INTEGER,INTENT(IN) :: start,finish36CHARACTER(LEN=*),INTENT(IN) :: substring37! calculates the result string by the following actions:38! inserts the substring into string beginning at position39! start replacing the following finish-start+1 characters of the string40! and enlarging or shrinking the string if necessary.41! If start is greater than LEN(string) substring is simply appended to string42! by concatenation. If start is less than 1, start = 1 is used43! If finish is greater than LEN(string), finish = LEN(string) is used44! If finish is less than start, substring is inserted before start45CHARACTER,POINTER,DIMENSION(:) :: work46INTEGER :: ip,is,if,nw,lsub,ls47lsub = LEN(substring); ls = LEN(string)48is = MAX(start,1)49ip = MIN(ls+1,is)50if = MAX(ip-1,MIN(finish,ls))51nw = lsub + ls - if+ip-152ALLOCATE(work(1:nw))53DO i=1,ip-154
work(i) = string(i:i)55ENDDO56DO i=1,lsub57
work(i+ip-1) = substring(i:i)58ENDDO59DO i=1,nw-ip-lsub+160
work(i+ip+lsub-1) = string(if+i:if+i)61ENDDO62replace_cc_sf%chars => work63
ENDFUNCTION replace_cc_sf64
FUNCTION replace_sss(string,target,substring,every,back)65type(VARYING_STRING) :: replace_sss66type(VARYING_STRING),INTENT(IN) :: string,target,substring67LOGICAL,INTENT(IN),OPTIONAL :: every,back68! calculates the result string by the following actions:69! searches for occurences of target in string, and replaces these with70
45
ISO/IEC 1539-2 : 1993 (E) CD version 2
! substring. if back present with value true search is backward otherwise1! search is done forward. if every present with value true all occurences2! of target in string are replaced, otherwise only the first found is3! replaced. if target is not found the result is the same as string.4LOGICAL :: dir_switch, rep_search5CHARACTER,DIMENSION(:),POINTER :: work,temp6INTEGER :: ls,lt,lsub,ipos,ipow7ls = LEN(string); lt = LEN(target); lsub = LEN(substring)8IF(lt==0)THEN9
WRITE(*,*) " Zero length target in REPLACE"10STOP11
ENDIF12ALLOCATE(work(1:ls)); work = string%chars13IF( PRESENT(back) )THEN14
dir_switch = back15ELSE16
dir_switch = .FALSE.17ENDIF18IF( PRESENT(every) )THEN19
rep_search = every20ELSE21
rep_search = .FALSE.22ENDIF23IF( dir_switch )THEN ! backwards search24
ipos = ls-lt+125DO26
IF( ipos < 1 )EXIT ! search past start of string27! test for occurance of target in string at this position28IF( ALL(string%chars(ipos:ipos+lt-1) == target%chars) )THEN29! match found allocate space for string with this occurance of30! target replaced by substring31ALLOCATE(temp(1:SIZE(work)+lsub-lt))32! copy work into temp replacing this occurance of target by33! substring34temp(1:ipos-1) = work(1:ipos-1)35temp(ipos:ipos+lsub-1) = substring%chars36temp(ipos+lsub:) = work(ipos+lt:)37work => temp ! make new version of work point at the temp space38IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted39! move search and replacement positions over the effected positions40ipos = ipos-lt+141
ENDIF42ipos=ipos-143
ENDDO44ELSE ! forward search45
ipos = 1; ipow = 146DO47
IF( ipos > ls-lt+1 )EXIT ! search past end of string48! test for occurance of target in string at this position49IF( ALL(string%chars(ipos:ipos+lt-1) == target%chars) )THEN50! match found allocate space for string with this occurance of51! target replaced by substring52ALLOCATE(temp(1:SIZE(work)+lsub-lt))53! copy work into temp replacing this occurance of target by54! substring55temp(1:ipow-1) = work(1:ipow-1)56temp(ipow:ipow+lsub-1) = substring%chars57temp(ipow+lsub:) = work(ipow+lt:)58work => temp ! make new version of work point at the temp space59IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted60! move search and replacement positions over the effected positions61ipos = ipos+lt-1; ipow = ipow+lsub-162
ENDIF63ipos=ipos+1; ipow=ipow+164
ENDDO65ENDIF66replace_sss%chars => work67
ENDFUNCTION replace_sss68
FUNCTION replace_ssc(string,target,substring,every,back)69type(VARYING_STRING) :: replace_ssc70type(VARYING_STRING),INTENT(IN) :: string,target71
46
CD version 2 ISO/IEC 1539-2 : 1993 (E)
CHARACTER(LEN=*),INTENT(IN) :: substring1LOGICAL,INTENT(IN),OPTIONAL :: every,back2! calculates the result string by the following actions:3! searches for occurences of target in string, and replaces these with4! substring. if back present with value true search is backward otherwise5! search is done forward. if every present with value true all occurences6! of target in string are replaced, otherwise only the first found is7! replaced. if target is not found the result is the same as string.8LOGICAL :: dir_switch, rep_search9CHARACTER,DIMENSION(:),POINTER :: work,temp10INTEGER :: ls,lt,lsub,ipos,ipow11ls = LEN(string); lt = LEN(target); lsub = LEN(substring)12IF(lt==0)THEN13
WRITE(*,*) " Zero length target in REPLACE"14STOP15
ENDIF16ALLOCATE(work(1:ls)); work = string%chars17IF( PRESENT(back) )THEN18
dir_switch = back19ELSE20
dir_switch = .FALSE.21ENDIF22IF( PRESENT(every) )THEN23
rep_search = every24ELSE25
rep_search = .FALSE.26ENDIF27IF( dir_switch )THEN ! backwards search28
ipos = ls-lt+129DO30
IF( ipos < 1 )EXIT ! search past start of string31! test for occurance of target in string at this position32IF( ALL(string%chars(ipos:ipos+lt-1) == target%chars) )THEN33! match found allocate space for string with this occurance of34! target replaced by substring35ALLOCATE(temp(1:SIZE(work)+lsub-lt))36! copy work into temp replacing this occurance of target by37! substring38temp(1:ipos-1) = work(1:ipos-1)39DO i=1,lsub40
temp(i+ipos-1) = substring(i:i)41ENDDO42temp(ipos+lsub:) = work(ipos+lt:)43work => temp ! make new version of work point at the temp space44IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted45! move search and replacement positions over the effected positions46ipos = ipos-lt+147
ENDIF48ipos=ipos-149
ENDDO50ELSE ! forward search51
ipos = 1; ipow = 152DO53
IF( ipos > ls-lt+1 )EXIT ! search past end of string54! test for occurance of target in string at this position55IF( ALL(string%chars(ipos:ipos+lt-1) == target%chars) )THEN56! match found allocate space for string with this occurance of57! target replaced by substring58ALLOCATE(temp(1:SIZE(work)+lsub-lt))59! copy work into temp replacing this occurance of target by60! substring61temp(1:ipow-1) = work(1:ipow-1)62DO i=1,lsub63
temp(i+ipow-1) = substring(i:i)64ENDDO65temp(ipow+lsub:) = work(ipow+lt:)66work => temp ! make new version of work point at the temp space67IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted68! move search and replacement positions over the effected positions69ipos = ipos+lt-1; ipow = ipow+lsub-170
ENDIF71ipos=ipos+1; ipow=ipow+172
47
ISO/IEC 1539-2 : 1993 (E) CD version 2
ENDDO1ENDIF2replace_ssc%chars => work3ENDFUNCTION replace_ssc4
FUNCTION replace_scs(string,target,substring,every,back)5type(VARYING_STRING) :: replace_scs6type(VARYING_STRING),INTENT(IN) :: string,substring7CHARACTER(LEN=*),INTENT(IN) :: target8LOGICAL,INTENT(IN),OPTIONAL :: every,back9! calculates the result string by the following actions:10! searches for occurences of target in string, and replaces these with11! substring. if back present with value true search is backward otherwise12! search is done forward. if every present with value true all accurences13! of target in string are replaced, otherwise only the first found is14! replaced. if target is not found the result is the same as string.15LOGICAL :: dir_switch, rep_search16CHARACTER,DIMENSION(:),POINTER :: work,temp,tget17INTEGER :: ls,lt,lsub,ipos,ipow18ls = LEN(string); lt = LEN(target); lsub = LEN(substring)19IF(lt==0)THEN20
WRITE(*,*) " Zero length target in REPLACE"21STOP22
ENDIF23ALLOCATE(work(1:ls)); work = string%chars24ALLOCATE(tget(1:lt))25DO i=1,lt26
tget(i) = target(i:i)27ENDDO28IF( PRESENT(back) )THEN29
dir_switch = back30ELSE31
dir_switch = .FALSE.32ENDIF33IF( PRESENT(every) )THEN34
rep_search = every35ELSE36
rep_search = .FALSE.37ENDIF38IF( dir_switch )THEN ! backwards search39
ipos = ls-lt+140DO41
IF( ipos < 1 )EXIT ! search past start of string42! test for occurance of target in string at this position43IF( ALL(string%chars(ipos:ipos+lt-1) == tget) )THEN44! match found allocate space for string with this occurance of45! target replaced by substring46ALLOCATE(temp(1:SIZE(work)+lsub-lt))47! copy work into temp replacing this occurance of target by48! substring49temp(1:ipos-1) = work(1:ipos-1)50temp(ipos:ipos+lsub-1) = substring%chars51temp(ipos+lsub:) = work(ipos+lt:)52work => temp ! make new version of work point at the temp space53IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted54! move search and replacement positions over the effected positions55ipos = ipos-lt+156
ENDIF57ipos=ipos-158
ENDDO59ELSE ! forward search60
ipos = 1; ipow = 161DO62
IF( ipos > ls-lt+1 )EXIT ! search past end of string63! test for occurance of target in string at this position64IF( ALL(string%chars(ipos:ipos+lt-1) == tget) )THEN65! match found allocate space for string with this occurance of66! target replaced by substring67ALLOCATE(temp(1:SIZE(work)+lsub-lt))68! copy work into temp replacing this occurance of target by69! substring70temp(1:ipow-1) = work(1:ipow-1)71
48
CD version 2 ISO/IEC 1539-2 : 1993 (E)
temp(ipow:ipow+lsub-1) = substring%chars1temp(ipow+lsub:) = work(ipow+lt:)2work => temp ! make new version of work point at the temp space3IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted4! move search and replacement positions over the effected positions5ipos = ipos+lt-1; ipow = ipow+lsub-16
ENDIF7ipos=ipos+1; ipow=ipow+18
ENDDO9ENDIF10replace_scs%chars => work11
ENDFUNCTION replace_scs12
FUNCTION replace_scc(string,target,substring,every,back)13type(VARYING_STRING) :: replace_scc14type(VARYING_STRING),INTENT(IN) :: string15CHARACTER(LEN=*),INTENT(IN) :: target,substring16LOGICAL,INTENT(IN),OPTIONAL :: every,back17! calculates the result string by the following actions:18! searches for occurences of target in string, and replaces these with19! substring. if back present with value true search is backward otherwise20! search is done forward. if every present with value true all accurences21! of target in string are replaced, otherwise only the first found is22! replaced. if target is not found the result is the same as string.23LOGICAL :: dir_switch, rep_search24CHARACTER,DIMENSION(:),POINTER :: work,temp,tget25INTEGER :: ls,lt,lsub,ipos,ipow26ls = LEN(string); lt = LEN(target); lsub = LEN(substring)27IF(lt==0)THEN28
WRITE(*,*) " Zero length target in REPLACE"29STOP30
ENDIF31ALLOCATE(work(1:ls)); work = string%chars32ALLOCATE(tget(1:lt))33DO i=1,lt34
tget(i) = target(i:i)35ENDDO36IF( PRESENT(back) )THEN37
dir_switch = back38ELSE39
dir_switch = .FALSE.40ENDIF41IF( PRESENT(every) )THEN42
rep_search = every43ELSE44
rep_search = .FALSE.45ENDIF46IF( dir_switch )THEN ! backwards search47
ipos = ls-lt+148DO49
IF( ipos < 1 )EXIT ! search past start of string50! test for occurance of target in string at this position51IF( ALL(string%chars(ipos:ipos+lt-1) == tget) )THEN52! match found allocate space for string with this occurance of53! target replaced by substring54ALLOCATE(temp(1:SIZE(work)+lsub-lt))55! copy work into temp replacing this occurance of target by56! substring57temp(1:ipos-1) = work(1:ipos-1)58DO i=1,lsub59
temp(i+ipos-1) = substring(i:i)60ENDDO61temp(ipos+lsub:) = work(ipos+lt:)62work => temp ! make new version of work point at the temp space63IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted64! move search and replacement positions over the effected positions65ipos = ipos-lt+166
ENDIF67ipos=ipos-168
ENDDO69ELSE ! forward search70
ipos = 1; ipow = 171
49
ISO/IEC 1539-2 : 1993 (E) CD version 2
DO1IF( ipos > ls-lt+1 )EXIT ! search past end of string2! test for occurance of target in string at this position3IF( ALL(string%chars(ipos:ipos+lt-1) == tget) )THEN4! match found allocate space for string with this occurance of5! target replaced by substring6ALLOCATE(temp(1:SIZE(work)+lsub-lt))7! copy work into temp replacing this occurance of target by8! substring9temp(1:ipow-1) = work(1:ipow-1)10DO i=1,lsub11
temp(i+ipow-1) = substring(i:i)12ENDDO13temp(ipow+lsub:) = work(ipow+lt:)14work => temp ! make new version of work point at the temp space15IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted16! move search and replacement positions over the effected positions17ipos = ipos+lt-1; ipow = ipow+lsub-118
ENDIF19ipos=ipos+1; ipow=ipow+120
ENDDO21ENDIF22replace_scc%chars => work23
ENDFUNCTION replace_scc24
FUNCTION replace_css(string,target,substring,every,back)25type(VARYING_STRING) :: replace_css26CHARACTER(LEN=*),INTENT(IN) :: string27type(VARYING_STRING),INTENT(IN) :: target,substring28LOGICAL,INTENT(IN),OPTIONAL :: every,back29! calculates the result string by the following actions:30! searches for occurences of target in string, and replaces these with31! substring. if back present with value true search is backward otherwise32! search is done forward. if every present with value true all accurences33! of target in string are replaced, otherwise only the first found is34! replaced. if target is not found the result is the same as string.35LOGICAL :: dir_switch, rep_search36CHARACTER,DIMENSION(:),POINTER :: work,temp,str37INTEGER :: ls,lt,lsub,ipos,ipow38ls = LEN(string); lt = LEN(target); lsub = LEN(substring)39IF(lt==0)THEN40
WRITE(*,*) " Zero length target in REPLACE"41STOP42
ENDIF43ALLOCATE(work(1:ls)); ALLOCATE(str(1:ls))44DO i=1,ls45
str(i) = string(i:i)46ENDDO47work = str48IF( PRESENT(back) )THEN49
dir_switch = back50ELSE51
dir_switch = .FALSE.52ENDIF53IF( PRESENT(every) )THEN54
rep_search = every55ELSE56
rep_search = .FALSE.57ENDIF58IF( dir_switch )THEN ! backwards search59
ipos = ls-lt+160DO61
IF( ipos < 1 )EXIT ! search past start of string62! test for occurance of target in string at this position63IF( ALL(str(ipos:ipos+lt-1) == target%chars) )THEN64! match found allocate space for string with this occurance of65! target replaced by substring66ALLOCATE(temp(1:SIZE(work)+lsub-lt))67! copy work into temp replacing this occurance of target by68! substring69temp(1:ipos-1) = work(1:ipos-1)70temp(ipos:ipos+lsub-1) = substring%chars71
50
CD version 2 ISO/IEC 1539-2 : 1993 (E)
temp(ipos+lsub:) = work(ipos+lt:)1work => temp ! make new version of work point at the temp space2IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted3! move search and replacement positions over the effected positions4ipos = ipos-lt+15
ENDIF6ipos=ipos-17
ENDDO8ELSE ! forward search9
ipos = 1; ipow = 110DO11
IF( ipos > ls-lt+1 )EXIT ! search past end of string12! test for occurance of target in string at this position13IF( ALL(str(ipos:ipos+lt-1) == target%chars) )THEN14! match found allocate space for string with this occurance of15! target replaced by substring16ALLOCATE(temp(1:SIZE(work)+lsub-lt))17! copy work into temp replacing this occurance of target by18! substring19temp(1:ipow-1) = work(1:ipow-1)20temp(ipow:ipow+lsub-1) = substring%chars21temp(ipow+lsub:) = work(ipow+lt:)22work => temp ! make new version of work point at the temp space23IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted24! move search and replacement positions over the effected positions25ipos = ipos+lt-1; ipow = ipow+lsub-126
ENDIF27ipos=ipos+1; ipow=ipow+128
ENDDO29ENDIF30replace_css%chars => work31
ENDFUNCTION replace_css32
FUNCTION replace_csc(string,target,substring,every,back)33type(VARYING_STRING) :: replace_csc34type(VARYING_STRING),INTENT(IN) :: target35CHARACTER(LEN=*),INTENT(IN) :: string,substring36LOGICAL,INTENT(IN),OPTIONAL :: every,back37! calculates the result string by the following actions:38! searches for occurences of target in string, and replaces these with39! substring. if back present with value true search is backward otherwise40! search is done forward. if every present with value true all accurences41! of target in string are replaced, otherwise only the first found is42! replaced. if target is not found the result is the same as string.43LOGICAL :: dir_switch, rep_search44CHARACTER,DIMENSION(:),POINTER :: work,temp,str45INTEGER :: ls,lt,lsub,ipos,ipow46ls = LEN(string); lt = LEN(target); lsub = LEN(substring)47IF(lt==0)THEN48
WRITE(*,*) " Zero length target in REPLACE"49STOP50
ENDIF51ALLOCATE(work(1:ls)); ALLOCATE(str(1:ls))52DO i=1,ls53
str(i) = string(i:i)54ENDDO55work = str56IF( PRESENT(back) )THEN57
dir_switch = back58ELSE59
dir_switch = .FALSE.60ENDIF61IF( PRESENT(every) )THEN62
rep_search = every63ELSE64
rep_search = .FALSE.65ENDIF66IF( dir_switch )THEN ! backwards search67
ipos = ls-lt+168DO69
IF( ipos < 1 )EXIT ! search past start of string70! test for occurance of target in string at this position71
51
ISO/IEC 1539-2 : 1993 (E) CD version 2
IF( ALL(str(ipos:ipos+lt-1) == target%chars) )THEN1! match found allocate space for string with this occurance of2! target replaced by substring3ALLOCATE(temp(1:SIZE(work)+lsub-lt))4! copy work into temp replacing this occurance of target by5! substring6temp(1:ipos-1) = work(1:ipos-1)7DO i=1,lsub8
temp(i+ipos-1) = substring(i:i)9ENDDO10temp(ipos+lsub:) = work(ipos+lt:)11work => temp ! make new version of work point at the temp space12IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted13! move search and replacement positions over the effected positions14ipos = ipos-lt+115
ENDIF16ipos=ipos-117
ENDDO18ELSE ! forward search19
ipos = 1; ipow = 120DO21
IF( ipos > ls-lt+1 )EXIT ! search past end of string22! test for occurance of target in string at this position23IF( ALL(str(ipos:ipos+lt-1) == target%chars) )THEN24! match found allocate space for string with this occurance of25! target replaced by substring26ALLOCATE(temp(1:SIZE(work)+lsub-lt))27! copy work into temp replacing this occurance of target by28! substring29temp(1:ipow-1) = work(1:ipow-1)30DO i=1,lsub31
temp(i+ipow-1) = substring(i:i)32ENDDO33temp(ipow+lsub:) = work(ipow+lt:)34work => temp ! make new version of work point at the temp space35IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted36! move search and replacement positions over the effected positions37ipos = ipos+lt-1; ipow = ipow+lsub-138
ENDIF39ipos=ipos+1; ipow=ipow+140
ENDDO41ENDIF42replace_csc%chars => work43
ENDFUNCTION replace_csc44
FUNCTION replace_ccs(string,target,substring,every,back)45type(VARYING_STRING) :: replace_ccs46type(VARYING_STRING),INTENT(IN) :: substring47CHARACTER(LEN=*),INTENT(IN) :: string,target48LOGICAL,INTENT(IN),OPTIONAL :: every,back49! calculates the result string by the following actions:50! searches for occurences of target in string, and replaces these with51! substring. if back present with value true search is backward otherwise52! search is done forward. if every present with value true all accurences53! of target in string are replaced, otherwise only the first found is54! replaced. if target is not found the result is the same as string.55LOGICAL :: dir_switch, rep_search56CHARACTER,DIMENSION(:),POINTER :: work,temp57INTEGER :: ls,lt,lsub,ipos,ipow58ls = LEN(string); lt = LEN(target); lsub = LEN(substring)59IF(lt==0)THEN60
WRITE(*,*) " Zero length target in REPLACE"61STOP62
ENDIF63ALLOCATE(work(1:ls))64DO i=1,ls65
work(i) = string(i:i)66ENDDO67IF( PRESENT(back) )THEN68
dir_switch = back69ELSE70
dir_switch = .FALSE.71
52
CD version 2 ISO/IEC 1539-2 : 1993 (E)
ENDIF1IF( PRESENT(every) )THEN2
rep_search = every3ELSE4
rep_search = .FALSE.5ENDIF6IF( dir_switch )THEN ! backwards search7
ipos = ls-lt+18DO9
IF( ipos < 1 )EXIT ! search past start of string10! test for occurance of target in string at this position11IF( string(ipos:ipos+lt-1) == target )THEN12! match found allocate space for string with this occurance of13! target replaced by substring14ALLOCATE(temp(1:SIZE(work)+lsub-lt))15! copy work into temp replacing this occurance of target by16! substring17temp(1:ipos-1) = work(1:ipos-1)18temp(ipos:ipos+lsub-1) = substring%chars19temp(ipos+lsub:) = work(ipos+lt:)20work => temp ! make new version of work point at the temp space21IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted22! move search and replacement positions over the effected positions23ipos = ipos-lt+124
ENDIF25ipos=ipos-126
ENDDO27ELSE ! forward search28
ipos = 1; ipow = 129DO30
IF( ipos > ls-lt+1 )EXIT ! search past end of string31! test for occurance of target in string at this position32IF( string(ipos:ipos+lt-1) == target )THEN33! match found allocate space for string with this occurance of34! target replaced by substring35ALLOCATE(temp(1:SIZE(work)+lsub-lt))36! copy work into temp replacing this occurance of target by37! substring38temp(1:ipow-1) = work(1:ipow-1)39temp(ipow:ipow+lsub-1) = substring%chars40temp(ipow+lsub:) = work(ipow+lt:)41work => temp ! make new version of work point at the temp space42IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted43! move search and replacement positions over the effected positions44ipos = ipos+lt-1; ipow = ipow+lsub-145
ENDIF46ipos=ipos+1; ipow=ipow+147
ENDDO48ENDIF49replace_ccs%chars => work50
ENDFUNCTION replace_ccs51
FUNCTION replace_ccc(string,target,substring,every,back)52type(VARYING_STRING) :: replace_ccc53CHARACTER(LEN=*),INTENT(IN) :: string,target,substring54LOGICAL,INTENT(IN),OPTIONAL :: every,back55! calculates the result string by the following actions:56! searches for occurences of target in string, and replaces these with57! substring. if back present with value true search is backward otherwise58! search is done forward. if every present with value true all accurences59! of target in string are replaced, otherwise only the first found is60! replaced. if target is not found the result is the same as string.61LOGICAL :: dir_switch, rep_search62CHARACTER,DIMENSION(:),POINTER :: work,temp63INTEGER :: ls,lt,lsub,ipos,ipow64ls = LEN(string); lt = LEN(target); lsub = LEN(substring)65IF(lt==0)THEN66
WRITE(*,*) " Zero length target in REPLACE"67STOP68
ENDIF69ALLOCATE(work(1:ls))70DO i=1,ls71
53
ISO/IEC 1539-2 : 1993 (E) CD version 2
work(i) = string(i:i)1ENDDO2IF( PRESENT(back) )THEN3
dir_switch = back4ELSE5
dir_switch = .FALSE.6ENDIF7IF( PRESENT(every) )THEN8
rep_search = every9ELSE10
rep_search = .FALSE.11ENDIF12IF( dir_switch )THEN ! backwards search13
ipos = ls-lt+114DO15
IF( ipos < 1 )EXIT ! search past start of string16! test for occurance of target in string at this position17IF( string(ipos:ipos+lt-1) == target )THEN18! match found allocate space for string with this occurance of19! target replaced by substring20ALLOCATE(temp(1:SIZE(work)+lsub-lt))21! copy work into temp replacing this occurance of target by22! substring23temp(1:ipos-1) = work(1:ipos-1)24DO i=1,lsub25
temp(i+ipos-1) = substring(i:i)26ENDDO27temp(ipos+lsub:) = work(ipos+lt:)28work => temp ! make new version of work point at the temp space29IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted30! move search and replacement positions over the effected positions31ipos = ipos-lt+132
ENDIF33ipos=ipos-134
ENDDO35ELSE ! forward search36
ipos = 1; ipow = 137DO38
IF( ipos > ls-lt+1 )EXIT ! search past end of string39! test for occurance of target in string at this position40IF( string(ipos:ipos+lt-1) == target )THEN41! match found allocate space for string with this occurance of42! target replaced by substring43ALLOCATE(temp(1:SIZE(work)+lsub-lt))44! copy work into temp replacing this occurance of target by45! substring46temp(1:ipow-1) = work(1:ipow-1)47DO i=1,lsub48
temp(i+ipow-1) = substring(i:i)49ENDDO50temp(ipow+lsub:) = work(ipow+lt:)51work => temp ! make new version of work point at the temp space52IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted53! move search and replacement positions over the effected positions54ipos = ipos+lt-1; ipow = ipow+lsub-155
ENDIF56ipos=ipos+1; ipow=ipow+157
ENDDO58ENDIF59replace_ccc%chars => work60
ENDFUNCTION replace_ccc61
!----- Remove procedures ----------------------------------------------------!62FUNCTION remove_s(string,start,finish)63type(VARYING_STRING) :: remove_s64type(VARYING_STRING),INTENT(IN) :: string65INTEGER,INTENT(IN),OPTIONAL :: start66INTEGER,INTENT(IN),OPTIONAL :: finish67! returns as result the string produced by the actions68! removes the characters between start and finish from string reducing it in69! size by MAX(0,ABS(finish-start+1))70! if start < 1 or is missing then assumes start=171
54
CD version 2 ISO/IEC 1539-2 : 1993 (E)
! if finish > LEN(string) or is missing then assumes finish=LEN(string)1CHARACTER,DIMENSION(:),POINTER :: arg_str2INTEGER :: is,if,ls3ls = LEN(string)4IF (PRESENT(start)) THEN5
is = MAX(1,start)6ELSE7
is = 18ENDIF9IF (PRESENT(finish)) THEN10
if = MIN(ls,finish)11ELSE12
if = ls13ENDIF14IF( if < is ) THEN ! zero characters to be removed, string is unchanged15
ALLOCATE(arg_str(1:ls))16arg_str = string%chars17
ELSE18ALLOCATE(arg_str(1:ls-if+is-1) )19arg_str(1:is-1) = string%chars(1:is-1)20arg_str(is:) = string%chars(if+1:)21
ENDIF22remove_s%chars => arg_str23
ENDFUNCTION remove_s2425
FUNCTION remove_c(string,start,finish)26type(VARYING_STRING) :: remove_c27CHARACTER(LEN=*),INTENT(IN) :: string28INTEGER,INTENT(IN),OPTIONAL :: start29INTEGER,INTENT(IN),OPTIONAL :: finish30! returns as result the string produced by the actions31! removes the characters between start and finish from string reducing it in32! size by MAX(0,ABS(finish-start+1))33! if start < 1 or is missing then assumes start=134! if finish > LEN(string) or is missing then assumes finish=LEN(string)35CHARACTER,DIMENSION(:),POINTER :: arg_str36INTEGER :: is,if,ls37ls = LEN(string)38IF (PRESENT(start)) THEN39
is = MAX(1,start)40ELSE41
is = 142ENDIF43IF (PRESENT(finish)) THEN44
if = MIN(ls,finish)45ELSE46
if = ls47ENDIF48IF( if < is ) THEN ! zero characters to be removed, string is unchanged49
ALLOCATE(arg_str(1:ls))50DO i=1,ls51
arg_str(i) = string(i:i)52ENDDO53
ELSE54ALLOCATE(arg_str(1:ls-if+is-1) )55DO i=1,is-156
arg_str(i) = string(i:i)57ENDDO58DO i=is,ls-if+is-159
arg_str(i) = string(i-is+if+1:i-is+if+1)60ENDDO61
ENDIF62remove_c%chars => arg_str63
ENDFUNCTION remove_c6465
!----- Extract procedures ---------------------------------------------------!66FUNCTION extract_s(string,start,finish)67type(VARYING_STRING),INTENT(IN) :: string68INTEGER,INTENT(IN),OPTIONAL :: start69INTEGER,INTENT(IN),OPTIONAL :: finish70type(VARYING_STRING) :: extract_s71! extracts the characters between start and finish from string and72
55
ISO/IEC 1539-2 : 1993 (E) CD version 2
! delivers these as the result of the function, string is unchanged1! if start < 1 or is missing then it is treated as 12! if finish > LEN(string) or is missing then it is treated as LEN(string)3INTEGER :: is,if4IF (PRESENT(start)) THEN5
is = MAX(1,start)6ELSE7
is = 18ENDIF9IF (PRESENT(finish)) THEN10
if = MIN(LEN(string),finish)11ELSE12
if = LEN(string)13ENDIF14ALLOCATE(extract_s%chars(1:if-is+1))15extract_s%chars = string%chars(is:if)16ENDFUNCTION extract_s17
18FUNCTION extract_c(string,start,finish)19CHARACTER(LEN=*),INTENT(IN) :: string20INTEGER,INTENT(IN),OPTIONAL :: start21INTEGER,INTENT(IN),OPTIONAL :: finish22type(VARYING_STRING) :: extract_c23! extracts the characters between start and finish from character string and24! delivers these as the result of the function, string is unchanged25! if start < 1 or is missing then it is treated as 126! if finish > LEN(string) or is missing then it is treated as LEN(string)27INTEGER :: is,if28IF (PRESENT(start)) THEN29
is = MAX(1,start)30ELSE31
is = 132ENDIF33IF (PRESENT(finish)) THEN34
if = MIN(LEN(string),finish)35ELSE36
if = LEN(string)37ENDIF38ALLOCATE(extract_c%chars(1:if-is+1))39DO i=is,if40
extract_c%chars(i-is+1) = string(i:i)41ENDDO42ENDFUNCTION extract_c43
!----- Split procedures ------------------------------------------------------!44SUBROUTINE split_s(string,word,set,separator,back)45type(VARYING_STRING),INTENT(INOUT) :: string46type(VARYING_STRING),INTENT(OUT) :: word47type(VARYING_STRING),INTENT(IN) :: set48type(VARYING_STRING),INTENT(OUT),OPTIONAL :: separator49LOGICAL,INTENT(IN),OPTIONAL :: back50! splits the input string at the first(last) character in set51! returns the leading(trailing) substring in word and the trailing(leading)52! substring in string. The search is done in the forward or backward53! direction depending on back. If separator is present, the actual separator54! character found is returned in separator.55! If no character in set is found string and separator are returned as56! zero length and the whole input string is returned in word.57LOGICAL :: dir_switch58INTEGER :: ls,tpos59ls = LEN(string)60IF( PRESENT(back) )THEN61
dir_switch = back62ELSE63
dir_switch = .FALSE.64ENDIF65IF(dir_switch)THEN ! backwards search66
DO tpos = ls,1,-167IF(ANY(string%chars(tpos) == set%chars))EXIT68
ENDDO69word%chars => string%chars(tpos+1:ls)70IF(PRESENT(separator))THEN71
56
CD version 2 ISO/IEC 1539-2 : 1993 (E)
IF(tpos==0)THEN1separator = ""2
ELSE3separator%chars => string%chars(tpos:tpos)4
ENDIF5ENDIF6string%chars => string%chars(1:tpos-1)7
ELSE ! forwards search8DO tpos =1,ls9
IF(ANY(string%chars(tpos) == set%chars))EXIT10ENDDO11word%chars => string%chars(1:tpos-1)12IF(PRESENT(separator))THEN13IF(tpos==ls+1)THEN14
separator = ""15ELSE16
separator%chars => string%chars(tpos:tpos)17ENDIF18
ENDIF19string%chars => string%chars(tpos+1:ls)20
ENDIF21ENDSUBROUTINE split_s22
SUBROUTINE split_c(string,word,set,separator,back)23type(VARYING_STRING),INTENT(INOUT) :: string24type(VARYING_STRING),INTENT(OUT) :: word25CHARACTER(LEN=*),INTENT(IN) :: set26type(VARYING_STRING),INTENT(OUT),OPTIONAL :: separator27LOGICAL,INTENT(IN),OPTIONAL :: back28! splits the input string at the first(last) character in set29! returns the leading(trailing) substring in word and the trailing(leading)30! substring in string. The search is done in the forward or backward31! direction depending on back. If separator is present, the actual separator32! character found is returned in separator.33! If no character in set is found string and separator are returned as34! zero length and the whole input string is returned in word.35LOGICAL :: dir_switch36INTEGER :: ls,tpos,lset37ls = LEN(string); lset = LEN(set)38IF( PRESENT(back) )THEN39
dir_switch = back40ELSE41
dir_switch = .FALSE.42ENDIF43IF(dir_switch)THEN ! backwards search44
BSEARCH:DO tpos = ls,1,-145DO i=1,lset46
IF(string%chars(tpos) == set(i:i))EXIT BSEARCH47ENDDO48
ENDDO BSEARCH49word%chars => string%chars(tpos+1:ls)50IF(PRESENT(separator))THEN51IF(tpos==0)THEN52
separator = ""53ELSE54
separator%chars => string%chars(tpos:tpos)55ENDIF56
ENDIF57string%chars => string%chars(1:tpos-1)58
ELSE ! forwards search59FSEARCH:DO tpos =1,ls60
DO i=1,lset61IF(string%chars(tpos) == set(i:i))EXIT FSEARCH62
ENDDO63ENDDO FSEARCH64word%chars => string%chars(1:tpos-1)65IF(PRESENT(separator))THEN66IF(tpos==ls+1)THEN67
separator = ""68ELSE69
separator%chars => string%chars(tpos:tpos)70ENDIF71
57
ISO/IEC 1539-2 : 1993 (E) CD version 2
ENDIF1string%chars => string%chars(tpos+1:ls)2
ENDIF3ENDSUBROUTINE split_c4
!----- INDEX procedures ------------------------------------------------------!5FUNCTION index_ss(string,substring,back)6type(VARYING_STRING),INTENT(IN) :: string,substring7LOGICAL,INTENT(IN),OPTIONAL :: back8INTEGER :: index_ss9! returns the starting position in string of the substring10! scanning from the front or back depending on the logical argument back11LOGICAL :: dir_switch12INTEGER :: ls,lsub13ls = LEN(string); lsub = LEN(substring)14IF( PRESENT(back) )THEN15
dir_switch = back16ELSE17
dir_switch = .FALSE.18ENDIF19IF(dir_switch)THEN ! backwards search20
DO i = ls-lsub+1,1,-121IF( ALL(string%chars(i:i+lsub-1) == substring%chars) )THEN22
index_ss = i23RETURN24
ENDIF25ENDDO26index_ss = 027
ELSE ! forward search28DO i = 1,ls-lsub+129IF( ALL(string%chars(i:i+lsub-1) == substring%chars) )THEN30
index_ss = i31RETURN32
ENDIF33ENDDO34index_ss = 035
ENDIF36ENDFUNCTION index_ss37
38FUNCTION index_sc(string,substring,back)39type(VARYING_STRING),INTENT(IN) :: string40CHARACTER(LEN=*),INTENT(IN) :: substring41LOGICAL,INTENT(IN),OPTIONAL :: back42INTEGER :: index_sc43! returns the starting position in string of the substring44! scanning from the front or back depending on the logical argument back45LOGICAL :: dir_switch,matched46INTEGER :: ls,lsub47ls = LEN(string); lsub = LEN(substring)48IF( PRESENT(back) )THEN49
dir_switch = back50ELSE51
dir_switch = .FALSE.52ENDIF53IF (dir_switch) THEN ! backwards search54
DO i = ls-lsub+1,1,-155matched = .TRUE.56DO j = 1,lsub57
IF( string%chars(i+j-1) /= substring(j:j) )THEN58matched = .FALSE.59EXIT60
ENDIF61ENDDO62IF( matched )THEN63
index_sc = i64RETURN65
ENDIF66ENDDO67index_sc = 068
ELSE ! forward search69DO i = 1,ls-lsub+170matched = .TRUE.71
58
CD version 2 ISO/IEC 1539-2 : 1993 (E)
DO j = 1,lsub1IF( string%chars(i+j-1) /= substring(j:j) )THEN2
matched = .FALSE.3EXIT4
ENDIF5ENDDO6IF( matched )THEN7index_sc = i8RETURN9
ENDIF10ENDDO11index_sc = 012
ENDIF13ENDFUNCTION index_sc14
15FUNCTION index_cs(string,substring,back)16CHARACTER(LEN=*),INTENT(IN) :: string17type(VARYING_STRING),INTENT(IN) :: substring18LOGICAL,INTENT(IN),OPTIONAL :: back19INTEGER :: index_cs20! returns the starting position in string of the substring21! scanning from the front or back depending on the logical argument back22LOGICAL :: dir_switch,matched23INTEGER :: ls,lsub24ls = LEN(string); lsub = LEN(substring)25IF( PRESENT(back) )THEN26
dir_switch = back27ELSE28
dir_switch = .FALSE.29ENDIF30IF(dir_switch)THEN ! backwards search31
DO i = ls-lsub+1,1,-132matched = .TRUE.33DO j = 1,lsub34
IF( string(i+j-1:i+j-1) /= substring%chars(j) )THEN35matched = .FALSE.36EXIT37
ENDIF38ENDDO39IF( matched )THEN40
index_cs = i41RETURN42
ENDIF43ENDDO44index_cs = 045
ELSE ! forward search46DO i = 1,ls-lsub+147matched = .TRUE.48DO j = 1,lsub49
IF( string(i+j-1:i+j-1) /= substring%chars(j) )THEN50matched = .FALSE.51EXIT52
ENDIF53ENDDO54IF( matched )THEN55
index_cs = i56RETURN57
ENDIF58ENDDO59index_cs = 060
ENDIF61ENDFUNCTION index_cs62
63!----- SCAN procedures ------------------------------------------------------!64FUNCTION scan_ss(string,set,back)65type(VARYING_STRING),INTENT(IN) :: string,set66LOGICAL,INTENT(IN),OPTIONAL :: back67INTEGER :: scan_ss68! returns the first position in string occupied by a character from69! the characters in set, scanning is forward or backwards depending on back70LOGICAL :: dir_switch71INTEGER :: ls72
59
ISO/IEC 1539-2 : 1993 (E) CD version 2
CHARACTER::tmp ! inserted to work round a temporary bug in F90 1.11ls = LEN(string)2IF( PRESENT(back) )THEN3
dir_switch = back4ELSE5
dir_switch = .FALSE.6ENDIF7IF(dir_switch)THEN ! backwards search8
DO i = ls,1,-19tmp=string%chars(i) ! bug work round10
IF( ANY( set%chars == tmp ) )THEN11scan_ss = i12RETURN13
ENDIF14ENDDO15scan_ss = 016
ELSE ! forward search17DO i = 1,ls18
tmp=string%chars(i) ! bug work round19IF( ANY( set%chars == tmp ) )THEN20
scan_ss = i21RETURN22
ENDIF23ENDDO24scan_ss = 025
ENDIF26ENDFUNCTION scan_ss27
28FUNCTION scan_sc(string,set,back)29type(VARYING_STRING),INTENT(IN) :: string30CHARACTER(LEN=*),INTENT(IN) :: set31LOGICAL,INTENT(IN),OPTIONAL :: back32INTEGER :: scan_sc33! returns the first position in string occupied by a character from34! the characters in set, scanning is forward or backwards depending on back35LOGICAL :: dir_switch,matched36INTEGER :: ls37ls = LEN(string)38IF( PRESENT(back) )THEN39
dir_switch = back40ELSE41
dir_switch = .FALSE.42ENDIF43IF(dir_switch)THEN ! backwards search44
DO i = ls,1,-145matched = .FALSE.46DO j = 1,LEN(set)47
IF( string%chars(i) == set(j:j) )THEN48matched = .TRUE.49EXIT50
ENDIF51ENDDO52IF( matched )THEN53
scan_sc = i54RETURN55
ENDIF56ENDDO57scan_sc = 058
ELSE ! forward search59DO i = 1,ls60matched = .FALSE.61DO j = 1,LEN(set)62
IF( string%chars(i) == set(j:j) )THEN63matched = .TRUE.64EXIT65
ENDIF66ENDDO67IF( matched )THEN68
scan_sc = i69RETURN70
ENDIF71ENDDO72
60
CD version 2 ISO/IEC 1539-2 : 1993 (E)
scan_sc = 01ENDIF2
ENDFUNCTION scan_sc34
FUNCTION scan_cs(string,set,back)5CHARACTER(LEN=*),INTENT(IN) :: string6type(VARYING_STRING),INTENT(IN) :: set7LOGICAL,INTENT(IN),OPTIONAL :: back8INTEGER :: scan_cs9! returns the first position in character string occupied by a character from10! the characters in set, scanning is forward or backwards depending on back11LOGICAL :: dir_switch,matched12INTEGER :: ls13ls = LEN(string)14IF( PRESENT(back) )THEN15
dir_switch = back16ELSE17
dir_switch = .FALSE.18ENDIF19IF(dir_switch)THEN ! backwards search20
DO i = ls,1,-121matched = .FALSE.22DO j = 1,LEN(set)23
IF( string(i:i) == set%chars(j) )THEN24matched = .TRUE.25EXIT26
ENDIF27ENDDO28IF( matched )THEN29
scan_cs = i30RETURN31
ENDIF32ENDDO33scan_cs = 034
ELSE ! forward search35DO i = 1,ls36matched = .FALSE.37DO j = 1,LEN(set)38
IF( string(i:i) == set%chars(j) )THEN39matched = .TRUE.40EXIT41
ENDIF42ENDDO43IF( matched )THEN44
scan_cs = i45RETURN46
ENDIF47ENDDO48scan_cs = 049
ENDIF50ENDFUNCTION scan_cs51
52!----- VERIFY procedures ----------------------------------------------------!53FUNCTION verify_ss(string,set,back)54type(VARYING_STRING),INTENT(IN) :: string,set55LOGICAL,INTENT(IN),OPTIONAL :: back56INTEGER :: verify_ss57! returns the first position in string not occupied by a character from58! the characters in set, scanning is forward or backwards depending on back59LOGICAL :: dir_switch60INTEGER :: ls61
CHARACTER::tmp ! F90 1.1 bug work round62ls = LEN(string)63IF( PRESENT(back) )THEN64
dir_switch = back65ELSE66
dir_switch = .FALSE.67ENDIF68IF(dir_switch)THEN ! backwards search69
DO i = ls,1,-170tmp=string%chars(i) ! bug work round71
IF( .NOT.(ANY( set%chars == tmp )) )THEN72
61
ISO/IEC 1539-2 : 1993 (E) CD version 2
verify_ss = i1RETURN2
ENDIF3ENDDO4verify_ss = 05
ELSE ! forward search6DO i = 1,ls7
tmp=string%chars(i) ! bug work round8IF( .NOT.(ANY( set%chars == tmp )) )THEN9verify_ss = i10RETURN11
ENDIF12ENDDO13verify_ss = 014
ENDIF15ENDFUNCTION verify_ss16
17FUNCTION verify_sc(string,set,back)18type(VARYING_STRING),INTENT(IN) :: string19CHARACTER(LEN=*),INTENT(IN) :: set20LOGICAL,INTENT(IN),OPTIONAL :: back21INTEGER :: verify_sc22! returns the first position in string not occupied by a character from23! the characters in set, scanning is forward or backwards depending on back24LOGICAL :: dir_switch25INTEGER :: ls26ls = LEN(string)27IF( PRESENT(back) )THEN28
dir_switch = back29ELSE30
dir_switch = .FALSE.31ENDIF32IF(dir_switch)THEN ! backwards search33
back_string_search:DO i = ls,1,-134DO j = 1,LEN(set)35
IF( string%chars(i) == set(j:j) )CYCLE back_string_search36! cycle string search if string character found in set37
ENDDO38! string character not found in set index i is result39
verify_sc = i40RETURN41
ENDDO back_string_search42! each string character found in set43verify_sc = 044
ELSE ! forward search45frwd_string_search:DO i = 1,ls46DO j = 1,LEN(set)47
IF( string%chars(i) == set(j:j) )CYCLE frwd_string_search48ENDDO49
verify_sc = i50RETURN51
ENDDO frwd_string_search52verify_sc = 053
ENDIF54ENDFUNCTION verify_sc55
56FUNCTION verify_cs(string,set,back)57CHARACTER(LEN=*),INTENT(IN) :: string58type(VARYING_STRING),INTENT(IN) :: set59LOGICAL,INTENT(IN),OPTIONAL :: back60INTEGER :: verify_cs61! returns the first position in icharacter string not occupied by a character62! from the characters in set, scanning is forward or backwards depending on63! back64LOGICAL :: dir_switch65INTEGER :: ls66ls = LEN(string)67IF( PRESENT(back) )THEN68
dir_switch = back69ELSE70
dir_switch = .FALSE.71ENDIF72
62
CD version 2 ISO/IEC 1539-2 : 1993 (E)
IF(dir_switch)THEN ! backwards search1back_string_search:DO i = ls,1,-12
DO j = 1,LEN(set)3IF( string(i:i) == set%chars(j) )CYCLE back_string_search4
ENDDO5verify_cs = i6RETURN7
ENDDO back_string_search8verify_cs = 09
ELSE ! forward search10frwd_string_search:DO i = 1,ls11DO j = 1,LEN(set)12
IF( string(i:i) == set%chars(j) )CYCLE frwd_string_search13ENDDO14
verify_cs = i15RETURN16
ENDDO frwd_string_search17verify_cs = 018
ENDIF19ENDFUNCTION verify_cs20
21!----- LEN_TRIM procedure ----------------------------------------------------!22FUNCTION len_trim_s(string)23type(VARYING_STRING),INTENT(IN) :: string24INTEGER :: len_trim_s25! Returns the length of the string without counting trailing blanks26INTEGER :: ls27ls=LEN(string)28len_trim_s = 029DO i = ls,1,-130
IF (string%chars(i) /= BLANK) THEN31len_trim_s = i32EXIT33
ENDIF34ENDDO35
ENDFUNCTION len_trim_s3637
!----- TRIM procedure -------------------------------------------------------!38FUNCTION trim_s(string)39type(VARYING_STRING),INTENT(IN) :: string40type(VARYING_STRING) :: trim_s41! Returns the argument string with trailing blanks removed42INTEGER :: ls,pos43ls=LEN(string)44pos=045DO i = ls,1,-146
IF(string%chars(i) /= BLANK) THEN47pos=i48EXIT49
ENDIF50ENDDO51ALLOCATE(trim_s%chars(1:pos))52trim_s%chars(1:pos) = string%chars(1:pos)53
ENDFUNCTION trim_s5455
!----- IACHAR interface -----------------------------------------------------!56FUNCTION iachar_s(string)57type(VARYING_STRING),INTENT(IN) :: string58INTEGER :: iachar_s59! returns the position of the character string in the ISO 64660! collating sequence.61! string must be of length one62IF (LEN(string) /= 1) THEN63
WRITE(*,*) " ERROR, argument in IACHAR not of length one"64STOP65
ENDIF66iachar_s = IACHAR(string%chars(1))67
ENDFUNCTION iachar_s68
!----- ICHAR procedure ------------------------------------------------------!69FUNCTION ichar_s(string)70type(VARYING_STRING),INTENT(IN) :: string71
63
ISO/IEC 1539-2 : 1993 (E) CD version 2
INTEGER :: ichar_s1! returns the position of character from string in the processor collating2! sequence.3! string must be of length one4IF (LEN(string) /= 1) THEN5
WRITE(*,*) " Argument string in ICHAR has to be of length one"6STOP7
ENDIF8ichar_s = ICHAR(string%chars(1))9ENDFUNCTION ichar_s10
11!----- ADJUSTL procedure ----------------------------------------------------!12FUNCTION adjustl_s(string)13type(VARYING_STRING),INTENT(IN) :: string14type(VARYING_STRING) :: adjustl_s15! Returns the string adjusted to the left, removing leading blanks and16! inserting trailing blanks17INTEGER :: ls,pos18ls=LEN(string)19DO pos = 1,ls20
IF(string%chars(pos) /= blank) EXIT21ENDDO22! pos now holds the position of the first non-blank character23! or ls+1 if all characters are blank24ALLOCATE(adjustl_s%chars(1:ls))25adjustl_s%chars(1:ls-pos+1) = string%chars(pos:ls)26adjustl_s%chars(ls-pos+2:ls) = blank27
ENDFUNCTION adjustl_s2829
!----- ADJUSTR procedure ----------------------------------------------------!30FUNCTION adjustr_s(string)31type(VARYING_STRING),INTENT(IN) :: string32type(VARYING_STRING) :: adjustr_s33! Returns the string adjusted to the right, removing trailing blanks34! and inserting leading blanks35INTEGER :: ls,pos36ls=LEN(string)37DO pos = ls,1,-138
IF(string%chars(pos) /= blank) EXIT39ENDDO40! pos now holds the position of the last non-blank character41! or zero if all characters are blank42ALLOCATE(adjustr_s%chars(1:ls))43adjustr_s%chars(ls-pos+1:ls) = string%chars(1:pos)44adjustr_s%chars(1:ls-pos) = blank45
ENDFUNCTION adjustr_s4647
ENDMODULE ISO_VARYING_STRING48
64
CD version 2 ISO/IEC 1539-2 : 1993 (E)
Annex B1
(Informative)2
This annex includes some examples illustrating the use of facilities conformant with this International3Standard. It should be noted that while every care has been taken by the technical working group to4ensure that these example programs are a correct implementation of the stated problems using this5International Standard and in valid Fortran code, no guarantee is given or implied that this code will6produce correct results, or even that it will execute on any particular processor.7
PROGRAM word_count8!-----------------------------------------------------------------------------!9! Counts the number of "words" contained in a file. The words are assumed to !10! be terminated by any one of: !11! space,comma,period,!,?, or the EoR !12! The file may have records of any length and the file may contain any number !13! of records. !14! The program prompts for the name of the file to be subject to a word count !15! and the result is written to the default output unit !16!-----------------------------------------------------------------------------!17USE ISO_VARYING_STRING18type(VARYING_STRING) :: line,fname19INTEGER :: ierr,nd,wcount=020WRITE(*,ADVANCE=’NO’,FMT=’(A)’) " Input name of file?"21CALL GET(STRING=fname) ! read the required filename from the default22
! input unit assumed to be the whole of the record read23OPEN(UNIT=1,FILE=CHAR(fname)) ! CHAR(fname) converts to the type24
! required by FILE= specifier25file_read: DO ! until EoF reached26
CALL GET(1,line,IOSTAT=ierr) ! read next line of file27IF(ierr == -1)EXIT file_read28word_scan: DO ! until end of line29
nd=SCAN(line," ,.!?") ! scan to find end of word30IF(nd == 0)THEN ! EoR is end of word31nd = LEN(line)32EXIT word_scan33
ENDIF34IF(nd > 1) wcount=wcount+1 ! at least one non-terminator character35
! in the word36line = REMOVE(line,1,nd) ! strips the counted word and its terminator37
! from the line reducing its length before38! rescanning for the next word39
ENDDO word_scan40IF(nd > 0) wcount=wcount+141
ENDDO file_read42IF(ierr < 0)THEN43
WRITE(*,*) "No. of words in file =",wcount44ELSEIF(ierr > 0)THEN45
WRITE(*,*) "Error in GET file in word_count, No. ",ierr46ENDIF47ENDPROGRAM word_count48
Note, it is not claimed that the above program is the best way to code this problem, nor even that it49is a good way, merely that it is a way of solving this simple problem using the facilities defined by50this International Standard.51
A second and rather more realistic example is one which extends the above trivial example by52producing a full vocabulary list along with frequency of occurrence for each different word.53
PROGRAM vocabulary_word_count54!-----------------------------------------------------------------------------!55! Counts the number of "words" contained in a file. The words are assumed to !56! be terminated by any one of: !57
65
ISO/IEC 1539-2 : 1993 (E) CD version 2
! space,comma,period,!,?, or the EoR !1! The file may have records of any length and the file may contain any number !2! of records. !3! The program prompts for the name of the file to be subject to a word count !4! and the result is written to the default output unit !5! Also builds a list of the vocabulary found and the frequency of occurance !6! of each different word. !7!-----------------------------------------------------------------------------!8USE ISO_VARYING_STRING9type(VARYING_STRING) :: line,word,fname10INTEGER :: ierr,nd,wcount=011!-----------------------------------------------------------------------------!12! Vocabulary list and frequency count arrays. The size of these arrays will !13! be extended dynamically in steps of 100 as the used vocabulary grows !14!-----------------------------------------------------------------------------!15type(VARYING_STRING),ALLOCATABLE,DIMENSION(:) :: vocab16INTEGER,ALLOCATABLE,DIMENSION(:) :: freq17INTEGER :: list_size=100,list_top=018!-----------------------------------------------------------------------------!19! Initialise the lists and determine the file to be processed !20!-----------------------------------------------------------------------------!21ALLOCATE(vocab(1:list_size),freq(1:list_size))22WRITE(*,ADVANCE=’NO’,FMT=’(A)’) " Input name of file?"23CALL GET(STRING=fname) ! read the required filename from the default24
! input unit assumed to be the whole of the record read25OPEN(UNIT=1,FILE=CHAR(fname)) ! CHAR(fname) converts to the type26
! required by FILE= specifier27file_read: DO ! until EoF reached28
CALL GET(1,line,IOSTAT=ierr) ! read next line of file29IF(ierr == -1)EXIT file_read30word_scan: DO ! until end of line31
nd=SCAN(line," ,.!?") ! scan to find end of word32IF(nd == 0)THEN ! EoR is end of word33nd = LEN(line)34EXIT word_scan35
ENDIF36IF(nd > 1)THEN ! at least one non-terminator character in the word37
wcount=wcount+138word = EXTRACT(line,1,nd-1)39CALL update_vocab_lists40
ENDIF41line = REMOVE(line,1,nd) ! strips the counted word and its terminator42
! from the line reducing its length before43! rescanning for the next word44
ENDDO word_scan45IF(nd > 0)THEN ! at least one character in the word46
wcount=wcount+147word = EXTRACT(line,1,nd-1)48CALL update_vocab_lists49
ENDIF50ENDDO file_read51IF(ierr < 0)THEN52
WRITE(*,*) "No. of words in file =",wcount53WRITE(*,*) "There are ",list_top," distinct words"54WRITE(*,*) "with the following frequencies of occurance"55print_loop: DO i=1,list_top56
WRITE(*,FMT=’(1X,I6,2X)’,ADVANCE=’NO’) freq(i)57CALL PUT_LINE(STRING=vocab(i))58
ENDDO print_loop59ELSEIF(ierr > 0)THEN60
WRITE(*,*) "Error in GET in vocabulary_word_count, No.",ierr61ENDIF62
CONTAINS63
SUBROUTINE extend_lists64!-----------------------------------------------------------------------------!65! Accesses the host variables: !66! type(VARYING_STRING),ALLOCATABLE,DIMENSION(:) :: vocab !67! INTEGER,ALLOCATABLE,DIMENSION(:) :: freq !68! INTEGER :: list_size !69! so as to extend the size of the lists preserving the existing vocabulary !70
66
CD version 2 ISO/IEC 1539-2 : 1993 (E)
! and frequency information in the new extended lists !1!-----------------------------------------------------------------------------!2type(VARYING_STRING),DIMENSION(list_size) :: vocab_swap3INTEGER,DIMENSION(list_size) :: freq_swap4INTEGER,PARAMETER :: list_increment=1005INTEGER :: new_list_size,alerr6vocab_swap = vocab ! copy old list into temporary space7freq_swap =freq8new_list_size = list_size + list_increment9DEALLOCATE(vocab,freq)10ALLOCATE(vocab(1:new_list_size),freq(1:new_list_size),STAT=alerr)11IF(alerr /= 0)THEN12
WRITE(*,*) "Unable to extend vocabulary list"13STOP14
ENDIF15vocab(1:list_size) = vocab_swap ! copy old list back into bottom16freq(1:list_size) = freq_swap ! of new extended list17list_size = new_list_size18ENDSUBROUTINE extend_lists19
SUBROUTINE update_vocab_lists20!-----------------------------------------------------------------------------!21! Accesses the host variables: !22! type(VARYING_STRING),ALLOCATABLE,DIMENSION(:) :: vocab !23! INTEGER,ALLOCATABLE,DIMENSION(:) :: freq !24! INTEGER :: list_size,list_top !25! type(VARYING_STRING) :: word !26! searches the existing words in vocab to find a match for word !27! if found increments the freq if not found adds word to !28! list_top + 1 vocab list and sets corresponding freq to 1 !29! if list_size exceeded extend the list size before updating !30!-----------------------------------------------------------------------------!31list_search: DO i=1,list_top32
IF(word == vocab(i))THEN33freq(i) = freq(i) + 134RETURN35
ENDIF36ENDDO list_search37IF(list_top == list_size)THEN38
CALL extend_lists39ENDIF40list_top = list_top + 141vocab(list_top) = word42freq(list_top) = 143ENDSUBROUTINE update_vocab_lists44
ENDPROGRAM vocabulary_word_count45
67