$eject /************************************************************* * MODULE NAME: TEXT08.SIM * * PUBLIC PROCEDURES: WIDTH, LENGTHS, SCOPY, SPREAD, PUTWORD * *************************************************************/ ptwd2: do; $nolist $include (:f1:datax.sim) declare flength byte external; $list brk: procedure external; end brk; min: procedure(v1,v2) byte external; declare (v1,v2) byte; end min; printmsg: procedure(a) external; declare a address; end printmsg; /************************************************************* * WIDTH - COMPUTE THE WIDTH OF CHARACTER STRINGS * * BACKSPACE IS SPECIAL CASE - HAS NEGATIVE LENGTH * *************************************************************/ width: procedure(abuff) byte public; declare abuff address, buff based abuff (lsize) byte; declare (i,w) byte; i, w = 0; do while buff(i) <> eos; if buff(i) = backspace then w = w - 1; else w = w + 1; i = i + 1; end; return w; end width; $eject /***************************************************************** * LENGTHS - COMPUTE THE LINE LENGTH, EACH CHARACTER HAS * * THE SAME LENGTH (ONE) * *****************************************************************/ lengths : procedure(a) byte public; declare a address, buf based a (lsize) byte; declare i byte; i = 0; do while buf(i) <> eos; i = i + 1; end; return i; end lengths; /*************************************************************** * COPY - COPIES THE CONTENT OF BUF2 INTO BUF1 START FROM * * THE POINTERS SPECIFIED, UNTIL EOS IS ENCOUNTERED * ***************************************************************/ scopy : procedure(a1,i,a2,j) public; declare (a1,a2) address, (i,j) byte; declare (buf1 based a1, buf2 based a2) (lsize) byte; do while buf2(j) <> eos; buf1(i) = buf2(j); i = i + 1; j = j + 1; end; buf1(i) = eos; end scopy; declare dir byte init (0); $eject /************************************************************** * SPREAD - INSERT THE EXTRA BLANKS BETWEEN SUBSEQUENT * * WORDS AND ARANGES IT SO THAT THE EXTRA SPACES * * ARE WELL DISTRIBUTED * **************************************************************/ spread : procedure(nextra,bufptr,p,ds) public; declare (bufptr,p,ds) address, outbuf based bufptr (maxout) byte; declare (outp based p, outwds based ds) byte; declare (nextra,i,j,nb,ne,nhole) byte; /* check the number of words and extra space */ if nextra <= 0 or outwds <= 1 then return; dir = 1 - dir; ne = nextra; nhole = outwds - 1; i = outp - 2; j = min(maxout,i+ne); do while i < j; outbuf(j) = outbuf(i); if outbuf(i) = blank then do; do; if dir = 0 then nb = (ne - 1) / nhole + 1; else nb = ne/nhole; end; ne = ne - nb; nhole = nhole - 1; do while nb > 0; j = j - 1; outbuf(j) = blank; nb = nb - 1; end; end; j = j - 1; i = i - 1; end; end spread; $eject /************************************************************** * PUTWORD - PUT A WORD IN OUTBUF, INCLUDE RIGHT MARGIN * * JUSTIFICATION IF SPECIFIED BY CALLING * * SPREAD ROUTINE * **************************************************************/ putword : procedure(bufptr,p,wt,ds) public; declare (bufptr,p,wt,ds) address, outbuf based bufptr (maxout) byte, (outp based p, outw based wt, outwds based ds) byte; declare (lasts,llval,nextra,w) byte; w = width(.wrdbuf); lasts = lengths(.wrdbuf) + outp + 1; llval = rmval - tival; /************************************************************ * CHECK THE BUFFER CONTENTS - FOR BUFFER OVERFLOW * ************************************************************/ if outp > 0 and ((outw+w) > llval or lasts >= maxout) then do; lasts = lasts-outp; nextra = llval-outw+1; /* check if need to spread the line */ if rm$just or flength > 0 then do; if nextra > 0 and outwds > 1 then do; call spread(nextra, bufptr, p, ds); outp = outp + nextra; end; end; call brk; end; call scopy(.outbuf, outp, .wrdbuf, 0); outp = lasts; outbuf(outp - 1) = blank; outw = outw + w + 1; outwds = outwds + 1; end putword; end ptwd2; eof