SPL,L,O,"<SCAN>"
! 
      NAME SCAN(7)"92425-16029 REV.1841 780927" 
! 
!-------------------------------------------------------------
! 
! 
!     F. WARREN         17MAY76    REV. A 
! 
!     "C" COPYRIGHT HEWLETT-PACKARD COMPANY 1976. 
!     ALL RIGHTS RESERVED.  NO PART OF THIS PROGRAM 
!     MAY BE PHOTOCOPIED, REPRODUCED OR TRANSLATED
!     TO ANOTHER PROGRAM LANGUAGE WITHOUT THE PRIOR 
!     WRITTEN CONSENT OF THE HEWLETT-PACKARD COMPANY. 
! 
!-------------------------------------------------------------
! 
! 
      LET PUT BE SUBROUTINE,EXTERNAL,DIRECT   ! PUT A CHAR
      LET GET BE FUNCTION,EXTERNAL,DIRECT     ! GET A CHAR
! 
      LET SQUOT BE CONSTANT(47K)                 ! SINGLE QUOTE 
      LET DQUOT BE CONSTANT(42K)                 ! DOUBLE QUOTE 
      LET TRUE  BE CONSTANT(177777K)             ! ABSOLUTELY TRUE
      LET FALSE BE CONSTANT(0)                   ! ABSOLUTELY FALSE 
! 
! 
! 
!     SCAN: PURPOSE: TO PROVIDE A GENERAL-PURPOSE SCAN OF A STANDARD STRING 
!                RETURNING ONE TOKEN EACH TIME IT IS CALLED.
!                PARAMETERS:
!                    SCANA - (INPUT) STRING WHICH IS TO BE SCANNED
!                    SCANT - (OUTPUT) RESULTING TOKEN IS RETURNED HERE. 
!                            IF THERE ARE NO MORE TOKENS IN THE STRING, 
!                            THEN TOKEN(1) = 0 (I.E. THE NULL STRING) 
!                            AND SCAN FRETURNS. 
!                    NIN   - (INPUT AND OUTPUT) LAST CHARACTER SCANNED. 
!                            FOR THE FIRST CALL, NIN SOULD BE SET TO
!                            ZERO BY THE CALLER. SCAN WILL MODIFY IT
!                            EACH TIME.  THE CALLER ROUTINE CAN USE 
!                            NIN TO DETERMINE WHERE THE SCAN STOPPED, 
!                            E.G. FOR ERROR MESSAGES. 
!                    QUOTF - (OUTPUT) SET TO TRUE IF THE OUTPUT TOKEN 
!                            WAS A QUOTED STRING.  NOTE THAT QUOTES ARE 
!                            STRIPPED OFF THE STRING DURING THE SCAN. 
! 
!     EXAMPLES: 
!        INPUT: CATALOG, PDQ(13), "ABC DEF" 
!        OUTPUT:       CALL      SCAN TOKEN      QUOTF
!                        1          CATALOG      FALSE
!                        2          PDQ          FALSE
!                        3          (            FALSE
!                        4          13           FALSE
!                        5          )            FALSE
!                        6          ABC DEF      TRUE 
! 
! 
!     NOTES:
!            SCAN USES EITHER A COMMA OR A BLANK AS A PRIMARY 
!            DELIMITER AND DOES NOT RETURN EITHER IN THE SCAN 
!            TOKEN.  SCAN ALSO TREATS A ! AS AN END OF STRING 
!            AND DOES NOT SCAN FURTHER NOR RETURN THE ! AS
!            A TOKEN. 
! 
! 
! 
SCAN: FUNCTION (SCANA,SCANT,NIN,QUOTF) GLOBAL,FEXIT 
      LET SCANA(1) BE INTEGER          !
      LET SCANT(1) BE INTEGER          !
      LET NXCH BE FUNCTION             ! NEXT CHARACTER 
      QUOTF _ FALSE                    ! SET QUOTF TO FALSE 
      IF NIN > SCANA(1) THEN GOTO X0   ! DONE WITH SCAN 
      IF NIN = 0 THEN CHR _" "\        ! DEFAULT IF NO PREV CHAR
       ,ELSE[\                         ! OTHERWISE
          .B._@SCANA;\                 ! REGET
          .A._NIN ; \                  ! CURRENT
          CHR_GET\                     ! CHARACTER
       ]                               !
      SCANT(1) _ 0                     ! ZERO TARGET STRING 
      IF CHR="!" THEN [\               ! LOOKING AT ! 
X0:      SCANT(1)_ -1;\                ! SET EOS
         FRETURN -1;\                  ! FEXIT
      ]                                !
X1:   IF(CHR # " ")AND(CHR#",") THEN GOTO X2! DIDN'T DEFAULT
      CHR _ NXCH ? X8                  ! SKIP BLANKS & COMMAS 
      GO TO X1                         ! LOOP 
X2:   IF CHR # SQUOT AND CHR # DQUOT THEN GO TO X5 ! NOT QUOTES 
      QUOTF _ TRUE                     ! YES-PROCESS STRING 
      CHR _ NXCH ? X10                 ! GET NEXT CHAR
X3:   IF CHR = SQUOT OR CHR = DQUOT THEN GO TO X4 ! END WITH QUOTE
      .B. _ @SCANT                     ! PREPARE FOR ATTACH 
      .A. _ CHR                        ! LOAD UP THE CHARACTER
      PUT                              ! PUT IT ONTO THE STRING 
      CHR _ NXCH ? X8                  ! GET NEXT CHARACTER 
      GO TO X3                         ! LOOP 
X4:   CHR _ NXCH ? X8                  ! GET NEXT CHAR
      GO TO X10                        !
X5: 
!     HANDLE /*   */ COMMENTS 
X6:   IF CHR = "." THEN GO TO X7       ! PERIOD IN NUMB OK
      IF CHR >= "A" AND CHR <= "Z" THEN GO TO X7! ALPHA 
      IF CHR >= "0" AND CHR <= "9" THEN GO TO X7! NUMBER
      IF SCANT(1)#0 THEN GO TO X10     ! FINISHED 
      .B. _ @SCANT                     ! SETUP STRING 
      .A. _ CHR                        ! PROCESS PUNCTUATION
      PUT                              ! PUT IT 
      CHR _ NXCH ? X8                  ! GET NEXT CHAR
      GO TO X10                        ! FINISHED 
X7:   .B. _ @SCANT                     ! SETUP STRING 
      .A. _ CHR                        !SETUP CHR 
      PUT                              ! PUT IT 
      CHR _ NXCH ? X8                  ! GET NEXT CHAR
      GO TO X6                         ! LOOP 
X8:   CHR _ " "                        !SET CHAR TO BLANK 
X10:  STMP _ SCANT(1)                  ! SAVE STRING COUNT
      .B. _ @SCANT                     ! SETUP STRING 
      .A. _ " "                        ! PASS BLANK 
      PUT                              ! PUT IT 
      SCANT(1) _ STMP                  ! RESTORE COUNT
      IF SCANT(1)=0 AND CHR=" " THEN[\ ! END OF STRING
         SCANT(1)_ -1;\                ! ILL SIZE 
         FRETURN -1\                   ! FEXIT
      ]                                !
      RETURN 0                         !
      END                              !
! 
! 
NXCH: FUNCTION FEXIT
      IF NIN < SCANA(1) THEN GO TO NXCH2 ! STILL HAVE CHARS LEFT
      NXCHV _ " "                      ! NO MORE CHARS
      NIN _ NIN + 1                    ! INCREMENT CURRENT CHAR POS CNT 
      FRETURN                          ! FEXIT
NXCH2:                                 !
      NIN _ NIN + 1                    ! INCREMENT COUNT
      .B. _ @SCANA                     ! SETUP STRING 
      .A. _ NIN                        ! PUT COUNT IN A 
      NXCHV _ GET                      ! PUT NEXT CHR IN RETURN VARIB 
      IF NXCHV = "!" THEN[\            ! DON'T SCAN PAST !
         NXCHV_" ";\                   ! DON'T PASS ! THRU
         FRETURN;\                     ! FAKE END OF STRING 
      ]                                !
      RETURN                           !
      END                              !
! 
! 
END 
END$
                                      