Google
 

Trailing-Edge - PDP-10 Archives - BB-AI48A-BM - datatrieve/tutor.bli
There are no other files named tutor.bli in the archive.
%TITLE 'TUTOR - A Callable Datatrieve Example'
MODULE TUTOR (MAIN = MAINPROG) =
!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
!
!			  T U T O R
!
!		   COPYRIGHT (c)  1984 BY
!	       DIGITAL EQUIPMENT CORPORATION, MAYNARD
!		MASSACHUSETTS.  ALL RIGHTS RESERVED.
!
!	THIS SOFTWARE  IS FURNISHED UNDER A LICENSE AND MAY
!	BE USED  AND  COPIED  ONLY  IN  ACCORDANCE WITH THE
!	TERMS OF SUCH LICENSE AND WITH THE INCLUSION OF THE
!	ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY OTHER
!	COPIES THEREOF  MAY NOT  BE PROVIDED  OR  OTHERWISE
!	MADE  AVAILABLE TO  ANY OTHER  PERSON.  NO TITLE TO
!	AND   OWNERSHIP   OF   THE   SOFTWARE   IS   HEREBY
!	TRANSFERRED.
!	
!	THE  INFORMATION  IN  THIS  SOFTWARE IS  SUBJECT TO
!	CHANGE  WITHOUT  NOTICE AND SHOULD NOT BE CONSTRUED
!	AS A COMMITMENT  BY  DIGITAL EQUIPMENT CORPORATION.
!
!	DIGITAL ASSUMES  NO  RESPONSIBILITY  FOR THE USE OR
!	RELIABILITY OF  ITS  SOFTWARE ON  EQUIPMENT THAT IS
!	NOT SUPPLIED BY DIGITAL.
!
!
!    FUNCTIONAL DESCRIPTION
!       The program tutor allows one to make Datatrieve Tutorial files
!       which a user follows along.  The general structure of the 
!       tutorial is:
!              1. An instruction to the user is displayed
!              2. The users commands are passed to Callable
!                 datatrieve.
!              3. If errors are detected, then the program 
!                 displays a help message and then goes back to
!                 step 2.
!              4. The process repeats again
!
!       This sequence is followed along as a series of steps until
!       the tutorial file runs out.
!       
!       +--------------------------------+
!       | 1. Print Instructions for user |
!       +-------------+------------------+
!                     |
!                     V                     +-----------------------+
!                     +<--------------------+ 3. Print help message |
!                     |                     +-----------+-----------+
!                     V                                 ^
!       +--------------------------------+              |
!       | 2. Send users commands to      |              |
!       |    Callable Datatrieve         |              |
!       +-------------+------------------+              |
!                     |                                 |
!               ''''''+``````                           |
!               '  Results  +---errors----------------->+
!               ``````+''''''
!                     |
!                  no errors
!                     |
!                     V
!       +-------------+------------------+
!       ! 3. Print completion message    !
!       +--------------------------------+
!
!       The text for each complete step is read in before the 
!       step is presented.  It is stored in three seperate buffers
!       (BEGBUF,HLPBUF,and ENDBUF, corresponding to steps 1,3 and 4
!       respectively).  
!       The tutor also allows you to directly interact with Datatrieve
!       this is done by typing DTR20 to tutor.  The program then goes
!       into a mode where commands are typed directly to Datatrieve.
!       The makes <?> and <esc> work, and allows for multiple Datatrieve
!       commands per Tutor step.  To quit this mode type EXIT to the 
!       DTR> prompt
!
!	Linking instructions:
!		@LOAD TUTOR,SYS:DTRLIB,BLI:EZIO20
!
!    VERSION NUMBER
!       1
! 
!    HISTORY
!       This module was made primarily to show an example of 
!       Callable Datatrieve and not as a Tutorial Package.
!       as a result the standard I/O packages: EZIO20 and TUTIO
!       were used. A sample tutorial file was named TUTOR.TXT
!
!------------------------------------------------------------------------
BEGIN

! To use Callable Datatrieve we need a few external libraries:

LIBRARY 'DABSYM';	! Include Definitions Of The DAB
LIBRARY 'DYNLIB';	! Dynamic library symbols

! Also use a few require files
REQUIRE 'DAB.REQ';	! The DAB itself
REQUIRE 'BLI:TUTIO';	! Standard hack I/O routines
! Need limited set of routines
FORWARD ROUTINE
   FILL_BUFFER  : NOVALUE,   ! Fills a buffer with text
   INTERACTION  : NOVALUE,   ! Interact with the user
   PUSH_DTR     : NOVALUE,   ! Run DTR as Pseudo inferior
   READLINE,                 ! Read a line from the tutorial file
   READSTEP     : NOVALUE,   ! Read a step from the tutorial file
   STARS        : NOVALUE,   ! Print a line of stars
   STARTUP,                  ! Initialize things etc
   MAINPROG     : NOVALUE;   

! This buffer is used to display commands etc.
! Unfortunately, EZIO20 contains an internal buffer whose
! size is 1000 (literal named: "myspacesize")  This makes the
! maximum length string which can be read by FILIN 998 (the last 
! 2 characters are reserved for <CR><LF>).  This also restricts
! the size of our buffer to 998

LITERAL
   BUFFER_SIZE = 998;

LITERAL
    TRUE = 1,
    FALSE = 0;

! Get storage for global buffers
OWN
   INPTR,                        ! Pointer to incoming text
   INLEN,                        ! Length of incoming text
   BUF    : BLOCK[CH$ALLOCATION(BUFFER_SIZE)], ! General buffer
   BEGBUF : BLOCK[CH$ALLOCATION(BUFFER_SIZE)], ! Instruction buffer
   HLPBUF : BLOCK[CH$ALLOCATION(BUFFER_SIZE)], ! Help buffer
   ENDBUF : BLOCK[CH$ALLOCATION(BUFFER_SIZE)], ! Finishing buffer
   BEGLEN,                       ! Instruction buffer length
   HLPLEN,                       ! Help buffer length
   ENDLEN,                       ! Finishing buffer length
   MISTAKE,                      ! Command completed
   QUIT;                         ! EOF read

! Outside routines
EXTERNAL ROUTINE
   FILOPN,                       ! Standard Hack I/O routines
   FILCLS,
   FILOUT,
   FILIN;

! Make messages easy to display (follows message with a CRLF)
MACRO 
   MSG(S) = FILOUT(-1,%CHARCOUNT(S),CH$PTR(UPLIT(S))) %;
ROUTINE FILL_BUFFER (A_BUF,A_LEN) : NOVALUE =
!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
!
!    F I L B U F
!
!    FUNCTIONAL DESCRIPTION
!       Reads lines from the tutorial file, until a blankline
!       is found.  The info is stuffed into the given buffer
!       and the buffer length is updated.
!
!    FORMAL PARAMETERS
!       A_BUF - Address of buffer
!       A_LEN - Address of length of the buffer
!
!    IMPLICIT PARAMETERS
!       The string length is changed
!
!    RETURNED VALUE
!       none
!
!------------------------------------------------------------
BEGIN
LOCAL
   BUFPTR;
BUFPTR = CH$PTR(.A_BUF);
WHILE (TRUE) DO BEGIN
   INLEN = READLINE(BUFFER_SIZE,BUF);
   IF (.INLEN EQL 0) THEN EXITLOOP;

   ! Add <*><space> to each tutorial line.  This is
   ! done to help keep tutorial instructions seperate from
   ! Datatrieve instructions
   BUFPTR = CH$MOVE(2,CH$PTR(UPLIT('* ')),.BUFPTR);
   ! Move in the line
   BUFPTR = CH$MOVE(.INLEN,CH$PTR(BUF),.BUFPTR);
   ! Write in the CRLFs which were stripped off
   CH$WCHAR_A(10,BUFPTR);
   CH$WCHAR_A(13,BUFPTR);
END;
! Find out the length
.A_LEN = CH$DIFF(.BUFPTR,CH$PTR(.A_BUF));
END;     
ROUTINE INTERACTION : NOVALUE =
!+++++++++++++++++++++++++++++++++++++++++++++++++++
!
!    I N T E R A C T I O N
!
!    FUNCTIONAL DESCRIPTION
!       While waiting at a command stallpoint, display
!       the tutor prompt, get the users command and
!       then display the resulting Datatrieve messages
!       and lines which come back.  Continue grabbing
!       lines and displaying results until either success
!       or error is found
!
!    FORMAL PARAMETERS
!	None
!
!    IMPLICIT PARAMETERS
!       If an error is found then MISTAKE is set to true
!       else it is set to false
!
!    RETURNED VALUE
!       None
!
!------------------------------------------------------
BEGIN

LOCAL
   DONE;

DONE = FALSE;        ! Keep a flag of when success or error is found
DO BEGIN
   WHILE (.DAB[DAB$W_STATE] EQL DTR$K_STL_CMD) DO BEGIN
      DO BEGIN
         ! Prompt
         TTY_PUT_QUO('TUTOR>');      
         DAB[DAB$W_VAL_LEN] = FILIN(-1,.DAB[DAB$W_VAL_BUF_LEN],
                                 CH$PTR(.DAB[DAB$A_VAL_BUF]));
      END WHILE (.DAB[DAB$W_VAL_LEN] LEQ 0);  
      ! If the user typed DTR20 go into the submode DTR> otherwise continue
      IF CH$EQL(5,CH$PTR(UPLIT('DTR20')),5,CH$PTR(.DAB[DAB$A_VAL_BUF]))
         THEN PUSH_DTR()
         ELSE DTR$COMMAND(DAB);                   ! Pass commands to DTR
   END;
   ! Display any resulting print lines
   WHILE (.DAB[DAB$W_STATE] EQL DTR$K_STL_LINE) DO BEGIN
      TTY_PUT_MSG(.DAB[DAB$A_MSG_BUF],.DAB[DAB$W_MSG_LEN]);
      TTY_PUT_CRLF();
      DTR$CONTINUE(DAB);
   END;
   ! Display any resulting messages
   WHILE (.DAB[DAB$W_STATE] EQL DTR$K_STL_MSG) DO BEGIN
      ! If command is completed correctly set flags and return
      IF (.DAB[DAB$L_CONDITION] EQL DTR$_SUCCESS) THEN BEGIN
         MISTAKE = FALSE;
         DONE = TRUE;
      ! If command is completed incorrecly then set flags and return
      END ELSE IF (.DAB[DAB$L_CONDITION] EQL DTR$_ERROR) THEN BEGIN
         MISTAKE = TRUE;
         DONE = TRUE;
      ! Otherwise print to the TTY
      END ELSE BEGIN
         TTY_PUT_MSG(.DAB[DAB$A_MSG_BUF],.DAB[DAB$W_MSG_LEN]);
         TTY_PUT_CRLF();
      END;
      DTR$CONTINUE(DAB);
   END;
END UNTIL .DONE;
END;
ROUTINE PUSH_DTR : NOVALUE =
!++++++++++++++++++++++++++++++++++++++++++++++++++
!
!    P U S H _ D T R
!
!    FUNCTIONAL DESCRIPTION
!       This routine demonstrates another neat feature of 
!       Callable Datatrieve.  If Datatrieve is sent a value
!       buffer of length 0 then the user is talking directly
!       to the DTR command parser.  This enables the <?> and
!       <esc> keys and allows the user to try multi-line
!       datatrieve steps for one Tutor step.  This mode
!       is entered by typing DTR20 (all caps) to Tutor.
!       It is exited by typing EXIT.
!       
!    FORMAL PARAMETERS
!       None
!
!    IMPLICIT PARAMETERS
!       None
!
!    RETURNED VALUE
!
!--------------------------------------------------
BEGIN
! Set up loop to keep getting values
WHILE (TRUE) DO 
   CASE .DAB[DAB$W_STATE] FROM DTR$K_STL_MIN TO DTR$K_STL_MAX OF SET
      ! Strange error should never happen
      [INRANGE,OUTRANGE] :
         BEGIN
            TTY_PUT_QUO('Unknown stall point : ');
            TTY_PUT_INTEGER(.DAB[DAB$W_STATE],10,2);
            DTR$UNWIND(DAB);
            RETURN;
         END;
      ! After commands are completed.  If exit wasn't typed,
      ! stay in mode by sending a command of length 0, otherwise
      ! return
      [DTR$K_STL_CMD] :
         BEGIN
            IF .DAB[DAB$V_EXIT] THEN BEGIN
               DAB[DAB$V_EXIT] = FALSE;
               RETURN;
            END;
            DAB[DAB$W_VAL_LEN] = 0;
            DTR$COMMAND(DAB);
         END;
      ! Let's not get this example to complicated
      [DTR$K_STL_PGET,DTR$K_STL_PPUT] :
         BEGIN
            TTY_PUT_QUO('Tutor has disabled reading and writing ports');
            DTR$UNWIND(DAB);
         END;
      ! Displays normal messages
      [DTR$K_STL_MSG] :
         BEGIN
            IF ((.DAB[DAB$L_CONDITION] NEQ DTR$_SUCCESS) AND
                (.DAB[DAB$L_CONDITION] NEQ DTR$_ERROR)) THEN BEGIN
               TTY_PUT_MSG(.DAB[DAB$A_MSG_BUF],.DAB[DAB$W_MSG_LEN]);
               TTY_PUT_CRLF();
            END;
            DTR$CONTINUE(DAB);
         END;
      ! Displays normal lines
      [DTR$K_STL_LINE] :
         BEGIN
            TTY_PUT_MSG(.DAB[DAB$A_MSG_BUF],.DAB[DAB$W_MSG_LEN]);
            TTY_PUT_CRLF();
            DTR$CONTINUE(DAB);
         END;
      ! Let Datatrieve prompt for values
      [DTR$K_STL_PRMPT] :      
         BEGIN
            TTY_PUT_MSG(.DAB[DAB$A_MSG_BUF],.DAB[DAB$W_MSG_LEN]);
            DAB[DAB$W_VAL_LEN] = FILIN(-1,.DAB[DAB$W_VAL_BUF_LEN],
                                    CH$PTR(.DAB[DAB$A_VAL_BUF]));
            DTR$PUT_VALUE(DAB);
         END;
   TES;
END;
ROUTINE READLINE(SIZE,ADDR) =
!+++++++++++++++++++++++++++++++++++++++++++++++++++
!
!    R E A D L I N E
!
!    FUNCTIONAL DESCRIPTION
!       Reads a line from input channel 1 which is otherwise
!       defined to be Tutorial file.  Returns the number
!       of characters read
!
!    FORMAL PARAMETERS
!	SIZE - Maximum size which may be read
!       ADDR - A place to put the line, caller must provide
!              storage and allocation
!
!    IMPLICIT PARAMETERS
!       The location of Quit is changed if the EOF is read
!
!    RETURNED VALUE
!       Length of string read.
!
!------------------------------------------------------
BEGIN
LOCAL
   PTR,
   LEN;
LEN = FILIN(1,.SIZE,CH$PTR(.ADDR));
IF (.LEN LSS 0) THEN QUIT = TRUE;
.LEN
END;
ROUTINE READSTEP : NOVALUE =
!+++++++++++++++++++++++++++++++++++++++++++++++++++
!
!    R E A D S T E P
!
!    FUNCTIONAL DESCRIPTION
!       Parses together and fills the buffers from the
!       tutorial files.  The general syntax of a Step
!       starts with the keyword: STEP and ends with the
!       word PETS. Both of these (and the other three commands)
!       at the beginning and on their own lines as well as
!       entirely in Capital letters.
!
!    FORMAL PARAMETERS
!	None
!
!    IMPLICIT PARAMETERS
!       The tutorial input file, and the local buffers are
!       all modified
!
!    RETURNED VALUE
!       None
!------------------------------------------------------
BEGIN
! Read until STEP or EOF
DO BEGIN
   INLEN = READLINE(BUFFER_SIZE,BUF);
   IF (.QUIT) THEN RETURN;
END UNTIL (CH$EQL(4,CH$PTR(UPLIT('STEP')),4,CH$PTR(BUF)));
! Grab the subcommands and fill buffers
WHILE (TRUE) DO BEGIN
   INLEN = READLINE(BUFFER_SIZE,BUF);
   IF (.QUIT) THEN RETURN;
   IF CH$EQL(5,CH$PTR(UPLIT('BEGIN')),5,CH$PTR(BUF)) 
      THEN FILL_BUFFER(BEGBUF,BEGLEN)
   ELSE IF CH$EQL(4,CH$PTR(UPLIT('HELP')),4,CH$PTR(BUF))
      THEN FILL_BUFFER(HLPBUF,HLPLEN)
   ELSE IF CH$EQL(3,CH$PTR(UPLIT('END')),3,CH$PTR(BUF))
      THEN FILL_BUFFER(ENDBUF,ENDLEN)
   ELSE IF CH$EQL(4,CH$PTR(UPLIT('PETS')),4,CH$PTR(BUF)) ! Stop
      THEN EXITLOOP;
END;
END;
ROUTINE STARS : NOVALUE =
!+++++++++++++++++++++++++++++++++++++++++++++++++++
!
!    S T A R S
!
!    FUNCTIONAL DESCRIPTION
!       Displays stars on the TTY.  Used to seperate
!       out Tutor output and instructions from Datatrieve
!       output and instructions
!
!    FORMAL PARAMETERS
!	None
!
!    IMPLICIT PARAMETERS
!       None
!
!    RETURNED VALUE
!       None
!
!------------------------------------------------------
BEGIN
LITERAL
   STARLENGTH = 76;
LOCAL
   STARS : BLOCK [CH$ALLOCATION(STARLENGTH)];
CH$FILL(%C'*',STARLENGTH,CH$PTR(STARS));
TTY_PUT_MSG(STARS,STARLENGTH);
TTY_PUT_CRLF();
END;
ROUTINE STARTUP =
!+++++++++++++++++++++++++++++++++++++++++++++++++++
!
!    S T A R T U P
!
!    FUNCTIONAL DESCRIPTION
!       Initializes the Channels and starts things up
!
!    FORMAL PARAMETERS
!	None
!
!    IMPLICIT PARAMETERS
!       None
!
!    RETURNED VALUE
!       True if successful, else a false
!
!------------------------------------------------------
BEGIN
   FILOPN(-1,0,0,0);              ! Open TTY
   INPTR = CH$PTR(BUF);
   ! Get the name, and redo in case of error
   DO BEGIN
      MSG('Please enter tutorial file name');
      INLEN = FILIN(-1,BUFFER_SIZE,.INPTR);
      FILOPN(1,.INLEN,.INPTR,0);
   END UNTIL (.INLEN NEQ 0);
   QUIT = FALSE;
   ! Call external initialization routine, which also has storage
   ! of DAB buffers
   DTR$INIT(DAB)
END;
ROUTINE MAINPROG : NOVALUE =
!+++++++++++++++++++++++++++++++++++++++++++++++++++
!
!    M A I N P R O G
!
!    FUNCTIONAL DESCRIPTION
!       Performs the main tutorial loop.  First things
!       are initialized, then interaction is allowed to continue
!       until an EOF is found.  At this point the system
!       shuts down gracefully
!
!    FORMAL PARAMETERS
!	None
!
!    IMPLICIT PARAMETERS
!       None
!
!    RETURNED VALUE
!       None
!
!------------------------------------------------------
BEGIN
   DY$MIN();
   STARTUP();
   STARS();
   UNTIL (.QUIT) DO BEGIN
      READSTEP();
      IF (.QUIT) THEN EXITLOOP;
      TTY_PUT_MSG(BEGBUF,.BEGLEN);
      STARS();
      DO BEGIN
         INTERACTION();
         IF (.MISTAKE) THEN BEGIN
            STARS();
            TTY_PUT_MSG(HLPBUF,.HLPLEN);
            STARS();
         END ELSE EXITLOOP;
      END UNTIL (.QUIT);
      IF (.QUIT) THEN EXITLOOP;
      STARS();
      TTY_PUT_MSG(ENDBUF,.ENDLEN);
   END;
   STARS();
   DTR$FINISH(DAB);
END;

END 
ELUDOM