From:	SMTP%"RELAY-INFO-VAX@CRVAX.SRI.COM" 27-MAY-1993 09:49:58.11
To:	EVERHART
CC:	
Subj:	Re: Q: Detecting number of arguments in VAX Fortran

Date:    Wed, 26 May 93 13:56:40 PDT
From: mahan@TGV.COM (Patrick L. Mahan)
Message-Id: <930526135640.6100046f@TGV.COM>
Subject: Re: Q: Detecting number of arguments in VAX Fortran
To: fairfield@slacvx.slac.stanford.edu, info-vax@sri.com
X-St-Vmsmail-To: ST%"fairfield@slacvx.slac.stanford.edu"

In article <1993May25.151214.1@slacvx.slac.stanford.edu> you write:
#In article <1993May25.183335.1@vxdesy.desy.de>, pawlak@vxdesy.desy.de writes:
#> Is it possible to check within a FORTRAN routine the number of actual
#> arguments it was called with? So that:
#> 
#> CALL SUB(a,b)
#> CALL SUB(a,b,c)
#> END
#> 
#> SUBROUTINE SUB (x,y,z)
#> n = (magic code...)
#> PRINT *,' # of arguments: ',n
#> END
#> 
#> Will print:
#> 
#> # of arguments: 2
#> # of arguments: 3
#> 
#> ???
#> 
#> I know the program is not legal in the first place, However I have reasons
#> to do it. It should be possible - the number of arguments is, after all,
#> sent together with the argument list..
#
#    Yes, it's possible by calling a routine written in Macro that looks at 
#the AP, etc..  We've done it for years (illegally!).  There are any number 
#of incarnations of such a thing...I'd be happy to send our version along 
#if requested.  However...
#
#    In a recent exchange with Steve Lionel it became clear that not only
#does this violate the Fortran 77 standard, it will NOT work under AXP/VMS,
#and it MAY fail under VAX/VMS when you use the new DEC Fortran V6.0, unless
#you use the right qualifier(s) on the compile (like /VAX_ARCHAIC :-).  The
#AXP version fails because (my understanding) the AXP doesn't have a call
#frame like VAXen do; the VAX version will fail (without the qualifier)
#because of design changes to the compiler that increase performance (and
#isn't that what we all want, RISC etc.?).
#
#    I think it's time for us all to revisit the nasty things we did because
#we knew the architecture/hardware so well and start writing standard/portable
#code (CERNLIB not withstanding ;-).
#

That depends.  Portable code is not always efficient code.  As for determining
the number of arguments passed to a routine on the Alpha, below is a routine
in C that I have used so far with success.  Note that this method is probably
unsupported as well.  Also, this code assumes that the compiler used correctly
fills in the Call Frame.  If it doesn't work, then don't come looking for me ;-).


/*
 *	ALPHA_ARGCNT.C
 *
 *	This program can should return the number of arguments
 *	that a routine was called with.
 *
 *	WARNING: This will only work for Alpha/VMS systems
 *
 *	Author: Written by Burns Fisher (sp?) at around 2 a.m.
 *	        while helping us port stuff to the Alpha at the
 *		Atlanta DECUS Symposium Spring 1992.
 */

#ifndef __ALPHA

int ArgCnt()	/* for VMS, just use a stub holder */
{
	return(-1);	/* always return an error */
}

#else

extern void LIB$GET_CURRENT_INVO_CONTEXT();
extern int  LIB$GET_PREVIOUS_INVO_CONTEXT();

int ArgCnt()
{
	char context[560];	/* context block */
	int status;		/* status returned by LIB$ */

	/* get the context block for the call to this routine */

	LIB$GET_CURRENT_INVO_CONTEXT(&context[0]);

	/* Now get the context for the person who called us */

	status = LIB$GET_PREVIOUS_INVO_CONTEXT(&context[0]);

	/*
	 * if status is 1, return the least significant
	 * byte of the AI register.  Otherwise, return
	 * -1.
	 */

	return ((status & 1) ? context[527] : -1 );
}

#endif /* __ALPHA */

--
Patrick L. Mahan

--- TGV Window Washer ------------------------------- Mahan@TGV.COM ---------

Waking a person unnecessarily should not be considered  - Lazarus Long
a capital crime.  For a first offense, that is            From the Notebooks of
							  Lazarus Long


