File: reada.f

package info (click to toggle)
mopac7 1.15-5
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 3,748 kB
  • sloc: fortran: 35,321; sh: 9,039; ansic: 417; makefile: 95
file content (156 lines) | stat: -rw-r--r-- 4,346 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
      DOUBLE PRECISION FUNCTION READA(STRING,ISTART)
C     FORTRAN FUNCTION TO EXTRACT NUMBER FROM STRING
C
      CHARACTER STRING*(*)
      DOUBLE PRECISION DIGIT
      LOGICAL EXPNNT
C
C     DEFINE ASCII VALUES OF NUMERIC FIELD CHARACTERS
      I0=ICHAR('0')
      I9=ICHAR('9')
      IDOT=ICHAR('.')
      INEG=ICHAR('-')
      IPOS=ICHAR('+')
      ICAPD=ICHAR('D')
      ICAPE=ICHAR('E')
      ISMLD=ICHAR('d')
      ISMLE=ICHAR('e')
C
      L=LEN(STRING)
C
C     FIND THE START OF THE NUMERIC FIELD
      DO 10 I=ISTART,L
         IADD=0
         N=ICHAR(STRING(I:I))
C
C       SIGNAL START OF NUMERIC FIELD IF DIGIT FOUND
         IF(N.GE.I0.AND.N.LE.I9)GOTO 20
C
C       ACCOUNT FOR CONSECUTIVE SIGNS [- AND(OR) +]
         IF(N.EQ.INEG.OR.N.EQ.IPOS)THEN
            IADD=IADD+1
            IF(I+IADD.GT.L)GOTO 50
            N=ICHAR(STRING(I+IADD:I+IADD))
            IF(N.GE.I0.AND.N.LE.I9)GOTO 20
         ENDIF
C
C       ACCOUNT FOR CONSECUTIVE DECIMAL POINTS (.)
         IF(N.EQ.IDOT)THEN
            IADD=IADD+1
            IF(I+IADD.GT.L)GOTO 50
            N=ICHAR(STRING(I+IADD:I+IADD))
            IF(N.GE.I0.AND.N.LE.I9)GOTO 20
         ENDIF
   10 CONTINUE
      GOTO 50
C
C     FIND THE END OF THE NUMERIC FIELD
   20 EXPNNT=.FALSE.
      DO 30 J=I+1,L
         IADD=0
         N=ICHAR(STRING(J:J))
C
C       CONTINUE SEARCH FOR END IF DIGIT FOUND
         IF(N.GE.I0.AND.N.LE.I9)GOTO 30
C
C       CONTINUE SEARCH FOR END IF SIGN FOUND AND EXPNNT TRUE
         IF(N.EQ.INEG.OR.N.EQ.IPOS)THEN
            IF(.NOT.EXPNNT)GOTO 40
            IADD=IADD+1
            IF(J+IADD.GT.L)GOTO 40
            N=ICHAR(STRING(J+IADD:J+IADD))
            IF(N.GE.I0.AND.N.LE.I9)GOTO 30
         ENDIF
         IF(N.EQ.IDOT)THEN
            IADD=IADD+1
            IF(J+IADD.GT.L)GOTO 40
            N=ICHAR(STRING(J+IADD:J+IADD))
            IF(N.GE.I0.AND.N.LE.I9)GOTO 30
            IF(N.EQ.ICAPE.OR.N.EQ.ISMLE.OR.N.EQ.ICAPD.OR.N.EQ.ISMLD)
     1    GOTO 30
         ENDIF
         IF(N.EQ.ICAPE.OR.N.EQ.ISMLE.OR.N.EQ.ICAPD.OR.N.EQ.ISMLD)THEN
            IF(EXPNNT)GOTO 40
            EXPNNT=.TRUE.
            GOTO 30
         ENDIF
         GOTO 40
   30 CONTINUE
      J=L+1
   40 N=ICHAR(STRING(J-1:J-1))
      IF(N.EQ.ICAPE.OR.N.EQ.ISMLE.OR.N.EQ.ICAPD.OR.N.EQ.ISMLD)J=J-1
C
C     FOUND THE END OF THE NUMERIC FIELD (IT RUNS 'I' THRU 'J-1')
      N=0
      N=N+INDEX(STRING(I:J-1),'e')
      N=N+INDEX(STRING(I:J-1),'E')
      N=N+INDEX(STRING(I:J-1),'d')
      N=N+INDEX(STRING(I:J-1),'D')
      IF(N.EQ.0)THEN
         READA=DIGIT(STRING(I:J-1),1)
      ELSE
         READA=DIGIT(STRING(:I+N-2),I)*1.D1**DIGIT(STRING(:J-1),I+N)
      ENDIF
      RETURN
C
C     DEFAULT VALUE RETURNED BECAUSE NO NUMERIC FIELD FOUND
   50 READA=0.D0
      RETURN
      END
C     ******************************************************************
      DOUBLE PRECISION FUNCTION DIGIT(STRING,ISTART)
C     FORTRAN FUNCTION TO CONVERT NUMERIC FIELD TO DOUBLE PRECISION
C     NUMBER.  THE STRING IS ASSUMED TO BE CLEAN (NO INVALID DIGIT
C     OR CHARACTER COMBINATIONS FROM ISTART TO THE FIRST NONSPACE,
C     NONDIGIT, NONSIGN, AND NONDECIMAL POINT CHARACTER).
C
      CHARACTER STRING*(*)
      DOUBLE PRECISION C1,C2,DECIML
      LOGICAL SIGN
C
C     DEFINE ASCII VALUES OF NUMERIC FIELD CHARACTERS
      I0=ICHAR('0')
      I9=ICHAR('9')
      INEG=ICHAR('-')
      IPOS=ICHAR('+')
      IDOT=ICHAR('.')
      ISPC=ICHAR(' ')
C
      C1=0.D0
      C2=0.D0
      SIGN=.TRUE.
      L=LEN(STRING)
C
C     DETERMINE THE CONTRIBUTION TO THE NUMBER GREATER THAN ONE
      IDIG=0
      DO 10 I=ISTART,L
         N=ICHAR(STRING(I:I))
         IF(N.GE.I0.AND.N.LE.I9)THEN
            IDIG=IDIG+1
            C1=C1*1.D1+N-I0
         ELSEIF(N.EQ.INEG.OR.N.EQ.IPOS.OR.N.EQ.ISPC)THEN
            IF(N.EQ.INEG)SIGN=.FALSE.
         ELSEIF(N.EQ.IDOT)THEN
            GOTO 20
         ELSE
            GOTO 40
         ENDIF
   10 CONTINUE
C
C     DETERMINE THE CONTRIBUTION TO THE NUMBER LESS THAN THAN ONE
   20 DECIML=1.D0
      DO 30 J=I+1,L
         N=ICHAR(STRING(J:J))
         IF(N.GE.I0.AND.N.LE.I9)THEN
            DECIML=DECIML/1.D1
            C2=C2+(N-I0)*DECIML
         ELSEIF(N.NE.ISPC)THEN
            GOTO 40
         ENDIF
   30 CONTINUE
C
C     PUT THE PIECES TOGETHER
   40 DIGIT=C1+C2
      IF(.NOT.SIGN)DIGIT=-DIGIT
      RETURN
      END