/*-------------------------------------------------------------------+
 |                                                                    |
 |           Copyright (c) 1995 - SAS Institute, Inc.                 |
 |             Unpublished - All Rights Reserved                      |
 |                                                                    |
 |  Name   : A2CMCEX  - for entry point $MAINC                        |
 |           A2CMOEX  - for entry point $MAINO                        |
 |                                                                    |
 |  Purpose: This exec supports three samples that demonstrate how    |
 |           to call a C main via the SAS/C provided entry points     |
 |           MAIN, $MAINC, and $MAINO.                                |
 |                                                                    |
 | Function: Produce executable files using the SAS/C compiler,       |
 |           HLASM, and LKED.                                         |
 |                                                                    |
 |  Source : See SAMPLASM MACLIB members -                            |
 |                                                                    |
 |          - For Asm-> $MAINO                                        |
 |            A2CMO     - C Main                                      |
 |            A2CMOASM  - Assembler                                   |
 |            A2CMOEMG  - C function to display messages for asm      |
 |                                                                    |
 |          - For Asm-> $MAINC                                        |
 |            A2CMC     - C Main                                      |
 |            A2CMCASM  - Assembler                                   |
 |            A2CMCEMG  - C function to display messages for asm      |
 |                                                                    |
 |   Note  :  Modules generated by this exec will be AMODE(24)        |
 |            RMODE(24).  The sample will run, as is, on either       |
 |            MACH=370 or MACH=XA/XC/ESA.                             |
 |                                                                    |
 +-------------------------------------------------------------------*/

 Trace o

 Parse upper arg args .

 Parse Source . . execname .

 Address command


/*--------------------------------------------------------------------*/
/* Misc Varialbles and Constants - Initialization                     */
/*--------------------------------------------------------------------*/
  break_line = '------------------------------------------------------'

  execname = execname||': '

  asm_command = 'HLASM'

  If args = 'DEBUG'
      Then load_map = "MAP"
      Else load_map = "NOMAP"

  exit_rc = 0

/*--------------------------------------------------------------------*/
/* Setup various parameters based on the exec name being used.        */
/*--------------------------------------------------------------------*/
  If substr(execname,1,5) = 'A2CMM'
    Then
     Do
        entry_point        = 'MAIN'
        modname_main       = 'A2CMM'
        modname_asm        = modname_main||'ASM'
        modname_emg        = modname_main||'EMG'
        modname_out        = 'SYSOUTM'
        asm_options        = ' '
        main_cool_options  = ''
        main_comp_options  = ''
        emg_comp_options   = 'INDEP '
     End

  If substr(execname,1,5) = 'A2CMO'
    Then
     Do
        entry_point        = '$MAINO'
        modname_main       = 'A2CMO'
        entry_point        = '$MAINO'
        modname_asm        = modname_main||'ASM'
        modname_emg        = modname_main||'EMG'
        modname_out        = 'SYSOUTO'
        asm_options        = ' '
        main_cool_options  = ''
        main_comp_options  = ''
        emg_comp_options   = 'INDEP '
     End

  If substr(execname,1,5) = 'A2CMC'
    Then
     Do
        entry_point        = '$MAINC'
        modname_main       = 'A2CMC'
        entry_point        = '$MAINC'
        modname_asm        = modname_main||'ASM'
        modname_emg        = modname_main||'EMG'
        modname_out        = 'SYSOUTC'
        asm_options        = ' '
        main_cool_options  = 'ALLRESIDENT'
        main_comp_options  = 'DOLLARS SNAME A2CMC '
        emg_comp_options   = 'INDEP '
     End


/*--------------------------------------------------------------------*/
/* Display help information if requested.                             */
/*--------------------------------------------------------------------*/
 If args = '?' | args = 'HELP'
   Then
    Do
     Call SHOW_HELP
     Signal EXIT_SAMPLE
    End

/*--------------------------------------------------------------------*/
/* VM/ESA 2.2 CMS Maclibs                                 <== Verify  */
/*--------------------------------------------------------------------*/
  vm_mac_fn      = 'DMSGPI'
  vm_maclib      = vm_mac_fn||' MACLIB *'

  vm_macos_fn    = 'OSMACRO'            /* For ABEND macro           */
  vm_macoslib    = vm_macos_fn||' MACLIB *'

/*--------------------------------------------------------------------*/
/* SAS/C Maclibs                                          <== Verify  */
/*--------------------------------------------------------------------*/
  sascomp_mac_fn = 'LC370'
  sascomp_maclib = sascomp_mac_fn||' MACLIB *'

  sasasm_mac_fn  = 'LCUSER'
  sasasm_maclib  = sasasm_mac_fn||' MACLIB *'

/*--------------------------------------------------------------------*/
/* SAS/C Resident Libraries                               <== Verify  */
/*--------------------------------------------------------------------*/
  sasbas_txtlib  = 'LC370BAS'
  sasstd_txtlib  = 'LC370STD'

/*--------------------------------------------------------------------*/
/* Cleanup any files that maybe around.                               */
/*--------------------------------------------------------------------*/
 Call DELETE_FILES 'START'

/*--------------------------------------------------------------------*/
/* Tell'm we are here.                                                */
/*--------------------------------------------------------------------*/
  Say execname 'SAS/C Compiler Example Running'
  Say execname

/*--------------------------------------------------------------------*/
/* COMPILE:  SAS/C function to display messages for assembler program */
/*--------------------------------------------------------------------*/
  say execname||break_line

  Call SAS_COMPILE modname_emg emg_comp_options
  parse var result rc .

  If exit_rc >  0 Then signal EXIT_SAMPLE

/*--------------------------------------------------------------------*/
/* COMPILE:  SAS/C Main                                               */
/*--------------------------------------------------------------------*/
  Say execname||break_line
  Call SAS_COMPILE modname_main main_comp_options
  parse var result exit_rc .

  If exit_rc >  0 Then signal EXIT_SAMPLE

/*--------------------------------------------------------------------*/
/* Create C main executable for each entry point and put each into    */
/* the same loadlib for execution.                                    */
/*--------------------------------------------------------------------*/
  Say execname||break_line

  call LKED_CMAIN modname_main main_cool_options
  parse var result exit_rc .

  If exit_rc >  0 Then signal EXIT_SAMPLE

/*--------------------------------------------------------------------*/
/* Create the assembler runtime module                                */
/*--------------------------------------------------------------------*/
  Say execname||break_line

  Call HLASM_ASM modname_asm
  parse var result exit_rc .

  If exit_rc >  0 Then signal EXIT_SAMPLE

  'TXTLIB GEN ' modname_asm||' '||modname_emg

  'GLOBAL TXTLIB' sasbas_txtlib||' '||sasstd_txtlib||' '|| modname_asm

   load_options = '(RLD RESET ASMAIN AMODE 24 RMODE 24 CLEAR '||load_map
  'LOAD' modname_asm  load_options

  'GENMOD' modname_asm '(FROM ASMAIN'

  'GLOBAL TXTLIB'

  If rc > 0
       Then
        Do
          Say execname||break_line
          Say execname||'Assemlber module failed to build correctly!'
          Say execname||'Terninating!'
          Say execname||break_line
          Signal EXIT_SAMPLE
        End

/*--------------------------------------------------------------------*/
/* Tell'm we have finished and the command names.                     */
/*--------------------------------------------------------------------*/
  Say execname||break_line
  Say execname||'Sample ' modname_main ' has been successfully built.'
  Say execname' To execute issue the following:'
  Say execname' '
  Say execname'    GLOBAL LOADLIB ' modname_main
  Say execname' '
  Say execname'    'modname_asm
  Say execname' '
  Say execname' Output will be in fileid: ' modname_out ' FILE A'
  Say execname' '

EXIT_SAMPLE:

  Say execname||break_line

  If args = 'DEBUG'
    Then Nop
    Else Call DELETE_FILES 'FINISH'

exit exit_rc

/*--------------------------------------------------------------------*/
/*                                                                    */
/* Internal Rexx Functions Follow                                     */
/*                                                                    */
/*--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*/
/* Name    : DELETE_FILES                                             */
/* Function: Cleanup files that are not needed, at entry to and exit  */
/*           from the exec.                                           */
/*--------------------------------------------------------------------*/
  DELETE_FILES:
  parse upper arg remove_type
  Trace o
  If remove_type = 'START'
    Then Do
     'SET CMSTYPE HT'                /* Lower the curtain            */
     'ERASE ' modname_main ' LOADLIB A'
     'ERASE ' modname_asm  ' TXTLIB A'
     'ERASE ' modname_main ' LISTING A'
     'ERASE ' modname_main ' TEXT    A'
     'ERASE ' modname_asm  ' LISTING A'
     'ERASE ' modname_asm  ' TEXT    A'
     'ERASE ' modname_emg  ' LISTING A'
     'ERASE ' modname_emg  ' TEXT    A'
     'ERASE ' modname_out  ' FILE    A'
     'SET CMSTYPE RT'                /* Lower the curtain            */
    end

  If remove_type = 'FINISH'
    Then Do
     'SET CMSTYPE HT'                /* Lower the curtain            */
     'ERASE ' modname_asm  ' TXTLIB A'
     'ERASE ' modname_main ' TEXT    A'
     'ERASE ' modname_asm  ' TEXT    A'
     'ERASE ' modname_emg  ' TEXT    A'
     'SET CMSTYPE RT'                /* Lower the curtain            */
    end

  Trace o
  Return(0)


/*--------------------------------------------------------------------*/
/* Name    : SAS_COMPILE                                              */
/* Function: Compile a C source file.                                 */
/*--------------------------------------------------------------------*/
  SAS_COMPILE: procedure expose execname sascomp_mac_fn

   parse upper arg sasc_file sasc_options

  Trace o

  'GLOBAL MACLIB' sascomp_mac_fn

  Say execname 'Compile : Start module: ' sasc_file

  'SET CMSTYPE RT'                            /* Lower Curtain        */
  'EXEC LC370' sasc_file   '(' sasc_options ')'
  compile_rc = rc

  'SET CMSTYPE RT'                            /* Raise Curtain        */

  If compile_rc ^= 0
    Then Do
      Say execname 'SAS/C Failed    : 'sasc_file
      Say execname 'Return Code was: ' compile_rc
      Say execname 'Make corrections as needed and re-run'
      Exit 16
     End

  Say execname 'Compile : End   -  Return Code: ' compile_rc

  Trace o
  return compile_rc

/*--------------------------------------------------------------------*/
/* Name    : HLASM_ASM                                                */
/* Function: Assemble a source file                                   */
/*--------------------------------------------------------------------*/
HLASM_ASM:
  Trace o

  Say execname 'Assemble: Start module: ' modname_asm

  'GLOBAL MACLIB'||' '|| vm_mac_fn||' '|| vm_macos_fn
  exit_rc = rc

  If exit_rc  > 0
    Then Do
      Say execname 'Global Maclib Failed'
      Say execname 'Return Code was: ' exit_rc
      Say execname 'Make corrections as needed and re-run'
      signal  EXIT_ASSEMBLE
     End

  'MAKEBUF'
  'QUERY MACLIB ( STACK'
  parse upper pull maclist
  'DROPBUF'

  Say execname  maclist

  asm_command modname_asm '(' asm_options ')'
  exit_rc = rc

  If exit_rc ^= 0
    Then Do
      Say execname 'Assembler failed: 'modname_asm
      Say execname 'Return Code was: ' exit_rc
      Say execname 'Make corrections as needed and re-run'
     End

  Say execname 'Assemble: End   -  Return Code: ' exit_rc

  EXIT_ASSEMBLE:
  Trace o
  return exit_rc

/*--------------------------------------------------------------------*/
/* Name    : SHOW_HELP                                                */
/* Function: Display help information about this sample.              */
/*--------------------------------------------------------------------*/
SHOW_HELP:

  Say execname||break_line
  Say execname' '||modname_main ' is a SAS/C sample to demonstrate '
  Say execname' how to call a C main function by the entry point '
  Say execname' '||entry_point||'.  For a detailed description see: '
  Say execname' SAMPLASM MACLIB member: ' modname_main
  Say execname' '
  Return 4

/*--------------------------------------------------------------------*/
/* Name    : LKED_CMAIN                                               */
/* Function: LKED a C main into a LOADLIB so that it can be           */
/*           dynamically loaded for execution.                        */
/*--------------------------------------------------------------------*/
LKED_CMAIN:
  trace o
  Say execname 'Building C main: Start       Entry- ' modname_main

  'SET CMSTYPE HT'                    /* Lower the curtain            */
  'ERASE CLINK370 TEXT  A'
  'ERASE' modname_main||' '||'LOADLIB A'
  'ERASE' entry_point||' '||'TEXT  A'
  'SET CMSTYPE RT'                    /* Raise the curtain            */

  text1 = " MODE AMODE(24),RMODE(24)"
  text2 = " INCLUDE "||modname_main
  text3 = " ENTRY   "||' '||entry_point
  text4 = " NAME    "||' '||modname_main||' (R)'

  'EXECIO 1 DISKW COOLTEXT  TEXT A 1 F 80 (        VAR TEXT1'
  'EXECIO 1 DISKW COOLTEXT  TEXT A 2 F 80 (        VAR TEXT2'
  'EXECIO 1 DISKW COOLTEXT  TEXT A 3 F 80 (        VAR TEXT3'
  'EXECIO 1 DISKW COOLTEXT  TEXT A 4 F 80 ( FINIS  VAR TEXT4'

  'GLOBAL TXTLIB' sasbas_txtlib||' '||sasstd_txtlib

  'SET CMSTYPE HT'

  cool_args = main_cool_options||' LKED LIBE '||modname_main
  'EXEC CLINK COOLTEXT ( '||cool_args
  exit_rc = rc
  'SET CMSTYPE RT'

  If exit_rc ^= 0
    Then Do
     Say execname 'CLINK failed, rc: ' exit_rc
     signal EXIT_SAMPLE
    End
   Else
    Do
    'SET CMSTYPE HT'
    'ERASE CLINK370 TEXT   A'
    'ERASE COOLTEXT TEXT   A'
    'ERASE CLINK370 LKEDIT A'
    'SET CMSTYPE RT'
    End

  EXIT_LKED:
  Say execname 'Building C main: End         RC:  '  exit_rc
  Trace o
  return exit_rc