*DECK NS$HCP
USETEXT COM$NS
USETEXT DEF$NS
USETEXT ERR$NS
USETEXT HOC$NS
USETEXT KDS$NS
USETEXT LIN$NS
USETEXT SMB$NS
      PROC NS$HCP(CMDTEXT,(CC),ERRCODE,KC); # HOP COMMAND PREPROCESSOR #
  
# TITLE NS$HCP - HOP COMMAND PROCESSOR.                                #
  
      BEGIN    # NS$HCP # 
# 
**    NS$HCP - HOP COMMAND PROCESSOR. 
* 
*     J.C. LEE    1981
* 
*     THIS ROUTINE PROCESS ALL HOP COMMANDS.
* 
*     PROC NS$HCP(CMDTEXT,(CC),ERRCODE,KC)
* 
*     ENTRY:  
*       CMDTEXT = HOP COMMAND TEXT
*       CC      = CHARACTER COUNT OF TEXT.
* 
*     EXIT: 
*       ERRCODE = ERROR CODE VALUE. 
*       KC      = HOP COMMAND ERROR REASON CODE.
* 
*     METHOD: 
*       SAVE HOP COMMAND TEXT IN LOCAL ARRAY AND ZERO FILLED LAST 
*         WORD OF COMMAND TEXT. 
*       IF K-DISPLAY NOT ASSIGNED, FLAG ERROR AND EXIT. 
*       DISCARD LINES CURRENTLY QUEUED IN PAGE-WAIT BUFFER. 
*       ECHO HOP COMMAND BACK TO K-DISPLAY. 
*       TOKENIZE HOP COMMAND AND PERFORM SYNTAX CHECKING. 
*       IF PASSED SYNTAX CHECKING, PROCEED TO RECOGNIZE THE COMMAND.
*       IF VALID COMMAND VERB FOUND, PROCEED TO VALIDATE HOP COMMAND
*         PARAMETERS. 
*       IF PASSED ALL CHECKINGS, PUT PARAMETERIZED COMMAND IN 
*         COMMON BLOCK. 
*       IN ALL CASES, IF ERROR DETECTED, FLAG ERRCODE AND KC, 
*         AND EXIT. 
* 
# 
  
      ARRAY CMDTEXT;         # HOP COMMAND TEXT                        #
        BEGIN 
        ITEM CMDTXTWORD U(00,00,60);
        END 
      ITEM CC         U;     # COMMAND TEXT DISPLAY CODE CHAR COUNT    #
      ITEM ERRCODE    U;     # ERROR CODE VALUE                        #
      ITEM KC         U;     # HOP COMMAND ERROR REASON CODE           #
  
      $BEGIN
      XREF
        BEGIN 
        PROC NS$DBG;         # TRACE CALL                              #
        END 
      $END
  
      XREF
        BEGIN 
        PROC EXREDUC;        # REDUCE TSB SIZE                         #
        PROC MOVEI;          # MOVE DATA                               #
        PROC MOVEOK;         # ALLOW TSB TO MOVE                       #
        FUNC NS$FEC U;       # FORMAT ERROR CODE                       #
        PROC NS$MSG;         # DISPATCH MESSAGE                        #
        PROC NS$TKD;         # TRANSFER DATA TO K DISPLAY BUFFER       #
        PROC TSBINFO;        # LOCATE TSB                              #
        END 
  
      DEF CHAR$A     # O"01" #;        # ALPHA A                       #
      DEF CHAR$9     # O"44" #;        # NUMERAL 9                     #
      DEF CHAR$COMMA # O"56" #;        # COMMA                         #
      DEF CHAR$EQUAL # O"54" #;        # EQUAL                         #
      DEF CHAR$TERM  # O"57" #;        # PERIOD                        #
  
      ITEM BLANK      C(7) =  " ";
      ITEM CHAR       U;     # HOP COMMAND TEXT CHARACTER              #
      ITEM CMDORDINAL U;     # HOP COMMAND ORDINAL                     #
      ITEM CNT        U;     # TOKEN COUNT                             #
      ITEM COUNT      U;     # TOKEN CHARACTER COUNT                   #
      ITEM DONE       B;     # DONE FLAG                               #
      ITEM I          I;     # LOOP VARIABLE                           #
      ITEM INDEX      U;     # INDEX                                   #
      ITEM J          I;     # LOOP VARIABLE                           #
      ITEM K          I;     # TEMPORARY                               #
      ITEM M          I;     # TEMPORARY                               #
      ITEM PWBTSBN    U;     # PAGE WAIT BUFFER TSB NUMBER             #
      ITEM TEMP       U;     # TEMPORARY                               #
      ITEM TLC        U;     # TEXT LENGTH IN CHARACTERS               #
      ITEM TLW        U;     # TEXT LENGTH IN WORDS                    #
      ITEM TSBFWA     U;     # TSB FWA                                 #
      ITEM TSBSIZE    U;     # TSB SIZE                                #
  
      DEF MAX$CMDKEY # 8 #; # MAX HOP COMMAND VERBS ALLOWED            #
      ARRAY HOPCMDVERB[1:MAX$CMDKEY]S(1); 
        BEGIN                          # VALID HOP COMMAND VERB TABLE  #
        ITEM HC$KEYWORD C(0,0,8) = [   # VALID COMMAND VERB            #
            "STATUS", 
            "ST", 
            "HISTORY",
            "HI", 
            "FILE", 
            "FI", 
            "NOFILE", 
            "NO", 
                                   ]; 
        ITEM HC$ORDINAL S:HCT(0,48,12) = [ #CORR CMD ORDINAL           #
            S"CMD$STATUS",
            S"CMD$STATUS",
            S"CMD$HIST",
            S"CMD$HIST",
            S"CMD$FILE",
            S"CMD$FILE",
            S"CMD$NOFILE",
            S"CMD$NOFILE",
                                          ];
        END 
  
      DEF MAX$CMDPRM # 9 #; # MAX HOP COMMAND PARAMETERS ALLOWED       #
      ARRAY HOPCMDPARM[1:MAX$CMDPRM]S(1); 
        BEGIN # VALID HOP COMMAND PARAMETER TABLE                      #
        ITEM HCP$PARAM  C(0,0,8) = [ # VALID HOP CMD PARAMETERS        #
            "NPU    =", 
            "NP     =", 
            "ALL",
            "NLF    =", 
            "NL     =", 
            "UN     =", 
            "PW     =", 
            "NPUS", 
            "NPS",
                                   ]; 
        ITEM HCP$SEPAR  C(0,42,1); # SEPARATOR CHARACTER               #
        ITEM HCP$PARORD U(0,48,12) = [ # CORR PARAMETER ORD            #
            PAR$NPU,
            PAR$NPU,
            PAR$ALL,
            PAR$NLF,
            PAR$NLF,
            PAR$UN, 
            PAR$PW, 
            PAR$NPUS, 
            PAR$NPUS, 
                                      ];
        END 
  
      DEF L$TOKENTAB # 10 #; # SIZE OF TOKEN TABLE                     #
      ARRAY TOKENTAB[0:L$TOKENTAB]S(1); 
        BEGIN # TABLE OF HOP COMMAND TOKENS/SEPARATORS                 #
        ITEM TT$WORD    C(0,0,10); # WHOLE WORD                        #
        ITEM TT$TCOUNT  U(0,0,60); # TOKEN COUNT                       #
        ITEM TT$TOKEN   C(0,0,8); # TOKEN PLUS SEPARATOR               #
        ITEM TT$ATOKEN  C(0,0,7); # TOKEN                              #
        ITEM TT$SEP     C(0,42,1); # SEPARATOR                         #
        END 
  
      ARRAY VALIDPARAM [HCT"CMD$STATUS":HCT"CMD$NOFILE"] S(1);
        BEGIN # MAP OF VALID PARAMETER FOR EACH HOP COMMAND            #
# 
        A TRUE SETTING INDICATES THE CORRESPONDING PARAMETER IS VALID 
        FOR THE COMMAND,
          VALIDPARAM[1] IS FOR STATUS COMMAND 
          VALIDPARAM[2] IS FOR HISTORY COMMAND
          VALIDPARAM[3] IS FOR FILE COMMMAND
          VALIDPARAM[4] IS FOR NOFILE COMMAND 
# 
        ITEM PARM$NPU   U(00,01,01) = [1,0,1,0]; # NPU= PARAMETER      #
        ITEM PARM$ALL   U(00,02,01) = [0,1,0,0]; # ALL PARAMETER       #
        ITEM PARM$NLF   U(00,03,01) = [0,0,1,0]; # NLF PARAMETER       #
        ITEM PARM$UN    U(00,04,01) = [0,0,1,0]; # UN PARAMETER        #
        ITEM PARM$PW    U(00,05,01) = [0,0,1,0]; # PW PARAMETER        #
        ITEM PARM$NPUS  U(00,06,01) = [1,0,0,0]; # NPUS PARAMETER      #
        ITEM PARM$WORD  U(00,00,60); # WHOLE WORD                      #
        END 
  
      ARRAY LINHEADER [0:0] S(LIN$HDRL);
        BEGIN # HOP COMMAND LINE HEADER                                #
        ITEM LINE$ID    U(00,00,24);
        ITEM LINE$SIZE  U(00,42,18);
        END 
  
      DEF MAX$CMDTLC # 50 #; # MAX COMMAND TEXT DISPLAY CODE CHARACTERS#
      DEF MAX$CMDTLW # 05 #; # MAX COMMAND TEXT LENGTH IN WORDS        #
      ARRAY HCMDTEXT [0:MAX$CMDTLW] S(1); 
        BEGIN # HOP COMMAND TEXT                                       #
        ITEM HCMD$WORD  U(00,00,60) = [MAX$CMDTLW(0)];
        END 
  
      CONTROL EJECT;
  
      $BEGIN
      NS$DBG("HCP");         # TRACE CALL                              #
      $END
  
      ERRCODE = 0;
      KC = 0; 
# 
      SAVE HOP COMMAND TEXT IN LOCAL ARRAY
# 
      IF MAX$CMDTLC LS CC 
      THEN # COMMAND TEXT CHARACTER COUNT EXCEEEDS LIMIT               #
        CC = MAX$CMDTLC; # SET CHARACTER COUNT TO LIMIT ALLOWED        #
  
      TLW = (CC+9)/10; # TEXT LENGTH IN CM WORDS                       #
      IF TLW EQ 0 
      THEN # RECEIVED NO HOP COMMAND TEXT                              #
        TLW = 1; # SET TEXT LENGTH TO 1 TO GENERATE SYNTAX ERROR       #
      ELSE # RECEIVED HOP COMMAND TEXT                                 #
        MOVEI(TLW,LOC(CMDTEXT),LOC(HCMDTEXT)); # MOVE TEXT             #
      K = (TLW*10) - CC;
      IF K NQ 0 
      THEN # ZERO-FILLED LAST WORD OF COMMAND TEXT                     #
        B<(10-K)*6,K*6>HCMD$WORD[TLW-1] = 0;
      IF K LS 2 
      THEN # ASSURE LINE TERMINATOR 6-66 BITS OF BINARY ZEROES         #
        BEGIN 
        HCMD$WORD[TLW] = 0; 
        TLW = TLW + 1;
        END 
  
      IF DCW$F$ASS[0] # K DISPLAY IS ASSIGNED                          #
        AND DCW$F$IA[0] # AND INPUT IS ALLOWED                         #
      THEN
        BEGIN 
# 
        DISCARD LINES CURRENTLY QUEUED IN PAGE WAIT BUFFER
# 
        PWBTSBN = DCW$PWBTSB[0]; # PAGE WAIT BUFFER TSB NUMBER         #
        TSBINFO(TSBSIZE,TSBFWA,PWBTSBN); # LOCATE PWB FWA              #
        P<PWB$BUFFER> = 0;
        IF PWB$LC[TSBFWA] NQ 0
        THEN # LINES QUEUED IN PAGE WAIT BUFFER                        #
          BEGIN # DISCARD ALL LINES QUEUED                             #
          EXREDUC(PWB$WC[TSBFWA]-PWB$HDRL,PWBTSBN,FALSE,TSBFWA);
          PWB$LC[TSBFWA] = 0; # RESET LINE COUNT                       #
          PWB$WC[TSBFWA] = PWB$HDRL; # RESET WORD COUNT                #
          END 
  
        MOVEOK(PWBTSBN); # ALLOW PAGE WAIT BUFFER TO MOVE              #
# 
        ECHO HOP COMMAND BACK TO K DISPLAY
# 
  
        DCW$F$IA[0] = FALSE; # SET INPUT NOT ALLOWED                   #
        DCW$LC[0] =0; # RESET NAM K-DISPLAY LINE COUNT                 #
        P<LIN$HEADER> = LOC(LINHEADER); # FWA OF LINE HEADER           #
        LIN$HDRWD[0] = 0; 
        LIN$ID[0] = LIN$IDENT; # LINE IDENTIFIER                       #
        LIN$LNSIZE[0] = TLW + LIN$HDRL; # SET LINE SIZE OF HOP COMMAND #
        NS$TKD(LINHEADER,TLW+LIN$HDRL,1); # ECHO HOP COMMAND TO K DIS  #
# 
        TOKENIZE HOP COMMAND
# 
        COUNT = 0; # INITIALIZE CHARACTER COUNT OF TOKEN               #
        CNT =0; # INITIALIZE TOKEN COUNT                               #
        INDEX = 0; # INITIALIZE WORD INDEX OF HOP COMMAND TEXT         #
  
        FOR I=0 STEP 1 UNTIL L$TOKENTAB 
        DO # REINITIALIZE TOKEN TABLE                                  #
          TT$WORD[I] = " "; 
  
        FOR I=0 STEP 1 WHILE I LS CC
                  AND KC EQ 0 # NO ERROR OCCURRED                      #
        DO # UNPACK HOP COMMAND TEXT INTO TOKENS/SEPARATORS            #
          BEGIN 
  
          J = I - (INDEX * 10); # BIT POSITION OF WORD                 #
          IF J GQ 10
          THEN # GO TO NEXT WORD OF HOP COMMAND TEXT                   #
            BEGIN 
            INDEX = INDEX + 1;
            J = 0; # RESET BIT POSITION OF WORD                        #
            END 
          CHAR = C<J,1>HCMD$WORD[INDEX]; # CURRENT CHARACTER           #
  
          IF CHAR GQ CHAR$A 
            AND CHAR LQ CHAR$9
          THEN # CHARACTER IS ALPHANUMERIC                             #
            BEGIN # ASSEMBLE TOKEN                                     #
  
            IF CNT LS L$TOKENTAB # TOKEN COUNT WITHIN LIMIT            #
              AND COUNT LS 7 # TOKEN CHARACTER COUNT OK                #
            THEN
              BEGIN # ASSEMBLE CHARACTER INTO TOKEN                    #
              C<COUNT,1>TT$WORD[CNT+1] = CHAR;
              COUNT = COUNT + 1; # INCREMENT TOKEN CHARACTER COUNT     #
              END 
  
            ELSE # BAD TOKEN, SYNTAX ERROR                             #
              KC = HOPCMDERR"SYNTAX"; 
            END 
  
          ELSE # CHARACTER IS NON-ALPHANUMERIC                         #
            BEGIN 
  
            IF CHAR EQ CHAR$COMMA 
              OR CHAR EQ CHAR$EQUAL 
            THEN # CHARACTER IS A LEGAL SEPARATOR                      #
              BEGIN 
  
              IF TT$WORD[CNT+1] NQ BLANK
              THEN # TOKEN EXISTS                                      #
                BEGIN 
                IF CHAR EQ CHAR$EQUAL 
                THEN
                  TT$SEP[CNT+1] = CHAR$EQUAL; # STORE EQUAL ONLY       #
  
                CNT = CNT + 1; # INCREMENT TOKEN COUNT                 #
                COUNT = 0; # RESET TOKEN CHARACTER COUNT               #
                END 
  
              ELSE # TWO SEPARATORS IN A ROW                           #
                KC = HOPCMDERR"SYNTAX"; # HOP COMMAND SYNTAX ERROR     #
              END 
  
            ELSE # CHARACTER NOT A SEPARATOR                           #
              BEGIN 
              IF CHAR EQ CHAR$TERM
              THEN # ITS A PERIOD                                      #
                I = CC; # TERMINATE UNPACKING COMMAND                  #
  
              ELSE # ILLEGAL CHARACTER IN HOP COMMAND                  #
                KC = HOPCMDERR"SYNTAX"; 
              END 
  
            END 
  
          END # END I FOR LOOP                                         #
  
        IF KC EQ 0
        THEN
          BEGIN 
          IF TT$WORD[CNT+1] NQ BLANK
          THEN  # LAST TOKEN EXISTS                                    #
            TT$TCOUNT[0] = CNT + 1; # SET TOKEN COUNT                  #
  
          ELSE # HOP COMMAND NOT PROPERLY TERMINATED                   #
            KC = HOPCMDERR"SYNTAX"; 
          END 
# 
        RECOGNIZE HOP COMMAND 
# 
        IF KC EQ 0
        THEN
          BEGIN 
  
          FOR I=0 STEP 1 UNTIL PAR$NPUS 
          DO # CLEAR HOP COMMAND ARRAY IN COMMON                       #
            BEGIN 
            CMD$WORD[I] = 0;
            END 
  
          DONE = FALSE; 
          FOR I=1 STEP 1 WHILE I LQ MAX$CMDKEY
                           AND NOT DONE 
          DO # CHECK IF COMMAND VERB IS A VALID ONE                    #
            BEGIN 
            IF HC$KEYWORD[I] EQ TT$TOKEN[1] 
            THEN # MATCH WITH A VALID COMMAND VERB                     #
              BEGIN 
              CMDORDINAL = HC$ORDINAL[I]; 
              CMD$ORD[0] = CMDORDINAL;
              DONE = TRUE;
              END 
            END # END FOR LOOP                                         #
  
          IF DONE 
          THEN # VALID COMMAND VERB FOUND, PROCEED                     #
            BEGIN # VALIDATE HOP COMMAND PARAMETERS                    #
            COUNT = TT$TCOUNT[0]; # TOKEN COUNT                        #
  
            FOR I=2 STEP M+1 WHILE I LQ COUNT 
                               AND DONE 
            DO
              BEGIN 
              M = 0;
              DONE = FALSE; 
  
              FOR J=1 STEP 1 WHILE J LQ MAX$CMDPRM
                               AND NOT DONE 
              DO
                BEGIN # SCAN VALID PARAMETER LIST                      #
  
                IF TT$TOKEN[I] EQ HCP$PARAM[J]
                THEN # PARAMETER MATCH                                 #
                  BEGIN # STORE VALID PARAMETER IN COMMON              #
                  K = HCP$PARORD[J]; # PARAMETER ORDINAL/BIT POSITION  #
  
                  IF B<K,1>PARM$WORD[CMDORDINAL] NQ 0 
                  THEN # SIGN BIT SET                                  #
                    BEGIN # PARAMETER VALID FOR THIS COMMAND           #
  
                    IF HCP$SEPAR[J] EQ CHAR$EQUAL 
                    THEN # NEXT TOKEN IS AN EQUATE VALUE               #
                      BEGIN # STORE VALUE IN HOPCOMMAND ARRAY          #
                      CMD$WORD[K] = TT$WORD[I+1]; 
                      M =1; # INCREMENT STEP COUNT                     #
                      END 
  
                    ELSE
                      CMD$WORD[K] = 1; # INDICATE PARAMETER SPECIFIED  #
  
                    DONE = TRUE;
                    END 
                  END 
  
                END # END J FOR LOOP                                   #
  
              END # END I FOR LOOP                                     #
  
            IF NOT DONE 
            THEN # ERROR DETECTED IN HOP COMMAND PARAMETER             #
              KC = HOPCMDERR"PARAMETER";
  
            END 
  
          ELSE # ERROR DETECTED IN COMMAND VERB                        #
            KC = HOPCMDERR"CMDVERB";
  
          END 
  
        IF KC EQ 0
        THEN # NO ERRORS DETECTED IN HOP COMMAND                       #
          BEGIN # LOG VALID COMMAND IN NETWORK LOG FILE                #
          NS$MSG(HCMDTEXT, TLW, DM$NAMLOG+DM$HOPCMD+DM$LOCAL);
          END 
  
        END 
  
      ELSE # NAM ERROR, HOP/CMD NOT ALLOWED                            #
        ERRCODE = NS$FEC(EC"ERR$SM",SMEC"HSM$HOPSM"); 
  
      RETURN; 
      END # NS$HCP #
      TERM
