/*--------------------------------------------------------------------+
| |
| Copyright(c) 1995, SAS Institute Inc. |
| Unpublished - All Rights Reserved |
| |
| S A S / C S A M P L E |
| |
| Name: A2CMC |
| |
| Language: C |
| |
| EntryPoint: $MAINC |
| |
| 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(A2CMCASM) |
| CMS see SAMPLASM MACLIB(A2CMCASM) |
| |
| MVS - |
| Compile/Link/Go: see prefix.SAMPLE.ASM(A2CMCASM) prolog. |
| |
| CMS - |
| Compile/Link/Go: see SAMPLASM MACLIB(A2CMCASM) prolog. |
| |
| Misc Notes: |
| - stdout is re-directed to DD name SYSOUTC in 'source' |
| |
+--------------------------------------------------------------------*/
#include <resident.h> /* <---NOTE: Required for ALL RESIDENT */
#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
/* Re-direct stdout to DD name SYSOUTC for entry point $MAINC, */
/* also note that any redirection overrides _stdonm. */
extern char *_stdonm = "SYSOUTC";
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, should not be any for $MAINC |
+-------------------------------------------------------------------*/
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);
}
|