www.sas.com > Service and Support > Technical Support
 
Technical Support SAS - The power to know(tm)
  TS Home | Intro to Services | News and Info | Contact TS | Site Map | FAQ | Feedback


/*--------------------------------------------------------------------+
|                                                                     |
|            Copyright(c) 1995, SAS Institute Inc.                    |
|              Unpublished - All Rights Reserved                      |
|                                                                     |
|                     S A S / C  S A M P L E                          |
|                                                                     |
|       Name: A2CMO                                                   |
|                                                                     |
|   Language: C                                                       |
|                                                                     |
| EntryPoint: $MAINO                                                  |
|                                                                     |
| Entry Type: C Linkage                                               |
|                                                                     |
| Files Note: 'prefix' is the installation defined high level         |
|             qualifier for the SAS/C product.                        |
|                                                                     |
|   Function: The main function of A2CMC is to support being called   |
|             from assembler using SAS/C entry point $MAINC.  It      |
|             will display the arguments passed via argv[] array      |
|             elements which are expected to be integers.  It will    |
|             also display any environment variables passed.          |
|                                                                     |
|             Additionally, functions cuserid() and  intract() are    |
|             used to display userid and how this module is being     |
|             executed.                                               |
|                                                                     |
|             Function crabadr() uses inline machine code to obtain   |
|             the CRAB address and time.  This information is then    |
|             formatted and displayed.                                |
|                                                                     |
|    Purpose: MVS see prefix.SAMPLE.ASM(A2CMOASM)                     |
|             CMS see SAMPLASM MACLIB(A2CMOASM)                       |
|                                                                     |
| MVS -                                                               |
|       Compile/Link/Go: see prefix.SAMPLE.ASM(A2CMOASM) prolog.      |
|                                                                     |
| CMS -                                                               |
|       Compile/Link/Go: see SAMPLASM MACLIB(A2CMOASM) prolog.        |
|                                                                     |
| Misc Notes:                                                         |
|                                                                     |
+--------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <lcio.h>
#include <svc.h>
#include <regs.h>

#include <code.h>
#include <dec370.h>
#include <str370.h>

#define LEN_PACKED 4
#define LEN_UNPACKED 8

int crabadr(void);

int main(int argc, char * (*argv), char * ( *envp) )
{
 int i         = 0;
 int intsum    = 0;
 int retcode   = 0;
 char username[L_cuserid];

 /*-------------------------------------------------------------------+
 | Display userid and indicate mode (batch or interactive)            |
 +-------------------------------------------------------------------*/
 cuserid(username);

 printf("\nUserid : %s  ",username);

 if (intractv() == 0)
   {printf("Running: Batch Mode\n");}
  else
   {printf("Running: Interacative Mode\n");};

 /*-------------------------------------------------------------------+
 | Dispaly the CRAB address, then program name(via argv[0], then      |
 | the total number of argv variables to process.                     |
 +-------------------------------------------------------------------*/
 crabadr();    /* display the crab address being used                */

 printf("\nProgarm Name (via argv[0]): %s\n", argv[0] );

 /*-------------------------------------------------------------------+
 |  Display variables passsed as argv[1] to argv[n], the values are   |
 |  expected to be integers.  Note that in order to process the       |
 |  variables they are cast from char to int.                         |
 +-------------------------------------------------------------------*/
 for(i=1; i < argc; i++)
  {
   intsum += * (int *) argv[i];
   printf("    argv[%d] is integer: %d\n", i, * (int *)(argv[i])  );
  };
 printf("Total of Integers: %d \n", intsum);

 /*-------------------------------------------------------------------+
 | Display environment variables passed.                              |
 +-------------------------------------------------------------------*/
 i = 0;
 if (*envp == NULL)
   {
    printf("\nEnviroment Variables to process: None\n");
   }
  else
  {
   printf("\nEnviroment Variables :\n");
   while(*envp)
       printf("    envp[%d] is - %s\n", i++,*envp++);
  };

 printf("\nRetcode: %d\n\n", retcode);

 exit(retcode);
}

#pragma eject
/*--------------------------------------------------------------------+
|                                                                     |
|   Function: crabadr                                                 |
|                                                                     |
|   Language: C                                                       |
|                                                                     |
| Entry Type: C Linkage                                               |
|                                                                     |
|    Purpose: C function to display the CRAB address.                 |
|                                                                     |
| Misc Notes:                                                         |
|                                                                     |
+--------------------------------------------------------------------*/

int crabadr(void)
{
  char gmt_time[4];
  char date_packed [LEN_PACKED];
  char date_unpacked [LEN_UNPACKED];
  int  retcode;

  long r12area;
  /**************************************************************/
  /*                                                            */
  /* NOTE: The purpose of the following code is to illustrate   */
  /*       the use of inline machine code.  It is not the best  */
  /*       way to obtain or manipulate time information.        */
  /*                                                            */
  /*       Inline machine code has two 'frame' instructions,    */
  /*         - ldregs() starts a sequence inline machine code   */
  /*         - stregs() ends a sequence inline machine code     */
  /*                                                            */
  /*           Note: the inline machine code sequence also ends */
  /*                 when the first normal C code is            */
  /*                 encountered                                */
  /*                                                            */
  /**************************************************************/

                          /*------------------------------------*/
  _ldregs(0);             /* Frame: Start inline machine code   */
                          /*        sequence                    */
  _stregs(R12,            /* Frame: End inline mach code        */
                          /*        sequence.                   */
          &r12area);      /*        Save CRAB address in R12    */
                          /*------------------------------------*/

                          /*------------------------------------*/
  _ldregs(R1,0X82);       /* Frame: Start inline machine code   */
                          /*        sequence.  Setup for SVC 11 */
                          /*        (TIME) call by setting R1   */
                          /*        for ZONE = GMT (x80) and    */
                          /*        DEC type time (x02).        */
                          /*------------------------------------*/

                          /*------------------------------------*/
  _ossvc(11);             /* Issue the SVC call                 */
                          /*------------------------------------*/

                          /*------------------------------------*/
  _stregs(R0+R1+R15,      /* Frame: End inline mach code        */
                          /*        machine code sequence.      */
                          /*        Save registers:             */
          &gmt_time,      /*        R0 -> time in HHMMSSth      */
          &date_packed,   /*        R1 -> date in 0CYYYDDF      */
          &retcode);      /*        R15-> return code           */
                          /*------------------------------------*/

                          /*------------------------------------*/
  _ldregs(R2+R3,          /* Frame: Start inline mach code      */
                          /*        sequence.                   */
        &date_unpacked,   /* R2->Address of unpacked area       */
        &date_packed);    /* R3->Address of packed data from    */
                          /*     SVC 11 (TIME) above.           */
                          /*------------------------------------*/

                          /*------------------------------------*/
  UNPK(0+b(2),            /* R2: address of output              */
     LEN_UNPACKED,        /* Length of output area              */
     0+b(3),              /* R3: address of packed data         */
     LEN_PACKED);         /* Length of packed data              */
                          /*------------------------------------*/

                          /*------------------------------------*/
  MVC(0+b(2),2,3+b(2));   /* Move Year to first 2 bytes         */
  MVC(3+b(2),3,5+b(2));   /* Move day-of-year to left two bytes */
                          /*------------------------------------*/

  /* Note: _stregs is not used because it is not necessary in   */
  /*       in this case.  The first instance of regular C code  */
  /*       will also terminate an inline machine code sequence. */

  date_unpacked[2] = '/' ;/* Setup YYDDD and                    */
  date_unpacked[6] = 0x00;/* .. null terminate the string.      */

  printf("\nCRAB address = R12 (hex) = %X"
         "  GMT is %02X:%02X:%02X.%02X   Date: %s\n",
         r12area,
         gmt_time[0],
         gmt_time[1],
         gmt_time[2],
         gmt_time[3],
         date_unpacked);

  return(0);
}

Copyright (c) 2000 SAS Institute Inc. All Rights Reserved.
Terms of Use & Legal Information | Privacy Statement