home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / turbopas / keyword.lbr / KEYWORD.PQS / KEYWORD.PAS
Pascal/Delphi Source File  |  1986-05-18  |  9KB  |  364 lines

  1. PROGRAM KEYWORD;
  2. (* Program reads a file and removes all words.  Puts words in list   *)
  3.  
  4. CONST
  5.      DATE     = '4/18/86';
  6.      VERSION  = 'VERSION 1.0';
  7.      WORDLEN  = 40;
  8. TYPE
  9.      SWORD    = STRING[WORDLEN];
  10.      S20      = STRING[20];
  11.      S4       = STRING[4];
  12.      S128     = STRING[128];
  13.  
  14.      KWPTR    = ^KWORD;
  15.      KWORD    = RECORD
  16.                     KW    : SWORD;
  17.                     KWCAP : SWORD;
  18.                     LEFT  : KWPTR;
  19.                     RIGHT : KWPTR;
  20.                  END;
  21.  
  22.      CHARSET  = SET OF CHAR;
  23. VAR
  24.      HEAD     : KWPTR;
  25.      NAME     : S20;
  26.      D1       : TEXT;
  27.      WORDSET  : CHARSET;
  28.      STARTSET : CHARSET;
  29.      WSIZE    : INTEGER;
  30.      SIZE     : INTEGER;
  31.  
  32. (* **************************************************************** *)
  33. (*                     PROCEDURES/FUNCTIONS                         *)
  34. (* **************************************************************** *)
  35.  
  36. PROCEDURE GET_FILE_NAME(VAR NAME : S20);
  37. VAR
  38.      CMDLINE  : S20 ABSOLUTE $80;
  39.      F1       : TEXT;
  40. BEGIN
  41.      NAME := CMDLINE;
  42.      ASSIGN(F1,NAME);
  43.      {$I-} RESET(F1); {$I+}
  44.      IF IORESULT <> 0 THEN
  45.      BEGIN
  46.         WRITELN('INVALID NAME. PLEASE REDO.');
  47.         HALT;
  48.      END;
  49.      CLOSE(F1);
  50. END;
  51.  
  52. PROCEDURE GET_SIZE(VAR SIZE : INTEGER;
  53.                        NAME : S20     );
  54. VAR
  55.    FZ  : FILE;
  56. BEGIN
  57.      ASSIGN(FZ,NAME);
  58.      RESET(FZ);
  59.      SIZE := FILESIZE(FZ);
  60.      CLOSE(FZ);
  61. END;
  62.  
  63. PROCEDURE UPSHIFT(VAR X : SWORD);
  64. VAR
  65.      I,J  : INTEGER;
  66. BEGIN
  67.      FOR I := 1 TO LENGTH(X) DO
  68.         IF X[I] IN ['a'..'z'] THEN
  69.            X[I] := UPCASE(X[I]);
  70. END;
  71.  
  72. PROCEDURE GET_OUT_DEVICE(VAR D1 : TEXT );
  73. VAR
  74.      ONAME : SWORD;
  75.      GOOD  : BOOLEAN;
  76. BEGIN
  77.      REPEAT
  78.         GOOD := TRUE;
  79.         WRITE('ENTER OUTPUT DEVICE (CON:,LST:,FILENAME) -> ');
  80.         READLN(ONAME);
  81.         UPSHIFT(ONAME);
  82.         
  83.         IF ONAME = 'CON:' THEN
  84.         BEGIN
  85.            ASSIGN(D1,'CON:');
  86.            RESET(D1);
  87.         END
  88.         ELSE
  89.         IF ONAME = 'LST:' THEN
  90.         BEGIN
  91.            ASSIGN(D1,'LST:');
  92.            RESET(D1);
  93.         END
  94.         ELSE
  95.         BEGIN                   (* OPEN FILE                        *)
  96.            ASSIGN(D1,ONAME);
  97.            {$I-} RESET(D1); {$I+}
  98.            IF IORESULT = 0 THEN 
  99.            BEGIN
  100.               WRITELN('FILE - ',ONAME,' - ALREADY EXISTS');
  101.               CLOSE(D1);
  102.               GOOD := FALSE;
  103.            END
  104.            ELSE
  105.            BEGIN                (* OPEN FILE FOR WRITE              *)
  106.               {$I-} REWRITE(D1); {$I+}
  107.               IF IORESULT <> 0 THEN
  108.               BEGIN
  109.                  WRITELN('INVALID NAME - ',ONAME);
  110.                  GOOD := FALSE;
  111.               END;
  112.            END;                 (* END OF OPEN FILE FOR WRITE       *)
  113.         END;                 (* END OF OPEN FILE                    *)
  114.      UNTIL GOOD;          (* OUTPUT DEVICE OPENED                   *)
  115. END;                   (* END OF PROCEDURE GET_OUTPUT_DEVICE        *)
  116.  
  117. FUNCTION GET_SETS(X  : S4) : BOOLEAN;
  118. VAR
  119.      A  : CHAR;
  120. BEGIN
  121.      REPEAT
  122.         WRITE('   INCLUDE "',X,'" (Y/N) -> ');
  123.         READLN(A);
  124.         A := UPCASE(A);
  125.      UNTIL A IN ['Y','N'];
  126.      IF A = 'Y' THEN
  127.         GET_SETS := TRUE
  128.      ELSE
  129.         GET_SETS := FALSE;
  130. END;
  131.  
  132. PROCEDURE GET_CHAR_SET(VAR WSET  : CHARSET;
  133.                        VAR A     : CHAR;
  134.                            WX    : S20    );
  135. VAR
  136.      GOOD  : BOOLEAN;
  137.      ASET  : S20;
  138.      I     : INTEGER;
  139. BEGIN
  140.      WSET := [];
  141.      WRITELN;
  142.      WRITELN('DEFINE CHARACTERS IN ',WX);
  143.  
  144.      IF GET_SETS('A..Z') THEN
  145.         WSET := WSET + ['A'..'Z'];
  146.      IF GET_SETS('a..z') THEN
  147.         WSET := WSET + ['a'..'z'];
  148.      IF GET_SETS('0..9') THEN
  149.         WSET := WSET + ['0'..'9'];
  150.      WRITE('   ENTER ANY OTHER CHARACTERS IN ',WX,' -> ');
  151.      READLN(ASET);
  152.      FOR I := 1 TO LENGTH(ASET) DO
  153.         WSET := WSET + [ASET[I]];
  154.  
  155.      WRITELN;
  156.      WRITE(WX,' => ');
  157.      IF 'A' IN WSET THEN
  158.         WRITE('A..Z ');
  159.      IF 'a' IN WSET THEN
  160.         WRITE('a..z ');
  161.      IF '0' IN WSET THEN
  162.         WRITE('0..9 ' );
  163.      WRITELN(ASET);
  164.      REPEAT
  165.         WRITE('IS THIS CORRECT (Y/N) -> ');
  166.         READLN(A);
  167.         A := UPCASE(A);
  168.      UNTIL A IN ['Y','N'];
  169. END;                             (* END PROCEDURE GET_CHAR_SET     *)
  170.  
  171. PROCEDURE GET_OPTIONS(VAR WSIZE    : INTEGER;
  172.                       VAR WORDSET  : CHARSET;
  173.                       VAR STARTSET : CHARSET );
  174. VAR
  175.      A     : CHAR;
  176.      WX    : S20;
  177. BEGIN
  178.      REPEAT
  179.         WRITE('ENTER SIZE OF SMALLEST KEY WORD (1,2,etc) -> ');
  180.         READLN(WSIZE);
  181.         IF NOT (WSIZE IN [1..(WORDLEN DIV 2)]) THEN
  182.         BEGIN
  183.            WRITELN('INVALID WORD SIZE');
  184.            WSIZE := 0;
  185.         END;
  186.      UNTIL WSIZE > 0;
  187.  
  188.      REPEAT
  189.         WX := 'KEY WORD SET';
  190.         GET_CHAR_SET(WORDSET,A,WX);
  191.      UNTIL A = 'Y';
  192.  
  193.      REPEAT
  194.         WX := 'START WORD SET';
  195.         GET_CHAR_SET(STARTSET,A,WX);
  196.      UNTIL A = 'Y';
  197.  
  198. END;                                   (* END PROCEDURE GET_OPTIONS *)
  199.  
  200. PROCEDURE INITIALIZE(VAR HEAD   : KWPTR );
  201. BEGIN
  202.      HEAD := NIL;
  203. END;
  204.  
  205. PROCEDURE PUT_WORD_IN_TREE(VAR HEAD    : KWPTR;
  206.                                W       : SWORD );
  207. VAR
  208.      CUR   : KWPTR;
  209.      PREV  : KWPTR;
  210.      TW    : SWORD;
  211. BEGIN
  212.      TW := W;
  213.      UPSHIFT(TW);
  214.      IF HEAD = NIL THEN
  215.      BEGIN
  216.         NEW(HEAD);
  217.         HEAD^.KW := W;
  218.         HEAD^.KWCAP := TW;
  219.         HEAD^.LEFT  := NIL;
  220.         HEAD^.RIGHT := NIL;
  221.      END
  222.      ELSE
  223.      BEGIN
  224.         CUR := HEAD;
  225.         PREV:=CUR;
  226.  
  227.         WHILE (CUR <> NIL) AND (CUR^.KWCAP <> TW) DO
  228.         BEGIN
  229.            PREV := CUR;
  230.            IF TW < CUR^.KWCAP THEN
  231.               CUR := CUR^.LEFT
  232.            ELSE
  233.               CUR := CUR^.RIGHT;
  234.         END;
  235.  
  236.         IF CUR = NIL THEN
  237.         BEGIN
  238.            NEW(CUR);
  239.            CUR^.KW    := W;
  240.            CUR^.KWCAP := TW;
  241.            CUR^.LEFT  := NIL;
  242.            CUR^.RIGHT := NIL;
  243.            IF TW < PREV^.KWCAP THEN
  244.               PREV^.LEFT := CUR
  245.            ELSE
  246.               PREV^.RIGHT := CUR;
  247.         END;
  248.      END;                     (* END NOT FIRST WORD                 *)
  249. END;                      (* END PROCEDURE PUT_WORD_IN_TREE         *)
  250.  
  251. PROCEDURE READ_FILE(VAR WSIZE   : INTEGER;
  252.                         WORDSET : CHARSET;
  253.                         STARTSET: CHARSET;
  254.                     VAR HEAD    : KWPTR;
  255.                         NAME    : S20;
  256.                         SIZE    : INTEGER   );
  257. VAR
  258.      F1    : FILE;
  259.      A     : CHAR;
  260.      W     : SWORD;
  261.      DONE  : BOOLEAN;
  262.      CNT   : REAL;
  263.      FSIZE : REAL;
  264.      BUF   : S128;
  265.      PT    : INTEGER;
  266.  
  267.      PROCEDURE READ_CHAR(VAR A    : CHAR;
  268.                          VAR BUF  : S128;
  269.                          VAR PT   : INTEGER );
  270.      VAR
  271.         RECREAD   : INTEGER;
  272.      BEGIN
  273.           IF PT = 128 THEN
  274.           BEGIN
  275.              BLOCKREAD(F1,BUF,1,RECREAD);
  276.              IF RECREAD = 0 THEN
  277.              BEGIN
  278.                   WRITELN('READ ERROR');
  279.                   HALT;
  280.              END;
  281.              PT := 0;
  282.           END;
  283.  
  284.           PT := PT + 1;
  285.           A := BUF[PT];
  286.      END;                  (* END OF PROCEDURE READ_CHAR            *)
  287.  
  288. BEGIN
  289.      ASSIGN(F1,NAME);
  290.      RESET(F1);
  291.      CNT := 0;
  292.      PT  := 128;
  293.      BUF := '';
  294.      FSIZE := SIZE * 128.0;
  295.  
  296.      WHILE CNT < FSIZE DO
  297.      BEGIN
  298.         DONE := FALSE;
  299.         READ_CHAR(A,BUF,PT);
  300.         CNT := CNT + 1.0;
  301.         WHILE (NOT DONE) AND (NOT (A IN STARTSET)) DO
  302.         BEGIN
  303.            IF CNT = FSIZE THEN
  304.               DONE := TRUE
  305.            ELSE
  306.            BEGIN
  307.               READ_CHAR(A,BUF,PT);
  308.               CNT := CNT + 1.0;
  309.            END;
  310.         END;
  311.  
  312.         W := '';
  313.         WHILE (NOT DONE) AND (A IN WORDSET) DO
  314.         BEGIN
  315.            IF LENGTH(W) = WORDLEN THEN
  316.            BEGIN
  317.               PUT_WORD_IN_TREE(HEAD,W);
  318.               W := '';
  319.            END;
  320.            W := W + A;
  321.            IF CNT < FSIZE THEN
  322.            BEGIN
  323.               READ_CHAR(A,BUF,PT);
  324.               CNT := CNT + 1.0;
  325.            END
  326.            ELSE
  327.               DONE := TRUE;
  328.         END;
  329.  
  330.         IF LENGTH(W) >= WSIZE THEN
  331.            PUT_WORD_IN_TREE(HEAD,W);
  332.      END;                              (* END OF WHILE NOT EOF      *)
  333.      CLOSE(F1);
  334. END;                   (* END OF PROCEDURE READ_FILE                *)
  335.  
  336. {$A-}
  337. PROCEDURE PRINT_WORDS(CUR   : KWPTR );
  338. BEGIN
  339.      IF CUR <> NIL THEN
  340.      BEGIN
  341.         PRINT_WORDS(CUR^.LEFT);
  342.         WRITELN(D1,CUR^.KW);
  343.         PRINT_WORDS(CUR^.RIGHT)        
  344.      END;
  345. END;
  346. {$A+}
  347.  
  348. (* **************************************************************** *)
  349. (*                     MAIN PROGRAM                                 *)
  350. (* **************************************************************** *)
  351.  
  352. BEGIN
  353.      GET_FILE_NAME(NAME);
  354.      GET_SIZE(SIZE,NAME);
  355.      GET_OUT_DEVICE(D1);
  356.      GET_OPTIONS(WSIZE,WORDSET,STARTSET);
  357.      INITIALIZE(HEAD);
  358.  
  359.      READ_FILE(WSIZE,WORDSET,STARTSET,HEAD,NAME,SIZE);
  360.  
  361.      PRINT_WORDS(HEAD);
  362.      CLOSE(D1);
  363. END.
  364.