Clicky

Fortran Wiki
expand

Expanding C escape characters

I have seen a number of requests for something that expands C escape characters in strings, so I extracted this routine from the M_strings module …


NAME

expand - [M_strings] expand C-like escape sequences

SYNOPSIS

function expand(line,escape) result(lineout)

 character(len=*)                      :: line
 character(len=1),intent(in),optional  :: escape
 character(len=:),allocatable          :: lineout

DESCRIPTION

 EXPAND() expands sequences used to represent commonly used escape sequences
 or control characters. By default ...

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

 The default escape character is the backslash, but this may be changed using
 the optional parameter ESCAPE.

EXAMPLES

Sample Program:

 program demo_expand
 !  test filter to expand escape sequences in input lines
 use M_strings, only : expand
 character(len=1024) :: line
 integer             :: ios
    READFILE: block
       do
          read(*,'(A)',iostat=ios)line
          if(ios /= 0) exit READFILE
          write(*,'(a)')trim(expand(line))
       enddo
    endblock READFILE
 end program demo_expand

module M_strings
private
public expand
contains
function expand(line,escape) result(lineout)
USE ISO_C_BINDING ,ONLY: c_horizontal_tab
implicit none
character(len=*),parameter::ident="@(#)M_strings::expand(3f): return string with escape sequences expanded"
character(len=*)                      :: line
character(len=1),intent(in),optional  :: escape ! escape character. Default is backslash
! expand escape sequences found in input string
! Escape sequences
!    %%     escape character           %a     alert (BEL) -- gi is an alias for a
!    %b     backspace                  %c     suppress further output
!    %e     escape                     %E     escape
!    %f     form feed                  %n     new line
!    %r     carriage return            %t     horizontal tab
!    %v     vertical tab
!    %oNNN  byte with octal value NNN (3 digits)
!    %dNNN  byte with decimal value NNN (3 digits)
!    %xHH   byte with hexadecimal value HH (2 digits) -- h is an alias for x
   character(len=1)             :: esc    ! escape character. Default is %
   character(len=:),allocatable :: lineout
   integer                      :: i
   integer                      :: j
   integer                      :: ilen
   character(len=3)             :: thr
   integer                      :: xxx
   integer                      :: ios
   j=0 ! pointer into output
   i=0 ! pointer into input
   ilen=len_trim(line)
   lineout=''
   if (present(escape))then
      esc=escape
   else
      esc=char(92)
   endif
   EXP: do
      i=i+1
      if(line(i:i).eq.esc)then
         i=i+1
         j=j+1
         if(line(i:i).ne.esc)then
            BACKSLASH: select case(line(i:i))
            case('a','A','g','G');lineout=lineout//char(  7) ! %a     alert (BEL)
            case('b','B');lineout=lineout//char(  8)         ! %b     backspace
            case('c','C');exit EXP                           ! %c     suppress further output
            case('d','D')                                    ! %d     Dnnn decimal value
                      thr=line(i+1:)
                   read(thr,'(i3)',iostat=ios)xxx
                      lineout=lineout//char(xxx)
                   i=i+3
            case('e','E');lineout=lineout//char( 27)         ! %e     escape
            case('f','F');lineout=lineout//char( 12)         ! %f     form feed
            case('n','N');lineout=lineout//char( 10)         ! %n     new line
          !!case('n','N');lineout=lineout//new_line()        ! %n     new line
            case('o','O')
                      thr=line(i+1:)
                   read(thr,'(o3)',iostat=ios)xxx
                      lineout=lineout//char(xxx)
                   i=i+3
            case('r','R');lineout=lineout//char( 13)         ! %r     carriage return
            case('t','T');lineout=lineout//char(  9)         ! %t     horizontal tab
          !!case('t','T');lineout=lineout//c_horizontal_tab  ! %t     horizontal tab
            case('v','V');lineout=lineout//char( 11)         ! %v     vertical tab
            case('x','X','h','H')                            ! %x     xHH  byte with hexadecimal value HH (1 to 2 digits)
                      thr=line(i+1:)
                   read(thr,'(z2)',iostat=ios)xxx
                      lineout=lineout//char(xxx)
                   i=i+2
            end select BACKSLASH
         else
            lineout=lineout//esc                             ! escape character, defaults to backslash
         endif
      else
         j=j+1
         lineout=lineout//line(i:i)
      endif
      if(i.ge.ilen)exit EXP
   enddo EXP
end function expand
end module M_strings
!===================================================================================================================================
!()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()!
!===================================================================================================================================
program demo_expand
!  test filter to expand escape sequences in input lines
use M_strings, only : expand
character(len=1024) :: line
integer             :: ios
   READFILE: block
      do
         read(*,'(A)',iostat=ios)line
         if(ios /= 0) exit READFILE
         write(*,'(a)')trim(expand(line))
      enddo
   endblock READFILE
end program demo_expand

category: code