FTN4 C C C NAME: EDTU2 C SOURCE: 92074-18008 C RELOC: PART OF 92074-12002 C PGMR: J.D.J. C C <800822.0800> C include ratdef C the define are merged in here - normally they're in file ratdef C C ampersand CAPOSTROPHE C exclamation mark C pushback buffer for ngetch and putbak C used for debug - change to (DB,) or (DB,#) C END OF QUOTE STRING C temporarily same as standard output C must be one more than HASHSZ C "`" C card size C characters for outnum C max chars in a defn C max space for for reinit clauses C must be 1 more than MAXCARD C file name size in gettok C number of defines in lookup C max stack depth for parser C max chars in all definitions C MAXTBUF = MAXTOK/2 + 1 C max chars in a token C number of special characters C max depth of file inclusion C "?" C TILDE for now; change for ebcdic C PPAT ZERO LENGTH LINE MATCH CHAR. CDEFINE(BOLCHAR,201B) # PPAT BEGINNIG OF LINE CHAR. C AMATCH (NON-RECURSIVE) - LOOK FOR MATCH STARTING AT LIN(FROM) INTEGER FUNCTION AMATCH(LIN ,FROM ,PAT) C,92074-1X008 REV.2034 800818 INTEGERLIN(82) ,PAT(100) INTEGER OMATCH ,PATSIZ INTEGER FROM ,I ,J ,OFFSET ,STACK ,TAGED ,TAGLVL ,RCNT ,PATJ C COMMON BLOCK FOR TAG POINTER IN MATCH PROGRAM COMMON /TAG/ TAGSRT(10),TAGSTP(10),TAGCNT INTEGER TAGSRT,TAGSTP,TAGCNT INTEGER BUFF(3) TAGED = 0 STACK = 0 C NEXT UNEXAMINED INPUT CHARACTER OFFSET = FROM CONTINUE J = 1 23000 IF(.NOT.(PAT(J) .NE. -2))GOTO 23002 PATJ = PAT(J) IF(.NOT. (PATJ .EQ. 42))GOTO 23003 C A CLOSURE ENTRY STACK = J C STEP OVER CLOSURE J = J + 4 CONTINUE I = OFFSET 23005 IF(.NOT.(LIN(I) .NE. -2))GOTO 23007 C MATCH AS MANY AS IF(.NOT. (OMATCH(LIN, I, PAT, J) .EQ. 0))GOTO 23008 C POSSIBLE GOTO 23007 23008 CONTINUE 23006 GOTO 23005 23007 CONTINUE PAT(STACK+1) = I - OFFSET PAT(STACK+3) = OFFSET C CHARACTER THAT MADE US FAIL OFFSET = I GOTO 23004 23003 CONTINUE IF(.NOT. (PATJ .EQ. 123.OR. PATJ .EQ. 125))GOTO 23010 C TAG FIELD C SAVE POSITION IN PATTERN PAT(J+1) = OFFSET TAGED = 1 CCALL EXEC(2,1,'/AMATCH: FOUND TAG _',-QLENGTH) CCALL EXEC(2,1,PATJ,1) CCALL EXEC(2,1,'/AMATCH: OFFSET=_',-QLENGTH) CCALL CNUMD(OFFSET,BUFF) CCALL EXEC(2,1,BUFF,3) GOTO 23011 23010 CONTINUE IF(.NOT. (OMATCH(LIN, OFFSET, PAT, J) .EQ. 0))GOTO 23012 C NON-CLOSURE CONTINUE 23014 IF(.NOT.(STACK .GT. 0))GOTO 23016 IF(.NOT. (PAT(STACK+1) .GT. 0))GOTO 23017 GOTO 23016 23017 CONTINUE 23015 STACK=PAT(STACK+2) GOTO 23014 23016 CONTINUE IF(.NOT. (STACK .LE. 0))GOTO 23019 C STACK IS EMPTY C RETURN FAILURE AMATCH = 0 RETURN 23019 CONTINUE PAT(STACK+1) = PAT(STACK+1) - 1 J = STACK + 4 OFFSET = PAT(STACK+3) + PAT(STACK+1) C ELSE OMATCH SUCCEEDED 23012 CONTINUE 23011 CONTINUE 23004 CONTINUE 23001 J=J+PATSIZ(PAT,J) GOTO 23000 23002 CONTINUE AMATCH = OFFSET CCALL EXEC(2,1,'/AMATCH: MATCH =_',-QLENGTH) CCALL EXEC(2,1,LIN(FROM), (AMATCH-FROM)) IF(.NOT.( TAGED .EQ. 1))GOTO 23021 C THEN THERE WERE TAGS IN THE PATTERN CCALL EXEC(2,1,'/AMATCH: TAGED = YES',-QLENGTH) TAGCNT = 0 RCNT = 0 TAGLVL = 0 CONTINUE J=1 23023 IF(.NOT.(PAT(J) .NE. -2))GOTO 23025 C RESCAN IF(.NOT.( PAT(J) .EQ. 123))GOTO 23026 TAGCNT = TAGCNT + 1 C PULL START POS. OUT OF PATTERN TAGSRT(TAGCNT) = PAT(J+1) TAGLVL = TAGLVL + 1 CCALL EXEC(2,1,'/AMATCH: TAGLVL=_',-QLENGTH) CCALL CNUMD(TAGLVL,BUFF) CCALL EXEC(2,1,BUFF,3) CCALL EXEC(2,1,'/AMATCH: TAGCNT=_',-QLENGTH) CCALL CNUMD(TAGCNT,BUFF) CCALL EXEC(2,1,BUFF,3) CCALL EXEC(2,1,'/AMATCH: PAT(J+1)=_',-QLENGTH) CCALL CNUMD(PAT(J+1),BUFF) CCALL EXEC(2,1,BUFF,3) CCALL EXEC(2,1,'/AMATCH: J=_',-QLENGTH) CCALL CNUMD(J,BUFF) CCALL EXEC(2,1,BUFF,3) GOTO 23027 23026 CONTINUE IF(.NOT.( PAT(J) .EQ. 125))GOTO 23028 C PULL STOP POS. OUT OF PATTERN TAGSTP(RCNT+TAGLVL) = PAT(J+1) TAGLVL = TAGLVL - 1 IF(.NOT.( TAGLVL .EQ. 0 ))GOTO 23030 RCNT = RCNT + 1 CCALL EXEC(2,1,'/AMATCH: TAGLVL=_',-QLENGTH) CCALL CNUMD(TAGLVL,BUFF) CCALL EXEC(2,1,BUFF,3) CCALL EXEC(2,1,'/AMATCH: RCNT=_',-QLENGTH) CCALL CNUMD(RCNT,BUFF) CCALL EXEC(2,1,BUFF,3) CCALL EXEC(2,1,'/AMATCH: PAT(J+1)=_',-QLENGTH) CCALL CNUMD(PAT(J+1),BUFF) CCALL EXEC(2,1,BUFF,3) CCALL EXEC(2,1,'/AMATCH: J=_',-QLENGTH) CCALL CNUMD(J,BUFF) CCALL EXEC(2,1,BUFF,3) 23030 CONTINUE C ELSE SKIP PATTERN 23028 CONTINUE 23027 CONTINUE CCALL EXEC(2,1,'/AMATCH: TAGSRT AND TAGSTP ARRAYS',-QLENGTH) CFOR(KK=1;KK. NOTE THAT SET MUST BE C SCANED FROM HIGH TO LOW INDEX TO FIND THE DASH FLAG FIRST. C C SUBROUTINE DODASH(VALID ,ARRAY ,I ,SET ,J ,MAXSET) C,92074-1X008 REV.2034 800818 INTEGERESC INTEGER ADDSET ,INDEX INTEGER I ,J ,JUNK ,K ,LIMIT ,MAXSET INTEGERARRAY(100) ,SET(MAXSET) ,VALID(100) C SKIP DASH I = I + 1 C C OLD CODE C J = J - 1 C LIMIT = INDEX(VALID, ESC(ARRAY, I)) C FOR (K = INDEX(VALID, SET(J)); K <= LIMIT; K = K + 1) C JUNK = ADDSET(VALID(K), SET, J, MAXSET) C C NEW CODE C JUNK = ADDSET(ESC(ARRAY ,I) ,SET ,J ,MAXSET) JUNK = ADDSET(-1 ,SET ,J ,MAXSET) CCALL EXEC(2,1,'/DODASH: SET =_',-QLENGTH) CCALL EXEC(2,1,SET,J) RETURN END C ESC - MAP ARRAY(I) INTO ESCAPED CHARACTER IF APPROPRIATE INTEGERFUNCTION ESC(ARRAY ,I) C,92074-1X008 REV.2034 800818 INTEGERARRAY(100) INTEGER I INTEGER ESCAPE COMMON /ESCCH/ ESCAPE IF(.NOT. (ARRAY(I) .NE. ESCAPE))GOTO 23189 ESC = ARRAY(I) GOTO 23190 23189 CONTINUE IF(.NOT. (ARRAY(I+1) .EQ. -2))GOTO 23191 C ESC NOT SPECIAL AT END ESC = ESCAPE GOTO 23192 23191 CONTINUE I = I + 1 ESC = ARRAY(I) 23192 CONTINUE 23190 CONTINUE RETURN END C FILSET - EXPAND SET AT ARRAY(I) INTO SET(J), STOP AT DELIM SUBROUTINE FILSET(DELIM ,ARRAY ,I ,SET ,J ,MAXSET) C,92074-1X008 REV.2034 800818 INTEGERESC INTEGER ADDSET ,INDEX INTEGER I ,J ,JUNK ,MAXSET INTEGERARRAY(100) ,DELIM ,SET(MAXSET) INTEGER ESCAPE COMMON /ESCCH/ ESCAPE C STRING DIGITS "0123456789" INTEGER DIGITS(11) C STRING LOWALF "ABCDEFGHIJKLMNOPQRSTUVWXYZ" INTEGER LOWALF(27) C STRING UPALF "ABCDEFGHIJKLMNOPQRSTUVWXYZ" INTEGER UPALF(27) DATA DIGITS(1)/48/ ,DIGITS(2)/49/ ,DIGITS(3)/50/ DATA DIGITS(4)/51/ ,DIGITS(5)/52/ ,DIGITS(6)/53/ DATA DIGITS(7)/54/ ,DIGITS(8)/55/ ,DIGITS(9)/56/ DATA DIGITS(10)/57/ ,DIGITS(11)/-2/ DATA LOWALF(01)/97/ DATA LOWALF(02)/98/ DATA LOWALF(03)/99/ DATA LOWALF(04)/100/ DATA LOWALF(05)/101/ DATA LOWALF(06)/102/ DATA LOWALF(07)/103/ DATA LOWALF(08)/104/ DATA LOWALF(09)/105/ DATA LOWALF(10)/106/ DATA LOWALF(11)/107/ DATA LOWALF(12)/108/ DATA LOWALF(13)/109/ DATA LOWALF(14)/110/ DATA LOWALF(15)/111/ DATA LOWALF(16)/112/ DATA LOWALF(17)/113/ DATA LOWALF(18)/114/ DATA LOWALF(19)/115/ DATA LOWALF(20)/116/ DATA LOWALF(21)/117/ DATA LOWALF(22)/118/ DATA LOWALF(23)/119/ DATA LOWALF(24)/120/ DATA LOWALF(25)/121/ DATA LOWALF(26)/122/ DATA LOWALF(27)/-2/ DATA UPALF(01) /65/ DATA UPALF(02) /66/ DATA UPALF(03) /67/ DATA UPALF(04) /68/ DATA UPALF(05) /69/ DATA UPALF(06) /70/ DATA UPALF(07) /71/ DATA UPALF(08) /72/ DATA UPALF(09) /73/ DATA UPALF(10) /74/ DATA UPALF(11) /75/ DATA UPALF(12) /76/ DATA UPALF(13) /77/ DATA UPALF(14) /78/ DATA UPALF(15) /79/ DATA UPALF(16) /80/ DATA UPALF(17) /81/ DATA UPALF(18) /82/ DATA UPALF(19) /83/ DATA UPALF(20) /84/ DATA UPALF(21) /85/ DATA UPALF(22) /86/ DATA UPALF(23) /87/ DATA UPALF(24) /88/ DATA UPALF(25) /89/ DATA UPALF(26) /90/ DATA UPALF(27) /-2/ CONTINUE 23193 IF(.NOT.(ARRAY(I) .NE. DELIM .AND. ARRAY(I) .NE. -2))GOTO 23195 IF(.NOT. (ARRAY(I) .EQ. ESCAPE))GOTO 23196 JUNK = ADDSET(ESC(ARRAY ,I) ,SET ,J ,MAXSET) GOTO 23197 23196 CONTINUE IF(.NOT. (ARRAY(I) .NE. 45))GOTO 23198 JUNK = ADDSET(ARRAY(I) ,SET ,J ,MAXSET) GOTO 23199 23198 CONTINUE IF(.NOT. (J .LE. 1 .OR. ARRAY(I+1) .EQ. -2))GOTO 23200 C LITERAL - JUNK = ADDSET(45 ,SET ,J ,MAXSET) GOTO 23201 23200 CONTINUE IF(.NOT. (INDEX(DIGITS, SET(J-1)) .GT. 0))GOTO 23202 CALL DODASH(DIGITS ,ARRAY ,I ,SET ,J ,MAXSET) GOTO 23203 23202 CONTINUE IF(.NOT. (INDEX(LOWALF, SET(J-1)) .GT. 0))GOTO 23204 CALL DODASH(LOWALF ,ARRAY ,I ,SET ,J ,MAXSET) GOTO 23205 23204 CONTINUE IF(.NOT. (INDEX(UPALF, SET(J-1)) .GT. 0))GOTO 23206 CALL DODASH(UPALF ,ARRAY ,I ,SET ,J ,MAXSET) GOTO 23207 23206 CONTINUE JUNK = ADDSET(45 ,SET ,J ,MAXSET) 23207 CONTINUE 23205 CONTINUE 23203 CONTINUE 23201 CONTINUE 23199 CONTINUE 23197 CONTINUE 23194 I=I+1 GOTO 23193 23195 CONTINUE RETURN END C MAKSET - MAKE SET FROM ARRAY(K) IN SET INTEGER FUNCTION MAKSET(ARRAY ,K ,SET ,SIZE) C,92074-1X008 REV.2034 800818 INTEGER ADDSET INTEGER I ,J ,K ,SIZE INTEGERARRAY(100) ,SET(SIZE) I = K J = 1 CALL FILSET(-2 ,ARRAY ,I ,SET ,J ,SIZE) MAKSET = ADDSET(-2 ,SET ,J ,SIZE) RETURN END C XINDEX - INVERT CONDITION RETURNED BY INDEX INTEGER FUNCTION XINDEX(ARRAY ,C ,ALLBUT ,LASTTO) C,92074-1X008 REV.2034 800818 INTEGERARRAY(100) ,C INTEGER INDEX INTEGER ALLBUT ,LASTTO IF(.NOT. (C .EQ. -12))GOTO 23208 XINDEX = 0 GOTO 23209 23208 CONTINUE IF(.NOT. (ALLBUT .EQ. 0))GOTO 23210 XINDEX = INDEX(ARRAY ,C) GOTO 23211 23210 CONTINUE IF(.NOT. (INDEX(ARRAY, C) .GT. 0))GOTO 23212 XINDEX = 0 GOTO 23213 23212 CONTINUE XINDEX = LASTTO + 1 23213 CONTINUE 23211 CONTINUE 23209 CONTINUE RETURN END C## GETLN - GET AN INPUT LINE C# INTEGER FUNCTION GETLN(LINE,INFILE) C# INTEGER LINE(ARB) C# INTEGER INFILE C# INTEGER C C# INTEGER GETCH C## C# FOR(I=1; I<=MAXLINE; I=I+1)[ C# C = GETCH(C,INFILE) C# LINE(I) = C C# IF( C == NEWLINE \C == EOF) C# BREAK C# ] C# LINE(I+1) = EOS C# IF ( C == NEWLINE ) C# GETLN = I C# ELSE C# GETLN = EOF C# RETURN C# END C CTOI - CONVERT STRING AT IN(I) TO INTEGER, INCREMENT I INTEGER FUNCTION CTOI(IN ,I) C,92074-1X008 REV.2034 800818 INTEGERIN(100) INTEGER INDEX INTEGER D ,I C STRING DIGITS "0123456789" INTEGER DIGITS(11) DATA DIGITS(1) /48/ DATA DIGITS(2) /49/ DATA DIGITS(3) /50/ DATA DIGITS(4) /51/ DATA DIGITS(5) /52/ DATA DIGITS(6) /53/ DATA DIGITS(7) /54/ DATA DIGITS(8) /55/ DATA DIGITS(9) /56/ DATA DIGITS(10) /57/ DATA DIGITS(11) /-2/ CONTINUE 23214 IF(.NOT. (IN(I) .EQ. 32.OR. IN(I) .EQ. 9))GOTO 23215 I = I + 1 GOTO 23214 23215 CONTINUE CONTINUE CTOI = 0 23216 IF(.NOT.(IN(I) .NE. -2))GOTO 23218 D = INDEX(DIGITS ,IN(I)) IF(.NOT. (D .EQ. 0))GOTO 23219 C NON-DIGIT GOTO 23218 23219 CONTINUE CTOI = 10 * CTOI + D - 1 23217 I=I+1 GOTO 23216 23218 CONTINUE RETURN END C###################################################################### C INDEX - FIND CHARACTER C IN STRING STR INTEGER FUNCTION INDEX(STR ,C) C,92074-1X008 REV.2034 800818 INTEGERC ,STR(100) CONTINUE INDEX = 1 23221 IF(.NOT.(STR(INDEX) .NE. -2))GOTO 23223 IF(.NOT. (STR(INDEX) .EQ. C))GOTO 23224 RETURN 23224 CONTINUE 23222 INDEX=INDEX+1 GOTO 23221 23223 CONTINUE INDEX = 0 RETURN END C LENGH - COMPUTE LENGTH OF STRING INTEGER FUNCTION LENGH(STR) C,92074-1X008 REV.2034 800818 INTEGER STR(100) CONTINUE LENGH = 0 23226 IF(.NOT.(STR(LENGH+1) .NE. -2))GOTO 23228 23227 LENGH=LENGH+1 GOTO 23226 23228 CONTINUE RETURN END C TYPE - RETURN LETTER, DIGIT OR CHARACTER C THIS ONE WORKS WITH ASCII ALPHABET INTEGER FUNCTION TYPE(C) C,92074-1X008 REV.2034 800818 INTEGER C IF(.NOT.( C .GE. 48.AND. C .LE. 57))GOTO 23229 TYPE = 2 GOTO 23230 23229 CONTINUE IF(.NOT.( C .GE. 97.AND. C .LE. 122))GOTO 23231 TYPE = 1 GOTO 23232 23231 CONTINUE IF(.NOT.( C .GE. 65.AND. C .LE. 90))GOTO 23233 TYPE = 1 GOTO 23234 23233 CONTINUE TYPE = C 23234 CONTINUE 23232 CONTINUE 23230 CONTINUE RETURN END SUBROUTINE ERROR(MESS) C,92074-1X008 REV.2034 800818 INTEGER MESS(10) CALL EXEC(2,1,MESS,20) CALL ERTN END C========= chang program from chapter 5 ========== Cdefine(maxpat,128) C catsub - add replacement text to end of new SUBROUTINE CATSUB(LIN ,FROM ,TO ,SUB ,NEW ,K ,MAXNEW) C,92074-1X008 REV.2034 800818 INTEGER ADDSET ,FOLD ,FOLDW INTEGER FROM ,I ,J ,JUNK ,K ,MAXNEW ,TO ,ISTART ,STOP ,SUBF ,C INTEGERLIN(100) ,NEW(MAXNEW) ,SUB(100) ,IBUF(15) INTEGER SUBI CINTEGER BUFF(3) C COMMON BLOCK FOR TAG POINTER IN MATCH PROGRAM COMMON /TAG/ TAGSRT(10),TAGSTP(10),TAGCNT INTEGER TAGSRT,TAGSTP,TAGCNT CONTINUE I = 1 23235 IF(.NOT.(SUB(I) .NE. -2))GOTO 23237 SUBF = SUB(I) IF(.NOT. (SUBF .EQ. (-3).OR. SUBF .EQ. (-4).OR. SUBF .EQ. (-5)))GO *TO 23238 I = I + 1 SUBI = SUB(I) C C &T no longer an option in substring C define(TIME,(-6) C if( subi == TIME ) { C call ftime(ibuf) C for(ii=1 ; ii<=30 ; ii=ii+1 ) C junk = addset( lbyte(ibuf,ii), new, k, maxnew) C istart = 0 # copy nothing C stop = 0 C } C else IF(.NOT.( SUBI .EQ. 0))GOTO 23240 ISTART = FROM STOP = TO GOTO 23241 23240 CONTINUE IF(.NOT.( SUBI .GE. 1 .AND. SUBI .LE. TAGCNT ))GOTO 23242 ISTART = TAGSRT( SUBI ) STOP = TAGSTP( SUBI ) GOTO 23243 23242 CONTINUE IF(.NOT.( SUBI .GT. TAGCNT .AND. SUBI .LE. 10))GOTO 23244 C non-secified C copy nothing ISTART = 0 STOP = 0 GOTO 23245 23244 CONTINUE CALL ERROR(21HCATSUB : CANT HAPPEN.) CCALL EXEC(2,1,'/CATSUB: istart=_',-QLENGTH) CCALL CNUMD(istart,BUFF) CCALL EXEC(2,1,BUFF,3) CCALL EXEC(2,1,'/CATSUB: STOP=_',-QLENGTH) CCALL CNUMD(STOP,BUFF) CCALL EXEC(2,1,BUFF,3) 23245 CONTINUE 23243 CONTINUE 23241 CONTINUE CONTINUE J = ISTART 23246 IF(.NOT.(J .LT. STOP))GOTO 23248 C = LIN(J) IF(.NOT.( SUBF .EQ. (-4)))GOTO 23249 C = FOLD(C) GOTO 23250 23249 CONTINUE IF(.NOT.( SUBF .EQ. (-5)))GOTO 23251 C = FOLDW(C) 23251 CONTINUE 23250 CONTINUE JUNK = ADDSET(C ,NEW ,K ,MAXNEW) 23247 J=J+1 GOTO 23246 23248 CONTINUE GOTO 23239 23238 CONTINUE JUNK = ADDSET(SUB(I) ,NEW ,K ,MAXNEW) 23239 CONTINUE 23236 I=I+1 GOTO 23235 23237 CONTINUE RETURN END C chang - chang "from" into "to" INTEGER FUNCTION CHANG(LIN,NEW,MAXLIN,PAT,SUBSRC,SUB) C,92074-1X008 REV.2034 800818 INTEGERLIN(100) ,NEW(MAXLIN) ,PAT(100) ,SUBSRC(100) ,SUB(100) C subsrc is the unfolded lin to be used in subsitutions INTEGER ADDSET ,AMATCH ,PRESN INTEGER I ,JUNK ,K ,LASTM ,M C number of exchanges counter COMMON /FDCNT/ FDCNT INTEGER FDCNT C single exchange flag COMMON /SXFLG/ SXFLG INTEGER SXFLG CCALL EXEC(2,1,'/CHANG: LIN=_',-QLENGTH) CCALL EXEC(2,1,LIN,LENGTH(LIN)) CCALL EXEC(2,1,'/CHANG: PAT=_',-QLENGTH) CCALL EXEC(2,1,PAT,LENGTH(PAT)) CCALL EXEC(2,1,'/CHANG: SUB=_',-QLENGTH) CCALL EXEC(2,1,SUB,LENGTH(SUB)) CHANG = 0 K = 1 LASTM = 0 IF(.NOT.( PRESN(LIN, PAT) .EQ. 1))GOTO 23253 CONTINUE I =1 23255 IF(.NOT.(LIN(I) .NE. -2))GOTO 23257 IF(.NOT.( SXFLG .LT. 0 .AND. CHANG .EQ. 1))GOTO 23258 C test for single exchange M = 0 GOTO 23259 23258 CONTINUE M = AMATCH(LIN ,I ,PAT) 23259 CONTINUE IF(.NOT. (M .GT. 0 .AND. LASTM .NE. M))GOTO 23260 C replace matched text CHANG = 1 C bump counter FDCNT = FDCNT+1 CALL CATSUB(SUBSRC ,I ,M ,SUB ,NEW ,K ,MAXLIN) LASTM = M 23260 CONTINUE IF(.NOT. (M .EQ. 0 .OR. M .EQ. I))GOTO 23262 C no match or null match JUNK = ADDSET(SUBSRC(I) ,NEW ,K ,MAXLIN) I = I + 1 GOTO 23263 23262 CONTINUE C skip matched text I = M 23263 CONTINUE 23256 GOTO 23255 23257 CONTINUE 23253 CONTINUE IF(.NOT. (ADDSET(-2, NEW, K, MAXLIN) .EQ. 0))GOTO 23264 K = MAXLIN JUNK = ADDSET(-2 ,NEW ,K ,MAXLIN) CHANG = -1 CCALL EXEC(2,1,NEW,LENGTH(NEW)) 23264 CONTINUE RETURN END C fold - fold to upper case INTEGERFUNCTION FOLD(C) C,92074-1X008 REV.2034 800818 INTEGERC IF(.NOT.( C .GE. 97.AND. C .LE. 122))GOTO 23266 FOLD = C - 32 GOTO 23267 23266 CONTINUE FOLD = C 23267 CONTINUE RETURN END C foldw - fold to lower case INTEGERFUNCTION FOLDW(C) C,92074-1X008 REV.2034 800818 INTEGERC IF(.NOT.( C .GE. 65.AND. C .LE. 90))GOTO 23268 FOLDW = C + 32 GOTO 23269 23268 CONTINUE FOLDW = C 23269 CONTINUE RETURN END C getsub - get substitution pattern into sub INTEGER FUNCTION GETSUB(ARG ,SUB ,MAXPAT) C,92074-1X008 REV.2034 800818 INTEGERARG(128) ,SUB(MAXPAT) ,MAXPAT INTEGER MAKSUB GETSUB = MAKSUB(ARG ,1 ,-2 ,SUB,MAXPAT) RETURN END C maksub - make substitution string in sub INTEGER FUNCTION MAKSUB(ARG ,FROM ,DELIM ,SUB ,MAXPAT) C,92074-1X008 REV.2034 800818 INTEGERESC INTEGERARG(128) ,DELIM ,SUB(MAXPAT) INTEGER ADDSET INTEGER FROM ,I ,J ,JUNK ,ARGI ,SUBFLD INTEGER DIGITS(10) DATA DIGITS(1)/49/ ,DIGITS(2)/50/ ,DIGITS(3)/51/ DATA DIGITS(4)/52/ ,DIGITS(5)/53/ ,DIGITS(6)/54/ DATA DIGITS(7)/55/ ,DIGITS(8)/56/ ,DIGITS(9)/57/ DATA DIGITS(10)/-2/ CCALL EXEC(2,1,'MAKSUB: ARG=_',-QLENGTH) CCALL EXEC(2,1,ARG,LENGTH(ARG)) J = 1 CONTINUE I = FROM 23270 IF(.NOT.(ARG(I) .NE. DELIM .AND. ARG(I) .NE. -2))GOTO 23272 ARGI = ARG(I) IF(.NOT.( ARGI .EQ. 38))GOTO 23273 SUBFLD = (-3) GOTO 23274 23273 CONTINUE IF(.NOT.( ARGI .EQ. 62))GOTO 23275 SUBFLD = (-4) GOTO 23276 23275 CONTINUE IF(.NOT.(ARGI .EQ. 60))GOTO 23277 SUBFLD = (-5) GOTO 23278 23277 CONTINUE SUBFLD = 0 23278 CONTINUE 23276 CONTINUE 23274 CONTINUE IF(.NOT. (SUBFLD .NE. 0 ))GOTO 23279 JUNK = ADDSET(SUBFLD ,SUB ,J ,MAXPAT) C C &T no longer an option in subfield C C if( arg(i+1) == bigT \ arg(i+1) == lett ) { C junk = addset( TIME, sub, j, maxpat) C i = i + 1 C } C else K = INDEX(DIGITS ,ARG(I+1)) IF(.NOT.( K .NE. 0 ))GOTO 23281 I = I + 1 23281 CONTINUE JUNK = ADDSET( K ,SUB ,J ,MAXPAT) GOTO 23280 23279 CONTINUE JUNK = ADDSET(ESC(ARG ,I) ,SUB ,J ,MAXPAT) 23280 CONTINUE 23271 I=I+1 GOTO 23270 23272 CONTINUE IF(.NOT. (ARG(I) .NE. DELIM))GOTO 23283 C missing delimiter MAKSUB = -1 GOTO 23284 23283 CONTINUE IF(.NOT. (ADDSET(-2, SUB, J, MAXPAT) .EQ. 0))GOTO 23285 C no room MAKSUB = -1 GOTO 23286 23285 CONTINUE MAKSUB = I CCALL EXEC(2,1,'MAKSUB: SUB =_',-QLENGTH) CCALL EXEC(2,1,SUB,LENGTH(SUB)) 23286 CONTINUE 23284 CONTINUE RETURN END C COMMON BLOCKS BLOCK DATA C,92074-1X008 REV.2034 800818 C COMMON BLOCK FOR TAG POINTER IN MATCH PROGRAM COMMON /TAG/ TAGSRT(10),TAGSTP(10),TAGCNT INTEGER TAGSRT,TAGSTP,TAGCNT END END$ C C C NAME: EDTU2 C SOURCE: 92074-18008 C RELOC: PART OF 92074-12002 C PGMR: J.D.J. C # <800822.0800> INCLUDE RATDEF DEFINE(DB, #) DEFINE(DBP,#) DEFINE(DB1,#) DEFINE(DB3,#) DEFINE(DB4,#) DEFINE(DB5,#) DEFINE(DB6,#) DEFINE(DB7,#) DEFINE(DB9,#) DEFINE(ZEROLEN,200B) # PPAT ZERO LENGTH LINE MATCH CHAR. #DEFINE(BOLCHAR,201B) # PPAT BEGINNIG OF LINE CHAR. DEFINE(TAGS,10) DEFINE(COUNT,1) DEFINE(PREVCL,2) DEFINE(START,3) DEFINE(CLOSIZE,4) DEFINE(TRANSCL,PLUS) DEFINE(REPEATSC,LESS) DEFINE(REPEATEC,GREATER) DEFINE(INDEFCHAR,ATSIGN) DEFINE(NOT,CARET) DEFINE(BOL,CARET) DEFINE(ANY,PERIOD) DEFINE(EOL,DOLLAR) DEFINE(BOUNDARY,COLON) DEFINE(CLOSURE,STAR) DEFINE(CCL,LBRACK) DEFINE(CCLEND,RBRACK) DEFINE(LTAG,LBRACE) DEFINE(RTAG,RBRACE) DEFINE(NCCL,LETN) DEFINE(CHAR,LETA) DEFINE(DASH,MINUS) DEFINE(DASHFLAG,-1) # AMATCH (NON-RECURSIVE) - LOOK FOR MATCH STARTING AT LIN(FROM) INTEGER FUNCTION AMATCH(LIN, FROM, PAT) " C,92074-1X008 REV.2034 800818" CHARACTER LIN(MAXLINE), PAT(ARB) INTEGER OMATCH, PATSIZ INTEGER FROM, I, J, OFFSET, STACK, TAGED, TAGLVL, RCNT, PATJ INCLUDE CTAG INTEGER BUFF(3) TAGED = NO STACK = 0 OFFSET = FROM # NEXT UNEXAMINED INPUT CHARACTER FOR (J = 1; PAT(J) ^= EOS; J = J + PATSIZ(PAT, J))[ PATJ = PAT(J) IF (PATJ == CLOSURE) [ # A CLOSURE ENTRY STACK = J J = J + CLOSIZE # STEP OVER CLOSURE FOR (I = OFFSET; LIN(I) ^= EOS; ) # MATCH AS MANY AS IF (OMATCH(LIN, I, PAT, J) == NO) # POSSIBLE BREAK PAT(STACK+COUNT) = I - OFFSET PAT(STACK+START) = OFFSET OFFSET = I # CHARACTER THAT MADE US FAIL ] ELSE IF (PATJ == LTAG \ PATJ == RTAG)[ # TAG FIELD PAT(J+1) = OFFSET # SAVE POSITION IN PATTERN TAGED = YES DB5 CALL EXEC(2,1,'/AMATCH: FOUND TAG _',-QLENGTH) DB5 CALL EXEC(2,1,PATJ,1) DB6 CALL EXEC(2,1,'/AMATCH: OFFSET=_',-QLENGTH) DB6 CALL CNUMD(OFFSET,BUFF) DB6 CALL EXEC(2,1,BUFF,3) ] ELSE IF (OMATCH(LIN, OFFSET, PAT, J) == NO) [ # NON-CLOSURE FOR ( ; STACK > 0; STACK = PAT(STACK+PREVCL)) IF (PAT(STACK+COUNT) > 0) BREAK IF (STACK <= 0) [ # STACK IS EMPTY AMATCH = 0 # RETURN FAILURE RETURN ] PAT(STACK+COUNT) = PAT(STACK+COUNT) - 1 J = STACK + CLOSIZE OFFSET = PAT(STACK+START) + PAT(STACK+COUNT) ] # ELSE OMATCH SUCCEEDED ] AMATCH = OFFSET DB4 CALL EXEC(2,1,'/AMATCH: MATCH =_',-QLENGTH) DB4 CALL EXEC(2,1,LIN(FROM), (AMATCH-FROM)) IF( TAGED == YES ) [ # THEN THERE WERE TAGS IN THE PATTERN DB6 CALL EXEC(2,1,'/AMATCH: TAGED = YES',-QLENGTH) TAGCNT = 0 RCNT = 0 TAGLVL = 0 FOR( J=1 ; PAT(J) ^= EOS ; J = J + PATSIZ(PAT, J)) [ # RESCAN IF( PAT(J) == LTAG) [ TAGCNT = TAGCNT + 1 TAGSRT(TAGCNT) = PAT(J+1) # PULL START POS. OUT OF PATTERN TAGLVL = TAGLVL + 1 DB6 CALL EXEC(2,1,'/AMATCH: TAGLVL=_',-QLENGTH) DB6 CALL CNUMD(TAGLVL,BUFF) DB6 CALL EXEC(2,1,BUFF,3) DB6 CALL EXEC(2,1,'/AMATCH: TAGCNT=_',-QLENGTH) DB6 CALL CNUMD(TAGCNT,BUFF) DB6 CALL EXEC(2,1,BUFF,3) DB6 CALL EXEC(2,1,'/AMATCH: PAT(J+1)=_',-QLENGTH) DB6 CALL CNUMD(PAT(J+1),BUFF) DB6 CALL EXEC(2,1,BUFF,3) DB6 CALL EXEC(2,1,'/AMATCH: J=_',-QLENGTH) DB6 CALL CNUMD(J,BUFF) DB6 CALL EXEC(2,1,BUFF,3) ] ELSE IF( PAT(J) == RTAG ) [ TAGSTP(RCNT+TAGLVL) = PAT(J+1) # PULL STOP POS. OUT OF PATTERN TAGLVL = TAGLVL - 1 IF( TAGLVL == 0 ) RCNT = RCNT + 1 DB6 CALL EXEC(2,1,'/AMATCH: TAGLVL=_',-QLENGTH) DB6 CALL CNUMD(TAGLVL,BUFF) DB6 CALL EXEC(2,1,BUFF,3) DB6 CALL EXEC(2,1,'/AMATCH: RCNT=_',-QLENGTH) DB6 CALL CNUMD(RCNT,BUFF) DB6 CALL EXEC(2,1,BUFF,3) DB6 CALL EXEC(2,1,'/AMATCH: PAT(J+1)=_',-QLENGTH) DB6 CALL CNUMD(PAT(J+1),BUFF) DB6 CALL EXEC(2,1,BUFF,3) DB6 CALL EXEC(2,1,'/AMATCH: J=_',-QLENGTH) DB6 CALL CNUMD(J,BUFF) DB6 CALL EXEC(2,1,BUFF,3) ] # ELSE SKIP PATTERN ] DB3 CALL EXEC(2,1,'/AMATCH: TAGSRT AND TAGSTP ARRAYS',-QLENGTH) DB3 FOR(KK=1;KK OFFSET; I = I - 1)[ PATI = PAT(I) # # NEW CODE FOR DASH AS A SUB-PATTERN # IF( PATI == DASHFLAG ) [ I = I-2 IF( C>=PAT(I) & C<=PAT(I+1) ) [ LOCATE = YES DB7 CALL EXEC(2,1,'/LOCATE: RETURN YES FROM DASH PATTERN',-QLENGTH) RETURN ] ] ELSE IF (C == PATI) [ LOCATE = YES DB7 CALL EXEC(2,1,'/LOCATE: RETURN YES',-QLENGTH) RETURN ] ] # CLOSE FOR LOOP LOCATE = NO DB7 CALL EXEC(2,1,'/LOCATE: RETURN NO',-QLENGTH) RETURN END # SUFIX - TEST IF IT IS OK TO HAVE SUFIX ON THIS PATTERN INTEGER FUNCTION SUFIX(PAT) " C,92074-1X008 REV.2034 800818" INTEGER PAT IF (PAT==BOL \ PAT==EOL \ PAT==CLOSURE \ PAT==LTAG \ PAT==RTAG ) SUFIX = NO ELSE SUFIX = YES RETURN END # COPY - COPY N CHARACTERS, INCERMENT J SUBROUTINE COPY (N, FROM, I, TO, J, MAXTO) " C,92074-1X008 REV.2034 800818" INTEGER N, FROM(ARB), I, TO(MAXTO), J, MAXTO, II, JJ, K II = I FOR( K=1 ; K<=N ; K=K+1 ) [ IF( J > MAXTO ) RETURN TO(J) = FROM(II) J = J + 1 II = II + 1 ] RETURN END # MAKPAT - MAKE PATTERN FROM ARG(FROM), TERMINATE AT DELIM # - BUILD POSSIBLE MATCH INTO PPAT INTEGER FUNCTION MAKPAT(ARG, FROM, DELIM, PAT, PPAT, MAXPAT) " C,92074-1X008 REV.2034 800818" CHARACTER ESC CHARACTER ARG(MAXARG), DELIM, PAT(MAXPAT),PPAT(MAXPAT) INTEGER ADDSET, GETCCL, STCLOS, PATSIZ, SUFIX, CTOI INTEGER FROM, I, J, JUNK, LASTCL, LASTJ, LJ, LP, TAGPTR INTEGER ARGI,PATN COMMON /ESCCH/ ESCCH # PPAT ESCAPE CHAR INTEGER ESCCH COMMON /ANCCH/ ANCCH # PPAT ANCHOR CHAR INTEGER ANCCH COMMON /INDEF/ INDEF # PPAT INDEFINATE MATCH CHAR INTEGER INDEF DB CALL EXEC(2,1,'/MAKPAT: ARG=_',-QLENGTH) DB CALL EXEC(2,1,ARG,LENGTH(ARG)) J = 1 # PAT INDEX LASTJ = 1 LASTCL = 0 TAGPTR = 0 FOR (I = FROM; ARG(I) ^= DELIM & ARG(I) ^= EOS; I = I + 1) [ LJ = J ARGI = ARG(I) IF (ARGI == ANY) JUNK = ADDSET(ANY, PAT, J, MAXPAT) ELSE IF (ARGI == ANCCH & I == FROM) JUNK = ADDSET(BOL, PAT, J, MAXPAT) ELSE IF (ARGI == EOL & ARG(I + 1) == DELIM) JUNK = ADDSET(EOL, PAT, J, MAXPAT) ELSE IF(ARGI == BOUNDARY) JUNK = ADDSET(BOUNDARY, PAT, J, MAXPAT) ELSE IF (ARGI == CCL) [ IF (GETCCL(ARG, I, PAT, J, MAXPAT) == ERR) BREAK ] ELSE IF (ARGI==LTAG & ARG(I+1) ^= DELIM) [ TAGPTR = TAGPTR + 1 IF(TAGPTR > TAGS ) BREAK JUNK = ADDSET(LTAG, PAT, J, MAXPAT) JUNK = ADDSET(0, PAT, J, MAXPAT) # ROOM FOR POINTER ] ELSE IF(ARGI == RTAG & I > FROM) [ TAGPTR = TAGPTR - 1 IF( TAGPTR < 0 ) BREAK JUNK = ADDSET(RTAG, PAT, J, MAXPAT) JUNK = ADDSET(0, PAT, J, MAXPAT) # ROOM FOR POINTER ] ELSE IF ( ARGI == INDEF ) [ # ALLOW '@' TO BE '.*' JUNK = ADDSET(ANY, PAT, J, MAXPAT) LASTJ = LJ LJ = LASTJ LASTCL = STCLOS(PAT, J, LASTJ, LASTCL, MAXPAT) ] ELSE IF (ARGI == REPEATSC ) [ IF (SUFIX(PAT(LASTJ)) == NO ) BREAK L = I+1 K = CTOI (ARG, L) IF( ARG(L) ^= REPEATEC) [ JUNK = ADDSET( CHAR, PAT, J, MAXPAT) JUNK = ADDSET( ARGI, PAT, J, MAXPAT) ] ELSE [ # DO REPEAT COUNT I = L # SKIP OVER COUNT FOR( II=1 ; II<=K-1 ; II=II+1 ) [ L = J - LASTJ # GET SIZE JTEMP = LASTJ LASTJ = J CALL COPY(L, PAT, JTEMP, PAT, J, MAXPAT) LJ = J ] ] ] ELSE IF ((ARGI==CLOSURE \ ARGI == TRANSCL ) & I > FROM) [ IF( SUFIX(PAT(LASTJ)) == NO ) # OK TO SUFIX LAST PATTERN ? BREAK IF ( ARGI == TRANSCL ) [ # FOR TRANSTIVE CLOSURES L = J - LASTJ # COPY PREV PATTERN THEN DO CLOSURE JTEMP = LASTJ LASTJ = J CALL COPY(L, PAT, JTEMP, PAT, J, MAXPAT) LJ = J ] LJ = LASTJ LASTCL = STCLOS(PAT, J, LASTJ, LASTCL, MAXPAT) ] ELSE [ JUNK = ADDSET(CHAR, PAT, J, MAXPAT) JUNK = ADDSET(ESC(ARG, I), PAT, J, MAXPAT) ] LASTJ = LJ ] IF (ARG(I) ^= DELIM) # TERMINATED EARLY MAKPAT = ERR ELSE IF ( TAGPTR ^= 0 ) # UNBALANCED TAG FIELDS MAKPAT = ERR ELSE IF (ADDSET(EOS, PAT, J, MAXPAT) == NO) # NO ROOM MAKPAT = ERR ELSE [ # PATERN OK DB CALL EXEC(2,1,'/MAKPAT: PAT=_',-QLENGTH) DB CALL EXEC(2,1,PAT,LENGTH(PAT)) MAKPAT = I # # BUILD POSSIBLE MATCH PATTERN # # PPAT IS ALWAYS SMALLER THAN PAT SO WE DON'T NEED TO DO # LIMIT CHECKS J = 1 I = 1 LP = ERR IF( PAT(1) == BOL ) [ I = I + PATSIZ(PAT, 1) # SKIP BOL IF( PAT(2) == EOL ) [ # LOOK FOR ZERO LENGTH LINE LP = ZEROLEN # SPECIAL TO MATCH ZERO LENGTH LINE ] ELSE [ LP = ANCCH # SET IN ANCHOR CHAR ] PPAT(J) = LP J = 2 ] ELSE [ # PUT AN INDEF. CHAR AS START OF PATTERN LP = INDEF PPAT(J) = LP J = 2 ] FOR( ; PAT(I) ^= EOS; I=I+PATSIZ(PAT,I)) [ PATN = PAT(I) IF( PATN == CHAR )[ # SINGLE CHAR ? LP = PAT(I+1) IF( LP == ANCCH \ LP == INDEF \ LP == ESCCH ) [ # TEST FOR SPECIALS PPAT(J) = ESCCH # ESCAPE SPECIALS J = J + 1 ] PPAT(J) = LP J = J+1 ] ELSE IF( PATN == LTAG \ PATN == RTAG \ % PATN == EOL \ PATN == BOUNDARY) ; # JUST SKIP THEM ELSE IF(PATN == ANY \ PATN == CCL \ PATN == NCCL \ % PATN == CLOSURE ) [ IF( LP ^= INDEF ) [ LP = INDEF # USE AN INDEFINATE CHARACTER MATCH PPAT(J) = INDEF J = J + 1 ] IF( PATN == CLOSURE ) [ I = I + PATSIZ(PAT, I) # CLOSURE TAKES TWO PATTERNS ] ] ELSE [ DB PPAT(J) = PATN DB PPAT(J+1) = EOS DB CALL EXEC(2,1,'MAKPAT: PPAT=_',-QLENGTH) DB CALL EXEC(2,1,PPAT,LENGTH(PPAT)) CALL ERROR("BUG IN POSSIBLE MATCH.") ] ] # CLOSE FOR PPAT(J) = EOS DBP CALL EXEC(2,1,'MAKPAT: PPAT=_',-QLENGTH) DBP CALL EXEC(2,1,PPAT,LENGTH(PPAT)) ] # CLOSE ELSE PATTERN OK RETURN END # MATCH - FIND MATCH ANYWHERE ON LINE INTEGER FUNCTION MATCH(LIN, PAT) " C,92074-1X008 REV.2034 800818" CHARACTER LIN(MAXLINE), PAT(ARB) INTEGER AMATCH INTEGER I, PATSIZ, OMATCH, PATJ, PRESN DB CALL EXEC(2,1,'/MATCH: LIN=_',-QLENGTH) DB CALL EXEC(2,1,LIN,LENGTH(LIN)) DB CALL EXEC(2,1,'/MATCH: PAT=_',-QLENGTH) DB CALL EXEC(2,1,PAT,LENGTH(PAT)) IF( PRESN(LIN, PAT) == YES ) FOR (I = 1; LIN(I) ^= EOS; I = I + 1) IF (AMATCH(LIN, I, PAT) > 0) [ MATCH = YES RETURN ] MATCH = NO RETURN END # PRESC - DO PRESCAN TO SEE IF PATTERN MAY MATCH INTEGER FUNCTION PRESN(LIN,PAT) " C,92074-1X008 REV.2034 800818" # # # FIRST SCAN TO SEE IF ALL THE NON-CLOSURE PATTERNS CAN BE # MATCHED INORDER WHEN THEY ARE SEPERATED BY ANY NUMBER OF # CHARS. THIS PREVENT A HUGE AMOUNT OF BACKTRACKING FOR # PATTERNS LIKE .*[^ ].*[AB][AB] # INTEGER LIN(ARB), PAT(ARB), PATJ, PATSIZ, OMATCH I = 1 J = 1 REPEAT [ # UNTIL PAT(J) == EOS OR RETURN ON FAILURE PATJ = PAT(J) IF( PATJ == EOS ) BREAK # END OF PATTERN FOUND SO GO TRY REAL MATCH IF( PATJ == CLOSURE ) [ # SKIP CLOSURE AND IT PATTERN J = J + PATSIZ(PAT, J) ] ELSE IF( PATJ == LTAG \ PATJ == RTAG ) ; # JUST SKIP THEM ELSE [ # SEE IF PATTERN MATCH ANYWHERE ON LINE REPEAT [ IF( LIN(I) == EOS ) [ # THEN UNSUCCESSFUL PRESN = NO RETURN ] IF( OMATCH(LIN, I, PAT, J) == YES ) BREAK # ELSE I = I + 1 ] ] J = J + PATSIZ(PAT, J) DB9 CALL EXEC(2,1,'/MATCH: PRESCAN MATCHED PAT=_',-QLENGTH) DB9 CALL EXEC(2,1,PAT, J) ] # # WE NOW KNOW THERE IS ENOUGH NON-CLOSURE PATTERNS WHICH MATCH # SO THE CLOSURE MATCH MAY BE SUCCESSFUL. # DB9 CALL EXEC(2,1,'/PRESN: SUCCESS',-QLENGTH) PRESN = YES RETURN END # OMATCH - TRY TO MATCH A SINGLE PATTERN AT PAT(J) INTEGER FUNCTION OMATCH(LIN, I, PAT, J) " C,92074-1X008 REV.2034 800818" CHARACTER LIN(MAXLINE), PAT(ARB) INTEGER LOCATE, ALPNU INTEGER BUMP, I, J, PATJ, LINI OMATCH = NO IF (LIN(I) == EOS) RETURN BUMP = -1 PATJ = PAT(J) LINI = LIN(I) IF (PATJ == CHAR) [ IF (LINI == PAT(J + 1)) BUMP = 1 ] ELSE IF (PATJ == BOL) [ IF (I == 1) BUMP = 0 ] ELSE IF (PATJ == ANY) [ IF (LINI ^= NEWLINE) BUMP = 1 ] ELSE IF (PATJ == EOL) [ IF (LINI == NEWLINE) BUMP = 0 ] ELSE IF(PATJ == BOUNDARY) [ IF (I == 1) BUMP = 0 ELSE IF( IXOR(ALPNU(LIN(I-1)), ALPNU(LINI)) ^= 0 ) BUMP = 0 # IF TYPES ARE DIFFERENT THEN MATCH ] ELSE IF (PATJ == CCL) [ IF (LOCATE(LINI, PAT, J + 1) == YES) BUMP = 1 ] ELSE IF (PATJ == NCCL) [ IF (LINI ^= NEWLINE & LOCATE(LINI, PAT, J + 1) == NO) BUMP = 1 ] ELSE CALL ERROR("IN OMATCH: CAN'T HAPPEN.") IF (BUMP >= 0) [ I = I + BUMP OMATCH = YES ] RETURN END # ALPNU - RETURN 1 IF CHAR IS ALPHANUMERIC ELSE RETURN 0 INTEGER FUNCTION ALPNU(C) " C,92074-1X008 REV.2034 800818" CHARACTER C INTEGER TYPE,T T = TYPE(C) IF( T == DIGIT \ T == LETTER ) ALPNU = 1 ELSE ALPNU = 0 RETURN END # PATSIZ - RETURNS SIZE OF PATTERN ENTRY AT PAT(N) INTEGER FUNCTION PATSIZ(PAT, N) " C,92074-1X008 REV.2034 800818" CHARACTER PAT(ARB) INTEGER N, PATN PATN = PAT(N) IF (PATN == CHAR \ PATN == LTAG \ PATN == RTAG) PATSIZ = 2 ELSE IF (PATN == BOL \ PATN == EOL \ PATN == ANY \ PATN == BOUNDARY) PATSIZ = 1 ELSE IF (PATN == CCL \ PATN == NCCL) PATSIZ = PAT(N + 1) + 2 ELSE IF (PATN == CLOSURE) PATSIZ = CLOSIZE ELSE CALL ERROR("IN PATSIZ: CAN'T HAPPEN.") RETURN END # STCLOS - INSERT CLOSURE ENTRY AT PAT(J) INTEGER FUNCTION STCLOS(PAT, J, LASTJ, LASTCL, MAXPAT) " C,92074-1X008 REV.2034 800818" CHARACTER PAT(MAXPAT) INTEGER ADDSET INTEGER J, JP, JT, JUNK, LASTCL, LASTJ FOR (JP = J - 1; JP >= LASTJ; JP = JP - 1) [ # MAKE A HOLE JT = JP + CLOSIZE JUNK = ADDSET(PAT(JP), PAT, JT, MAXPAT) ] J = J + CLOSIZE STCLOS = LASTJ JUNK = ADDSET(CLOSURE, PAT, LASTJ, MAXPAT) # PUT CLOSURE IN IT JUNK = ADDSET(0, PAT, LASTJ, MAXPAT) # COUNT JUNK = ADDSET(LASTCL, PAT, LASTJ, MAXPAT) # PREVCL JUNK = ADDSET(0, PAT, LASTJ, MAXPAT) # START RETURN END # ADDSET - PUT C IN SET(J) IF IT FITS, INCREMENT J INTEGER FUNCTION ADDSET(C, SET, J, MAXSIZ) " C,92074-1X008 REV.2034 800818" INTEGER J, MAXSIZ CHARACTER C, SET(MAXSIZ) IF (J > MAXSIZ) ADDSET = NO ELSE [ SET(J) = C J = J + 1 ADDSET = YES ] RETURN END # DODASH - EXPAND ARRAY(I-1)-ARRAY(I+1) INTO SET(J)... FROM VALID # # NEW CODE IS BUILD DASH PATTERN AT ARRAY(I-1)-ARRAY(I+1) INTO # SET(J). SET(J-1) HAS ARRAY(I-1) ALREADY IN IT. # # PATTERN IS . NOTE THAT SET MUST BE # SCANED FROM HIGH TO LOW INDEX TO FIND THE DASH FLAG FIRST. # # SUBROUTINE DODASH(VALID, ARRAY, I, SET, J, MAXSET) " C,92074-1X008 REV.2034 800818" CHARACTER ESC INTEGER ADDSET, INDEX INTEGER I, J, JUNK, K, LIMIT, MAXSET CHARACTER ARRAY(ARB), SET(MAXSET), VALID(ARB) I = I + 1 # SKIP DASH # # OLD CODE # J = J - 1 # LIMIT = INDEX(VALID, ESC(ARRAY, I)) # FOR (K = INDEX(VALID, SET(J)); K <= LIMIT; K = K + 1) # JUNK = ADDSET(VALID(K), SET, J, MAXSET) # # NEW CODE # JUNK = ADDSET(ESC(ARRAY, I), SET, J, MAXSET) JUNK = ADDSET(DASHFLAG, SET, J, MAXSET) DB7 CALL EXEC(2,1,'/DODASH: SET =_',-QLENGTH) DB7 CALL EXEC(2,1,SET,J) RETURN END # ESC - MAP ARRAY(I) INTO ESCAPED CHARACTER IF APPROPRIATE CHARACTER FUNCTION ESC(ARRAY, I) " C,92074-1X008 REV.2034 800818" CHARACTER ARRAY(ARB) INTEGER I INTEGER ESCAPE COMMON /ESCCH/ ESCAPE IF (ARRAY(I) ^= ESCAPE) ESC = ARRAY(I) ELSE IF (ARRAY(I+1) == EOS) # ESC NOT SPECIAL AT END ESC = ESCAPE ELSE [ I = I + 1 ESC = ARRAY(I) ] RETURN END # FILSET - EXPAND SET AT ARRAY(I) INTO SET(J), STOP AT DELIM SUBROUTINE FILSET(DELIM, ARRAY, I, SET, J, MAXSET) " C,92074-1X008 REV.2034 800818" CHARACTER ESC INTEGER ADDSET, INDEX INTEGER I, J, JUNK, MAXSET CHARACTER ARRAY(ARB), DELIM, SET(MAXSET) INTEGER ESCAPE COMMON /ESCCH/ ESCAPE # STRING DIGITS "0123456789" INTEGER DIGITS(11) # STRING LOWALF "ABCDEFGHIJKLMNOPQRSTUVWXYZ" INTEGER LOWALF(27) # STRING UPALF "ABCDEFGHIJKLMNOPQRSTUVWXYZ" INTEGER UPALF(27) DATA DIGITS(1)/DIG0/, DIGITS(2)/DIG1/, DIGITS(3)/DIG2/ DATA DIGITS(4)/DIG3/, DIGITS(5)/DIG4/, DIGITS(6)/DIG5/ DATA DIGITS(7)/DIG6/, DIGITS(8)/DIG7/, DIGITS(9)/DIG8/ DATA DIGITS(10)/DIG9/, DIGITS(11)/EOS/ DATA LOWALF(01)/LETA/ DATA LOWALF(02)/LETB/ DATA LOWALF(03)/LETC/ DATA LOWALF(04)/LETD/ DATA LOWALF(05)/LETE/ DATA LOWALF(06)/LETF/ DATA LOWALF(07)/LETG/ DATA LOWALF(08)/LETH/ DATA LOWALF(09)/LETI/ DATA LOWALF(10)/LETJ/ DATA LOWALF(11)/LETK/ DATA LOWALF(12)/LETL/ DATA LOWALF(13)/LETM/ DATA LOWALF(14)/LETN/ DATA LOWALF(15)/LETO/ DATA LOWALF(16)/LETP/ DATA LOWALF(17)/LETQ/ DATA LOWALF(18)/LETR/ DATA LOWALF(19)/LETS/ DATA LOWALF(20)/LETT/ DATA LOWALF(21)/LETU/ DATA LOWALF(22)/LETV/ DATA LOWALF(23)/LETW/ DATA LOWALF(24)/LETX/ DATA LOWALF(25)/LETY/ DATA LOWALF(26)/LETZ/ DATA LOWALF(27)/EOS/ DATA UPALF(01) /BIGA/ DATA UPALF(02) /BIGB/ DATA UPALF(03) /BIGC/ DATA UPALF(04) /BIGD/ DATA UPALF(05) /BIGE/ DATA UPALF(06) /BIGF/ DATA UPALF(07) /BIGG/ DATA UPALF(08) /BIGH/ DATA UPALF(09) /BIGI/ DATA UPALF(10) /BIGJ/ DATA UPALF(11) /BIGK/ DATA UPALF(12) /BIGL/ DATA UPALF(13) /BIGM/ DATA UPALF(14) /BIGN/ DATA UPALF(15) /BIGO/ DATA UPALF(16) /BIGP/ DATA UPALF(17) /BIGQ/ DATA UPALF(18) /BIGR/ DATA UPALF(19) /BIGS/ DATA UPALF(20) /BIGT/ DATA UPALF(21) /BIGU/ DATA UPALF(22) /BIGV/ DATA UPALF(23) /BIGW/ DATA UPALF(24) /BIGX/ DATA UPALF(25) /BIGY/ DATA UPALF(26) /BIGZ/ DATA UPALF(27) /EOS/ FOR ( ; ARRAY(I) ^= DELIM & ARRAY(I) ^= EOS; I = I + 1) IF (ARRAY(I) == ESCAPE) JUNK = ADDSET(ESC(ARRAY, I), SET, J, MAXSET) ELSE IF (ARRAY(I) ^= DASH) JUNK = ADDSET(ARRAY(I), SET, J, MAXSET) ELSE IF (J <= 1 \ ARRAY(I+1) == EOS) # LITERAL - JUNK = ADDSET(DASH, SET, J, MAXSET) ELSE IF (INDEX(DIGITS, SET(J-1)) > 0) CALL DODASH(DIGITS, ARRAY, I, SET, J, MAXSET) ELSE IF (INDEX(LOWALF, SET(J-1)) > 0) CALL DODASH(LOWALF, ARRAY, I, SET, J, MAXSET) ELSE IF (INDEX(UPALF, SET(J-1)) > 0) CALL DODASH(UPALF, ARRAY, I, SET, J, MAXSET) ELSE JUNK = ADDSET(DASH, SET, J, MAXSET) RETURN END # MAKSET - MAKE SET FROM ARRAY(K) IN SET INTEGER FUNCTION MAKSET(ARRAY, K, SET, SIZE) " C,92074-1X008 REV.2034 800818" INTEGER ADDSET INTEGER I, J, K, SIZE CHARACTER ARRAY(ARB), SET(SIZE) I = K J = 1 CALL FILSET(EOS, ARRAY, I, SET, J, SIZE) MAKSET = ADDSET(EOS, SET, J, SIZE) RETURN END # XINDEX - INVERT CONDITION RETURNED BY INDEX INTEGER FUNCTION XINDEX(ARRAY, C, ALLBUT, LASTTO) " C,92074-1X008 REV.2034 800818" CHARACTER ARRAY(ARB), C INTEGER INDEX INTEGER ALLBUT, LASTTO IF (C == EOF) XINDEX = 0 ELSE IF (ALLBUT == NO) XINDEX = INDEX(ARRAY, C) ELSE IF (INDEX(ARRAY, C) > 0) XINDEX = 0 ELSE XINDEX = LASTTO + 1 RETURN END ### GETLN - GET AN INPUT LINE ## INTEGER FUNCTION GETLN(LINE,INFILE) ## INTEGER LINE(ARB) ## INTEGER INFILE ## INTEGER C ## INTEGER GETCH ### ## FOR(I=1; I<=MAXLINE; I=I+1)[ ## C = GETCH(C,INFILE) ## LINE(I) = C ## IF( C == NEWLINE \C == EOF) ## BREAK ## ] ## LINE(I+1) = EOS ## IF ( C == NEWLINE ) ## GETLN = I ## ELSE ## GETLN = EOF ## RETURN ## END # CTOI - CONVERT STRING AT IN(I) TO INTEGER, INCREMENT I INTEGER FUNCTION CTOI(IN, I) " C,92074-1X008 REV.2034 800818" CHARACTER IN(ARB) INTEGER INDEX INTEGER D, I # STRING DIGITS "0123456789" INTEGER DIGITS(11) DATA DIGITS(1) /DIG0/ DATA DIGITS(2) /DIG1/ DATA DIGITS(3) /DIG2/ DATA DIGITS(4) /DIG3/ DATA DIGITS(5) /DIG4/ DATA DIGITS(6) /DIG5/ DATA DIGITS(7) /DIG6/ DATA DIGITS(8) /DIG7/ DATA DIGITS(9) /DIG8/ DATA DIGITS(10) /DIG9/ DATA DIGITS(11) /EOS/ WHILE (IN(I) == BLANK \ IN(I) == TAB) I = I + 1 FOR (CTOI = 0; IN(I) ^= EOS; I = I + 1) [ D = INDEX(DIGITS, IN(I)) IF (D == 0) # NON-DIGIT BREAK CTOI = 10 * CTOI + D - 1 ] RETURN END ####################################################################### # INDEX - FIND CHARACTER C IN STRING STR INTEGER FUNCTION INDEX(STR, C) " C,92074-1X008 REV.2034 800818" CHARACTER C, STR(ARB) FOR (INDEX = 1; STR(INDEX) ^= EOS; INDEX = INDEX + 1) IF (STR(INDEX) == C) RETURN INDEX = 0 RETURN END # LENGH - COMPUTE LENGTH OF STRING INTEGER FUNCTION LENGH(STR) " C,92074-1X008 REV.2034 800818" INTEGER STR(ARB) FOR (LENGH = 0; STR(LENGH+1) ^= EOS; LENGH = LENGH + 1) ; RETURN END # TYPE - RETURN LETTER, DIGIT OR CHARACTER # THIS ONE WORKS WITH ASCII ALPHABET INTEGER FUNCTION TYPE(C) " C,92074-1X008 REV.2034 800818" INTEGER C IF( C >= DIG0 & C <= DIG9 ) TYPE = DIGIT ELSE IF( C >= LETA & C <= LETZ ) TYPE = LETTER ELSE IF( C >= BIGA & C <= BIGZ ) TYPE = LETTER ELSE TYPE = C RETURN END SUBROUTINE ERROR(MESS) " C,92074-1X008 REV.2034 800818" INTEGER MESS(10) CALL EXEC(2,1,MESS,20) CALL ERTN END DEFINE(DB, #) DEFINE(DB2,#) #========= chang program from chapter 5 ========== #define(maxpat,128) define(tags,10) define(MAXARG,128) define(ESCAPE,ATSIGN) define(DITTO,(-3)) define(FOLDUP,(-4)) define(FOLDDOWN,(-5)) # catsub - add replacement text to end of new subroutine catsub(lin, from, to, sub, new, k, maxnew) " C,92074-1X008 REV.2034 800818" integer addset, fold, foldw integer from, i, j, junk, k, maxnew, to, istart, stop, subf, c character lin(ARB), new(maxnew), sub(ARB), ibuf(15) integer subi DB2 INTEGER BUFF(3) include ctag for (i = 1; sub(i) ^= EOS; i = i + 1){ subf = sub(i) if (subf == DITTO \ subf == FOLDUP \ subf == FOLDDOWN ) { i = i + 1 subi = sub(i) # # &T no longer an option in substring # define(TIME,(-6) # if( subi == TIME ) { # call ftime(ibuf) # for(ii=1 ; ii<=30 ; ii=ii+1 ) # junk = addset( lbyte(ibuf,ii), new, k, maxnew) # istart = 0 # copy nothing # stop = 0 # } # else if( subi == 0) { istart = from stop = to } else if( subi >= 1 & subi <= tagcnt ) { istart = tagsrt( subi ) stop = tagstp( subi ) } else if( subi > tagcnt & subi <= TAGS ){ # non-secified istart = 0 # copy nothing stop = 0 } else call error('CATSUB : CANT HAPPEN.') DB2 CALL EXEC(2,1,'/CATSUB: istart=_',-QLENGTH) DB2 CALL CNUMD(istart,BUFF) DB2 CALL EXEC(2,1,BUFF,3) DB2 CALL EXEC(2,1,'/CATSUB: STOP=_',-QLENGTH) DB2 CALL CNUMD(STOP,BUFF) DB2 CALL EXEC(2,1,BUFF,3) for (j = istart; j < stop; j = j + 1) { c = lin(j) if( subf == FOLDUP ) c = fold(c) else if( subf == FOLDDOWN ) c = foldw(c) junk = addset(c, new, k, maxnew) } } else junk = addset(sub(i), new, k, maxnew) } return end # chang - chang "from" into "to" integer function chang(lin,new,maxlin,pat,subsrc,sub) " C,92074-1X008 REV.2034 800818" character lin(ARB), new(maxlin), pat(ARB), subsrc(ARB), sub(ARB) # subsrc is the unfolded lin to be used in subsitutions integer addset, amatch, presn integer i, junk, k, lastm, m common /fdcnt/ fdcnt # number of exchanges counter integer fdcnt common /sxflg/ sxflg # single exchange flag integer sxflg DB CALL EXEC(2,1,'/CHANG: LIN=_',-QLENGTH) DB CALL EXEC(2,1,LIN,LENGTH(LIN)) DB CALL EXEC(2,1,'/CHANG: PAT=_',-QLENGTH) DB CALL EXEC(2,1,PAT,LENGTH(PAT)) DB CALL EXEC(2,1,'/CHANG: SUB=_',-QLENGTH) DB CALL EXEC(2,1,SUB,LENGTH(SUB)) chang = NO k = 1 lastm = 0 if( presn(lin, pat) == yes ) for ( i =1; lin(i) ^= EOS; ) { if( sxflg < 0 & chang == YES ) # test for single exchange m = 0 else m = amatch(lin, i, pat) if (m > 0 & lastm ^= m) { # replace matched text chang = YES fdcnt = fdcnt+1 # bump counter call catsub(subsrc, i, m, sub, new, k, maxlin) lastm = m } if (m == 0 \ m == i) { # no match or null match junk = addset(subsrc(i), new, k, maxlin) i = i + 1 } else # skip matched text i = m } if (addset(EOS, new, k, maxlin) == NO) { k = maxlin junk = addset(EOS, new, k, maxlin) chang = ERR } DB CALL EXEC(2,1,NEW,LENGTH(NEW)) return end # fold - fold to upper case character function fold(c) " C,92074-1X008 REV.2034 800818" character c if( c >= leta & c <= letz ) fold = c - 32 else fold = c return end # foldw - fold to lower case character function foldw(c) " C,92074-1X008 REV.2034 800818" character c if( c >= biga & c <= bigz ) foldw = c + 32 else foldw = c return end # getsub - get substitution pattern into sub integer function getsub(arg, sub, maxpat) " C,92074-1X008 REV.2034 800818" character arg(MAXARG), sub(maxpat), maxpat integer maksub getsub = maksub(arg, 1, EOS, sub,maxpat) return end # maksub - make substitution string in sub integer function maksub(arg, from, delim, sub, maxpat) " C,92074-1X008 REV.2034 800818" character esc character arg(MAXARG), delim, sub(maxpat) integer addset integer from, i, j, junk, argi, subfld INTEGER DIGITS(10) DATA DIGITS(1)/DIG1/, DIGITS(2)/DIG2/, DIGITS(3)/DIG3/ DATA DIGITS(4)/DIG4/, DIGITS(5)/DIG5/, DIGITS(6)/DIG6/ DATA DIGITS(7)/DIG7/, DIGITS(8)/DIG8/, DIGITS(9)/DIG9/ DATA DIGITS(10)/EOS/ DB CALL EXEC(2,1,'MAKSUB: ARG=_',-QLENGTH) DB CALL EXEC(2,1,ARG,LENGTH(ARG)) j = 1 for (i = from; arg(i) ^= delim & arg(i) ^= EOS; i = i + 1){ argi = arg(i) if( argi == AMPER ) subfld = DITTO else if( argi == GREATER ) subfld = FOLDUP else if(argi == LESS ) subfld = FOLDDOWN else subfld = 0 if (subfld ^= 0 ) { junk = addset(subfld, sub, j, maxpat) # # &T no longer an option in subfield # # if( arg(i+1) == bigT \ arg(i+1) == lett ) { # junk = addset( TIME, sub, j, maxpat) # i = i + 1 # } # else { k = index(digits, arg(i+1)) if( k ^= 0 ) i = i + 1 junk = addset( k, sub, j, maxpat) } } else junk = addset(esc(arg, i), sub, j, maxpat) } if (arg(i) ^= delim) # missing delimiter maksub = ERR else if (addset(EOS, sub, j, maxpat) == NO) # no room maksub = ERR else maksub = i DB CALL EXEC(2,1,'MAKSUB: SUB =_',-QLENGTH) DB CALL EXEC(2,1,SUB,LENGTH(SUB)) return end # COMMON BLOCKS BLOCK DATA " C,92074-1X008 REV.2034 800818" INCLUDE CTAG END