next up previous contents index
Next: The Help File Up: SIC Programming Manual Previous: Initializing SIC: The Command

   
The Program Structure

In this section a complete example is described. The language name is set to USER, and it is highly recommended to use the same normalization conventions for the subroutine names. The example takes advantage of the multi-language capabilities of the SIC monitor by making also the GreG system available in addition to the user's commands. The extra code involved is marked by the flag !!GREG!! and can be removed without affecting the user commands.

The list of routines described here is, in current order :

        USER            The main program
        LOAD_USER       The initialization routine (#)
        EXEC_USER       To enter Execute Mode. Execute a single 
                        SIC/USER valid command (may be a call to a
                        procedure) and returns (#). 
                        Switches to Read Mode on an error condition
                        (Interactive session only) or if a PAUSE
                        is encountered. Switches back to Execute Mode
                        with CONTINUE or EXIT.
        PLAY_USER       To enter Read Mode with a SIC/USER valid
                        command passed as the first thing to do (#)
        ENTER_USER      To enter Read Mode (#). Reads commands on the
                        logical unit 5. Error recovery is provided for
                        interactive sessions only.
        RUN_USER        Dispatching program to execute the user commands
        COM1            Example of interface between a "simple" 
                        Fortran subroutine and a SIC command.
        US_EXEC         Interface routine for the Library Version
        US_ERROR        idem.

(#)     The inclusion of the extra code flagged as !!GREG!! gives
also access to the command of GREG in the three routines EXEC_USER
PLAY_USER and ENTER_USER.
In addition, the ``true'' library mode is accessible by calling US_EXEC, which is described completely in Section 2.6. This is a complete example which really contains all the relevant structure. The rules for building conventional names are quite obvious.

The following source program available in VMS GAG_UTIL:SICUSER.FOR, and UNIX $GAG_REF/help/sic/sicuser.f)

      PROGRAM USER
      INTEGER ICODE,SIC_GET_FOREIGN,LENC,L,NL,SIC_PURGE
      CHARACTER*80 FILE,COMMAND,CHAIN,NAME*12
      CHARACTER BACKSLASH*1
      LOGICAL EXIST
*
* Optionally, get the Foreign argument. 
      ICODE = SIC_GET_FOREIGN(COMMAND,NL)
      IF (MOD(ICODE,2).EQ.0) CALL SYSEXI(ICODE)
* Build the names of the log file.
      NAME = 'user'
      CALL SIC_PARSEF (NAME,FILE,'GAG_LOG:','.log')
* Purge older versions of the log file
      ICODE = SIC_PURGE (FILE,1)
      IF (MOD(ICODE,2).EQ.0) CALL SYSEXI(ICODE)
*
* Initialize the command monitor with a nice Prompt, and stack capability
      NAME = 'USER'
      CALL SIC_OPT(NAME,FILE,.TRUE.)
* Then load all languages
      CALL LOAD_USER
* Demonstration of multi-language capabilities
      CALL LOAD_GREG('LIBRARY')          !!GREG!!
* Define a default macro extension
      CHAIN = 'SIC'//BACKSLASH//'SIC EXTENSION .user'
* Execute the "login" macro
      NAME = 'init'
      CALL SIC_PARSEF (NAME,FILE,'GAG_INIT:','.user')
      L = LENC(FILE)
      INQUIRE (FILE=FILE(1:L),EXIST=EXIST)
      IF (EXIST) THEN
         CHAIN = '@ ``!'//FILE(1:L)//''''
         CALL EXEC_USER (CHAIN)
      ENDIF
* Activate the monitor 
      IF (NL.NE.0) THEN
* First executing the foreign argument if available
         CALL PLAY_USER(COMMAND(1:NL))
      ELSE
* Or not
         CALL ENTER_USER
      ENDIF
      END



      SUBROUTINE LOAD_USER
      INTEGER MCOM
      PARAMETER (MCOM=3)
      CHARACTER*12 VOCAB(MCOM)
      DATA VOCAB / ' COM1' , '/GAG' , ' COM2' /
      CALL SIC_LOAD('USER','GAG_HELP:sicuser.hlp',MCOM,VOCAB,
     &    '4.0    24-AUG-1984')
      END
The example shows how to retrieve a first command from the operating system at run time (SIC_GET_FOREIGN), how to define a default macro extension, and how to execute the user initialization macro if it exists. Two types of complete calls to the SIC/USER system are demonstrated.        
      SUBROUTINE EXEC_USER(BUFFER)
      LOGICAL ERROR
      CHARACTER*(*) BUFFER
      CHARACTER LINE*256, COMM*12, LANG*12
      INTEGER ICODE,OCODE
*
      LINE = BUFFER
      ICODE = -1
      GOTO 10
*
      ENTRY PLAY_USER(BUFFER)
      LINE = BUFFER
      ICODE = 2
      GOTO 10
*
      ENTRY ENTER_USER
      ICODE = 1
      GOTO 10
*
* Call the monitor again after completion of every user command.
10    CALL SIC_RUN (LINE,LANG,COMM,ERROR,ICODE,OCODE)
      IF (OCODE.EQ.0) THEN
         IF (LANG.EQ.'USER') THEN
            CALL RUN_USER (LINE,COMM,ERROR)
         ELSEIF (LANG.EQ.'GREG1') THEN !!GREG!! 
            CALL RUN_GREG1 (LINE,COMM,ERROR) !!GREG!!
         ELSEIF (LANG.EQ.'GREG2') THEN !!GREG!!
            CALL RUN_GREG2 (LINE,COMM,ERROR) !!GREG!!
         ELSEIF (LANG.EQ.'GTVL') THEN !!GREG!!
            CALL RUN_GTVL  (LINE,COMM,ERROR) !!GREG!!
            IF (COMM.EQ.'CLEAR') CALL GRESET !!GREG!!
         ELSE
            WRITE(6,*) 'Unrecognized Language ',LANG
            ERROR = .TRUE.
         ENDIF
      ELSEIF (OCODE.EQ.-1) THEN
* Must return immediately from the Execute Mode, 
         RETURN 
      ELSEIF (OCODE.EQ.1) THEN
* Any other code may be added before returning to the main program
         RETURN
      ENDIF
      ICODE = 0
      GOTO 10
      END
In the Execute Mode, all SIC capabilities are enabled. A more restrictive Library Mode, in which only the command line interpretor of SIC is used will be shown in Section 2.6
      SUBROUTINE RUN_USER(LINE,COMM,ERROR)
      CHARACTER*(*) LINE,COMM
      LOGICAL ERROR
*
* Call appropriate subroutine according to COMM
      IF (COMM.EQ.'COM1') THEN
         CALL COM1(LINE,ERROR)
      ELSEIF (COMM.EQ.'COM2') THEN
         WRITE (6,*) 'Command COM2 activated'
*        CALL COM2(LINE,ERROR)
      ENDIF
      END

      SUBROUTINE COM1(LINE,ERROR)
      CHARACTER*(*) LINE
      LOGICAL ERROR
      LOGICAL SIC_PRESENT
      INTEGER IARG1_OPT1
      REAL ARG1
*
* Test presence of option 1, and if so
*       Decode Argument 1 of this option with a default value
      IF (SIC_PRESENT(1,0)) THEN
          IARG1_OPT1 = 10
          CALL SIC_I4 (LINE,1,1,IARG1_OPT1,.FALSE.,ERROR)
          IF (ERROR) RETURN
          WRITE (6,*) 'Option 1 Set With Argument',IARG1_OPT1
      ENDIF
*
* Retrieves and decode first argument of the command 
      CALL SIC_R4 (LINE,0,1,ARG1,.TRUE.,ERROR)
      IF (ERROR) RETURN
      WRITE (6,*) 'Command COM1 activated. ARG1',ARG1
* End of interface analysis, call a standard FORTRAN routine with 
* all parameters now defined
*     CALL SUB1(ARG1,ARG2,...,IARG1,...,ERROR)
      RETURN
      END
As in this example, it is HIGHLY RECOMMENDED to pass the command buffer LINE by argument and NOT IN A COMMON. This will allow later an easy implementation of a multi-language program if necessary, and the possibility of sharing languages with other users. Use of commons may break these possibilities. It is also recommended to have an ``interface'' routine for each command which takes all the decoding functions. However, for very simple commands, this may not be necessary and the interface may be in the RUN_USER routine.


next up previous contents index
Next: The Help File Up: SIC Programming Manual Previous: Initializing SIC: The Command
Gildas manager
2002-06-07