PartMC  2.2.0
spec_line.F90
Go to the documentation of this file.
00001 ! Copyright (C) 2007-2010 Nicole Riemer and Matthew West
00002 ! Licensed under the GNU General Public License version 2 or (at your
00003 ! option) any later version. See the file COPYING for details.
00004 
00005 !> \file
00006 !> The pmc_spec_line module.
00007 
00008 !> A single line of formatted test for input.
00009 module pmc_spec_line
00010 
00011   use pmc_util
00012   
00013   !> Maximum size of a single line.
00014   integer, parameter :: SPEC_LINE_MAX_LEN = 10000
00015   !> Maximum size of a variable.
00016   integer, parameter :: SPEC_LINE_MAX_VAR_LEN = 300
00017 
00018   !> A single line of input data, split at whitespace.
00019   !!
00020   !! Input lines are assumed to be in the format
00021   !! <pre>
00022   !! # stand-alone comment
00023   !! &lt;name&gt; &lt;whitespace&gt; &lt;data1&gt; &lt;whitespace&gt; &lt;data2&gt; ... # optional comment
00024   !! </pre>
00025   !! An spec_line_t structure stores the name and data split at
00026   !! whitespace.
00027   type spec_line_t
00028      !> Variable name.
00029      character(len=SPEC_LINE_MAX_VAR_LEN) :: name
00030      !> Array of data as strings.
00031      character(len=SPEC_LINE_MAX_VAR_LEN), pointer :: data(:)
00032   end type spec_line_t
00033 
00034 contains
00035 
00036 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00037 
00038   !> Allocates memory for a spec_line.
00039   subroutine spec_line_allocate(spec_line)
00040 
00041     !> Struct to alloc.
00042     type(spec_line_t), intent(out) :: spec_line
00043 
00044     allocate(spec_line%data(0))
00045 
00046   end subroutine spec_line_allocate
00047 
00048 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00049 
00050   !> Allocates memory for a spec_line of the given size.
00051   subroutine spec_line_allocate_size(spec_line, n_data)
00052 
00053     !> Struct to alloc.
00054     type(spec_line_t), intent(out) :: spec_line
00055     !> Number of data items.
00056     integer, intent(in) :: n_data
00057 
00058     allocate(spec_line%data(n_data))
00059 
00060   end subroutine spec_line_allocate_size
00061 
00062 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00063 
00064   !> Frees all storage.
00065   subroutine spec_line_deallocate(spec_line)
00066 
00067     !> Struct to free.
00068     type(spec_line_t), intent(inout) :: spec_line
00069 
00070     deallocate(spec_line%data)
00071 
00072   end subroutine spec_line_deallocate
00073 
00074 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00075 
00076   !> Copies a spec_line.
00077   subroutine spec_line_copy(from_spec_line, to_spec_line)
00078 
00079     !> Original spec_line.
00080     type(spec_line_t), intent(in) :: from_spec_line
00081     !> Destination, already alloced.
00082     type(spec_line_t), intent(inout) :: to_spec_line
00083 
00084     if (size(to_spec_line%data) /= size(from_spec_line%data)) then
00085        call spec_line_deallocate(to_spec_line)
00086        call spec_line_allocate_size(to_spec_line, &
00087             size(from_spec_line%data))
00088     end if
00089     to_spec_line%name = from_spec_line%name
00090     to_spec_line%data = from_spec_line%data
00091 
00092   end subroutine spec_line_copy
00093 
00094 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00095 
00096   !> Strip the comments from a string. Comments are everything after
00097   !> the first # character.
00098   subroutine spec_line_strip_comment(string)
00099     
00100     !> Complete input string.
00101     character(len=*), intent(inout) :: string
00102     
00103     integer :: hash_index
00104     
00105     hash_index = index(string, '#')
00106     if (hash_index > 0) then
00107        string = string(1:(hash_index - 1))
00108     end if
00109     
00110   end subroutine spec_line_strip_comment
00111   
00112 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00113 
00114   !> Expand all tabs in a string into single spaces (one tab makes one
00115   !> space).
00116   subroutine spec_line_tabs_to_spaces(string)
00117 
00118     !> Complete input string.
00119     character(len=*), intent(inout) :: string
00120 
00121     integer :: i
00122 
00123     do i = 1,len(string)
00124        if (ichar(string(i:i)) == 9) then
00125           string(i:i) = ' '
00126        end if
00127     end do
00128 
00129   end subroutine spec_line_tabs_to_spaces
00130 
00131 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00132 
00133   !> Strip leading spaces from a string.
00134   subroutine spec_line_strip_leading_spaces(string)
00135 
00136     !> Complete input string.
00137     character(len=*), intent(inout) :: string
00138 
00139     integer :: i
00140 
00141     if (len_trim(string) > 0) then
00142        i = verify(string, ' ') ! first character not a space
00143        string = string(i:)
00144     end if
00145 
00146   end subroutine spec_line_strip_leading_spaces
00147 
00148 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00149 
00150 end module pmc_spec_line