! Misc Imp Library %option "-low-nocheck-nodiag-noline" %systemroutinespec phex(%Integer x) %externalroutine newline printsymbol(nl) %end %systemroutine newlines(%integer n) %while n>0 %cycle n = n-1; printsymbol(nl) %repeat %end %systemroutine space printsymbol(' ') %end %systemroutine spaces(%integer n) %while n>0 %cycle n = n-1; printsymbol(' ') %repeat %end %systempredicate resolves(%string(*)%name var,match,fore,aft) !!Resolve the string specified by VAR into FORE and AFT split by MATCH !![FORE and/or AFT absent is conventionally represented by an address !! of zero] @0%string(*) null %integer i %option "-noline" {Required due to V2 compiler bug} %integerfn resol(%string(*)%name var,match) !Return index position of first occurrence of MATCH within VAR %label yes,no *clr.l d0 *clr.w d1 *move.b (a1)+,d1 {length(match) *beq yes {match="" -> *clr.w d2 *move.b (a0)+,d2 {length(var) *sub.b d1,d2 *bcs no {length(match)>length(var) -> {*bug: was bmi *subq.w #1,d1 loop1: *lea 0(a0,d0),a2 *move.l a1,a3 *move d1,d3 loop2: *cmpm.b (a2)+,(a3)+ *dbne d3,loop2 {*bug?was dbeq *beq yes *addq.w #1,d0 *dbra d2,loop1 no: *moveq #-1,d0 yes:*addq.l #1,d0 !** (to be) re-coded for efficiency ** ! %integer i=0,j,l ! l = length(match) ! %cycle ! %result = 0 %if i > length(var)-l ! i = i+1 ! j = 0 ! %cycle ! %result = i %if j = l ! j = j+1 ! %repeat %until charno(var,i+j-1) # charno(match,j) ! %repeat %end %routine assign(%string(*)%name dest, %integer from,to) !! **NB use of TOSTRING is compiled in-line ** !! **OK when DEST is also source ** dest = "" %while from <= to %cycle dest = dest.tostring(charno(var,from)); from = from+1 %repeat %end %routine do aft assign(aft,i+length(match),length(var)) %unless aft==null %end i = resol(var,match) %false %if i = 0 %if fore ## null %start %if fore ## var %start assign(fore,1,i-1) do aft %finish %else %start do aft length(var) = i-1 %finish %finish %else do aft %true %end %systemstring(255)%fn readstring ! a STRING is deemed a sequence of non-control characters, ! hence, as for numbers, leading control characters are skipped, ! and the terminating one is not. %string(255)s %integer k s = "" readsymbol(k) %until k>' ' %cycle s = s.tostring(k) %exitif nextsymbol<=' ' readsymbol(k) %repeat %result = s %end %systemroutine readline(%string(255)%name s) ! a LINE is a sequence of non-NL characters and may be empty, ! hence blank lines are not skipped, and leading and trailing ! spaces are significant. The terminating NL is skipped, to ! make it "pipe-compatible" with printline. %integer k s = "" %cycle readsymbol(k); %exitif k=nl s = s.tostring(k) %repeat %end %systemroutine printline(%string(255)s) printstring(s) printsymbol(nl) %end %systemstring(9)%fn itoh(%integer n) %string(9)s="" %integer i,k %for i = 28,-4,0 %cycle k = n>>i&15; k = k+7 %if k>9; s = s.tostring(k+'0') %repeat %result = s %end %systemintegerfn htoi(%string(255)s) %integer n=0,p=0,k %cycle p = p+1 %result = n %if p>length(s) k = charno(s,p); %continueif k<=' ' k = k-'0' %if k>9 %start k = k-7 %if k-7>9 k = k-32 %if k>15 %finish %result = n %unless 0<=k<=15 n = n<<4+k %repeat %end %systemintegerfn stoi(%string(255) S) %integer i,k %integer sign=0, val=0 i = 0 %while i < length(s) %cycle i = i+1; k = charno(s,i) %continue %if k <= ' ' %if k = '-' %start sign = 1 %else %if '0' <= k <= '9' val = val<<3+val+val+k-'0' %elseunless k='+' %signal 4, 1, k, "Non-numeric character" %finish %repeat %result = val %if sign = 0 %result = -val %end %systemstring(127)%fn itos(%integer v,p) %string(127)store %bytename l %routine printsymbol(%integer x) l = l+1; charno(store,l) = x %end %routine spaces(%integer x) x = x-1 %and printsymbol(' ') %while x>0 %end %routine write(%integer n,p) %integer q,r %if p>0 %start p = \p; printsymbol(' ') %and p = p+1 %if n>=0 %finish p = -120 %if p<-120 q = n//10; *move.l d1,r %if q=0 %start p = p+1 %if n<0; spaces(-1-p); printsymbol('-') %if n<0 %else p = p+1 %if p<0; write(q,p) %finish printsymbol(|r|+'0') %end store = ""; l == length(store) write(v,p) %result = store %end %systemstring(127)%fn rtos(%real r,%integer n,m) %constreal pmax = 2147483647.0 %real y,z %integer i=0,l,count=0,sign %string(127) result = "" ! sign = ' ' sign = '-' %if r < 0 y = |r|+0.5/10.0\{^}m; !modulus, rounded %if y > pmax %start count = count+1 %and y = y/10.0 %until y < 10.0 %finish z = 1.0 %cycle i = i+1; z = z*10.0 %repeat %until z > y result = result." " %for l = 1,1,n-i; !l not used before here result = result.tostring(sign) %unless sign = ' ' %and n <= 0 %cycle z = z/10.0 l = int pt(y/z) y = y-l*z result = result.tostring(l+'0') i = i-1 %exit %if i+m <= 0 result = result."." %if i = 0 %repeat result = result."@".itos(count,0) %if count # 0 %result = result %end; !rtos %systemstring(127)%fn rtof(%real x, %integer n) %real y,round %integer count=-99,sign=0 %string(127) result="" ! %if x # 0 %start x = -x %and sign = 1 %if x < 0 !Adjust X so that 1.0 <= rounded(X) < 10.0 count = 0; round = 0.5\{^}n y = 1.0-round %if x < y %start; !ie rounded(X) < 1.0 count = count-1 %and x = x*10.0 %until x >= y %finish %else %start y = 10.0-round %while x >= y %cycle; !ie rounded(X) > 10.0 count = count+1; x = x/10.0 %repeat %finish x = -x %if sign # 0 %finish result = rtos(x,1,n) result = result."@".itos(count,0) %result = result %end; !flrtos %system %real %function S To R (%string (255) Input) {rmm} %integer Sign = 0, Sym, Pos = 1 %real Value, Exp %routine Next Pos = Pos + 1 %if Pos > Length (Input) %start Sym = 0 %else Sym = Char No (Input, Pos) %finish %end Sym = Char No (Input, Pos) %if Sym = '-' %start Sign = 1 Next %finish Value = 0 %if Sym # '.' %start %signal 6, 5, Pos %unless '0' <= Sym <= '9' {Char No out of range} %cycle Value = Value*10.0 + (Sym - '0') Next %repeat %until %not '0' <= Sym <= '9' %finish %if Sym = '.' %start Exp = 10.0 %cycle Next %exit %unless '0' <= Sym <= '9' Value = Value + (Sym - '0')/Exp Exp = Exp * 10.0 %repeat %finish %if Sym = '@' %start Sym = S To I (Sub String (Input, Pos + 1, Length (Input))) Value = Value * 10.0\Sym %finish Value = -Value %if Sign # 0 %result = Value %end {S To R} %systemrealfn ftor(%string(255)s) %result = stor(s) %end %systemintegerfn xread %alias "read" %integer i,k,sign,ten=10,max='9' %cycle k = next symbol %exit %if k > ' ' skip symbol %repeat sign = 0 %if k = '-' %start sign = 1 skip symbol; k = next symbol %finish %cycle %signal 4,1,nextsymbol,"Non-numeric character to READ" %unless '0'<=k<=max i = k-'0' %cycle skip symbol k = next symbol k = k-32 %if k>='a' %if k>'9' %start %exitif k<'A' k = k-7 %finish %exit %unless '0' <= k <= max i = i*ten-'0'+k %repeat %exitunless k='_'-7 ten = i; max = '0'+ten-1 skipsymbol; k = nextsymbol k = k-32 %if k>='a' %if k>'9' %start k = -1 %if k<'A' k = k-7 %finish %repeat i = -i %if sign # 0 %result = i %end %systemrealfn readreal %integer sign=0,sym %real value,exp %routine read(%integername n) n = xread %end %cycle sym = nextsymbol %exit %if sym > ' ' skipsymbol %repeat %if sym = '-' %start sign = 1 skip symbol; sym = nextsymbol %finish value = 0 %if sym # '.' %start %signal 4,1,sym,"Non-numeric character to READ" %unless '0' <= sym <= '9' %cycle value = value*10.0+(sym-'0') skip symbol; sym = nextsymbol %repeat %until %not '0' <= sym <= '9' %finish %if sym = '.' %start exp = 10.0 %cycle skip symbol; sym = nextsymbol %exit %unless '0' <= sym <= '9' value = value+(sym-'0')/exp exp = exp*10.0 %repeat %finish %if sym = '@' %start skipsymbol read(sym) value = value*10.0\sym {^} %finish value = -value %if sign # 0 %result = value %end; !read real %systemroutine write(%integer n,p) %integer q,r %if p>0 %start p = \p; printsymbol(' ') %and p = p+1 %if n>=0 %finish p = -120 %if p<-120 q = n//10; *move.l d1,r %if q=0 %start p = p+1 %if n<0; spaces(-1-p); printsymbol('-') %if n<0 %else p = p+1 %if p<0; write(q,p) %finish printsymbol(|r|+'0') %end %systemroutine print(%real x, %integer n,m) %constreal pmax = 2147483647.0 %real y,z %integer i=0,l,count=0,sign sign = ' ' sign = '-' %if x < 0 y = |x|+0.5/10.0\{^}m; !modulus, rounded %if y > pmax %start count = count+1 %and y = y/10.0 %until y < 10.0 %finish z = 1.0 %cycle i = i+1; z = z*10.0 %repeat %until z > y spaces(n-i) printsymbol(sign) %unless sign = ' ' %and n <= 0 %cycle z = z/10.0 l = int pt(y/z) y = y-l*z printsymbol(l+'0') i = i-1 %exit %if i+m <= 0 print symbol('.') %if i = 0 %repeat printsymbol('@') %and write(count,0) %if count # 0 %end; !print %systemroutine printfl(%real x, %integer n) %real y,round %integer count=-99,sign=0 %if x # 0 %start x = -x %and sign = 1 %if x < 0 !Adjust X so that 1.0 <= rounded(X) < 10.0 count = 0; round = 0.5\{^}n y = 1.0-round %if x < y %start; !ie rounded(X) < 1.0 count = count-1 %and x = x*10.0 %until x >= y %finish %else %start y = 10.0-round %while x >= y %cycle; !ie rounded(X) > 10.0 count = count+1; x = x/10.0 %repeat %finish x = -x %if sign # 0 %finish print(x,1,n) printsymbol('@') write(count,0) %end; !printfl %systemroutine phex1(%integer x) x = x&15; x = x+7 %if x>9; printsymbol(x+'0') %end %systemroutine phex2(%integer x) phex1(x>>4); phex1(x) %end %systemroutine phex4(%integer x) phex2(x>>8); phex2(x) %end %systemroutine phex(%integer x) phex4(x>>16); phex4(x) %end %systemintegerfn rhex %integer n=0,s %onevent 4 %start %signal 4,1,s,"Non-numeric character to RHEX" %finish %cycle s = nextsymbol; %exitif s>' ' skipsymbol %repeat s = s&95 %if s>='a' %signal 4 %unless '0'<=s<='9' %or 'A'<=s<='F' %while '0'<=s<='9' %or 'A'<=s<='F' %cycle s = s-'0'; s = s-7 %if s>9 n = n<<4+s; skipsymbol; s = nextsymbol s = s&95 %if s>='a' %repeat %result = n %end ! Bulk move %systemroutine smoveblock(%integer bytes,from,to) !"signed" move block !if bytes>0 then move (from)+ to (to)+ but !if bytes<0 then from:=from-bytes, to:=to-bytes, move -(from) to -(to) %label f1,f2,f3,f4,f5,f6,f7,b0,b1,b2,b3,b4,b5,b6,b7,end *move.l d1,a0 *move.l d2,a1 *eor d1,d2 *tst.l d0 *bmi b0; !copy backwards -> *beq end; !copy nothing -> *btst #0,d2; !if (from!!to)&1#0 then *bne f5; !copy bytewise -> *btst #0,d1; !if from&1=0 then *beq f1; !go for longword loop -> *move.b (a0)+,(a1)+; !copy first byte to even up *subq.l #1,d0 f1: *moveq #3,d2 *and d0,d2; !remainder for byte loop *subq.l #4,d0 *bmi f4; !bytes<4 -> *lsr.l #2,d0; !longwords-1 *bra f3 f2: *swap d0; !longword loop f3: *move.l (a0)+,(a1)+ *dbra d0,f3 *swap d0 *dbra d0,f2 f4: *move.l d2,d0 f5: *subq.l #1,d0; !bytes-1 *bmi end *bra f7 f6: *swap d0; !byte loop f7: *move.b (a0)+,(a1)+ *dbra d0,f7 *swap d0 *dbra d0,f6 *bra end b0: *neg.l d0; !backwards copy *add.l d0,a0; !adjust addresses for -() *add.l d0,a1 *btst #0,d2 *bne b5 *move a0,d1; !! *btst #0,d1 *beq b1 *move.b -(a0),-(a1) *subq.l #1,d0 b1: *moveq #3,d2 *and d0,d2 *subq.l #4,d0 *bmi b4 *lsr.l #2,d0 *bra b3 b2: *swap d0 b3: *move.l -(a0),-(a1) *dbra d0,b3 *swap d0 *dbra d0,b2 b4: *move.l d2,d0 b5: *subq.l #1,d0 *bmi end *bra b7 b6: *swap d0 b7: *move.b -(a0),-(a1) *dbra d0,b7 *swap d0 *dbra d0,b6 end: %end %systemroutine moveblock(%integer bytes,from,to) !in case of overlap copy without propagating ! %returnif bytes<=0 ! bytes = -bytes %if fromf.("%").a i = 1 %while s->f.("*").a %cycle r = r.f r = r.wc(i) %and i = i+1 %if i<=wp s = a %repeat r = r.s output = r {printstring(r);newline %end !%Routine trim (%String(*)%name s) ! %Integer l=length(s) ! length(s) = l-1 %if charno(s,l) = ':' !%End ! !%String(255)%Fn Cleanup (%String(255) s) ! %String(255) f,a ! ! %while s->f.(":.:").a %cycle ! s = f.(":").a ! %Repeat ! %Result = s !%ENd ! !%Recordformat filefm (%String(255) f,%Record(filefm)%name n) ! !%Routine Do Local Wild (%String(255) fore,aft, ! %Routine dothing (%String(255) in)) ! %record(filefm)%name top==NIL,next,last ! %String(255) f,a,file,temp,temp2 ! ! Mark !! Printstring("Fore=".fore." aft=".aft);newline ! Open Input (2,fore{.":"});selectinput(2) ! %Begin ! %Routine insert ! %if top == NIL %start ! top==new(top);top=0 ! top_f = file ! last==top ! %else ! last_n == new(last_n);last_n=0 ! last == last_n ! last_f = file ! %finish ! %End ! %Routine push ! next == new(next); next=0 ! next_f = file ! next_n == top ! top == next ! %End ! %on 9 %Start ! close input ! %signal 9,event_sub,0,event_message %if event_sub # 0 ! %Return ! %Finish ! %cycle ! readline(file) ! to lower (file) ! insert ;! %or push ! %Repeat ! %End ! ! %If aft -> f.(":").a %Start ! %if f = "..." %Start ! next == TOP ! %while next ## nil %cycle ! file=next_f ! %if charno(file,length(file))=':' %start ! do local wild (fore.file,"...:".a,dothing) ! %Else ! temp=file ! %if matches(temp,a) %start ! temp = cleanup(fore.{":".}file) ! dothing(temp) ! %finish ! %finish ! next == next_n ! %Repeat ! %Else ! temp = f.":" ! temp2 = f.">" !{ Printstring("Temp2=".temp2);newline ! next == TOP ! %while next ## NIL %cycle ! file=next_f ! %if matches (file,temp) %start !! trim(file) ! do local wild (fore.file,a,dothing) ! %elseif temp2 = file ! do local wild (fore.f.":",a,dothing) ! %Finish ! next == next_n ! %Repeat ! %Finish ! %Else ! next == TOP ! %while next ## NIL %Cycle ! file = next_f !!printstring("Try match ".file." ".aft);newline ! temp=file !! trim(temp) ! %if matches (temp,aft) %start !! printstring(file." = ".aft);newline !! trim(file) ! temp = cleanup(fore.file) ! do thing (temp) ! %Else !! printstring(file." # ".aft);newline ! %Finish ! next==next_n ! %Repeat ! %finish ! release !%end ! !%Externalroutine Do Wild (%string(255) filespec, ! %Routine dothing(%String(255)in)) ! %String(255) fore ! ! %Routine trans (%String(*)%Name s) ! %STring(255)f,a ! %While s -> f.(":").a %cycle ! %exitif f="" ! %Exitunless translate logicalname (f) ! s = f.":".a ! %Repeat ! %End ! ! to lower (filespec) ! trans (filespec) ! %if charno(filespec,1) = ':' %start ! filespec -> (":").filespec ! %if filespec="" %Start ! %Signal 9,2,0,"Bad filename - no device specified" ! %Finish ! %if filespec -> fore.(":").filespec %start ! fore=":".fore.":" ! %Else ! %Signal 9,2,0,"Bad filename" ! %Finish ! %else ! fore="default:" ! trans(fore) ! %Finish !! trim(fore) ! do local wild (fore,filespec,dothing) !%End %Externalroutine Do Wild (%string(255) filespec,%integer mode, %Routine dothing(%String(255)in, %integer flag)) {This routine should be rewritten - here temp only} %String(255) fore %Routine Do Local Wild (%String(255) fore,aft) {this routine is ok ?} %Recordformat filefm (%String(255) f,%Record(filefm)%name n) %record(filefm)%name top==NIL,next,last %String(255) f, r,rest, file, trest %Integer dir, bottom %on 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 %start dothing(event_message,1) {maybe more should be sent} %return %finish open input (2, fore) ; select input (2) mark %begin %routine insert %if top == NIL %start top==new(top);top=0 top_f = file last==top %else last_n == new(last_n);last_n=0 last == last_n last_f = file %finish %end %on 9 %Start close input dothing (event_message,1) %if event_sub # 0 %Return %Finish %cycle readline(file) to lower (file) insert %Repeat %End %if aft -> f.(":").rest %start %if f = "..." %start next == top %if rest = "" %then trest = "*:" %else trest = rest %while next ## nil %cycle file = next_f ; dir = 0 dir = 1 %if charno (file, length(file)) = ':' %if matches (file, trest) %start %if mode = 1 %start do thing (fore.file,0) %elseif mode = 2 do thing (fore.file,0) do local wild (fore.file, "...:".trest) %if dir = 1 %elseif mode = 3 do local wild (fore.file, "...:".trest) %if dir = 1 do thing (fore.file,0) %else {Internal consistency error} {}Printstring("Bad mode - ");write(mode,0);newline %finish %finish next == next_n %repeat %if mode = 1 %start next == top %while next ## nil %cycle file = next_f %if charno (file, length(file)) = ':' %start do local wild (fore.file,"...:".trest) %finish next == next_n %repeat %finish %else next == top ; r = f.">" ; f = f.":" %if rest = "" %then bottom = 1 %else bottom = 0 %while next ## nil %cycle file = next_f %if matches (f, file) %start %if bottom = 1 %start do thing (fore.file,0) %else do local wild (fore.file,rest) %finish %elseif matches (r,file) charno (file,length(file))=':' do local wild (fore.file,rest) %Finish next == next_n %repeat %finish %else next == top %while next ## nil %cycle file = next_f ; dir = 0 %if matches (file, aft) %start do thing (fore.file,0) %finish next == next_n %repeat %finish release {should also be done if problems occur} %end %Routine trans (%String(*)%Name s) %String(255)f,a %While s -> f.(":").a %cycle %exitif f="" %Exitunless translate logicalname (f) s = f.":".a %Repeat %End to lower (filespec) trans (filespec) %if charno(filespec,1) = ':' %start filespec -> (":").filespec %if filespec="" %Start %Signal 9,2,0,"Bad filename - no device specified" %Finish %if filespec -> fore.(":").filespec %start fore=":".fore.":" %Else %Signal 9,2,0,"Bad filename" %Finish %else fore="default:" trans(fore) %Finish filespec = "...:*" %if filespec = "..." do local wild (fore,filespec) %End