From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::%GIZMO.SRI.COM:RELAY-INFO-VAX" 24-APR-1989 14:16
To:	MRGATE::"ARISIA::EVERHART"
Subj:	re: ARGS PASSED to SUBR counter

Message-Id:  <8904241806.AA09580@crdgw1.ge.com>
Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Mon, 24 APR 89 09:12:13 PDT
Received: from Venus.YCC.Yale.Edu by KL.SRI.COM with TCP; Mon, 24 Apr 89 09:05:40 PDT
Date: Mon, 24 Apr 89 12:05 EDT
From: "Jerry Leichter (LEICHTER-JERRY@CS.YALE.EDU)"
 <LEICHTER@Venus.YCC.Yale.Edu>
Subject: re: ARGS PASSED to SUBR counter
To: RIC@RML2.SRI.COM, INFO-VAX@KL.SRI.COM
X-Vms-To: IN%"RIC@RML2.SRI.COM",INFOVAX

	A while ago I believe someone mentioned or posted a function, callable
	from Fortran, that can return the number of arguments that have been
	passed to the current subroutine.  Could someone possibly send me the
	(macro, C, or Fortran) source for this?

There's really not much to it.  Here's a three MACRO routines that are part of
the support library for stuff I work on.  Since all three may be handy, I've
just posted the whole file.

These routines were specifically designed for use with C, but you can use them
from any VMS language once you figure out the appropriate calling form.

							-- Jerry


;
;		Copyright ) 1987, 1988 by Jerrold Leichter
;
; You are free to use this code as you like, and redistribute it, as long as
; you leave this copyright notice intact.
;

	.TITLE		SUPPORT - Simple support routines
	.IDENT		'V01-000'
; EDITLEVEL=28

	.PSECT		SUPPORT_CODE,CON,EXE,GBL,PIC,SHR,RD,REL,NOWRT

	.SUBTITLE	Get number of arguments
;
;	int
;	nargs()
;
; Return to caller the number of arguments he was called with.  Only correct
; when all the arguments are actually longwords on the stack.

.ENTRY	nargs,^M<>
	MOVZBL		@8(FP),R0		;R0 <- count
	RET					;Easy enough

	.SUBTITLE	Get argument list
;
;	ARGLIST *
;	arglist()
;
; Return a pointer to the caller's argument list.
;
; Note that the VAX C compiler will use AP as a working register in a function
; that has no arguments.  (It could presumably also do so after all declared
; arguments become dead.)  Calling arglist() would then produce, at best,
; meaningless results.  If no fixed parameters are needed, use arglist() as
; follows:
;
;	f(dummy)
;	int dummy;			/* Type irrelevant	*/
;	{	...
;		alist = arglist(dummy);
;		...
;	}

.ENTRY	arglist,^M<>
	MOVL		8(FP),R0		;R0 <- Caller's AP
	RET					;Easy enough

	.SUBTITLE	Expand bit string
;
;	void
;	BitsToBytes(bytes,bits,n)
;	BYTE bytes[];
;	ADDR bits;
;	int n;
;
;	Expand a bit string of n < 65536 bits into a series of 0/-1 bytes.
;
;	R5 is used both as a bit count (from the input) and as a bit number;
;	we scan the bits from right to left, thus avoiding having to have
;	two induction variables.

.ENTRY	BitsToBytes,^M<R2,R3,R4,R5>
	MOVC5	#0,#0,#0,12(AP),@4(AP)	;Fill bytes[0...n-1] with 0's.
	MOVL	4(AP),R0		;R0 -> bytes
	MOVL	8(AP),R1		;R1 -> bits
	MOVL	12(AP),R5		;R5 = bit count, later bit number
	BRB	20$
10$:	
	BBC	R5,(R1),20$		;No need to do anything
	MNEGB	#1,(R0)[R5]		;Stick in -1
20$:	SOBGEQ	R5,10$			;Do next (really previous) bit, if any
	RET

	.END

