home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume3 / turbo_tools / part2 / chapter4.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1986-11-30  |  7.4 KB  |  399 lines

  1. {chapter4.pas}
  2.  
  3. {
  4.         Copyright (c) 1981
  5.         By:     Bell Telephone Laboratories, Inc. and
  6.                 Whitesmith's Ltd.,
  7.  
  8.         This software is derived from the book
  9.                 "Software Tools in Pascal", by
  10.                 Brian W. Kernighan and P. J. Plauger
  11.                 Addison-Wesley, 1981
  12.                 ISBN 0-201-10342-7
  13.  
  14.         Right is hereby granted to freely distribute or duplicate this
  15.         software, providing distribution or duplication is not for profit
  16.         or other commercial gain and that this copyright notice remains
  17.         intact.
  18. }
  19.  
  20. PROCEDURE SORT;
  21. CONST
  22.   MAXCHARS=10000;
  23.   MAXLINES=300;
  24.   MERGEORDER=5;
  25. TYPE
  26.   CHARPOS=1..MAXCHARS;
  27.   CHARBUF=ARRAY[1..MAXCHARS] OF CHARACTER;
  28.   POSBUF=ARRAY[1..MAXLINES] OF CHARPOS;
  29.   POS=0..MAXLINES;
  30.   FDBUF=ARRAY[1..MERGEORDER]OF FILEDESC;
  31. VAR
  32.   LINEBUF:CHARBUF;
  33.   LINEPOS:POSBUF;
  34.   NLINES:POS;
  35.   INFILE:FDBUF;
  36.   OUTFILE:FILEDESC;
  37.   HIGH,LOW,LIM:INTEGER;
  38.   DONE:BOOLEAN;
  39.   NAME:XSTRING;
  40. FUNCTION GTEXT(VAR LINEPOS:POSBUF;VAR NLINES:POS;
  41.   VAR LINEBUF:CHARBUF;INFILE:FILEDESC):BOOLEAN;
  42. VAR
  43.   I,LEN,NEXTPOS:INTEGER;
  44.   TEMP:XSTRING;
  45.   DONE:BOOLEAN;
  46. BEGIN
  47.   NLINES:=0;
  48.   NEXTPOS:=1;
  49.   REPEAT
  50.     DONE:=(GETLINE(TEMP,INFILE,MAXSTR)=FALSE);
  51.     IF(NOT DONE) THEN BEGIN
  52.       NLINES:=NLINES+1;
  53.       LINEPOS[NLINES]:=NEXTPOS;
  54.       LEN:=XLENGTH(TEMP);
  55.       FOR I:=1 TO LEN DO
  56.         LINEBUF[NEXTPOS+I-1]:=TEMP[I];
  57.       LINEBUF[NEXTPOS+LEN]:=ENDSTR;
  58.       NEXTPOS:=NEXTPOS+LEN+1
  59.     END
  60.   UNTIL (DONE) OR (NEXTPOS>= MAXCHARS-MAXSTR)
  61.     OR (NLINES>=MAXLINES);
  62.   GTEXT:=DONE
  63. END;
  64.  
  65. PROCEDURE PTEXT(VAR LINEPOS:POSBUF;NLINES:INTEGER;
  66.   VAR LINEBUF:CHARBUF;OUTFILE:FILEDESC);
  67. VAR
  68.   I,J:INTEGER;
  69. BEGIN
  70.   FOR I:=1 TO NLINES DO BEGIN
  71.       J:=LINEPOS[I];
  72.       WHILE (LINEBUF[J]<>ENDSTR)DO BEGIN
  73.         PUTCF(LINEBUF[J],OUTFILE);
  74.         J:=J+1
  75.       END
  76.     END
  77. END;
  78.  
  79.       
  80.  
  81. PROCEDURE EXCHANGE(VAR LP1,LP2:CHARPOS);
  82. VAR
  83.   TEMP:CHARPOS;
  84. BEGIN
  85.   TEMP:=LP1;
  86.   LP1:=LP2;
  87.   LP2:=TEMP
  88. END;
  89.  
  90. FUNCTION CMP (I,J:CHARPOS;VAR LINEBUF:CHARBUF)
  91.    :INTEGER;
  92. BEGIN
  93.   WHILE(LINEBUF[I]=LINEBUF[J])
  94.    AND (LINEBUF[I]<>ENDSTR) DO BEGIN
  95.      I:=I+1;
  96.      J:=J+1
  97.    END;
  98.    IF(LINEBUF[I]=LINEBUF[J]) THEN
  99.      CMP:=0
  100.    ELSE IF (LINEBUF[I]=ENDSTR) THEN
  101.      CMP:=-1
  102.    ELSE IF (LINEBUF[J]=ENDSTR) THEN
  103.      CMP:=+1
  104.    ELSE IF (LINEBUF[I]<LINEBUF[J]) THEN
  105.      CMP:=-1
  106.    ELSE
  107.      CMP:=+1
  108. END;(*CMP*)
  109.  
  110.  
  111. PROCEDURE QUICK(VAR LINEPOS:POSBUF; NLINE:POS;
  112.   VAR LINEBUF:CHARBUF);
  113. PROCEDURE RQUICK(LO,HI:INTEGER);
  114. VAR
  115.   I,J:INTEGER;
  116.   PIVLINE:CHARPOS;
  117. BEGIN
  118.   IF (LO<HI) THEN BEGIN
  119.     I:=LO;
  120.     J:=HI;
  121.     PIVLINE:=LINEPOS[J];
  122.     REPEAT
  123.       WHILE (I<J)
  124.         AND (CMP(LINEPOS[I],PIVLINE,LINEBUF)<=0) DO
  125.           I:=I+1;
  126.       WHILE  (J>I)
  127.         AND (CMP(LINEPOS[J],PIVLINE,LINEBUF)>=0) DO
  128.           J:=J-1;
  129.       IF(I<J) THEN
  130.       (*OUT OF ORDER PAIR*)
  131.         EXCHANGE(LINEPOS[I],LINEPOS[J])
  132.     UNTIL (I>=J);
  133.     EXCHANGE(LINEPOS[I],LINEPOS[HI]);
  134.     IF(I-LO<HI-I) THEN BEGIN
  135.       RQUICK(LO,I-1);
  136.       RQUICK(I+1,HI)
  137.     END
  138.     ELSE BEGIN
  139.       RQUICK(I+1,HI);
  140.       RQUICK(LO,I-1)
  141.     END
  142.   END
  143. END;(*RQUICK*)
  144.  
  145. BEGIN(*QUICK*)
  146.   RQUICK(1,NLINES)
  147. END;
  148.  
  149.  
  150. PROCEDURE GNAME(N:INTEGER;VAR NAME:XSTRING);
  151. VAR
  152.   JUNK:INTEGER;
  153.   BEGIN
  154.     NAME[1]:=ORD('S');
  155.     NAME[2]:=ORD('T');
  156.     NAME[3]:=ORD('E');
  157.     NAME[4]:=ORD('M');
  158.     NAME[5]:=ORD('P');
  159.     NAME[6]:=ENDSTR;
  160.   JUNK:=ITOC(N,NAME,XLENGTH(NAME)+1)
  161. END;
  162.  
  163. PROCEDURE GOPEN(VAR INFILE:FDBUF;F1,F2:INTEGER);
  164. VAR
  165.   NAME:XSTRING;
  166.   I:1..MERGEORDER;
  167. BEGIN
  168.   FOR I:=1 TO F2-F1+1 DO BEGIN
  169.     GNAME(F1+I-1,NAME);
  170.     INFILE[I]:=MUSTOPEN(NAME,IOREAD)
  171.   END
  172. END;
  173.  
  174. PROCEDURE GREMOVE(VAR INFILE:FDBUF;F1,F2:INTEGER);
  175. VAR
  176.   NAME:XSTRING;
  177.   I:1..MERGEORDER;
  178. BEGIN
  179.   FOR I:= 1 TO F2-F1+1 DO BEGIN
  180.     XCLOSE(INFILE[I]);
  181.     GNAME(F1+I-1,NAME);
  182.     REMOVE(NAME)
  183.   END
  184. END;
  185.  
  186.  
  187. FUNCTION MAKEFILE(N:INTEGER):FILEDESC;
  188. VAR
  189.   NAME:XSTRING;
  190. BEGIN
  191.   GNAME(N,NAME);
  192.  
  193.   MAKEFILE:=MUSTCREATE(NAME,IOWRITE)
  194. END;
  195.  
  196. PROCEDURE MERGE(VAR INFILE:FDBUF; NF:INTEGER;
  197.   OUTFILE:FILEDESC);
  198.  
  199. VAR
  200.   I,J:INTEGER;
  201.   LBP:CHARPOS;
  202.   TEMP:XSTRING;
  203.  
  204. PROCEDURE REHEAP(VAR LINEPOS:POSBUF;NF:POS;
  205.   VAR LINEBUF:CHARBUF);
  206. VAR
  207.   I,J:INTEGER;
  208. BEGIN
  209.   I:=1;
  210.   J:=2*I;
  211.   WHILE(J<=NF)DO BEGIN
  212.     IF(J<NF) THEN
  213.       IF(CMP(LINEPOS[J],LINEPOS[J+1],LINEBUF)>0)THEN
  214.         J:=J+1;
  215.     IF(CMP(LINEPOS[I],LINEPOS[J],LINEBUF)<=0)THEN
  216.       I:=NF
  217.     ELSE
  218.       EXCHANGE(LINEPOS[I],LINEPOS[J]);(*PERCOLATE*)
  219.     I:=J;
  220.     J:=2*I
  221.   END
  222. END;
  223.  
  224. PROCEDURE SCCOPY(VAR S:XSTRING; VAR CB:CHARBUF;
  225.   I:CHARPOS);
  226. VAR J:INTEGER;
  227. BEGIN
  228.   J:=1;
  229.   WHILE(S[J]<>ENDSTR)DO BEGIN
  230.     CB[I]:=S[J];
  231.     J:=J+1;
  232.     I:=I+1
  233.   END;
  234.   CB[I]:=ENDSTR
  235. END;
  236.  
  237. PROCEDURE CSCOPY(VAR CB:CHARBUF;I:CHARPOS;
  238.   VAR S:XSTRING);
  239. VAR J:INTEGER;
  240. BEGIN
  241.   J:=1;
  242.   WHILE(CB[I]<>ENDSTR)DO BEGIN
  243.     S[J]:=CB[I];
  244.     I:=I+1;
  245.     J:=J+1
  246.   END;
  247.   S[J]:=ENDSTR
  248. END;
  249.  
  250. BEGIN(*MERGE*)
  251.   J:=0;
  252.   FOR I:=1 TO NF DO
  253.     IF(GETLINE(TEMP,INFILE[I],MAXSTR)) THEN BEGIN
  254.       LBP:=(I-1)*MAXSTR+1;
  255.       SCCOPY(TEMP,LINEBUF,LBP);
  256.       LINEPOS[I]:=LBP;
  257.       J:=J+1
  258.     END;
  259.   NF:=J;
  260.   QUICK(LINEPOS,NF,LINEBUF);
  261.   WHILE (NF>0) DO BEGIN
  262.     LBP:=LINEPOS[1];
  263.     CSCOPY(LINEBUF,LBP,TEMP);
  264.     PUTSTR(TEMP,OUTFILE);
  265.     I:=LBP DIV MAXSTR +1;
  266.     IF (GETLINE(TEMP,INFILE[I],MAXSTR))THEN
  267.       SCCOPY(TEMP,LINEBUF,LBP)
  268.     ELSE BEGIN
  269.       LINEPOS[1]:=LINEPOS[NF];
  270.       NF:=NF-1
  271.     END;
  272.     REHEAP(LINEPOS,NF,LINEBUF)
  273.   END
  274. END;
  275.  
  276.  
  277. BEGIN
  278.   HIGH:=0;
  279.   REPEAT (*INITIAL FORMTION OF RUNS*)
  280.     DONE:=GTEXT(LINEPOS,NLINES,LINEBUF,STDIN);
  281.     QUICK(LINEPOS,NLINES,LINEBUF);
  282.     HIGH:=HIGH+1;
  283.     OUTFILE:=MAKEFILE(HIGH);
  284.     PTEXT(LINEPOS,NLINES,LINEBUF,OUTFILE);
  285.     XCLOSE(OUTFILE)
  286.   UNTIL (DONE);
  287.   LOW:=1;
  288.   WHILE (LOW<HIGH) DO BEGIN
  289.     LIM:=MIN(LOW+MERGEORDER-1,HIGH);
  290.     GOPEN(INFILE,LOW,LIM);
  291.     HIGH:=HIGH+1;
  292.     OUTFILE:=MAKEFILE(HIGH);
  293.     MERGE(INFILE,LIM-LOW+1,OUTFILE);
  294.     XCLOSE(OUTFILE);
  295.     GREMOVE(INFILE,LOW,LIM);
  296.     LOW:=LOW+MERGEORDER
  297.   END;
  298.   GNAME(HIGH,NAME);
  299.   OUTFILE:=OPEN(NAME,IOREAD);
  300.   FCOPY(OUTFILE,STDOUT);
  301.   XCLOSE(OUTFILE);
  302.   REMOVE(NAME)
  303. END;
  304.  
  305. PROCEDURE UNIQUE;
  306. VAR
  307.   BUF:ARRAY[0..1] OF XSTRING;
  308.   CUR:0..1;
  309. BEGIN
  310.   CUR:=1;
  311.   BUF[1-CUR][1]:=ENDSTR;
  312.   WHILE (GETLINE(BUF[CUR],STDIN,MAXSTR))DO
  313.     IF (NOT EQUAL (BUF[CUR],BUF[1-CUR])) THEN BEGIN
  314.       PUTSTR(BUF[CUR],STDOUT);
  315.       CUR:=1-CUR
  316.     END
  317. END;
  318.  
  319. PROCEDURE KWIC;
  320. CONST
  321.   FOLD=DOLLAR;
  322. VAR
  323.   BUF:XSTRING;
  324.  
  325. PROCEDURE PUTROT(VAR BUF:XSTRING);
  326. VAR I:INTEGER;
  327.  
  328. PROCEDURE ROTATE(VAR BUF:XSTRING;N:INTEGER);
  329. VAR I:INTEGER;
  330. BEGIN
  331.   I:=N;
  332.   WHILE (BUF[I]<>NEWLINE) AND (BUF[I]<>ENDSTR) DO BEGIN
  333.     PUTC(BUF[I]);
  334.     I:=I+1
  335.   END;
  336.   PUTC(FOLD);
  337.   FOR I:=1 TO N-1 DO
  338.     PUTC(BUF[I]);
  339.   PUTC(NEWLINE)
  340. END;(*ROTATE*)
  341.  
  342. BEGIN(*PUTROT*)
  343.   I:=1;
  344.   WHILE(BUF[I]<>NEWLINE) AND (BUF[I]<>ENDSTR) DO BEGIN
  345.     IF (ISALPHANUM(BUF[I])) THEN BEGIN
  346.       ROTATE(BUF,I);(*TOKEN STATRS AT "I"*)
  347.     REPEAT
  348.       I:=I+1
  349.     UNTIL (NOT ISALPHANUM(BUF[I]))
  350.   END;
  351.   I:=I+1
  352.   END
  353.   
  354. END;(*PUTROT*)
  355.  
  356. BEGIN(*KWIC*)
  357.   WHILE(GETLINE(BUF,STDIN,MAXSTR))DO
  358.     PUTROT(BUF)
  359. END;
  360.  
  361. PROCEDURE UNROTATE;
  362. CONST
  363.   MAXOUT=80;
  364.   MIDDLE=40;
  365.   FOLD=DOLLAR;
  366. VAR
  367.   INBUF,OUTBUF:XSTRING;
  368.   I,J,F:INTEGER;
  369. BEGIN
  370.   WHILE(GETLINE(INBUF,STDIN,MAXSTR))DO BEGIN
  371.     FOR I:=1 TO MAXOUT-1 DO
  372.       OUTBUF[I]:=BLANK;
  373.     F:=INDEX(INBUF,FOLD);
  374.     J:=MIDDLE-1;
  375.     FOR I:=XLENGTH(INBUF)-1 DOWNTO F+1 DO BEGIN
  376.       OUTBUF[J]:=INBUF[I];
  377.       J:=J-1;
  378.       IF(J<=0)THEN
  379.         J:=MAXOUT-1
  380.     END;
  381.     J:=MIDDLE+1;
  382.     FOR I:=1 TO F-1 DO BEGIN
  383.       OUTBUF[J]:=INBUF[I];
  384.       J:=J MOD (MAXOUT-1) +1
  385.     END;
  386.     FOR J:=1 TO MAXOUT-1 DO
  387.       IF(OUTBUF[J]<>BLANK) THEN
  388.         I:=J;
  389.     OUTBUF[I+1]:=ENDSTR;
  390.     PUTSTR(OUTBUF,STDOUT);
  391.     PUTC(NEWLINE)
  392.   END
  393. END;
  394.  
  395.  
  396.  
  397.  
  398.  
  399.