c To check whether the current line type is of an ISF type consistent with c the type of the previous line written. c The exception is line_type 'data_type' where previous line type is c assumed to be undefined. c Checks and resets the global variable isf_prev_line_type. c Returns 0 if the current line type is expected to follow the previous one. c Returns 1 if this line type should not follow the previous line type. integer function check_prev_line_type(line_type) character line_type*(*) include 'isf_bul.h' character allowed(10)*(ISF_LINE_LEN) integer i,n i = 1 if ( line_type(1:9) .eq. 'data_type') then isf_prev_line_type = line_type check_prev_line_type = 0 return else if ( line_type(1:8) .eq. 'event_id') then allowed(i) = 'data_type' i=i+1 allowed(i) = 'phase' i=i+1 allowed(i) = 'phase_com' i=i+1 allowed(i) = 'phase_info' else if ( line_type(1:11) .eq. 'origin_head') then allowed(i) = 'event_id' else if ( line_type(1:10) .eq. 'origin_com') then allowed(i) = 'origin' i=i+1 allowed(i) = 'origin_com' i=i+1 allowed(i) = 'axes' i=i+1 allowed(i) = 'axes_err' i=i+1 allowed(i) = 'fault_plane' i=i+1 allowed(i) = 'momten' else if ( line_type(1:6) .eq. 'origin') then allowed(i) = 'origin_head' i=i+1 allowed(i) = 'origin' i=i+1 allowed(i) = 'origin_com' else if ( line_type(1:11) .eq. 'momten_head') then allowed(i) = 'origin' i=i+1 allowed(i) = 'origin_com' i=i+1 allowed(i) = 'axes' i=i+1 allowed(i) = 'axes_err' i=i+1 allowed(i) = 'fault_plane' else if ( line_type(1:6) .eq. 'momten') then allowed(i) = 'momten' i=i+1 allowed(i) = 'momten_head' i=i+1 allowed(i) = 'origin_com' else if ( line_type(1:16) .eq. 'fault_plane_head') then allowed(i) = 'origin' i=i+1 allowed(i) = 'origin_com' i=i+1 allowed(i) = 'axes' i=i+1 allowed(i) = 'axes_err' i=i+1 allowed(i) = 'momten' else if ( line_type(1:11) .eq. 'fault_plane') then allowed(i) = 'fault_plane_head' i=i+1 allowed(i) = 'fault_plane' i=i+1 allowed(i) = 'origin_com' else if ( line_type(1:9) .eq. 'axes_head') then allowed(i) = 'origin' i=i+1 allowed(i) = 'origin_com' i=i+1 allowed(i) = 'fault_plane' i=i+1 allowed(i) = 'momten' else if ( line_type(1:13) .eq. 'axes_err_head') then allowed(i) = 'axes_head' else if ( line_type(1:8) .eq. 'axes_err') then allowed(i) = 'axes' else if ( line_type(1:4) .eq. 'axes') then allowed(i) = 'axes_head' i=i+1 allowed(i) = 'axes_err_head' i=i+1 allowed(i) = 'origin_com' else if ( line_type(1:11) .eq. 'netmag_head') then allowed(i) = 'origin' i=i+1 allowed(i) = 'origin_com' i=i+1 allowed(i) = 'momten' i=i+1 allowed(i) = 'axes' i=i+1 allowed(i) = 'axes_err' i=i+1 allowed(i) = 'fault_plane' else if ( line_type(1:10) .eq. 'netmag_com') then allowed(i) = 'netmag' i=i+1 allowed(i) = 'netmag_com' else if ( line_type(1:6) .eq. 'netmag') then allowed(i) = 'netmag_head' i=i+1 allowed(i) = 'netmag' i=i+1 allowed(i) = 'netmag_com' else if ( line_type(1:12) .eq. 'effects_head') then allowed(i) = 'origin' i=i+1 allowed(i) = 'origin_com' i=i+1 allowed(i) = 'momten' i=i+1 allowed(i) = 'axes' i=i+1 allowed(i) = 'axes_err' i=i+1 allowed(i) = 'fault_plane' i=i+1 allowed(i) = 'netmag' i=i+1 allowed(i) = 'netmag_com' else if ( line_type(1:7) .eq. 'effects') then allowed(i) = 'effects_head' i=i+1 allowed(i) = 'effects' i=i+1 allowed(i) = 'effects_com' else if ( line_type(1:10) .eq. 'phase_head') then allowed(i) = 'origin' i=i+1 allowed(i) = 'origin_com' i=i+1 allowed(i) = 'momten' i=i+1 allowed(i) = 'axes' i=i+1 allowed(i) = 'axes_err' i=i+1 allowed(i) = 'fault_plane' i=i+1 allowed(i) = 'netmag' i=i+1 allowed(i) = 'netmag_com' i=i+1 allowed(i) = 'effects' i=i+1 allowed(i) = 'effects_com' else if ( line_type(1:12) .eq. 'phase_origid') then allowed(i) = 'phase_head' i=i+1 allowed(i) = 'phase_info_head' else if ( line_type(1:15) .eq. 'phase_info_head') then allowed(i) = 'phase' i=i+1 allowed(i) = 'phase_com' else if ( line_type(1:14) .eq. 'phase_info_com') then allowed(i) = 'phase_info' i=i+1 allowed(i) = 'phase_info_com' else if ( line_type(1:10) .eq. 'phase_info') then allowed(i) = 'phase_origid' i=i+1 allowed(i) = 'phase_info' i=i+1 allowed(i) = 'phase_info_com' i=i+1 allowed(i) = 'phase_info_head' else if ( line_type(1:5) .eq. 'phase') then allowed(i) = 'phase_origid' i=i+1 allowed(i) = 'phase_head' i=i+1 allowed(i) = 'phase' i=i+1 allowed(i) = 'phase_com' else if ( line_type(1:4) .eq. 'stop') then allowed(i) = 'phase' i=i+1 allowed(i) = 'phase_com' i=i+1 allowed(i) = 'phase_info' i=i+1 allowed(i) = 'phase_info_com' end if n = i do i=1,n if (isf_prev_line_type .eq. allowed(i)) then isf_prev_line_type = line_type check_prev_line_type = 0 return end if end do isf_bulletin_error = & 'out of sequence: '//line_type//' following '//isf_prev_line_type isf_prev_line_type = line_type check_prev_line_type = 1 return end c Writes a real a bit more flexibly than can be achieved with a format. c If a number is too big for the ideal precision it is printed with less c precision until it fills the field width without a decimal point at all. c For example might want 99.9999 => 99.99 but 999.9999 => 999.9. subroutine write_real(file,x,width,max_prec) integer file,width,max_prec real x character form*(20) integer prec,spare if ( x .gt. 0 ) then spare = width - 1 - log10(abs(x)) else if ( x .lt. 0 ) then spare = width - 2 - log10(abs(x)) else spare = max_prec end if if (spare .le. 0) then write (form,"('(i',i2,',$)')") width write (file,form) int(x) else if (spare .ge. max_prec) then prec = max_prec else prec = spare end if write (form,"('(f',i1,'.',i1,',$)')") width,prec write (file,form) x end if end c Get a substring, removing leading white space. c Expects a string, an offset from the start of the string, and a maximum c length for the resulting substring. If this length is 0 it will take up c to the end of the input string. c Need to allow for ')' to come after the required field at the end of a c comment. Discard ')' at end of a string as long as there's no '(' c before it anywhere. c Returns the length of the resulting substring. integer function partline (substr,line,offset,numchars) character substr*(*), line*(*) integer offset, numchars integer i, start, end integer length integer bracket length = len(line) if (length .le. offset) then partline=0 return end if start=offset if (start .le. 0) then start=1 end if if (numchars .eq. 0) then end = length else end = offset + numchars - 1 end if do while (line(start:start) .eq. ' ' .and. start .lt. end) start=start+1 end do bracket = 0 do i=start,end if (line(i:i) .eq. '(' ) then bracket=1 end if end do if (bracket .eq. 1) then do while ((line(end:end) .eq. ' ') .and. (end .ge. start)) end=end-1 end do else do while ( ((line(end:end) .eq. ' ') .or. (line(end:end) .eq. ')') ) & .and. (end .ge. start)) end=end-1 end do end if substr = line(start:end) partline = end-start+1 return end c To check that a string has no spaces in it. c Returns 0 if there are no spaces or 1 if there is a space. integer function check_whole(str) character str*(*) include 'isf_bul.h' character substr*(ISF_LINE_LEN) integer i,length integer partline length = partline(substr,str,0,0) do i=1,length if (substr(i:i) .eq. ' ') then check_whole = 1 return end if end do check_whole = 0 return end c Check if a string is composed entirely of white space or not. c Returns 1 if it is, 0 if it isn't. integer function all_blank(str) character str*(*) include 'isf_bul.h' character substr*(ISF_LINE_LEN) integer i,length integer partline length = partline(substr,str,0,0) do i=1,length if (substr(i:i) .ne. ' ' .and. substr(i:i) .ne. ' ') then all_blank = 0 return end if end do all_blank = 1 return end c Check whether a real or integer is null or not. c Returns 1 if it is, 0 if it isn't. integer function is_null(x) real x include 'isf_bul.h' if (int(x) .eq. ISF_NULL) then is_null = 1 return end if is_null = 0 return end c To check that a string contains only sign/number characters and so c is suitable for atoi - atoi itself does no checking. c Returns 0 if OK, 1 if not. integer function check_int(str) character str*(*) include 'isf_bul.h' character substr*(ISF_LINE_LEN) integer length,start,i integer partline,isdigit length = partline(substr,str,0,0) start = 1 if (substr(1:1) .eq. '-' .or. substr(1:1) .eq. '+') then start = 2 end if do i=start, length if (isdigit(substr(i:i)) .eq. 0) then check_int = 1 return end if end do check_int = 0 return end c To check if a character is between 1 and 9 c Returns 0 if it is, 1 if not. integer function isdigit(a) character a integer i i = ichar(a) - ichar('0') if (i .gt. 9 .or. i .lt. 0) then isdigit = 0 return end if isdigit = 1 return end c To check if a character is between A and Z c Returns 0 if it is, 1 if not. integer function isupper(a) character a integer i i = ichar(a) - ichar('A') if (i .gt. 26 .or. i .lt. 0) then isupper = 0 return end if isupper = 1 return end c Converts a string of numbers into an integer. c No checking done so need to run check_int on the string first. integer function atoi(str) character str*(*) include 'isf_bul.h' character substr*(ISF_LINE_LEN) integer length,start,i integer partline length = partline(substr,str,0,0) start = 1 if (substr(1:1) .eq. '-' .or. substr(1:1) .eq. '+') then start = 2 end if atoi = 0 do i=start, length atoi = atoi + (ichar(substr(i:i))-ichar('0')) * (10**(length-i)) end do if (substr(1:1) .eq. '-') then atoi = atoi*-1 end if return end c To check that a string is suitable for ator c Returns 0 if OK, 1 if not. integer function check_real(str) character str*(*) include 'isf_bul.h' character substr*(ISF_LINE_LEN) integer length,start,i integer partline,isdigit length = partline(substr,str,0,0) start = 1 if (substr(1:1) .eq. '-' .or. substr(1:1) .eq. '+') then start = 2 end if do i=start, length if (isdigit(substr(i:i)) .eq. 0) then if (substr(i:i) .ne. '.' ) then check_real = 1 return end if end if end do check_real = 0 return end c Converts a string of numbers into a real. c No checking done so need to run check_real on the string first. real function ator(str) character str*(*) include 'isf_bul.h' character substr*(ISF_LINE_LEN) integer length,start,i,point integer partline length = partline(substr,str,0,0) start = 1 if (substr(1:1) .eq. '-' .or. substr(1:1) .eq. '+') then start = 2 end if point = length+1 do i=1,length if (substr(i:i) .eq. '.') then point = i end if end do ator = 0 do i=start, point-1 ator = ator + (ichar(substr(i:i))-ichar('0')) * (10.0**(point-i-1)) end do do i=point+1,length ator = ator + (ichar(substr(i:i))-ichar('0')) * (10.0**(point-i)) end do if (substr(1:1) .eq. '-') then ator = ator*-1.0 end if return end