home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / ENTERPRS / CPM / UTILS / S / TURBTOOL.ARC / CHAPTER4.PAS < prev    next >
Pascal/Delphi Source File  |  1989-09-27  |  8KB  |  395 lines

  1.  
  2. {chapter4.pas}
  3.  
  4. {
  5.         copyright (c) 1981
  6.         by:     bell telephone laboratories, inc. and
  7.                 whitesmith's ltd.,
  8.  
  9.         this software is derived from the book
  10.                 "software tools in pascal", by
  11.                 brian w. kernighan and p. j. plauger
  12.                 addison-wesley, 1981
  13.                 isbn 0-201-10342-7
  14.  
  15.         right is hereby granted to freely distribute or duplicate this
  16.         software, providing distribution or duplication is not for profit
  17.         or other commercial gain and that this copyright notice remains
  18.         intact.
  19. }
  20.  
  21. procedure sort;
  22. const
  23.   maxchars=10000;
  24.   maxlines=300;
  25.   mergeorder=5;
  26. type
  27.   charpos=1..maxchars;
  28.   charbuf=array[1..maxchars] of character;
  29.   posbuf=array[1..maxlines] of charpos;
  30.   pos=0..maxlines;
  31.   fdbuf=array[1..mergeorder]of filedesc;
  32. var
  33.   linebuf:charbuf;
  34.   linepos:posbuf;
  35.   nlines:pos;
  36.   infile:fdbuf;
  37.   outfile:filedesc;
  38.   high,low,lim:integer;
  39.   done:boolean;
  40.   name:xstring;
  41. function gtext(var linepos:posbuf;var nlines:pos;
  42.   var linebuf:charbuf;infile:filedesc):boolean;
  43. var
  44.   i,len,nextpos:integer;
  45.   temp:xstring;
  46.   done:boolean;
  47. begin
  48.   nlines:=0;
  49.   nextpos:=1;
  50.   repeat
  51.     done:=(getline(temp,infile,maxstr)=false);
  52.     if(not done) then begin
  53.       nlines:=nlines+1;
  54.       linepos[nlines]:=nextpos;
  55.       len:=xlength(temp);
  56.       for i:=1 to len do
  57.         linebuf[nextpos+i-1]:=temp[i];
  58.       linebuf[nextpos+len]:=endstr;
  59.       nextpos:=nextpos+len+1
  60.     end
  61.   until (done) or (nextpos>= maxchars-maxstr)
  62.     or (nlines>=maxlines);
  63.   gtext:=done
  64. end;
  65.  
  66. procedure ptext(var linepos:posbuf;nlines:integer;
  67.   var linebuf:charbuf;outfile:filedesc);
  68. var
  69.   i,j:integer;
  70. begin
  71.   for i:=1 to nlines do begin
  72.       j:=linepos[i];
  73.       while (linebuf[j]<>endstr)do begin
  74.         putcf(linebuf[j],outfile);
  75.         j:=j+1
  76.       end
  77.     end
  78. end;
  79.  
  80.       
  81.  
  82. procedure exchange(var lp1,lp2:charpos);
  83. var
  84.   temp:charpos;
  85. begin
  86.   temp:=lp1;
  87.   lp1:=lp2;
  88.   lp2:=temp
  89. end;
  90.  
  91. function cmp (i,j:charpos;var linebuf:charbuf)
  92.    :integer;
  93. begin
  94.   while(linebuf[i]=linebuf[j])
  95.    and (linebuf[i]<>endstr) do begin
  96.      i:=i+1;
  97.      j:=j+1
  98.    end;
  99.    if(linebuf[i]=linebuf[j]) then
  100.      cmp:=0
  101.    else if (linebuf[i]=endstr) then
  102.      cmp:=-1
  103.    else if (linebuf[j]=endstr) then
  104.      cmp:=+1
  105.    else if (linebuf[i]<linebuf[j]) then
  106.      cmp:=-1
  107.    else
  108.      cmp:=+1
  109. end;(*cmp*)
  110.  
  111.  
  112. procedure quick(var linepos:posbuf; nline:pos;
  113.   var linebuf:charbuf);
  114. procedure rquick(lo,hi:integer);
  115. var
  116.   i,j:integer;
  117.   pivline:charpos;
  118. begin
  119.   if (lo<hi) then begin
  120.     i:=lo;
  121.     j:=hi;
  122.     pivline:=linepos[j];
  123.     repeat
  124.       while (i<j)
  125.         and (cmp(linepos[i],pivline,linebuf)<=0) do
  126.           i:=i+1;
  127.       while  (j>i)
  128.         and (cmp(linepos[j],pivline,linebuf)>=0) do
  129.           j:=j-1;
  130.       if(i<j) then
  131.       (*out of order pair*)
  132.         exchange(linepos[i],linepos[j])
  133.     until (i>=j);
  134.     exchange(linepos[i],linepos[hi]);
  135.     if(i-lo<hi-i) then begin
  136.       rquick(lo,i-1);
  137.       rquick(i+1,hi)
  138.     end
  139.     else begin
  140.       rquick(i+1,hi);
  141.       rquick(lo,i-1)
  142.     end
  143.   end
  144. end;(*rquick*)
  145.  
  146. begin(*quick*)
  147.   rquick(1,nlines)
  148. end;
  149.  
  150.  
  151. procedure gname(n:integer;var name:xstring);
  152. var
  153.   junk:integer;
  154.   begin
  155.     name[1]:=ord('s');
  156.     name[2]:=ord('t');
  157.     name[3]:=ord('e');
  158.     name[4]:=ord('m');
  159.     name[5]:=ord('p');
  160.     name[6]:=endstr;
  161.   junk:=itoc(n,name,xlength(name)+1)
  162. end;
  163.  
  164. procedure gopen(var infile:fdbuf;f1,f2:integer);
  165. var
  166.   name:xstring;
  167.   i:1..mergeorder;
  168. begin
  169.   for i:=1 to f2-f1+1 do begin
  170.     gname(f1+i-1,name);
  171.     infile[i]:=mustopen(name,ioread)
  172.   end
  173. end;
  174.  
  175. procedure gremove(var infile:fdbuf;f1,f2:integer);
  176. var
  177.   name:xstring;
  178.   i:1..mergeorder;
  179. begin
  180.   for i:= 1 to f2-f1+1 do begin
  181.     xclose(infile[i]);
  182.     gname(f1+i-1,name);
  183.     remove(name)
  184.   end
  185. end;
  186.  
  187.  
  188. function makefile(n:integer):filedesc;
  189. var
  190.   name:xstring;
  191. begin
  192.   gname(n,name);
  193.  
  194.   makefile:=mustcreate(name,iowrite)
  195. end;
  196.  
  197. procedure merge(var infile:fdbuf; nf:integer;
  198.   outfile:filedesc);
  199.  
  200. var
  201.   i,j:integer;
  202.   lbp:charpos;
  203.   temp:xstring;
  204.  
  205. procedure reheap(var linepos:posbuf;nf:pos;
  206.   var linebuf:charbuf);
  207. var
  208.   i,j:integer;
  209. begin
  210.   i:=1;
  211.   j:=2*i;
  212.   while(j<=nf)do begin
  213.     if(j<nf) then
  214.       if(cmp(linepos[j],linepos[j+1],linebuf)>0)then
  215.         j:=j+1;
  216.     if(cmp(linepos[i],linepos[j],linebuf)<=0)then
  217.       i:=nf
  218.     else
  219.       exchange(linepos[i],linepos[j]);(*percolate*)
  220.     i:=j;
  221.     j:=2*i
  222.   end
  223. end;
  224.  
  225. procedure sccopy(var s:xstring; var cb:charbuf;
  226.   i:charpos);
  227. var j:integer;
  228. begin
  229.   j:=1;
  230.   while(s[j]<>endstr)do begin
  231.     cb[i]:=s[j];
  232.     j:=j+1;
  233.     i:=i+1
  234.   end;
  235.   cb[i]:=endstr
  236. end;
  237.  
  238. procedure cscopy(var cb:charbuf;i:charpos;
  239.   var s:xstring);
  240. var j:integer;
  241. begin
  242.   j:=1;
  243.   while(cb[i]<>endstr)do begin
  244.     s[j]:=cb[i];
  245.     i:=i+1;
  246.     j:=j+1
  247.   end;
  248.   s[j]:=endstr
  249. end;
  250.  
  251. begin(*merge*)
  252.   j:=0;
  253.   for i:=1 to nf do
  254.     if(getline(temp,infile[i],maxstr)) then begin
  255.       lbp:=(i-1)*maxstr+1;
  256.       sccopy(temp,linebuf,lbp);
  257.       linepos[i]:=lbp;
  258.       j:=j+1
  259.     end;
  260.   nf:=j;
  261.   quick(linepos,nf,linebuf);
  262.   while (nf>0) do begin
  263.     lbp:=linepos[1];
  264.     cscopy(linebuf,lbp,temp);
  265.     putstr(temp,outfile);
  266.     i:=lbp div maxstr +1;
  267.     if (getline(temp,infile[i],maxstr))then
  268.       sccopy(temp,linebuf,lbp)
  269.     else begin
  270.       linepos[1]:=linepos[nf];
  271.       nf:=nf-1
  272.     end;
  273.     reheap(linepos,nf,linebuf)
  274.   end
  275. end;
  276.  
  277.  
  278. begin
  279.   high:=0;
  280.   repeat (*initial formtion of runs*)
  281.     done:=gtext(linepos,nlines,linebuf,stdin);
  282.     quick(linepos,nlines,linebuf);
  283.     high:=high+1;
  284.     outfile:=makefile(high);
  285.     ptext(linepos,nlines,linebuf,outfile);
  286.     xclose(outfile)
  287.   until (done);
  288.   low:=1;
  289.   while (low<high) do begin
  290.     lim:=min(low+mergeorder-1,high);
  291.     gopen(infile,low,lim);
  292.     high:=high+1;
  293.     outfile:=makefile(high);
  294.     merge(infile,lim-low+1,outfile);
  295.     xclose(outfile);
  296.     gremove(infile,low,lim);
  297.     low:=low+mergeorder
  298.   end;
  299.   gname(high,name);
  300.   outfile:=open(name,ioread);
  301.   fcopy(outfile,stdout);
  302.   xclose(outfile);
  303.   remove(name)
  304. end;
  305.  
  306. procedure unique;
  307. var
  308.   buf:array[0..1] of xstring;
  309.   cur:0..1;
  310. begin
  311.   cur:=1;
  312.   buf[1-cur][1]:=endstr;
  313.   while (getline(buf[cur],stdin,maxstr))do
  314.     if (not equal (buf[cur],buf[1-cur])) then begin
  315.       putstr(buf[cur],stdout);
  316.       cur:=1-cur
  317.     end
  318. end;
  319.  
  320. procedure kwic;
  321. const
  322.   fold=dollar;
  323. var
  324.   buf:xstring;
  325.  
  326. procedure putrot(var buf:xstring);
  327. var i:integer;
  328.  
  329. procedure rotate(var buf:xstring;n:integer);
  330. var i:integer;
  331. begin
  332.   i:=n;
  333.   while (buf[i]<>newline) and (buf[i]<>endstr) do begin
  334.     putc(buf[i]);
  335.     i:=i+1
  336.   end;
  337.   putc(fold);
  338.   for i:=1 to n-1 do
  339.     putc(buf[i]);
  340.   putc(newline)
  341. end;(*rotate*)
  342.  
  343. begin(*putrot*)
  344.   i:=1;
  345.   while(buf[i]<>newline) and (buf[i]<>endstr) do begin
  346.     if (isalphanum(buf[i])) then begin
  347.       rotate(buf,i);(*token statrs at "i"*)
  348.     repeat
  349.       i:=i+1
  350.     until (not isalphanum(buf[i]))
  351.   end;
  352.   i:=i+1
  353.   end
  354.   
  355. end;(*putrot*)
  356.  
  357. begin(*kwic*)
  358.   while(getline(buf,stdin,maxstr))do
  359.     putrot(buf)
  360. end;
  361.  
  362. procedure unrotate;
  363. const
  364.   maxout=80;
  365.   middle=40;
  366.   fold=dollar;
  367. var
  368.   inbuf,outbuf:xstring;
  369.   i,j,f:integer;
  370. begin
  371.   while(getline(inbuf,stdin,maxstr))do begin
  372.     for i:=1 to maxout-1 do
  373.       outbuf[i]:=blank;
  374.     f:=index(inbuf,fold);
  375.     j:=middle-1;
  376.     for i:=xlength(inbuf)-1 downto f+1 do begin
  377.       outbuf[j]:=inbuf[i];
  378.       j:=j-1;
  379.       if(j<=0)then
  380.         j:=maxout-1
  381.     end;
  382.     j:=middle+1;
  383.     for i:=1 to f-1 do begin
  384.       outbuf[j]:=inbuf[i];
  385.       j:=j mod (maxout-1) +1
  386.     end;
  387.     for j:=1 to maxout-1 do
  388.       if(outbuf[j]<>blank) then
  389.         i:=j;
  390.     outbuf[i+1]:=endstr;
  391.     putstr(outbuf,stdout);
  392.     putc(newline)
  393.   end
  394. end;
  395.