22
22
! ! - [[GLOB]] function compares text strings, one of which can have wildcards ('*' or '?').
23
23
! ! - [[IS_FORTRAN_NAME]] determine whether a string is an acceptable Fortran entity name
24
24
! ! - [[TO_FORTRAN_NAME]] replace allowed special but unusuable characters in names with underscore
25
- ! !### Miscellaneous
25
+ ! !### Whitespace
26
+ ! ! - [[NOTABS]] Expand tab characters assuming a tab space every eight characters
26
27
! ! - [[LEN_TRIM]] Determine total trimmed length of **STRING_T** array
28
+ ! !### Miscellaneous
27
29
! ! - [[FNV_1A]] Hash a **CHARACTER(*)** string of default kind or a **TYPE(STRING_T)** array
28
30
! ! - [[REPLACE]] Returns string with characters in charset replaced with target_char.
29
31
! ! - [[RESIZE]] increase the size of a **TYPE(STRING_T)** array by N elements
30
32
! !
31
-
32
33
module fpm_strings
33
34
use iso_fortran_env, only: int64
35
+ use ,intrinsic :: iso_fortran_env, only : stdin= >input_unit, &
36
+ & stdout= >output_unit, &
37
+ & stderr= >error_unit
34
38
use iso_c_binding, only: c_char, c_ptr, c_int, c_null_char, c_associated, c_f_pointer, c_size_t
35
39
implicit none
36
40
@@ -39,6 +43,7 @@ module fpm_strings
39
43
public :: to_fortran_name, is_fortran_name
40
44
public :: string_array_contains, string_cat, len_trim, operator (.in .), fnv_1a
41
45
public :: replace, resize, str, join, glob
46
+ public :: notabs
42
47
43
48
type string_t
44
49
character (len= :), allocatable :: s
@@ -986,5 +991,112 @@ function is_fortran_name(line) result (lout)
986
991
lout = .false.
987
992
endif
988
993
end function is_fortran_name
994
+ ! >
995
+ ! !### NAME
996
+ ! ! notabs(3f) - [fpm_strings:NONALPHA] expand tab characters
997
+ ! ! (LICENSE:PD)
998
+ ! !
999
+ ! !### SYNOPSIS
1000
+ ! !
1001
+ ! ! subroutine notabs(INSTR,OUTSTR,ILEN)
1002
+ ! !
1003
+ ! ! character(len=*),intent=(in) :: INSTR
1004
+ ! ! character(len=*),intent=(out) :: OUTSTR
1005
+ ! ! integer,intent=(out) :: ILEN
1006
+ ! !
1007
+ ! !### DESCRIPTION
1008
+ ! ! NOTABS() converts tabs in INSTR to spaces in OUTSTR while maintaining
1009
+ ! ! columns. It assumes a tab is set every 8 characters. Trailing spaces
1010
+ ! ! are removed.
1011
+ ! !
1012
+ ! ! In addition, trailing carriage returns and line feeds are removed
1013
+ ! ! (they are usually a problem created by going to and from MSWindows).
1014
+ ! !
1015
+ ! ! What are some reasons for removing tab characters from an input line?
1016
+ ! ! Some Fortran compilers have problems with tabs, as tabs are not
1017
+ ! ! part of the Fortran character set. Some editors and printers will
1018
+ ! ! have problems with tabs. It is often useful to expand tabs in input
1019
+ ! ! files to simplify further processing such as tokenizing an input line.
1020
+ ! !
1021
+ ! !### OPTIONS
1022
+ ! ! instr Input line to remove tabs from
1023
+ ! !
1024
+ ! !### RESULTS
1025
+ ! ! outstr Output string with tabs expanded. Assumed to be of sufficient
1026
+ ! ! length
1027
+ ! ! ilen Significant length of returned string
1028
+ ! !
1029
+ ! !### EXAMPLES
1030
+ ! !
1031
+ ! ! Sample program:
1032
+ ! !
1033
+ ! ! program demo_notabs
1034
+ ! !
1035
+ ! ! ! test filter to remove tabs and trailing white space from input
1036
+ ! ! ! on files up to 1024 characters wide
1037
+ ! ! use fpm_strings, only : notabs
1038
+ ! ! character(len=1024) :: in,out
1039
+ ! ! integer :: ios,iout
1040
+ ! ! do
1041
+ ! ! read(*,'(A)',iostat=ios)in
1042
+ ! ! if(ios /= 0) exit
1043
+ ! ! call notabs(in,out,iout)
1044
+ ! ! write(*,'(a)')out(:iout)
1045
+ ! ! enddo
1046
+ ! ! end program demo_notabs
1047
+ ! !
1048
+ ! !### SEE ALSO
1049
+ ! ! GNU/Unix commands expand(1) and unexpand(1)
1050
+ ! !
1051
+ ! !### AUTHOR
1052
+ ! ! John S. Urban
1053
+ ! !
1054
+ ! !### LICENSE
1055
+ ! ! Public Domain
1056
+ elemental impure subroutine notabs(instr,outstr,ilen)
1057
+
1058
+ ! ident_31="@(#)fpm_strings::notabs(3f): convert tabs to spaces while maintaining columns, remove CRLF chars"
1059
+
1060
+ character (len=* ),intent (in ) :: instr ! input line to scan for tab characters
1061
+ character (len=* ),intent (out ) :: outstr ! tab-expanded version of INSTR produced
1062
+ integer ,intent (out ) :: ilen ! column position of last character put into output string
1063
+ ! that is, ILEN holds the position of the last non-blank character in OUTSTR
1064
+
1065
+ integer ,parameter :: tabsize= 8 ! assume a tab stop is set every 8th column
1066
+ integer :: ipos ! position in OUTSTR to put next character of INSTR
1067
+ integer :: lenin ! length of input string trimmed of trailing spaces
1068
+ integer :: lenout ! number of characters output string can hold
1069
+ integer :: istep ! counter that advances thru input string INSTR one character at a time
1070
+ character (len= 1 ) :: c ! character in input line being processed
1071
+ integer :: iade ! ADE (ASCII Decimal Equivalent) of character being tested
1072
+
1073
+ ipos= 1 ! where to put next character in output string OUTSTR
1074
+ lenin= len_trim (instr( 1 :len (instr) )) ! length of INSTR trimmed of trailing spaces
1075
+ lenout= len (outstr) ! number of characters output string OUTSTR can hold
1076
+ outstr= " " ! this SHOULD blank-fill string, a buggy machine required a loop to set all characters
1077
+
1078
+ SCAN_LINE: do istep= 1 ,lenin ! look through input string one character at a time
1079
+ c= instr(istep:istep) ! get next character
1080
+ iade= ichar (c) ! get ADE of the character
1081
+ EXPAND_TABS : select case (iade) ! take different actions depending on which character was found
1082
+ case (9 ) ! test if character is a tab and move pointer out to appropriate column
1083
+ ipos = ipos + (tabsize - (mod (ipos-1 ,tabsize)))
1084
+ case (10 ,13 ) ! convert carriage-return and new-line to space ,typically to handle DOS-format files
1085
+ ipos= ipos+1
1086
+ case default ! c is anything else other than a tab,newline,or return insert it in output string
1087
+ if (ipos > lenout)then
1088
+ write (stderr,* )" *notabs* output string overflow"
1089
+ exit
1090
+ else
1091
+ outstr(ipos:ipos)= c
1092
+ ipos= ipos+1
1093
+ endif
1094
+ end select EXPAND_TABS
1095
+ enddo SCAN_LINE
1096
+
1097
+ ipos= min (ipos,lenout) ! tabs or newline or return characters or last character might have gone too far
1098
+ ilen= len_trim (outstr(:ipos)) ! trim trailing spaces
1099
+
1100
+ end subroutine notabs
989
1101
990
1102
end module fpm_strings
0 commit comments