subroutine aptchtp (asrce, isrce, nchar, iamax, idmax, iemax, & aword, iword, fword, mtype, nerr) ccbeg. cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c SUBROUTINE APTCHTP c c call aptchtp (asrce, isrce, nchar, iamax, idmax, iemax, c & aword, iword, fword, mtype, nerr) c c Version: aptchtp Updated 1997 August 4 11:20. c aptchtp Originated 1993 February 16 11:50. c c Author: Arthur L. Edwards, LLNL, L-298, Telephone (925) 422-4123. c c c Purpose: To translate a character string to characters, an integer, c or a floating-point number. The string is in array asrce, c starting at character position isrce, and has a length of c nchar characters. Integers may have up to idmax digits. c Floating-point numbers may have exponents up to iemax. c The word length in character array aword is iamax characters. c The results are stored in the character array aword, the c integer word iword, and/or the floating point word fword, c depending on the data type of the string, mtype. c Flag nerr indicates any input or result error. c c Note: Do not convert this source file to all upper or lower case. c It contains both upper and lower case character variables. c c Input: asrce, isrce, nchar, idmax, iemax. c c Output: aword, iword, fword, mtype, nerr. c Note: do not equivalence fword and iword. c c Glossary: c c asrce Input A character array, containing the string to be c translated, starting in character position isrce, c with a length of nchar characters. c c aword Output A character array containing iamax characters per word, c compatible with a calling routine argument of type c character*iamax, or iamax words of type character*1, c etc. Always filled with up to iamax characters of c the character string, and right-filled with blanks c as necessary. Do not make aword = asrce. c c fword Output A floating-point number, initialized to zero. c The maximum allowable exponent is iemax. c If the string is translated into an integer c (mtype = 2) or into a floating-point number c (mtype = 3), its floating-point value will be c returned in fword. If the string is formatted as an c integer, but contains more than idmax digits after c any leading zeros, it will be translated into a c floating-point number, and returned in fword. c The character string may have leading or trailing c blanks. The first non-blank character may be a "+" c or "-". The mantissa may contain any positive number c of digits, but no more than one decimal point, and c may have trailing blanks. If an exponent is given, c it must begin with "e", "E", "d", "D", "+" or "-". c An initial "e", "E", "d" or "D" may be followed by c a "+" or "-". The digits of the exponent may have c leading and trailing blanks, but no additional c characters following any trailing blanks. c Note: do not equivalence iword to fword. c c iamax Input Number of characters in each word of type character c array aword. c c idmax Input Maximum number of digits in an integer. Depends on c the machine. At least 13 on a Cray. c Must be positive. c c iemax Input Maximum size (positive or negative) of the exponent c of a floating-point number. Depends on the machine. c Approximately 2465 on a Cray. Must be positive. c c isrce Input The character position in array asrec of the first c character of the string. E. g., isrce = 1 means c the leftmost character of asrce(1). c Must be positive. c c iword Output An integer. Initialized to zero. The maximum number c of digits is idmax. If the character string is c translated into an integer (mtype = 2), iword will c contain its integer value, and fword will contain its c floating-point value. Note: do not equivalence c fword and iword. The character string may have c leading or trailing blanks. The first non-blank c character may be a "+" or "-". All other characters c must be digits, with no more than idmax digits c following any leading zeros. c c mtype Output An integer. Indicates the data type of the character c string, and which results are returned: c 0: Not recognizable as an integer or floating-point c number, and longer than iamax characters c (nerr = 0), or a floating-point number whose c exponent exceeds the limit iemax (nerr = 5). c Returned in aword. c 1: Not recognizable as an integer or floating-point c number. String has 1 to iamax characters. c Returned in aword, left-adjusted, right-filled c with blanks, as necessary. c 2: Character string translated into integer mode. c The integer value is returned in iword, and the c floating-point value is returned in fword. c Also returned in aword, as for mtype = 1. c 3: Character string translated into floating-point c mode, and returned in fword. The integer value c can not be stored in iword, because of the c possibility of overflow of numbers with large c exponents. If nerr = 4, the character string was c an integer with more than idmax digits. c Also returned in aword, as for mtype = 1. c c nerr Output Indicates an input or result error, if not zero. c 1 if nchar is not positive. c 2 if isrce is not positive. c 3 if iamax, idmax or iemax is not positive. c 4 if an integer exceeds idmax characters. If so, c a floating-point result is returned in fword, c with mtype = 3. c 5 if a floating-point exponent exceeds iemax. c If so, a character string is returned in aword, c with mtype = 0. c c nchar Input The number of characters in the character string. c cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ccend. c.... Declarations for arguments. c---- Array of characters. dimension asrce (1) c---- Array of characters. character*1 asrce c---- Character interpretation of string. dimension aword (1) c---- Character interpretation of string. character*1 aword c.... Local variables. c---- Floating-point idig - 1. common /laptchtp/ fintadd c---- Floating-point mantissa value. common /laptchtp/ fintval c---- Indicates sign of mantissa. common /laptchtp/ fsign c---- Index in aword. common /laptchtp/ icharm c---- Index in array adigit. common /laptchtp/ idig c---- Integer mantissa value. common /laptchtp/ intval c---- Indicates position of decimal point. common /laptchtp/ ipt c---- Indicates sign of mantissa. common /laptchtp/ isign c---- Number of exponent digits. common /laptchtp/ kdigit c---- Integer exponent value. common /laptchtp/ kexp c---- Indicates sign of exponent. common /laptchtp/ ksign c---- Index in the string. common /laptchtp/ nbeg c---- Index in the string. common /laptchtp/ nc c---- Number of mantissa digits. common /laptchtp/ ndigall c---- Number of significant digits. common /laptchtp/ ndigit c---- Number of zeroes to insert. common /laptchtp/ nzeros c---- A single character in string. common /captchtp/ achar character*1 achar c---- Integer digits from 0 to 9. dimension adigit(10) character*1 adigit data adigit / '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' / c---- Powers of 10, 1 to 80. dimension tend(80) c---- DOUBLE PRECISION. c double precision tend c data tend / 1.d+01, 1.d+02, 1.d+03, 1.d+04, 1.d+05, 1.d+06, c & 1.d+07, 1.d+08, 1.d+09, 1.d+10, 1.d+11, 1.d+12, 1.d+13, c & 1.d+14, 1.d+15, 1.d+16, 1.d+17, 1.d+18, 1.d+19, 1.d+20, c & 1.d+21, 1.d+22, 1.d+23, 1.d+24, 1.d+25, 1.d+26, 1.d+27, c & 1.d+28, 1.d+29, 1.d+30, 1.d+31, 1.d+32, 1.d+33, 1.d+34, c & 1.d+35, 1.d+36, 1.d+37, 1.d+38, 1.d+39, 1.d+40, 1.d+41, c & 1.d+42, 1.d+43, 1.d+44, 1.d+45, 1.d+46, 1.d+47, 1.d+48, c & 1.d+49, 1.d+50, 1.d+51, 1.d+52, 1.d+53, 1.d+54, 1.d+55, c & 1.d+56, 1.d+57, 1.d+58, 1.d+59, 1.d+60, 1.d+61, 1.d+62, c & 1.d+63, 1.d+64, 1.d+65, 1.d+66, 1.d+67, 1.d+68, 1.d+69, c & 1.d+70, 1.d+71, 1.d+72, 1.d+73, 1.d+74, 1.d+75, 1.d+76, c & 1.d+77, 1.d+78, 1.d+79, 1.d+80 / c / c____ DOUBLE PRECISION. c____ SINGLE PRECISION. data tend / 1.e+01, 1.e+02, 1.e+03, 1.e+04, 1.e+05, 1.e+06, & 1.e+07, 1.e+08, 1.e+09, 1.e+10, 1.e+11, 1.e+12, 1.e+13, & 1.e+14, 1.e+15, 1.e+16, 1.e+17, 1.e+18, 1.e+19, 1.e+20, & 1.e+21, 1.e+22, 1.e+23, 1.e+24, 1.e+25, 1.e+26, 1.e+27, & 1.e+28, 1.e+29, 1.e+30, 1.e+31, 1.e+32, 1.e+33, 1.e+34, & 1.e+35, 1.e+36, 1.e+37, 1.e+38, 1.e+39, 1.e+40, 1.e+41, & 1.e+42, 1.e+43, 1.e+44, 1.e+45, 1.e+46, 1.e+47, 1.e+48, & 1.e+49, 1.e+50, 1.e+51, 1.e+52, 1.e+53, 1.e+54, 1.e+55, & 1.e+56, 1.e+57, 1.e+58, 1.e+59, 1.e+60, 1.e+61, 1.e+62, & 1.e+63, 1.e+64, 1.e+65, 1.e+66, 1.e+67, 1.e+68, 1.e+69, & 1.e+70, 1.e+71, 1.e+72, 1.e+73, 1.e+74, 1.e+75, 1.e+76, & 1.e+77, 1.e+78, 1.e+79, 1.e+80 / c____ SINGLE PRECISION. cbugc***DEBUG begins. cbugc---- # of characters of asrce to write. cbug common /laptchtp/ nmaxa cbug 9901 format (/ 'aptchtp translating an ASCII word.' / cbug & ' isrce=',i6,' nchar=',i6, cbug & ' iamax=',i3,' idmax=',i3,' iemax=',i6) cbug 9902 format (' asrce=',64a1) cbug write ( 3, 9901) isrce, nchar, iamax, idmax, iemax cbug nmaxa = 8 * (1 + (isrce + nchar - 2) / 8) cbug write ( 3, 9902) (asrce(nc), nc = 1, nmaxa) cbugc***DEBUG ends. c.... Initialize the output. nerr = 0 mtype = 1 iword = 0 fword = 0.0 c.... Test for input errors. if (nchar .le. 0) then nerr = 1 go to 210 endif if (isrce .le. 0) then nerr = 2 go to 210 endif if ((iamax .le. 0) .or. (idmax .le. 0) .or. (iemax .le. 0)) then nerr = 3 go to 210 endif c.... Put up to iamax characters of string into aword. icharm = nchar if (icharm .gt. iamax) then c---- Type character (>iamax) or bad f-p. mtype = 0 icharm = iamax endif c---- Loop over output characters. do 110 nc = 1, icharm aword(nc) = asrce(isrce +nc-1) c---- End of loop over output characters. 110 continue c.... Right-fill aword with blanks. nbeg = icharm + 1 if (nbeg .le. iamax) then do 105 nc = nbeg, iamax ! Loop over output characters. aword(nc) = ' ' 105 continue ! End of loop over output characters. endif c=======================================================================-------- c.... Look for the beginning of the mantissa field for integers and c.... floating-point numbers. Find the first non-blank character. c---- Loop over character string. do 115 nc = 1, nchar achar = asrce(isrce +nc-1) if (achar .ne. ' ') go to 120 c---- End of loop over character string. 115 continue c---- All characters are blank. go to 210 c.... See if the first non-blank character is "+" or "-". 120 if (achar .eq. '-') then nc = nc + 1 isign = -1 fsign = -1.0 elseif (achar .eq. '+') then nc = nc + 1 isign = 1 fsign = 1.0 else isign = 1 fsign = 1.0 endif c.... See if the only non-blank character in string is "+" or "-". c---- All characters are blank, "+" or "-". if (nc .gt. nchar) go to 210 c.... See if the first character after any sign and/or decimal point is not an c.... integer. If so, word can not be an integer or a floating point number. achar = asrce(isrce +nc-1) if (achar .eq. '.') achar = asrce(isrce +nc) do 121 idig = 1, 10 if (achar .eq. adigit(idig)) go to 122 121 continue go to 210 122 continue c=======================================================================-------- c.... Found the beginning of the mantissa. Initialize counters. intval = 0 ipt = -1000000 ndigall = 0 ndigit = 0 nzeros = 0 c.... Scan the remainder of the the mantissa and translate. nbeg = nc c---- Loop over rest of string. do 140 nc = nbeg, nchar achar = asrce(isrce +nc-1) c.... Test for any trailing blanks after the mantissa. c++++ Blank ends mantissa. if (achar .eq. ' ') go to 145 c.... Scan for a digit or decimal point (which are part of mantissa). c---- Loop over digits. do 125 idig = 1, 10 if (achar .eq. adigit(idig)) go to 130 c---- End of loop over digits. 125 continue c.... Not a digit. Test for first decimal point (only allow 1). c++++ End of mantissa. if ((ipt .ge. 0) .or. (achar .ne. '.')) go to 160 c---- Found first decimal point. ipt = 0 go to 140 c.... Found a digit. See if zero or non-zero, if after a decimal point. c---- String has a decimal point. 130 if (ipt .ge. 0) then c.... Save number of zeros following the decimal point. c---- Save zeros. if (idig .eq. 1) then nzeros = nzeros + 1 go to 140 endif c.... Non-zero digit found. Include effect of zeros after decimal point. c---- String has zeros after decimal. 135 if (nzeros .gt. 0) then c.... Only allow exponents up to iemax. c++++ Exponent overflows. if (ndigit .gt. (iemax + ipt)) then nerr = 5 if (nchar .le. iamax) then mtype = 1 else mtype = 0 endif go to 210 endif c.... Only allow integers with up to idmax digits. if (ndigit .lt. idmax) then intval = 10 * intval elseif (ndigit .eq. idmax) then fintval = intval fintval = tend(1) * fintval c---- More than idmax digits. else fintval = tend(1) * fintval endif c.... Insert zeroes before next number. ipt = ipt + 1 nzeros = nzeros - 1 ndigit = ndigit + 1 ndigall = ndigall + 1 go to 135 c---- Tested nzeros. endif c---- Tested ipt. endif c.... Found a digit. ndigall = ndigall + 1 c.... Ignore leading zeros. if ((ndigit .eq. 0) .and. (ipt .lt. 0) .and. & (idig .eq. 1)) go to 140 c.... Update the mantissa. c.... Only allow exponents up to iemax. c++++ Exponent overflows. if (ndigit .gt. (iemax + max (0, ipt))) then nerr = 5 if (nchar .le. iamax) then mtype = 1 else mtype = 0 endif go to 210 endif c.... Only allow integers with up to idmax digits. if (ndigit .lt. idmax) then intval = 10 * intval + (idig - 1) c++++ Start floating-point equivalent. elseif (ndigit .eq. idmax) then fintadd = idig - 1 fintval = intval fintval = tend(1) * fintval + fintadd c---- More than idmax digits. else fintadd = idig - 1 fintval = tend(1) * fintval + fintadd endif ipt = ipt + 1 ndigit = ndigit + 1 c---- End of loop over rest of string. 140 continue go to 155 c=======================================================================-------- c.... The mantissa ended with a blank. Look for next non-blank character. 145 nbeg = nc c---- Loop over rest of string. do 150 nc = nbeg, nchar achar = asrce(isrce +nc-1) if (achar .ne. ' ') go to 160 c---- End of loop over rest of string. 150 continue c=======================================================================-------- c.... Found the end of the mantissa, with no exponent field. c.... Return a character string if no digits were found. 155 if ((ndigall .le. 0) .and. (nzeros .le. 0)) go to 210 c.... See if a decimal point was found. c---- No decimal point. if (ipt .lt. 0) then c.... Assume floating-point if over idmax digits. c---- Return integer and floating-point. if (ndigit .le. idmax) then c---- Type integer. mtype = 2 iword = isign * intval fword = iword c---- Return only floating-point. else c---- Type integer, but too many digits. mtype = 3 fword = fsign * fintval nerr = 4 endif c---- A decimal point was found. else c---- Type floating-point. mtype = 3 if (ndigit .le. idmax) then fword = isign * intval c---- Return only floating-point. else fword = fsign * fintval endif 158 if (ipt .gt. 80) then fword = fword / tend(80) ipt = ipt - 80 go to 158 endif if (ipt .gt. 0) then fword = fword / tend(ipt) endif c---- Tested ipt. endif go to 210 c=======================================================================-------- c.... Found the end of the mantissa. Look for the beginning of the exponent. c.... The exponent may start with "e", "E", "d", "D", "+", or "-". 160 ksign = 0 if ((achar .eq. 'e') .or. (achar .eq. 'd') .or. & (achar .eq. 'E') .or. (achar .eq. 'D')) then nc = nc + 1 achar = asrce(isrce +nc-1) c---- Assume positive exponent. ksign = 1 endif c---- Exponent is positive. if (achar .eq. '+') then nc = nc + 1 ksign = 1 c---- Exponent is negative. elseif (achar .eq. '-') then nc = nc + 1 ksign = -1 endif c++++ Not an exponent. if ((nc .gt. nchar) .or. (ksign .eq. 0)) go to 210 c=======================================================================-------- c.... Found the beginning of the exponent. Find the next non-blank character. nbeg = nc c---- Loop over rest of string. do 165 nc = nbeg, nchar achar = asrce(isrce +nc-1) if (achar .ne. ' ') go to 170 c---- End of loop over rest of string. 165 continue c---- No digits in exponent. go to 210 170 kexp = 0 kdigit = 0 nbeg = nc c---- Loop over rest of string. do 180 nc = nbeg, nchar achar = asrce(isrce +nc-1) c++++ Imbedded blank ends exponent. if (achar .eq. ' ') go to 185 c---- Loop over digits. do 175 idig = 1, 10 c++++ Found digit. if (achar .eq. adigit(idig)) then kexp = 10 * kexp + (idig - 1) kdigit = kdigit + 1 go to 180 endif c---- End of loop over digits. 175 continue c---- Not a digit. Return character string. go to 210 c---- End of loop over rest of string. 180 continue go to 195 c=======================================================================-------- c.... Found imbedded blank in exponent. The rest of the string must be blank. 185 nbeg = nc c---- Loop over rest of string. do 190 nc = nbeg, nchar achar = asrce(isrce +nc-1) c++++ Illegal character in exponent field. if (achar .ne. ' ') go to 210 c---- End of loop over rest of string. 190 continue c=======================================================================-------- c.... Found the end of the exponent. c.... Return a character string if no digits were found in exponent field. 195 if (kdigit .le. 0) go to 210 c.... Translate the mantissa to floating-point. c---- Type real, or integer > idmax. mtype = 3 if (ndigit .le. idmax) then fword = isign * intval else fword = fsign * fintval endif c.... Find the exponent. kexp = ksign * kexp if (ipt .gt. 0) kexp = kexp - ipt if (abs (kexp + ndigit - 1) .gt. iemax) then c---- Exceeded maximum exponent. nerr = 5 if (nchar .le. iamax) then mtype = 1 else mtype = 0 endif fword = 0.0 go to 210 endif c.... Find the floating-point result, including the exponent. c---- Negative exponent. if (kexp .lt. 0) then kexp = -kexp 200 if (kexp .gt. 80) then fword = fword / tend(80) kexp = kexp - 80 go to 200 endif if (kexp .ne. 0) then fword = fword / tend(kexp) endif c---- Positive exponent. elseif (kexp .gt. 0) then 205 if (kexp .gt. 80) then fword = fword * tend(80) kexp = kexp - 80 go to 205 endif if (kexp .ne. 0) then fword = fword * tend(kexp) endif c---- Tested kexp. endif 210 continue cbugc***DEBUG begins. cbug 9903 format (/ 'aptchtp results: mtype=',i3,' nerr=',i3) cbug 9904 format (' aword=',80a1 / ' iword=',i16,' fword=',1pe22.14) cbug write ( 3, 9903) mtype, nerr cbug write ( 3, 9904) (aword(nc), nc = 1, 80), iword, fword cbugc***DEBUG ends. return c.... End of subroutine aptchtp. (+1 line.) end UCRL-WEB-209832