Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

expand.f

Go to the documentation of this file.
00001 
00002 c
00003 c       Copyright (c) 1986,1987,1988,1989,1990,1991,1992,1993,
00004 c       by Steve McMillan, Drexel University, Philadelphia, PA.
00005 c
00006 c       All rights reserved.
00007 c
00008 c       Redistribution and use in source and binary forms are permitted
00009 c       provided that the above copyright notice and this paragraph are
00010 c       duplicated in all such forms and that any documentation,
00011 c       advertising materials, and other materials related to such
00012 c       distribution and use acknowledge that the software was developed
00013 c       by the author named above.
00014 c
00015 c       THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
00016 c       IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
00017 c       WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00018 c
00019 
00020 c----------------------------------------------------------------------
00021 c
00022 c       Perform (historical) expansions of the input line.
00023 c
00024 c       expandr   - replace !! by !nhist
00025 c       expandh   - insert a range of history items
00026 c       expandl   - expand historical references
00027 c       expands   - expand historical references of the form "!string"
00028 c       applysubs - apply substitutions, after expansion
00029 c
00030 c----------------------------------------------------------------------
00031 
00032         subroutine expandr(line,nl)
00033         save
00034 c       
00035 c       Expand repeat references within a line (!! --> !nhist).
00036 c
00037         character*(*) line
00038 c
00039         parameter (NHMAX = 500)
00040 c
00041         character*200 history(NHMAX)
00042         common /histchars/ history
00043         common /histnums/ lhist(NHMAX),nhist
00044 c
00045         if (nl.le.1) return
00046 c
00047 c       *** Special case -- line may start with ^..."...", meaning
00048 c           that the previous line is to be modified.  If the first
00049 c           nonblank character is "^", insert "!!" at the start of
00050 c           the line.
00051 c
00052         i = 1
00053         do while (line(i:i).le.' ')
00054             i = i + 1
00055         end do
00056         if (line(i:i).eq.'^') call repsubstr(line,nl,0,0,'!!',2)
00057 c
00058         is = 1
00059         ie = 0
00060 c
00061         i = 0
00062         do while (i.lt.nl)
00063             i = i+1
00064             if (is.eq.0) then
00065                 if (line(i:i).ne.';') go to 100
00066                 if (line(i+1:i+1).eq.';') then
00067                     i = i+1
00068                     go to 100
00069                 end if
00070                 is = 1
00071                 ie = 0
00072             else
00073                 if (line(i:i).le.' ') go to 100
00074                 if (line(i:i).ne.'!') then
00075                     is = 0
00076                 else if (ie.eq.0) then
00077                     ie = 1
00078                 else
00079 c
00080 c                   Perform the substitution.
00081 c
00082                     do j = nl,i+1,-1
00083                         line(j+4:j+4) = line(j:j)
00084                     end do
00085                     nl = nl + 4
00086                     write(line(i:i+4),'(i5)')nhist
00087                     i = i + 4
00088                     is = 0
00089                 end if
00090             end if
00091 100     end do
00092 c
00093         end
00094 
00095 
00096         subroutine expandh(line,nl,ic0,ihmin,ihmax,lextra,iret)
00097         save
00098 c
00099 c       Expand the specified history range (ihmin to ihmax) into the line.
00100 c       The insertion is to occur immediately after character #ic0 in
00101 c       the line.  The total number of characters added is returned as
00102 c       lextra.  No trailing semicolon is added at the end.
00103 c
00104 c       Neither ic0 nor nl are altered.  (Bookkeeping is to be performed 
00105 c       by the calling routine.)
00106 c
00107 c       The status flag iret returns 1 iff an error occurs.
00108 c
00109         character*(*) line
00110 c
00111         parameter (NHMAX = 500)
00112 c       
00113         character*200 history(NHMAX)
00114         common /histchars/ history
00115         common /histnums/ lhist(NHMAX),nhist
00116 c
00117         iret = 0
00118         lextra = 0
00119 c
00120         do ih = ihmin,ihmax
00121 c
00122             jh = ih
00123             do while (jh.gt.NHMAX)
00124                 jh = jh - NHMAX
00125             end do
00126 c
00127             if (nl+lhist(jh).ge.len(line)) then
00128                 write(6,*)'Expanded line too long.'//
00129      &                    ' Check for possible recursion.'
00130                 iret = 1
00131                 return
00132             end if
00133 c
00134             l0 = lextra
00135             lextra = lextra + lhist(jh)
00136 c
00137             line(ic0+l0+1:ic0+lextra) = history(jh)(1:lhist(jh))
00138 c
00139 c           Add a delimiting ";", except at the end.
00140 c
00141             if (ih.lt.ihmax) then
00142                 lextra = lextra + 1
00143                 line(ic0+lextra:ic0+lextra) = ';'
00144             end if
00145 c
00146         end do
00147 c
00148         end
00149 
00150         
00151         subroutine expandl(line,nl,isuppr,*)
00152         save
00153 c
00154 c       Repeatedly expand historical references in line.  This routine
00155 c       serves a dual function, so the substring to be expanded can be
00156 c       of the form "!  n;" or "!  n^".  This allows use during normal
00157 c       line expansion, and during substitutions.
00158 c
00159 c       The expansion is recursive unless isuppr is nonzero.
00160 c       
00161         character*(*) line
00162 c
00163         parameter (NHMAX = 500)
00164 c       
00165         character*200 history(NHMAX),lsto
00166         common/histchars/history
00167         common/histnums/lhist(NHMAX),nhist
00168 c       
00169         character*80 temp
00170         character*1 which
00171 c
00172         if (nl.le.0) return 1
00173 c       
00174 c       The logic here is similar to that used in mcdraw when
00175 c       interpreting individual commands.
00176 c
00177         iscolon = 0
00178 10      if (iscolon.ge.nl) return
00179 c
00180 c       Find the next substring.  If may be terminated by ";" or "^".
00181 c       Note that if "^" is the terminator, we will have to search
00182 c       for the next ";" before continuing.
00183 c
00184 c       Note that the two expected expansion patterns are "!....;"
00185 c       and "!...^xxx"yyy";".
00186 c
00187         ic0 = iscolon
00188         which = ';'
00189 c
00190 15      do ic1 = iscolon+1,nl
00191             which = line(ic1:ic1)
00192             if (which.eq.';'.or.which.eq.'^') go to 20
00193         end do
00194         ic1 = nl + 1
00195 20      if (ic1.lt.nl.and.line(ic1+1:ic1+1).eq.which) then
00196             iscolon = ic1 + 1
00197             go to 15
00198         end if
00199 c
00200 c       The piece to be expanded runs from ic0+1 to ic1-1.
00201 c       The terminating character is "which", at location ic1.
00202 c
00203         nin = ic1 - ic0 - 1
00204         temp(1:nin) = line(ic0+1:ic1-1)
00205         iscolon = ic1
00206 c       
00207 c       Expand any historical references.
00208 c       
00209         do i = 1,nin
00210             if (temp(i:i).gt.' ') then
00211                 if (temp(i:i).ne.'!') go to 100
00212                 if (i.ge.nin) then
00213                     write(6,*)'warning: possible input error...'
00214                     go to 100
00215                 end if
00216                 call rdecode(temp(i+1:nin),nhist,ihmin,ihmax,*1001)
00217                 go to 32
00218             end if
00219         end do
00220 c
00221 c       Continue expanding the line.
00222 c
00223         go to 100
00224 c       
00225 c       Save the remainder of the string before expansion.
00226 c
00227 32      nlsto = 0
00228         if (ic1.lt.nl) then
00229 c
00230 c           Note that the trailing ";" or "^" is saved.
00231 c
00232             nlsto = nl - ic1 + 1
00233             lsto(1:nlsto) = line(ic1:nl)
00234         end if
00235 c
00236 c       Expand the history list (no trailing delimiter added).
00237 c
00238         call expandh(line,nl,ic0,ihmin,ihmax,lextra,iret)
00239         if (iret.ne.0) return 1
00240 c
00241 c       Restore the rest of the line.  (Note: this would be a good
00242 c       place for a consistency check, as the string lengths are not
00243 c       forced to agree...)
00244 c       
00245         nl = nl - nin + lextra
00246         if (nlsto.gt.0) then
00247             line(ic0+lextra+1:nl) = lsto(1:nlsto)
00248         end if
00249 c
00250 c       Continue recursively at ic0, or non-recursively, depending on
00251 c       input option isuppr.
00252 c
00253 100     if (isuppr.eq.0.and.which.eq.';') then
00254             iscolon = ic0
00255         else
00256 c
00257 c           Start at the next ';'.
00258 c
00259             iscolon = ic0 + lextra + 1
00260             if (which.eq.'^') then
00261                 do while (iscolon.le.nl
00262      &                  .and.line(iscolon:iscolon).ne.';')
00263                     iscolon = iscolon + 1
00264                 end do
00265             end if
00266         end if
00267 c
00268         go to 10
00269 c       
00270 1001    return 1
00271         end
00272 
00273 
00274         subroutine expands(line,nl)
00275         save
00276 c
00277 c       Perform symbolic history expansion on line, replacing !string
00278 c       by !ihist.
00279 c
00280         character*(*)line
00281         character*6 temp
00282 c
00283         parameter (NHMAX = 500)
00284 c       
00285         character*200 history(NHMAX)
00286         common/histchars/history
00287         common/histnums/lhist(NHMAX),nhist
00288 c
00289         i2 = 0
00290 10      if (i2+1.ge.nl) return
00291 c
00292         call locsubstr(line,nl,'!',';',i1,i2,1)
00293         if (i1.le.0) return
00294 c
00295 c       Strip leading and trailing blanks.
00296 c
00297         i1save = i1
00298         i1 = i1 + 1
00299         do while (line(i1:i1).le.' ')
00300             i1 = i1 + 1
00301         end do
00302 c
00303 c       Note that i2 is either the location of a ";" or nl + 1.
00304 c
00305         i2save = i2
00306         i2 = i2 - 1
00307         do while (line(i2:i2).le.' ')
00308             i2 = i2 - 1
00309         end do
00310 c
00311         if (i1.le.i2) then
00312 c
00313 c           Now the string to be searched for lies in line(i1:i2).
00314 c           Only try to substitute if the entire string is non-numeric.
00315 c
00316             do i=i1,i2
00317                 if (line(i:i).lt.'0'.or.line(i:i).gt.'9') go to 50
00318             end do
00319             go to 100
00320 c
00321 50          do ihist = nhist,max(1,nhist-NHMAX),-1
00322 c
00323                 jh = ihist
00324                 do while (jh.gt.NHMAX)
00325                     jh = jh - NHMAX
00326                 end do
00327 c
00328                 if (index(history(jh)(1:lhist(jh)),line(i1:i2)).eq.1)
00329      &                  then
00330                     write(temp,'(''!'',i5)')ihist
00331                     call repsubstr(line,nl,i1save,i2save-1,temp,6)
00332 c
00333 c                   Note that we keep the trailing ";", if one exists.
00334 c
00335                     go to 100
00336                 end if
00337 c
00338             end do
00339         end if
00340 c
00341 c       Continue the search.
00342 c
00343 100     i2 = i2save
00344         go to 10
00345 c
00346         end
00347 
00348 
00349         subroutine applysubs(line,nl,*)
00350         save
00351 c
00352 c       Apply substitutions to the input line.  Expand each subcommand
00353 c       as necessary before making the changes.
00354 c
00355         character*(*) line
00356         character temp*200,subsn*80,subso*80
00357 c
00358         parameter (NHMAX = 500)
00359 c
00360         character*200 history(NHMAX)
00361         common /histchars/ history
00362         common /histnums/ lhist(NHMAX),nhist
00363 c
00364 c       Locate and process each reference.
00365 c
00366         i2 = 0
00367 c
00368 100     call locsubstr(line,nl,'!',';',i1,i2,1)
00369         if (i1.eq.0) return
00370 c
00371         nt = i2 - i1
00372         temp(1:nt) = line(i1:i2-1)
00373 c
00374 c       Note that temp includes the leading "!" but not the trailing ";".
00375 c
00376         kount = 0
00377         no = 1
00378         do while (no.gt.0.and.kount.lt.100)
00379 c
00380             call chksubs(temp,nt,nhist,iexpand,subso,no,subsn,nn)
00381 c
00382 c           Perform expansion, non-recursively, prior to substitution.
00383 c
00384             if (iexpand.gt.0) call expandl(temp,nt,1,*99999)
00385             if (no.gt.0) call substitute(temp,nt,subso,no,subsn,nn)
00386             kount = kount + 1
00387 c
00388         end do
00389 c
00390         call repsubstr(line,nl,i1,i2-1,temp,nt)
00391 c
00392 c       Continue the search.
00393 c
00394         i2 = i1 + nt
00395         go to 100
00396 c
00397 99999   return 1
00398 c
00399         end

Generated at Sun Feb 24 09:57:00 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001