home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / norskdata / ndkcom.pas < prev    next >
Pascal/Delphi Source File  |  2020-01-01  |  29KB  |  769 lines

  1. (* tab p; *)
  2.  
  3. (*
  4.  *          Command-handling
  5.  *
  6.  *                for
  7.  *
  8.  *             ND-KERMIT
  9.  *
  10.  *)
  11.  
  12. (*
  13. UTILITY ROUTINES:
  14. *)
  15.  
  16.     function    AtoI ( IntString : NameType; VAR Int : integer ): boolean;
  17.     (*
  18.      * Abstract :   Converts the string in IntString to an integer.
  19.      *      Returns false if IntString does
  20.      *      not contain a valid integer.
  21.      *)
  22.     var     i        : integer;
  23.             ch       : char;
  24.             OkSoFar  : boolean;
  25.     begin (* AtoI *)
  26.         OkSoFar := IntString.Valid <= 4;(* Allow only up to 4 digits       *)
  27.         Int := 0;                       (* in order to prevent overflow... *)
  28.         for i := MinWord to IntString.Valid do
  29.         begin
  30.             ch := IntString.String(.i.);
  31.             OkSoFar := OkSoFar and ( ( ch >= '0' ) and
  32.                                      ( ch <= '9' ) );
  33.             if OkSoFar then
  34.                 Int := Int * 10  + ord(ch) - ord('0');
  35.         end;
  36.         AtoI := OkSoFar;
  37.     end;  (* AtoI *)
  38.  
  39.     function    OkFileSyntax( FileName : NameType ): boolean;
  40.     begin (* OkFileSyntax *)
  41.         (* This one could be complicated - leave it out so long. *)
  42.         OkFileSyntax := true;
  43.     end;  (* OkFileSyntax *)
  44.  
  45. (*
  46.  *      END of Utility routines.
  47.  *)
  48.  
  49.     procedure   Bell;
  50.     begin
  51.         write( ctl('G') );
  52.     end;
  53.  
  54.     procedure   EditLine ( VAR Line : CmdLinType; RePrint : boolean );
  55.     (*
  56.      * Abstract :   Returns with a command line in Line.  The "Valid" field
  57.      *      may be non-zero in order to continue editing of a line already
  58.      *      containing parts of a complete command.
  59.      *      Repeats until a non-empty command line has been input and terminated.
  60.      *      Terminating characters may be <ESC>, "?" or <CR>.
  61.      *      Editing characters recognized by this routine:
  62.      *          ^H    - deletes last character and does BsSpBs.
  63.      *          <DEL> - same
  64.      *          ^A    - same (ND style).
  65.      *          ^Q    - deletes hole line by doing BsSpBs several times.
  66.      *                      (also ND style). (Unless Xon/Xoff is enabled).
  67.      *          ^X    - same  (CP/M style).
  68.      *          ^U    - same  (DEC style)
  69.      *          ^W    - deletes last word (also ND style).
  70.      *)
  71.     type    CharTypes   =   (   CtlQ, CtlW, CtlA, CtlH, chQMark, chCR,
  72.                                 chESC, CtlX, CtlU, Del, OtherCtl, PrintAble );
  73.  
  74.     var     ch      : char;
  75.             Ech     : CharTypes;
  76.             i       : integer;
  77.             PrevSpace,fin,DoTest,Done    : boolean;
  78.             Returning : boolean;
  79.  
  80.         procedure   BsSpBs;
  81.         begin
  82.             write( ctl('H') , ' ' , ctl('H') );
  83.         end;
  84.  
  85.         function    GetChar : char;
  86.         (*
  87.          * Abstract :   Read a character from the user's terminal.
  88.          *      Hangs until a character has been typed, and returns this
  89.          *      character as the function result.
  90.          *)
  91.         begin (* GetChar *)
  92.             GetChar := inbt ( idev );
  93.         end;  (* GetChar *)
  94.  
  95.     begin (* EditLine *)
  96.         with Line do
  97.         repeat
  98.             Returning := false;
  99.             if Valid >= MinName then
  100.                 PrevSpace := String(.Valid.) = ' '
  101.             else
  102.                 PrevSpace := true;  (* previous character was <space> *)
  103.             Cursor    := MinName; 
  104.             if RePrint then begin
  105.                 write( Prompt );
  106.                 for i := 1 to Valid do
  107.                     write( String(.i.) );
  108.             end;
  109.             RePrint := true;
  110.             repeat
  111.                 (* perform editing of Line.String *)
  112.                 fin := false;
  113.                 ch := GetChar;
  114.                 if ( ch = ctl('A') )
  115.                  or( ch = ctl('H') )
  116.                  or( ch = ctl('?') )   (* DEL *)
  117.                 then
  118.                 begin
  119.                     if Valid >= 1 then begin
  120.                         BsSpBs;
  121.                         Valid := Valid - 1;
  122.                     end else
  123.                         Bell;
  124.                     if Valid >= MinName then
  125.                         PrevSpace := String(.Valid.) = ' '
  126.                     else
  127.                         PrevSpace := true;
  128.                 end else
  129.                 if ( ch = ctl('Q') )
  130.                  or( ch = ctl('X') )
  131.                  or( ch = ctl('U') )
  132.                 then
  133.                 begin
  134.                     for i := 1 to Valid do
  135.                         BsSpBs;
  136.                     Valid := 0;
  137.                     PrevSpace := true;
  138.                 end else
  139.                 if ch = ctl('W') then
  140.                 begin
  141.                     if Valid <> 0 then
  142.                     begin
  143.                         (* back-space over blanks: *)
  144.                         repeat
  145.                             Done := false;
  146.                             if ( Valid >= 1 ) then
  147.                                 if ( String(.Valid.) = ' ' ) then
  148.                                 begin
  149.                                     BsSpBs;
  150.                                     Valid := Valid - 1;
  151.                                 end else
  152.                                     Done := true
  153.                             else    Done := true;
  154.                         until Done;
  155.                         DoTest := Valid >= MinName;
  156.                         if DoTest then
  157.                         begin
  158.                             (* back-space over word *)
  159.                             while DoTest do
  160.                             begin
  161.                                 if  String(.Valid.) <> ' ' then
  162.                                 begin
  163.                                     BsSpBs;
  164.                                     Valid := Valid - 1;
  165.                                 end
  166.                                 else
  167.                                     DoTest := false;
  168.                                 DoTest := DoTest and (Valid >= MinName)
  169.                             end;
  170.                             PrevSpace := true;
  171.                         end;
  172.                     end else
  173.                         Bell;
  174.                 end else 
  175.                 if ch = ctl('M') (* CR *) then
  176.                 begin
  177.                     fin := true;
  178.                     Returning := Valid > 0;
  179.                     if not Returning then
  180.                         writeln;
  181.                     Terminator := CR;
  182.                 end else
  183.                 if ch = '?' then
  184.                 begin
  185.                     write('?');
  186.                     fin := true;
  187.                     Returning := true;
  188.                     Terminator := QMark;
  189.                 end else
  190.                 if ch = ctl('[') then
  191.                 begin
  192.                     fin := (Valid > 0) and (not PrevSpace);
  193.                     if not fin then
  194.                         Bell;
  195.                     Returning := fin;
  196.                     Terminator := ESC;
  197.                 end else
  198.                 if ( ch >= ctl('@') )
  199.                 and( ch < ' ')  (* other control characters *)
  200.                 then
  201.                 begin
  202.                     if ch = ctl('T') then
  203.                     begin
  204.                         (* output debug info *)
  205.                         writeln;
  206.                         writeln('Valid =',Valid:2,' Cursor =',Cursor:2);
  207.                         write('EndW  =',EndWord:2,' String :');
  208.                         for i := MinName to Valid do 
  209.                             write(String(.i.));
  210.                         writeln;
  211.                         fin := true;
  212.                     end else
  213.                         Bell;
  214.                 end
  215.                 else
  216.                 (* ch is printable character *)
  217.                 begin
  218.                     if Valid < MaxName then begin
  219.                         Valid := Valid + 1;
  220.                         String(.Valid.) := ch;
  221.                         write( ch );
  222.                     end else
  223.                         Bell;
  224.                     PrevSpace := ch = ' ';
  225.                 end;
  226.             until fin;
  227.         until Returning;
  228.     end;  (* EditLine *)
  229.  
  230.     function    AtEnd ( VAR Buffer : CmdLinType ) : boolean;
  231.     begin   (* AtEnd *)
  232.         AtEnd :=   Buffer.Cursor = Buffer.Valid + 1;
  233.     end;    (* AtEnd *)
  234.  
  235.     procedure   GetWord (   VAR Buffer  : CmdLinType;
  236.                             VAR Word    : WordType );
  237.     (*
  238.      * Abstract :   Get the next word from "Buffer" - Buffer.Cursor points
  239.      *      to next character to be read.  Leading blanks are stripped off.
  240.      *      Only blanks are recognized as word separators.
  241.      *      Buffer.Cursor is advanced to next non-blank or to end of string.
  242.      *)
  243.     var     i,j  : integer;
  244.     begin (* GetWord *)
  245.         with Buffer do
  246.         begin
  247.             i          := Cursor;                         (* Starting pos. *)
  248.             PrevCursor := Cursor;
  249.             while   (Buffer.String(.i.) = ' ')
  250.                 and ( i <= Valid )      (* Space over leading blanks *)
  251.             do
  252.                 i := i + 1;
  253.             j := MinWord;
  254.             while ( i <= Valid ) and
  255.                   ( String(.i.) <> ' ' ) and
  256.                   ( j <= MaxWord ) do
  257.             begin
  258.                                            (* Copy word from buffer to Word. *)
  259.                 Word.String(.j.) := String(.i.);
  260.                 i := i + 1;                (* and increment pointers *)
  261.                 j := j + 1;
  262.             end;
  263.             Word.Valid := j - 1;
  264.             EndWord    := i - 1;
  265.             while ( String(.i.) <> ' ' )(* Advance cursor to next blank *)
  266.               and ( i <= Valid )        (* or to end *)
  267.             do
  268.                 i := i + 1;
  269.             if i = Valid then
  270.                 Cursor := i + 1
  271.             else
  272.                 Cursor := i;
  273.         end;  (* With *)
  274.     end;  (* GetWord *)
  275.  
  276.     procedure   GetName (   VAR Buffer  : CmdLinType;
  277.                             VAR Name    : NameType );
  278.     (*
  279.      * Abstract :   Get the next item from "Buffer" - Buffer.Cursor points
  280.      *      to next character to be read.  Leading blanks are stripped off.
  281.      *      Only blanks are recognized as word separators.
  282.      *      Buffer.Cursor is advanced to next non-blank or to end of string.
  283.      *)
  284.     var     i,j  : integer;
  285.     begin (* GetName *)
  286.         with Buffer do
  287.         begin
  288.             i          := Cursor;                         (* Starting pos. *)
  289.             PrevCursor := Cursor;
  290.             while   (Buffer.String(.i.) = ' ')
  291.                 and ( i <= Valid )      (* Space over leading blanks *)
  292.             do
  293.                 i := i + 1;
  294.             j := MinName;
  295.             while ( i <= Valid ) and
  296.                   ( String(.i.) <> ' ' ) and
  297.                   ( j <= MaxName ) do
  298.             begin
  299.                                            (* Copy word from buffer to Word. *)
  300.                 Name.String(.j.) := String(.i.);
  301.                 i := i + 1;                (* and increment pointers *)
  302.                 j := j + 1;
  303.             end;
  304.             Name.Valid := j - 1;
  305.             EndWord    := i - 1;
  306.             while ( String(.i.) <> ' ' )(* Advance cursor to next blank *)
  307.               and ( i <= Valid )        (* or to end *)
  308.             do
  309.                 i := i + 1;
  310.             if i = Valid then
  311.                 Cursor := i + 1
  312.             else
  313.                 Cursor := i;
  314.         end;  (* With *)
  315.     end;  (* GetName *)
  316.  
  317.     procedure   WordToSymbol (  Word         : WordType;
  318.                                 VAR Symbol   : VocabType;
  319.                                 VAR Status   : MatchType;
  320.                                 VAR Matching : VocabSet;
  321.                                 VAR Expect   : VocabSet );
  322.     (*
  323.      * Abstract :   Translates from Word to Symbol.  Status is set according
  324.      *      to the result of the match.  The matching words become members
  325.      *      of the set Matching.
  326.      *)
  327.     var     MatchFound, ThisWordMatch : boolean;
  328.             i,j         : integer;
  329.             Index,RetVal: VocabType;
  330.         
  331.         function    WordsMatch ( Abbrev , Reference : WordType ):boolean;
  332.         var     i : integer;
  333.                 Match : boolean;
  334.         begin (* WordsMatch *)
  335.             Match := true;
  336.             if ( Abbrev.Valid <= Reference.Valid ) and
  337.                ( Abbrev.Valid >= MinWord )
  338.             then
  339.                 for i := MinWord to Abbrev.Valid do
  340.                     Match := Match and
  341.                         ( uc(Abbrev.String(.i.) ) = Reference.String(.i.))
  342.             else
  343.                 Match := False;
  344.             WordsMatch := Match;
  345.         end; (* WordsMatch *)
  346.  
  347.     begin (* WordToSymbol *)
  348.         RetVal := ExitSym;  (* in order to avoid ILLEGAL SUBRANGE ASSIGNMENT *)
  349.         Matching := (. .);
  350.         Status := NoMatch;
  351.         for Index := First( VocabType ) to Last( VocabType ) do
  352.         begin
  353.             if WordsMatch ( Word , VocabTable(.Index.) ) then
  354.             begin
  355.                 if Index in Expect then
  356.                 begin
  357.                     Matching := Matching + (. Index .);
  358.                     if Status = NoMatch then
  359.                     begin
  360.                         Status := Exact;
  361.                         Symbol := Index;
  362.                     end else
  363.                         Status := Ambigous;
  364.                 end;
  365.             end;
  366.         end;
  367.     end;  (* WordToSymbol *)
  368.  
  369.     procedure   GetCmd (    VAR Verb, Noun, Adj : VocabType;
  370.                             VAR ParBlock        : ParType  );
  371.     (*
  372.      *  Abstract :  Get a new command from the user's terminal.
  373.      *      Does appropriate checking so that returned values are consistent.
  374.      *      Repeats until valid command is given.
  375.      *      Does the following:
  376.      *          "?" preceded by at least a space:
  377.      *              Types out the expected parameters and continues
  378.      *              editing of same line.
  379.      *          "?" not preceded by a space:
  380.      *              Types out the matching parameters.
  381.      *              If no match is found, works as if the last word
  382.      *              had not been typed.  Continues editing of current
  383.      *              command.
  384.      *          <ESC> not preceded by a space:
  385.      *              Deabbreviates the current word. If no match is
  386.      *              found, acts as if "?" had been typed instead.
  387.      *              Continues editing of current command.
  388.      *          <ESC> preceded by a space is not allowed.
  389.      *              (Taken care of by EditLine.)
  390.      *)
  391.     var     Expect  : VocabSet;
  392.             Sym     : VocabType;
  393.             Word    : WordType;
  394.             ValidCommand : boolean;
  395.             RePrint : boolean;
  396.             Buffer  : CmdLinType;
  397.  
  398.         procedure   BackWord;
  399.         begin
  400.             if Buffer.PrevCursor = MinName then
  401.                 Buffer.Valid := MinName - 1
  402.             else
  403.                 Buffer.Valid := Buffer.PrevCursor;
  404.         end;
  405.  
  406.         procedure   MakeEndBlank( VAR Buffer : CmdLinType );
  407.         begin
  408.             with Buffer do
  409.                 if ( Valid >= MinName ) and ( Valid < MaxName ) then
  410.                     if String(.Valid.) <> ' ' then
  411.                     begin
  412.                         String(.Valid + 1.) := ' ';
  413.                         Valid := Valid + 1;
  414.                     end;
  415.         end;
  416.  
  417.         function    ParseWord ( Expect  : VocabSet;
  418.                             VAR Symbol  : VocabType ): boolean;
  419.         (*
  420.          *
  421.          *)
  422.         var     Matching    : VocabSet;
  423.                 Status      : MatchType;
  424.                 RetVal      : boolean;
  425.  
  426.             procedure   WriteWord( Word : WordStr; Valid : integer );
  427.             var     i : integer;
  428.             begin 
  429.                 for i := MinWord to Valid do
  430.                     write( Word(.i.) );
  431.             end;
  432.  
  433.             procedure   OneOf( These : VocabSet );
  434.             const   LettersPrWord   =   8;
  435.                     WordsPrLine     =   6;
  436.                     InitSpace       =   4;
  437.             var     Index : VocabType;
  438.                     WordNo: integer;
  439.                     i     : integer;
  440.  
  441.                 procedure   PrintWord( This : VocabType );
  442.                 var     Need,i : integer;
  443.                 begin (* PrintWord *)
  444.                     Need := 1 + ( VocabTable(.This.).Valid + 2 )
  445.                                 div LettersPrWord;
  446.                     if WordNo + Need > WordsPrLine then
  447.                     begin
  448.                         writeln;
  449.                         write(' ':InitSpace);
  450.                         WordNo := 0;
  451.                     end;
  452.                     WordNo := WordNo + Need;
  453.                     with VocabTable(.This.) do
  454.                     begin
  455.                         WriteWord( String, Valid  );
  456.                         for i := ( ( Valid + 1 ) mod LettersPrWord )
  457.                                  to LettersPrWord
  458.                         do
  459.                             write( ' ' );
  460.                     end;
  461.                 end;  (* PrintWord *)
  462.  
  463.             begin (* OneOf *)
  464.                 writeln(' Use one of the following:');
  465.                 WordNo := 0;
  466.                 write(' ':InitSpace);
  467.                 for Index := First( VocabType ) to Last( VocabType ) do
  468.                     if Index in These then
  469.                     begin
  470.                         PrintWord( Index );
  471.                     end;
  472.                     writeln;
  473.             end;  (* OneOf *)
  474.  
  475.             procedure   Deabbr( Word : WordType;
  476.                                 Symbol : VocabType;
  477.                             VAR Buffer : CmdLinType );
  478.             var     i,j : integer;
  479.             begin (* Deabbr *)
  480.                 with Buffer do
  481.                 begin
  482.                     j := -1;
  483.                     for i := Word.Valid + 1 to VocabTable(. Symbol .).Valid do
  484.                     begin
  485.                         j := i - Word.Valid - 1;
  486.                         ch := VocabTable(. Symbol .).String(.i.);
  487.                         String(. j + Cursor .):= ch;
  488.                         write(ch);
  489.                     end;
  490.                     String(. j + Cursor + 1 .) := ' ';
  491.                     write(' ');
  492.                     Valid := j + Cursor + 1;
  493.                 end;
  494.                 RePrint := false;
  495.             end;  (* Deabbr *)
  496.  
  497.         begin (* ParseWord *)
  498.             if AtEnd( Buffer ) then
  499.             begin
  500.                 case Buffer.Terminator of
  501.                     QMark,Cr:
  502.                         with Buffer do
  503.                         begin
  504.                             if Terminator = Cr then
  505.                                 write(' Not confirmed.');
  506.                             OneOf( Expect );
  507.                             MakeEndBlank( Buffer );
  508.                         end;
  509.                     Esc     :   ;
  510.                 end;
  511.                 RetVal := false;
  512.             end else begin
  513.                 GetWord ( Buffer, Word );
  514.                 WordToSymbol ( Word, Symbol, Status, Matching, Expect );
  515.                 case Status of
  516.                     Exact   :
  517.                         begin
  518.                             if AtEnd( Buffer ) and ( Buffer.Terminator = Esc )
  519.                             then
  520.                             begin
  521.                                 RetVal := false;
  522.                                 Deabbr( Word, Symbol, Buffer );
  523.                             end else
  524.                                 RetVal := true;
  525.                         end;
  526.                     Ambigous:
  527.                         begin
  528.                             RetVal := false;
  529.                             if
  530.                                 not AtEnd( Buffer )
  531.                                 or ( Buffer.Terminator <> QMark )
  532.                             then
  533.                             begin
  534.                                 write(' Ambigous word: "');
  535.                                 WriteWord( Word.String, Word.Valid );
  536.                                 write('".');
  537.                             end;
  538.                             OneOf( Matching );
  539.                             Buffer.Valid := Buffer.EndWord;
  540.                         end;
  541.                     NoMatch :
  542.                         begin
  543.                             RetVal := false;
  544.                             write(' No match for word: "');
  545.                             WriteWord( Word.String, Word.Valid );
  546.                             write('"');
  547.                             OneOf( Expect );
  548.                             BackWord;
  549.                         end;
  550.                 end;
  551.             end;
  552.             ParseWord := RetVal;
  553.         end;  (* ParseWord *)
  554.  
  555.         function    TestConfirm: boolean;
  556.         begin (* TestConfirm *)
  557.             if not AtEnd( Buffer ) then
  558.             begin
  559.                 writeln(' No extra parameters needed.');
  560.                 Buffer.Valid := Buffer.EndWord;
  561.                 TestConfirm := false;
  562.             end else
  563.                 if Buffer.Terminator <> Cr then
  564.                 begin
  565.                     writeln(' Confirm with CR.');
  566.                     Buffer.Valid := Buffer.EndWord;
  567.                     TestConfirm := false;
  568.                 end
  569.                 else
  570.                     TestConfirm := true;
  571.         end; (* TestConfirm *)
  572.  
  573.         function    GetInt( VAR ParBlock : ParType ): boolean;
  574.         begin (* GetInt *)
  575.             if not AtEnd( Buffer ) then
  576.             begin
  577.                 GetName( Buffer, ParBlock.Name );
  578.                 if not AtoI( ParBlock.Name, ParBlock.int ) then
  579.                 begin
  580.                     GetInt := False;
  581.                     writeln(' Illegal number syntax.');
  582.                     BackWord;
  583.                 end;
  584.             end else 
  585.             begin
  586.                 writeln(' Confirm with valid integer.');
  587.                 GetInt := false;
  588.             end;
  589.             MakeEndBlank( Buffer );
  590.         end;  (* GetInt *)
  591.  
  592.         function    GetFileName (   VAR FileName : NameType ): boolean;
  593.         (*
  594.          * Abstract :   Get a filename from the input line-buffer.
  595.          *      Checks for valid syntax of the filename, but does not attempt
  596.          *      to open the file.
  597.          *)
  598.         var     RetVal : boolean;
  599.                 i      : integer;
  600.         begin (* GetFileName *)
  601.             if AtEnd ( Buffer ) then begin
  602.                 writeln(' File name required.');
  603.                 MakeEndBlank( Buffer );
  604.                 RetVal := false;
  605.             end else begin
  606.                 GetName ( Buffer, FileName );
  607.                 (* Convert filename to upper case. *)
  608.                 for i := MinName to FileName.Valid do
  609.                     FileName.String(.i.) := uc( FileName.String(.i.) );
  610.                 RetVal := OkFileSyntax( FileName );
  611.             end;
  612.             GetFileName := RetVal;
  613.         end;  (* GetFileName *)
  614.  
  615.         function    GetSetParameter (   VAR Noun, Adj : VocabType;
  616.                                         VAR ParBlock  : ParType ): boolean;
  617.         (*
  618.          * Abstract :   Get a SET parameter.
  619.          *      The verb SET has already been fetched from "Buffer".
  620.          *)
  621.         var     Valid : boolean;
  622.  
  623.             function    GetDbgParameter (   VAR Adj       : VocabType;
  624.                                             VAR ParBlock  : ParType ): boolean;
  625.             (*
  626.              * Abstract :   Get a valid parameter for SET DEBUG. 
  627.              *)
  628.             var     Valid : boolean;
  629.             begin (* GetDbgParameter *)
  630.                 Expect := (. OnSym, OffSym, LogFileSym, NoLogFileSym .);
  631.                 Valid := ParseWord ( Expect, Adj );
  632.                 if Valid then
  633.                     case Adj of
  634.                         OnSym   :   Valid := TestConfirm;
  635.                         OffSym  :   Valid := TestConfirm;
  636.                         LogFileSym  :
  637.                                     Valid := GetFileName ( ParBlock.Name );
  638.                         NoLogFileSym:   Valid := TestConfirm;
  639.                     end;
  640.                 GetDbgParameter := Valid;
  641.             end;  (* GetDbgParameter *)
  642.  
  643.             function    GetRSParameter (    VAR Adj       : VocabType;
  644.                                             VAR ParBlock  : ParType ): boolean;
  645.             (*
  646.              * Abstract :   Get a valid SET SEND or SET RECEIVE parameter.
  647.              *      Returns true if syntactically correct
  648.              *      command has been entered.
  649.              *)
  650.             var     Valid : boolean;
  651.             begin (* GetRSParameter *)
  652.                 Expect := (. TimeOutSym .);
  653.                 Valid := ParseWord ( Expect , Adj );
  654.                 if Valid then
  655.                     case Adj of
  656.                         TimeOutSym : 
  657.                             Valid := GetInt ( ParBlock );
  658.                     end;
  659.                 GetRSParameter := Valid;
  660.             end;  (* GetRSParameter *)
  661.  
  662.             function    GetUse8( VAR Adj : VocabType ): boolean;
  663.             var     Valid : boolean;
  664.                     Expect: VocabSet;
  665.             begin(* GetUse8 *)
  666.                 Expect := (. AutoSym, OffSym .);
  667.                 Valid := ParseWord( Expect, Adj );
  668.                 if Valid then
  669.                     Valid := TestConfirm;
  670.                 GetUse8 := Valid;
  671.             end; (* GetUse8 *)
  672.  
  673.             function    GetFWarn( VAR Adj : VocabType ): boolean;
  674.             var     Expect : VocabSet;
  675.                     Valid  : boolean;
  676.             begin(* GetFWarn *)
  677.                 Expect := (. OnSym, OffSym .);
  678.                 Valid := ParseWord( Expect, Adj );
  679.                 if Valid then
  680.                     Valid := TestConfirm;
  681.                 GetFWarn := Valid;
  682.             end; (* GetFWarn *)
  683.  
  684.         begin (* GetSetParameter *)
  685.             Expect := (.    DbgSym, DelaySym, (*  LogFileSym, *)
  686.                             FWarnSym, RcvSym, SendSym, Use8Sym .);
  687.             Valid := ParseWord ( Expect, Noun );
  688.             if Valid then
  689.                 case Noun of
  690.                     DbgSym  :   
  691.                         Valid := GetDbgParameter( Adj, ParBlock );
  692.                     DelaySym:
  693.                         Valid := GetInt ( ParBlock );
  694.                     LogFileSym: ;   (* Only to be used if this is a LOCAL Kermit *)
  695.                                     (* -- which this one can't be.               *)
  696.                     RcvSym, SendSym :
  697.                         Valid := GetRSParameter( Adj, ParBlock );
  698.                     Use8Sym :
  699.                         Valid := GetUse8( Adj );
  700.                     FWarnSym:
  701.                         Valid := GetFWarn( Adj );
  702.                 end;
  703.             GetSetParameter := Valid;
  704.         end;  (* GetSetParameter *)
  705.  
  706.     begin (* GetCmd *)
  707.         Descf;
  708.         Buffer.Valid := 0;
  709.         RePrint := true;
  710.         ValidCommand := false;
  711.         repeat
  712.             EditLine ( Buffer, RePrint );
  713.             RePrint := true;
  714.             Expect := (.    ExitSym, HelpSym, QuitSym, RcvSym,
  715.                             SendSym, SetSym,  StatisticsSym .);
  716.             ValidCommand := ParseWord ( Expect, Verb );
  717.             if ValidCommand then begin
  718.                 case Verb of
  719.                     ExitSym, QuitSym :  ValidCommand := TestConfirm;
  720.                     HelpSym :   ValidCommand := TestConfirm;
  721.                     RcvSym  :   ValidCommand := TestConfirm;
  722.                     SendSym :
  723.                         ValidCommand := GetFileName( ParBlock.Name );
  724.                     SetSym  :
  725.                         ValidCommand := GetSetParameter( Noun, Adj, ParBlock );
  726.                     StatisticsSym :
  727.                         ValidCommand := TestConfirm;
  728.                 end;
  729.             end;
  730.         until ValidCommand;
  731.         Eescf;
  732.     end;  (* GetCmd *)
  733.  
  734.     procedure   InitVocab;
  735.     (*
  736.      *  Abstract :  Initializes the vocabulary and stores it in
  737.      *              the global variable VocabTable.
  738.      *)
  739.     var     Index : VocabType;
  740.     begin (* InitVocab *)
  741.         VocabTable (. ExitSym       .).String := 'EXIT$';
  742.         VocabTable (. QuitSym       .).String := 'QUIT$';
  743.         VocabTable (. RcvSym        .).String := 'RECEIVE$';
  744.         VocabTable (. SendSym       .).String := 'SEND$';
  745.         VocabTable (. SetSym        .).String := 'SET$';
  746.         VocabTable (. DbgSym        .).String := 'DEBUG$';
  747.         VocabTable (. OnSym         .).String := 'ON$';
  748.         VocabTable (. OffSym        .).String := 'OFF$';
  749.         VocabTable (. LogFileSym    .).String := 'LOG-FILE$';
  750.         VocabTable (. DelaySym      .).String := 'DELAY$';
  751.         VocabTable (. TimeOutSym    .).String := 'TIMEOUT$';
  752.         VocabTable (. StatisticsSym .).String := 'STATISTICS$';
  753.         VocabTable (. HelpSym       .).String := 'HELP$';
  754.         VocabTable (. LogFileSym    .).String := 'LOG-FILE$';
  755.         VocabTable (. NoLogFileSym  .).String := 'NO-LOG-FILE$';
  756.         VocabTable (. AutoSym       .).String := 'AUTO$';
  757.         VocabTable (. Use8Sym       .).String := 'USE-8-BIT-QUOTE$';
  758.         VocabTable (. FWarnSym      .).String := 'FILE-WARNING$';
  759.         for Index := First( VocabType ) to Last( VocabType ) do
  760.             with VocabTable(.Index.) do
  761.             begin
  762.                 Valid := MinWord;
  763.                 while String(.Valid.) <> '$' do
  764.                     Valid := Valid + 1;
  765.                 Valid := Valid - 1;
  766.             end;
  767.     end;  (* InitVocab *)
  768. 
  769.