! Dated 24 Jan 85 ! const integer invi=x'80308030' external routine spec read profile(string (11) key, name info, integer name version, uflag) external routine spec write profile(string (11) key, name info, integer name version, uflag) external integer fn spec uinfi(integer i) external string fn spec itos alias "S#ITOS"(integer i) external string fn spec htos alias "S#HTOS"(integer i, pl) external routine spec uctranslate alias "S#UCTRANSLATE"(integer adr, len) external string fn spec ucstring(string (255) s) external string fn spec failure message alias "S#FAILUREMESSAGE"(integer i) external integer map spec comreg alias "S#COMREG"(integer i) routine spec rstrg(string name s) external string fn spec uinfs(integer i) record format parmf(integer dest, srce, p1, p2, p3, p4, p5, p6) external routine spec dpoff(record (parmf) name p) external integer fn spec dpermission(string (6) owner, user, string (8) date, string (15) file, integer fsys, type, adrprm) external integer fn spec dsfi(string (6) user, integer fsys, type, set, adr) external string fn spec derrs(integer i) external integer fn spec dfinfo(string (6) user, string (15) file, integer fsys, adr) external routine spec ddelay(integer seconds) external routine spec phex alias "S#PHEX"(integer i) external routine spec move alias "S#MOVE"(integer len, from, to) external routine spec etoi alias "S#ETOI"(integer ad, len) record format dfinfrecf(integer nkb, rup, eep, apf, use, arch, fsys, conseg, cct, codes, byte integer sp1, sp2, pool, codes2, integer ssbyte, string (6) offer) record format finfrecf(integer conad, filetype, relst, relend, size, rup, eep, mode, users, arch, string (6) tran, string (8) date, time, integer count, spare1, spare2) external routine spec finfo alias "S#FINFO"(string (31) s, integer mode, record (finfrecf) name r, integer name flag) external integer fn spec exist(string (63) file) external routine spec ncode alias "S#NCODE"(integer s, f, ff) external routine spec disconnect alias "S#DISCONNECT"(string (31) s, integer name f) external routine spec prompt(string (15) s) external routine spec clear(string (63) s) external routine spec define(string (63) s) external routine spec detach(string (255) s) external routine spec hazard(string (255) s) external routine spec outfile alias "S#OUTFILE"(string (31) s, integer length, maxbytes, prot, integer name conad, flag) record format conrecf(integer conad, filetype, relst, relend) external routine spec connect alias "S#CONNECT"(string (31) s, integer acc, maxb, prot, record (conrecf) name r, integer name flag) record format srcf(integer nextfreebyte, txtrelst, maxlen, zero) const string name date=x'80C0003F', time=x'80C0004B' external string fn fromstr(string (255) s, integer i, j) unless 0<i<=j and j<=length(s)>0 then result ="" if i>1 then charno(s, i-1)=j-i+1 else length(s)=j-i+1 result =string(addr(s)+i-1) end ; ! FROMSTR !-------------------------------------------------------------------------------- external integer fn val(integer adr, len, rw{set 0 for read, 1 for write}, psr) ! Result = 1 area OK (accessible) ! 0 area not OK (inaccessible) ! RW should be set 0 (to test for read access) ! or 1 (to test for write access) ! ! Parameter PSR is used in the VALIDATE, but if zero, the PSR HERE (or rather ! of the calling routine) is used. integer inseg0, beyond seg0, seg0, seg0 ad integer dr0 const integer write=1 seg0=adr>>18 result =0 if len<=0 if psr=0 start ; *lss_(lnb +1); *st_psr; finish if seg0#(adr+len-1)>>18 start seg0 ad=seg0<<18 inseg0=x'40000'-(adr-seg0 ad) beyond seg0=len-inseg0 result =val(adr, inseg0, rw, psr)&val(adr+inseg0, beyond seg0, rw, psr) finish ! WE SHOULD ALSO CHECK THAT THE AREA LIES WITHIN USER SEGMENTS, AND ! NOT IN ANY HIGHER ACR SEGMENTS AS WELL. dr0=x'18000000'!len *ldtb_dr0 *lda_adr *val_psr *jcc_8, <cczer> *jcc_4, <ccone> *jcc_2, <cctwo> ! THEN CC=3, INVALID result =0 cczer: ! READ AND WRITE PERMITTED result =1; ! OK ccone: ! READ, BUT NOT WRITE, PERMITTED if rw=write then result =0; ! BAD result =1; ! OK cctwo: ! WRITE, BUT NOT READ, PERMITTED result =0; ! BAD end ; ! VAL external routine uderrs(integer n) printstring("FLAG =") printstring(derrs(n)) newline end ; ! UDERRS !-------------------------------------------------------------------------------- external routine connflag(string (63) s, integer flag) ! Prints an error message for a failure of the CONNECT routine. integer currst if flag=0 then return currst=comreg(23) {save current output stream number} select output(0) printstring(s.": CONNECT FLAG =") write(flag, 1) printstring(" ".failure message(flag)) select output(currst) end ; ! CONNFLAG integer fn fpages(string (255) file) record (dfinfrecf) x integer j, owner given string (63) user, wk j=0 file=ucstring(file) user="" if file->user.(".").file start j=8 unless (length(user)=6 or length(user)=0) and 0<length(file)<=11 finish owner given=1 if user="" then user=uinfs(1) and owner given=0 if file->("T#").wk then file=file.tostring(uinfi(13)+'0') x=0 j=dfinfo(user, file, -1, addr(x)) if j=0 if j#0 start printstring("FPAGES fails"); write(j, 1) printstring(" for file ".user.".") if owner given#0 printstring(file) newline result =0 finish result =x_nkb>>2 end {fpages} external integer fn nwfilead(string (15) s, integer pgs) integer i, flag, curr flag=1 if 0<length(s)<=15 then outfile(s, pgs<<12, x'40000', 0, i, flag) if flag#0 start curr=comreg(23) select output(0) printstring("OUTFILE FLAG =") write(flag, 1) printstring(" ".failure message(flag)) i=0 select output(curr) finish result =i end ; ! NWFILEAD external integer fn tpfilead(string (15) s, integer pgs) ! SAME AS NWFILEAD, BUT SETS NEXT TO TOP BIT IN "PROTECT", THUS ! FORMING A FILE MARKED "TEMPFI" integer i, flag, curr flag=1 if 0<length(s)<=15 then outfile(s, pgs<<12, x'40000', x'40000000', i, flag) if flag#0 start curr=comreg(23) select output(0) printstring("OUTFILE FLAG =") write(flag, 1) if flag>9 then flag=flag-6; ! 16-24 -> 10-18 if flag+6=49 then flag=19 printstring(" ".failure message(flag)) i=0 select output(curr) finish result =i end ; ! TPFILEAD integer fn shortcfn(string name s) ! ! CHECK FILE NAME - 1-11 CHARS, ALPHA,NUMBERS OR HASH ! ! RESULT = 0 GOOD 1 BAD ! integer ch, j, l l=length(s) result =1 unless 0<l<=11 cycle j=1, 1, l ch=byteinteger(addr(s)+j) result =1 unless 'A'<=ch<='Z' or '0'<=ch<='9' or ch='#' or 'a'<=ch<='z' repeat result =0; ! FILENAME IS GOOD end ; ! SHORTCFN integer fn cfn(string name s) string (31) mas, mem if s->mas.("_").mem then result =shortcfn(mas)!shortcfn(mem) result =shortcfn(s) end ; ! CFN integer fn long cfn(string name s) ! RESULT 0 GOOD 1 BAD string (63) user, file if s->user.(".").file start if length(user)#6 or shortcfn(user)#0 or cfn(file)#0 then result =1 result =0; ! GOOD finish result =cfn(s) end ; ! LONG CFN external integer fn rdfilead(string (63) s) record (conrecf) r integer i, flag ! CONNECT IN A SUITABLE MODE flag=1 r=0 if 0<length(s)<=31 then connect(s, 0, x'40000', 0, r, flag) connflag(s, flag) i=r_conad i=0 if flag#0 result =i end ; ! RDFILEAD external integer fn wrfilead(string (31) s) record (conrecf) r integer i, flag ! CONNECT IN WRITE MODE flag=1 r=0 if 0<length(s)<=31 then connect(s, 3, x'40000', 0, r, flag) connflag(s, flag) i=r_conad i=0 if flag#0 result =i end ; ! WRFILEAD !-------------------------------------------------------------------------------- external routine copf(string (71) s) integer j, sizebytes record (finfrecf) r string (63) file1, file2 integer fromad, toad, flag unless length(s)>0 and s->file1.(",").file2 and 0<length(file1)<=31 and c 0<length(file2)<=31 then ->bad fromad=rdfilead(file1) return if fromad<=0 finfo(file1, 0, r, flag) monitor if flag#0 sizebytes=r_size toad=nwfilead(file2, (sizebytes+x'FFF')>>12) return if toad<=0 move(sizebytes, fromad, toad) disconnect(file2, j) return bad: printstring("Params should be INFILE,OUTFILE ") end ; ! COPF integer fn spec hxstobin(string (29) s) ! external integer fn bin(string (255) s) ! RESULT IS VALUE REPRESENTED BY THE STRING PARAM ! ERROR RESULT IS X80308030 (BAD CHAR IN STRING OR BAD ! LENGTH) integer i, q, l, as, ch, sign string (255) a, b sign=1 while s->a.(" ").b and a="" cycle ; s=b; repeat if s->a.("-").b and a="" then sign=-1 and s=b while s->a.(" ").b and a="" cycle ; s=b; repeat if (s->a.("X").b or s->a.("x").b) and a="" start s=b i=hxstobin(s) if i#x'80308030' then i=i*sign result =i finish as=addr(s) l=length(s) result =x'80308030' if l=0 i=0 cycle q=1, 1, l ch=byteinteger(as+q) result =x'80308030' unless '0'<=ch<='9' i=10*i+ch-48 repeat result =i*sign end ; ! BIN external routine nrstrg(string name s) ! READS NEXT LINE FROM CURRENT INPUT STREAM, SETTING S TO BE CONTENTS ! OF THE LINE WITHOUT THE NEWLINE. integer i s="" cycle readsymbol(i) exit if i=nl s=s.tostring(i) repeat end ; ! nrstrg !-------------------------------------------------------------------------------- external routine rstrg(string name s) nrstrg(s) until s#"" end ; ! RSTRG external routine ucstrg(string name s) rstrg(s) uctranslate(addr(s)+1, length(s)) end ; ! ucstrg routine ucnstrg(string name s) nrstrg(s) s=ucstring(s) end {ucnstrg} external integer fn hxstobin(string (29) s) ! RESULT IS VALUE REPRESENTED BY UP TO 8 HEX DIGITS IN THE PARAM. ! ERROR RESULT IS X80308030 integer i, q, l, as, ch as=addr(s) l=length(s) result =x'80308030' if l>8 or l=0 i=0 cycle q=1, 1, l ch=byteinteger(as+q) result =x'80308030' unless '0'<=ch<='9' or 'A'<=ch<='F' if ch>'9' then ch=ch-55 else ch=ch-48 i=i<<4!ch repeat result =i end ; ! HXSTOBIN external integer fn rdints(string (255) s) ! READS NEXT UNSIGNED DEC NO. OR HEX NO. (NOT X80308030). own string (15) array ns(1:10)=""(10) string (1) t string (255) rest, rest2 integer i own integer np=0,nl=0 if s#"" then ->nonnull start if np>=nl then start reset: ucstrg(s) nonnull start: np=0; nl=0 while s->rest.(" ").rest2 and rest="" cycle ; s=rest2; repeat while s->ns(nl+1).(" ").s cycle while s->rest.(" ").rest2 and rest="" cycle ; s=rest2; repeat if ns(nl+1)="X" or ns(nl+1)="x" or ns(nl+1)="-" start t=ns(nl+1) while s->rest.(" ").rest2 and rest="" cycle ; s=rest2; repeat unless s->rest.(" ").s then rest=s and s="" ns(nl+1)=t.rest finish nl=nl+1 repeat if s#"" start nl=nl+1 ns(nl)=s finish finish !---------------------------------------- ! ! np=np+1 s=ns(np) i=bin(s) if i=x'80308030' then start printstring("Invalid hex or dec no. ") if np>1 start np=np-1 printstring("Last taken was ") printstring(ns(np)) newline finish ->reset finish result =i end ; ! RDINTS !-------------------------------------------------------------------------------- external routine rdint(integer name i) i=rdints("") end ; ! RDINT external integer next=-1 external string fn separate(string name s) ! SEPARATES STRING S INTO SUB-STRINGS COMPRISING THINGS BETWEEN ! (ENDS OR) COMMAS IN S. AT SUCCESSIVE CALS OF THIS FN, S AND THE ! RESULT ARE SET TO THE "NEXT" SUB-STRING. RESULT IS "" WHEN THERE ! ARE NO SUB-STRINGS LEFT. A NULL SUB-STRING (IE. ",," IN THE ! ORIGINAL) ALSO TERMINATES THE SET OF SUB-STRINGS. own string (127) array fs(0:19)=""(20) own integer n=0 string (127) lh, rh integer j ! ! if next<0 start if length(s)=0 then result ="" next=0 s=lh.rh while s->lh.(" ").rh cycle j=0, 1, 19; fs(j)=""; repeat ; ! TO ALLOW SERIAL RE-USE n=0 fs(0)=s n=n+1 while fs(n)->fs(n).(",").fs(n+1) finish if fs(next)="" then next=-1 and s="" and result ="" next=next+1 s=fs(next-1) result =s end ; ! SEPARATE ! ! ! !-------------------------------------------------------------------------------- external routine qinfo(string (255) file) record format dfinfrecf(integer nkb, rup, eep, apf, use, arch, fsys, conseg, cct, codes, byte integer sp1, sp2, pool, codes2, integer ssbyte, string (6) offer) record (dfinfrecf) x const integer unava=1, wrconn=1 const integer offer=2, newge=2 const integer tempfi=4, oldge=4 const integer vtempf=8, wsallow=8 const integer tempfs=12 const integer chersh=16, comms=16 const integer privat=32, discfi=32 const integer violat=64 const integer noarch=128, dead=128 integer j, owner given string (31) user ! string (31) w1, w2 while separate(file)#"" cycle j=0 user="" if file->user.(".").file start j=8 unless (length(user)=6 or length(user)=0) and 0<length(file)<=11 finish owner given=1 if user="" then user=uinfs(1) and owner given=0 x=0 j=dfinfo(user, file, -1, addr(x)) if j=0 if x_codes&chersh#0 then printsymbol('*') and space printstring(user.".") if owner given#0 printstring(file.":") if j#0 start uderrs(j) continue finish printstring(" CONN ") if x_conseg>15 then printsymbol('X') printstring(htos(x_conseg, 2)) printstring("; PGS ") if x_nkb>>2>15 then printsymbol('X') printstring(htos(x_nkb>>2, 3)) printstring("; OWP"); write(x_rup, 1) printstring("; EEP"); write(x_eep&15, 1) printstring("; APF "); printstring(htos(x_apf, 3)) printstring("; USERS"); write(x_use, 1) printstring("; CCT"); write(x_cct, 1) if length(x_offer)=6 then printstring("; OFF: ".x_offer) if x_codes&violat#0 then printstring("; VIOL") if x_codes&tempfs#0 then printstring("; ") if x_codes&vtempf#0 then printstring("V") if x_codes&tempfs#0 then printstring("TEMPFI") if x_codes&noarch#0 then printstring("; NOARCH") if x_codes2&(newge!oldge)#0 then printstring("; GENRS") newline ! %if S->W1.(".").W2 %then %continue ! J=0 ! %while J<U_CT %cycle ! PRINTSTRING(U_PS(J)_USER ) ! WRITE(U_PS(J)_PRM,1) ! NEWLINE ! J=J+1 ! %repeat repeat newline end ; ! QINFO !------------------------------------------------------------------------------ external routine dump(integer start, finish, printst, lim) ! ! DUMP ROUTINE FOR .LP OR EQUIVALENT FILE ! ! LIM GIVE BYTES PER LINE REQUIRED ! BUT IN ADDITION, LIM=-1 WILL GIVE LIM=32, AND ! LIM=-16 WILL GIVE LIM=16 AND EBCDIC PRINT, AND ! LIM=-32 WILL GIVE LIM=32 AND EBCDIC PRINT routine spec print text integer fn spec exlines(integer print abs) integer j, k, sameas, msgind, acurl, ac0, ac1, dr0, dr1, v, psr integer align, mainstop, lm1, acl4 integer ebcdic byte integer ch2 ebcdic=0 printst=start if printst=-1 if start&3#printst&3 then printstring("DUMP: WRONG PARAMS ") start=start&(¬3) finish=finish&(¬3) printst=printst&(¬3) msgind=0 if lim=-16 then ebcdic=1 and lim=16 if lim=-32 then ebcdic=1 and lim=32 lim=32 unless lim=16; ! ONLY THESE TWO VALUES VALID lm1=lim-1 align=printst&lm1 acurl=start-align printst=printst-align mainstop=finish&(¬lm1) j=exlines(1) return if j=0 j=exlines(0) return if j=0 *lss_(lnb +1) *st_psr while acurl<mainstop cycle ! Validate next LIM bytes dr0=x'18000000'!lim *ldtb_dr0 *lda_acurl *val_psr *jcc_8, <cczer> *jcc_4, <ccone> *jcc_2, <cctwo> ! THEN CC=3, INVALID cctwo: v=0 ->vout cczer: ! READ AND WRITE PERMITTED ccone: ! READ, BUT NOT WRITE, PERMITTED v=1 vout: if v=0 start if msgind#0 then print text printstring("(") phex(acurl) printstring(") ") printstring("Address Validation Fails") newline return finish ! Are next LIM bytes identical to preceding? acl4=acurl+lim-4 sameas=1 ! %cycle J=ACURL,4,ACL4 ! %if INTEGER(J-LIM)#INTEGER(J) %then SAMEAS=0 %and %exit ! %repeat dr0=x'58000000'!lim dr1=acurl ac0=dr0 ac1=dr1-lim *ld_dr0 *lsd_ac0 *put_x'A500'; ! CPS *jcc_8, <equal> sameas=0; ! DIFFERENT equal: if sameas=0 start if msgind#0 then print text msgind=0 finish else msgind=msgind+1 {counts no of lines identical to last printed} if msgind=0 start ; ! NOT SAME, GO ON ! PRINT ADDRESS OF LINESTART printsymbol('(') phex(printst) printstring(") ") ! PRINT HEX PART cycle k=acurl, 4, acl4 printstring(" ") phex(integer(k)) repeat printstring(" ") ! PRINT CHAR PART cycle k=acurl, 1, acurl+lm1 ch2=byteinteger(k) if ebcdic#0 then etoi(addr(ch2), 1) if 32<=ch2<=126 then printsymbol(ch2) else space repeat newline finish else start ; ! NOT SAME, GO ON/ELSE START SAME if msgind=1 start printsymbol('(') phex(printst) printstring(") ") finish finish ; ! SAME acurl=acurl+lim printst=printst+lim repeat if msgind#0 then print text j=exlines(0) return routine print text integer zer, k zer=1 cycle k=acurl-lim, 4, acurl-4 if integer(k)#0 then zer=0 and exit repeat if msgind=1 then printstring("1 LINE ") else printstring(itos(msgind)." LINES ") if zer=0 then printstring("SAME AS ABOVE") else printstring("OF ZEROES") newline end {print text} integer fn exlines(integer print abs) integer k !--- STARTING AND FINAL LINES --- result =0 unless acurl+lim>start and acurl<finish if val(acurl, lim, 0, 0)=0 start printstring("(") phex(acurl) printstring(") ") printstring("Address Validation Fails") newline result =0 finish ! PRINT ADDRESS OF LINESTART printsymbol('(') if print abs=0 then phex(printst) else phex(acurl) printstring(") ") ! PRINT HEX PART cycle k=acurl, 4, acurl+lim-4 printstring(" ") if start<=k<finish then phex(integer(k)) else spaces(8) repeat printstring(" ") ! PRINT CHAR PART cycle k=acurl, 1, acurl+lim-1 ch2=byteinteger(k) if ebcdic#0 then etoi(addr(ch2), 1) if start<=k<=finish and 32<=ch2<=126 then printsymbol(ch2) else space repeat acurl=acurl+lim printst=printst+lim newline result =1 end ; ! EXLINES end ; ! DUMP routine reduce params(integer a, b, c, d) ncode(a, b, c) d=0 end ; ! REDUCE PARAMS routine reduce params2(integer a, b, c, d) dynamic routine spec ibmrecode(integer a, b, c) ibmrecode(a, b, c) d=0 end {reduce params2} routine ocdump(string (255) s, routine dumprt(integer a, b, c, d), integer type) integer par, st, fi, filead, filename prompted for integer printst, lim string (71) fis, sts, devs, file record (srcf) name hdr filename prompted for=0 par=1 prompt("File: ") next=-1 file=separate(s) uctranslate(addr(s)+1, length(s)) ucstrg(file) and filename prompted for=1 while long cfn(file)#0 filead=rdfilead(file) if filead=0 then return hdr==record(filead) sts=separate(s) prompt("Relstart: ") st=rdints(sts) prompt("Relfinish or Bytes: ") fis=separate(s) fi=rdints(fis) if fi=0 then fi=hdr_nextfreebyte if fi<=st then fi=st+fi if type=2 start ; ! DUMPCODE unless 0<=st<fi and fi<=hdr_nextfreebyte then ->fail finish devs=separate(s) if devs="" and filename prompted for=0 then devs=".OUT" prompt("To file/dev: ") cycle exit if ".OUT"=devs or fromstr(devs, 1, 3)=".LP" or cfn(devs)=0 ucnstrg(devs) devs=".OUT" if devs="" repeat lim=16 s=separate(s) if s=".LONG" then lim=32 define("ST63,".devs.",512") select output(63) if devs#".OUT" start lim=32 printstring("Dumped from file: ".file) spaces(5) printstring(date." ".time) newlines(3) finish if type=1 {dumpfile} then printst=st else printst=st-hdr_txtrelst if type=3 {ebcdicdump} then lim=-lim dumprt(filead+st, filead+fi, printst, lim) newlines(2) select output(0) close stream(63) clear("") return fail: printstring("Addresses must be rel to file start and within file length ") end ; ! OCDUMP !-------------------------------------------------------------------------------- external routine dumpfile(string (71) s) ocdump(s, dump, 1) end ; ! DUMPFILE !-------------------------------------------------------------------------------- external routine ibmcode(string (255) s) ocdump(s, reduce params2, 2) end {ibmcode} external routine dumpcode(string (71) s) ocdump(s, reduce params, 2) end ; ! DUMPCODE !-------------------------------------------------------------------------------- external routine recode(string (71) s) ocdump(s, reduce params, 2) end ; ! RECODE !-------------------------------------------------------------------------------- external routine ebcdicdump(string (71) s) ocdump(s, dump, 3) end ; ! EBCDICDUMP !-------------------------------------------------------------------------------- routine processvm(routine process(integer a, b, c, d)) integer lim integer start, finish, as at, j, segad string (255) s lim=32 prompt("Addr or segno: ") rdint(start) if 0<start<1<<18 start prompt("Relstart: ") rdint(j) start=start<<18+j finish segad=start&x'FFFC0000' prompt("Addr or relend:") rdint(finish) if 0<finish<2<<18 then finish=segad+finish as at=0 prompt("To file/dev: ") ucstrg(s) define("STREAM01,".s) select output(1) if s=".OUT" then lim=16 else start printstring("VIRTUAL MEMORY from X'".htos(start, 8)."' to X'".htos(finish, 8)."' on ".date." at ".time) newlines(4) finish process(start, finish, start, lim) newline select output(99) close stream(1) clear("") end ; ! processvm external routine dumpvm(string (255) s) processvm(dump) end ; ! dumpvm external routine recode vm(string (255) s) processvm(reduce params) end ; ! recode vm routine vlist(integer start, finish, pstart, lim) integer j, ad, mask, ch mask=-1 ad=start&(¬63) finish=(finish+63)&(¬63) while ad<finish cycle printstring("(") phex(ad&mask) mask=x'0003FFFF' printstring(") ") if val(ad, 64, 0, 0)#0 start cycle j=0, 1, 63 ch=byteinteger(ad+j) printch(ch) if ch=nl then spaces(12) repeat finish else start printstring("Address validation fails") exit finish newline ad=ad+64 repeat end ; ! VLIST external routine listvm(string (255) s) processvm(vlist) end ; ! LISTVM routine isearch(integer from, to, segad) string (63) type, seek string (63) file, s integer lseekm1, aseekplus1 integer j, k, fin, n, kind, ch integer seek1, seek2 switch search, search again(0:2) j=from fin=to prompt("STR/SHORT/INT: ") ucstrg(type) until type="STR" or type="SHORT" or type="INT" kind=0; ! STRING if type="SHORT" then kind=1 if type="INT" then kind=2 ->search(kind) search(0): ! STRING prompt("STRING: ") rstrg(seek) lseekm1=length(seek)-1 aseekplus1=addr(seek)+1 search again(0): until j>=fin-lseekm1 cycle cycle k=0, 1, lseekm1 if byteinteger(j+k)#byteinteger(aseekplus1+k) then exit ->found if k=lseekm1; ! GOT THROUGH ALL BYTES WITHOUT DISAGREEMENT repeat j=j+1 repeat ->not found search(1): ! SHORT prompt("Search for: ") rdint(seek2) until seek2&x'FFFF0000'=0 search again(1): ! SHORT until j>fin-2 cycle if j&3=0 then k=integer(j)>>16 else k=integer(j)&x'FFFF' if k=seek2 then ->found j=j+2 repeat ->not found search(2): ! INTEGER prompt("Search for: ") rdint(k) seek1=k>>16 seek2=k&x'FFFF' search again(2): until j>fin-4 cycle if j&3=0 start if integer(j)=k then ->found finish else start if byteinteger(j)<<8!byteinteger(j+1)=seek1 and c byteinteger(j+2)<<8!byteinteger(j+3)=seek2 then ->found finish j=j+2 repeat not found: printstring(" NOT FOUND ") return found: printstring(" FOUND: ") k=j+16 k=fin if k>fin n=j-16 n=segad if n<segad dump(n, k, n-segad, 16) newline return if j>fin-16 j=j+16 prompt("Continue? ") until ch='Y' or ch='y' or ch='N' or ch='n' cycle ucstrg(s) ch=charno(s, 1) repeat if ch='Y' or ch='y' then ->search again(kind) end ; ! ISEARCH !------------------------------------------------------------------------------- external routine searchvm(string (255) s) integer lim integer start, finish, as at, j, segad lim=32 prompt("Addr or segno: ") rdint(start) if 0<start<1<<18 start prompt("Relstart: ") rdint(j) start=start<<18+j finish segad=start&x'FFFC0000' prompt("Addr or relend:") rdint(finish) if 0<finish<2<<18 then finish=segad+finish isearch(start, finish, segad) end ; ! SEARCHVM !-------------------------------------------------------------------------------- external routine ysearch(string (255) file) record (srcf) name h string (255) aa, bb integer start, j, fin, bytes prompt("File: ") if file="" then rstrg(file) start=rdfilead(file) return if start<=0 if file->aa.("_").bb start h==record(start) bytes=h_maxlen finish else bytes=fpages(file)<<12 prompt("Relstart: ") rdint(j) until 0<=j<bytes fin=start+bytes isearch(start+j, fin, start) end ; ! YSEARCH !-------------------------------------------------------------------------------- external routine ycomp(string (255) s) record (finfrecf) finf integer origs1, flag string (63) file1, file2 integer u, v, s1, s2, sa, lim prompt("File1: ") rstrg(file1) prompt("File2: ") rstrg(file2) prompt("Rel start: ") rdint(sa) sa=sa&(¬b'11'); ! ALIGN TO WORD s1=rdfilead(file1) s2=rdfilead(file2) return if s1<=0 or s2<=0 origs1=s1 finfo(file1, 0, finf, flag) if flag#0 start printstring("Error"); write(flag, 1); newline; return finish lim=finf_size finfo(file2, 0, finf, flag) if flag#0 start printstring("ERROR"); write(flag, 1); newline; return finish ! SET LIM TO SHORTER OF THE TWO FILESIZES if lim>finf_size then lim=finf_size s1=s1+sa s2=s2+sa lim=origs1+lim cycle u=integer(s1) v=integer(s2) if u#v then ->diff s1=s1+4 s2=s2+4 ->done if s1>=lim repeat diff: printstring("DIFF AT REL ADDRESS: ") phex(s1-origs1) spaces(5) phex(u); spaces(2) phex(v); newline return done: printstring("FINISHED AT REL ADDRESS: ") phex(s1-origs1) newline end ; ! YCOMP !------------------------------------------------------------------------------ integer fn different(integer len, a, b) integer dr0, dr1, ac0, ac1 dr0=x'58000000'!len dr1=a ac0=dr0 ac1=b *ld_dr0 *lsd_ac0 *put_x'A500'; ! CPS *jcc_8, <equal> result =1; ! DIFFERENT equal: result =0; ! SAME end ; ! DIFFERENT ! !------------------------------------------------------------------------------- ! external routine compare(string (255) s) ! If a null parameter is supplied, the progrma prompts for filenames for comparison. ! It then prompts : for the "COMPARE" ! commands. ! If the PARAMETER parameter comprises two filenames separated by comma, then comparison commences right away. ! Unless a third parameter, .F is appended, the program returns ! after a difference has been found. It returns anyway if the files ! are found identical. (This feature is only for program use). ! If a PDfile member is being compared with a file having the same name ! and belonging to the process owner, then the file is HAZARDed if no ! difference is found. But only for the command form: ! COMPARE(PDFILE_MEMBER) ! i.e. second filename implied. ! routine spec cfhelp routine spec context routine spec lrstrg(string name s) record (srcf) name h, h2 integer i, j, c, f, as, l, agoflag, fncall, hazfile, qd, k integer outstrm, outfile, cur in to out, ad1, ad2 string (63) u, v, pd, mem string (255) array cur(1:2) integer curip integer array fa, fb, fp, fl(1:2) switch a('A':'Z') on event 14 start h==record(ad1) h2==record(ad2) if h_nextfreebyte#h2_nextfreebyte or different(h_nextfreebyte, ad1, ad2)#0 then c printstring("DIFF ") printstring("Invalid input file") newline return finish qd=0 {"Type ?" flag} fncall=0 outstrm=0 cur in to out=1 curip=1 as=addr(s) agoflag=0 outfile=0 hazfile=0 u=""; v="" if s="?" then cfhelp if length(s)>0 start unless s->u.(",").v start if s->pd.("_").mem start if exist(mem)#0 start u=pd."_".mem v=mem hazfile=1 finish else start printstring("File ".mem." does not exist") newline return finish finish finish agoflag=1 outfile=0 s=".N" ! IF PARAMETER ,.F APPENDED, WE SET "FNCALL" TO INDICATE RETURN ! REQUIRED AFTER DIFFERENCE FOUND, AS WELL AS WHEN IDENTITY FOUND. if v->v.(",.F") then fncall=1 finish if u="" start prompt("File1:") rstrg(u) finish i=rdfilead(u) h==record(i) return if i<=0 fa(1)=i; ad1=i fp(1)=i+h_txtrelst; fl(1)=i+h_nextfreebyte; fb(1)=fp(1) if v="" start prompt("File2:") rstrg(v) finish j=rdfilead(v) return if j<=0 h==record(j) fa(2)=j; ad2=j fp(2)=j+h_txtrelst; fl(2)=j+h_nextfreebyte; fb(2)=fp(2) advance: curip=1 lrstrg(cur(1)) curip=2 lrstrg(cur(2)) if length(cur(1))=255 start ; f=1; ->eof; finish if length(cur(2))=255 start ; f=2; ->eof; finish if agoflag#0 start agoflag=0 s="GO" ->l11 finish nextcmd: if qd=0 start printstring("Type ? for commands") newline qd=1 finish prompt(":") rstrg(s) uctranslate(addr(s)+1, 2) {command letters to upper case} if s=":" or s="%C" then s="Q" l11: l=length(s) c=byteinteger(as+1) f=byteinteger(as+2)-'0' ->no unless c='M' or c='P' or c='G' or c='F' or c='Q' or c='A' or c='E' or c='C' ->a(c) a('A'): ->no unless l=1 or s="AGO" agoflag=1 ->advance a('M'): ->no unless l>=3 and (1<=f<=2 or f+'0'='B') s=substring(s, 3, l) i=bin(s) ->no if i<=0 if f+'0'='B' then k=2 and f=1 else k=1 {no of files we are doing} cycle curip=f cycle j=1, 1, i lrstrg(cur(f)) if length(cur(f))=255 then ->eof repeat f=f+1 k=k-1; exit if k=0 repeat ->print both a('E'): a('Q'): ->no unless l=1 return a('C'): ! Context context ->nextcmd a('P'): ->no unless l=2 and (1<=f<=2 or f+'0'='B') if f+'0'='B' start print both: if length(cur(1))=255 then printstring("**EOF1** ") else printstring(cur(1)." ") if length(cur(2))=255 then printstring("**EOF2** ") else printstring(cur(2)." ") ->nextcmd finish if length(cur(f))=255 then printstring("**EOF** ") else printstring(cur(f)." ") ->nextcmd a('G'): cycle ->no unless l=2 and f+'0'='O' if length(cur(1))=255 or length(cur(2))=255 then ->print both if cur(1)#cur(2) then ->diff curip=1 lrstrg(cur(1)) curip=2 lrstrg(cur(2)) repeat a('F'): ->no unless l>2 and (1<=f<=2 or f+'0'='B') s=substring(s, 3, l) if f+'0'='B' then j=0 and f=1 else j=1 ! J=0 MEANS DO BOTH FILES, 1 MEANS DO JUST ONE. cycle curip=f cycle if length(cur(f))=255 then ->eof if cur(f)->u.(s).v then exit lrstrg(cur(f)) repeat ->print both if j=1 ! THEN BOTH FILES ARE BEING DONE. NO. 2 NEXT. f=2 j=1; ! TO STOP IT AFTER THIS TIME. repeat no: if c='?' then cf help and ->nextcmd printstring("NO ") ->nextcmd diff: hazfile=0 printstring("DIFF ") cycle j=1, 1, 2 spaces(20) if fncall#0 printstring(cur(j)) newline repeat if fncall#0 then return ->nextcmd eof: if curip=1 then printstring("**EOF1**") else printstring("**EOF2**") newline return eofs: if hazfile#0 then hazard(mem) printstring("Comparison complete ") routine lrstrg(string name s) ! SETS S TO THE NEXT LINE (WITHOUT THE NL CHARACTER) FROM THE ! RELEVANT FILE AND SETS FP(CURIP) TO POINT TO THE CHARACTER ! AFTER THE NL. integer as, curp, i, l as=addr(s) curp=fp(curip) i=fl(curip) if curp>=i then ->leof l=0 while 10#byteinteger(curp)#12 cycle l=l+1 if l>=256 then signal event 14 byteinteger(as+l)=byteinteger(curp) curp=curp+1 repeat byteinteger(as)=l ->out leof: byteinteger(as)=255; ! EOF INDICATION out: fp(curip)=curp+1; ! POINTS TO CHAR AFTER NEWLINE return end ; ! LRSTRG routine context integer i, ad, ip, j, nls for ip=1, 1, 2 cycle printstring("File"); write(ip, 1) printstring(" -------------------------"); newline ad=fp(ip) i=ad; nls=0 while i>fb(ip) and nls<5 cycle i=i-1 if byteinteger(i)=nl then nls=nls+1 repeat ad=ad+1 while ad<fl(ip) and byteinteger(ad)#nl for j=i, 1, ad cycle printsymbol(byteinteger(j)) repeat repeat end ; ! CONTEXT routine cfhelp printstring("A Advance one line in each file and proceed with comparison. ") printstring("C Context: five lines printed from each file; current lines last. ") printstring("E End (same as Quit) "); printstring("Fftext Find <text> in file f (Case-dependent search). f=1, or 2, or B ") printstring(" meaning both. "); printstring("GO Proceed with comparison, from current line (will not go if current ") printstring(" lines different). "); printstring("Mfn Move n lines in file f (f=1, or 2, or B meaning both) ") printstring("Pf Print current line in file f (f=1, or 2, or B meaning both). ") printstring("Q, :, %c Quit "); end {cfhelp} end {compare} !-------------------------------------------------------------------------------- external routine tim(string (255) s) printstring(time) newline end ; ! TIM !-------------------------------------------------------------------------------- record format ssf(integer switch, sessno, junkno, string (9) date) external routine deta(string (255) par) integer do det, fad, n, j, tvalid, mins, secs, reset sess, flag, vsn const integer topstr=39 string (79) array strs(0:topstr) string (79) a, b, dstrg, paramfile, opfile string (255) s, origs record (srcf) name h record (ssf) ss if par="INIT" then reset sess=1 else if par="CANCEL" then reset sess=2 else reset sess=0 do det=1 n=0 if reset sess=0 start cycle rstrg(origs); s=ucstring(origs) if s="Q" then return if s=":" or s="%C" then exit tvalid=0; mins=0; secs=0 mins=bin(s) if mins>0 then tvalid=1 else if s->a.(",").b start mins=0 mins=bin(a) if a#"" secs=bin(b) if b#"" if 10000>=mins>=0 and 600000>=secs>=0 and not (mins=secs=0 or (mins#0 and c secs>=60)) start tvalid=1 j=secs//60 mins=mins+j secs=secs-j*60 finish finish if tvalid=0 start if n>=topstr start printstring("Too many lines (".itos(topstr).". file SS#DET will be written to date, but not detached ") do det=0 exit finish strs(n)=origs n=n+1 finish else exit repeat finish paramfile=""; opfile="" if not (par->a.("LP").b) start if exist("PF")=0 or reset sess#0 start vsn=1 read profile("Session", ss, vsn, flag) if flag=0 or reset sess#0 start if reset sess=2 then vsn=-1 {delete} if ss_date#date or reset sess=1 start ss=0 ss_date=date finish ss_junkno=ss_junkno+1 opfile="J".itos(ss_junkno) paramfile="T#PAR" write profile("Session", ss, vsn, flag) if flag#0 then printstring("Write profile flag") and write(flag, 1) and newline return if reset sess#0 finish finish else paramfile="PF" finish if opfile#"" start fad=nwfilead(paramfile, 1) if fad#0 start h==record(fad) s="OUT=FILE OUTNAME=".opfile." .END " move(length(s), addr(s)+1, fad+h_txtrelst) h_nextfreebyte=h_txtrelst+length(s) finish finish disconnect(paramfile, flag) fad=nwfilead("SS#DET", 1) if fad#0 start h==record(fad) if tvalid#0 start if uinfi(16)#0 then s="CPULIMIT(".itos(mins).",".itos(secs).")" else c s="CPULIMIT ".itos(mins).",".itos(secs) s=s." " move(length(s), addr(s)+1, fad+h_nextfreebyte) h_nextfreebyte=h_nextfreebyte+length(s) finish j=0 while j<n cycle s=strs(j)." " move(length(s), addr(s)+1, fad+h_nextfreebyte) h_nextfreebyte=h_nextfreebyte+length(s) j=j+1 repeat finish dstrg="" if tvalid#0 then dstrg=",".itos(mins*60+secs) if paramfile#"" start if dstrg="" then dstrg="," paramfile=",".paramfile finish detach("SS#DET".dstrg.paramfile) ! printstring("SS#DET".dstrg.paramfile) ! newline if opfile#"" start printstring("Output file ".opfile) newline finish end ; ! DETA end of file