[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference noted::hackers_v1

Title:-={ H A C K E R S }=-
Notice:Write locked - see NOTED::HACKERS
Moderator:DIEHRD::MORRIS
Created:Thu Feb 20 1986
Last Modified:Mon Aug 03 1992
Last Successful Update:Fri Jun 06 1997
Number of topics:680
Total number of notes:5456

324.0. "Number of arguments from Fortran routine???" by MEO78B::MACKAY (Don Mackay) Mon Sep 29 1986 22:36

    AS this is a 'hack' I have put this here rather than the Fortran
    notes file...
    
    I have a situation where I want to call a sub-routine that will be
    written in Fortran (for a number of reasons that are not relavent here)
    but can have arguments missing. I think that I can detect arguments
    that have been left out of the middle (by %loc(parmaeter_name) =
    0 if missing) but I cannot thinkof a way of obtaining the number
    of parameters passed. ie if I expect 4 parameters but only the first
    was given, %loc(param_2) etc will return random numbers (???? I
    guess).
    
    Any ideas... ?    thanks
    
    Don Mackay
T.RTitleUserPersonal
Name
DateLines
324.1and a pinch of Macro32 & *poof*ANYWAY::GORDONWhat happens after the fire?Tue Sep 30 1986 01:3785
    	It is possible to implement optional arguments in VAX FORTRAN
    if you're willing to cheat with a small macro routine (attached)
    and none of your optional arguments are strings.  The reason that
    strings cannot be optional, is that the FORTRAN compiler always
    allocates a static descriptor in the subroutine and copies the
    descriptors off the arglist into the routines static storage WHETHER
    OR NOT THE STRING IS EVER REFERENCED.  Therefor, an omitted string
    argument will always ACCVIO.
    
    	The Macro routine attached to the end of this note is call
    ARGCOUNT.  It should be called immediately upon entering the routine
    and needs to be declared INTEGER.  An example (from a real routine
    of mine...):
    
    	Integer*4 function enable_out_of_band_AST
     &	  	( Enable_Mask, AST_routine, channel )
*
*  Calling Sequence:
*
*	ret-status.wlc.v = Enable_Out_of_Band_AST( Enable_Mask.rlu.r,
*	  AST_routine.fzeml.v [, [Channel.ml.r]])
*
	implicit integer*4 (a - z)

	byte first/.true./, chann_arg_present
	integer*2 chan
	integer*4 Enable_Mask, AST_routine, channel, argcount, num_args

	num_args = argcount()
	chann_arg_present = (num_args .ge. 3 .and.
     &	  				%loc(channel) .ne. 0)
    			.
    			:
*
*	Check for optional args and take action as required
*
	if(chann_arg_present) channel = chan
    			.
    			:
    
    	You should get the idea...  Send me mail ( {ISWISS/ANYWAY}::GORDON)
    if you need more, or want some more complete routines.  The Macro
    routine follows...
    
    -----------------------cut-----here-------------------------------
;---------------------------------------------------------------
	.title	ARGCOUNT -- Number of Arguments passed to caller
	.ident	\1-002\
;					Douglas A. Gordon
;					Arcon Corporation
;					 5-Feb-1985
;  Last Revision Date: Mon 24-Jun-85 08:30
;
;  Functional Description:
;
;	Function to return the number of  arguments passed to the caller
;	of this routine.  This routine is really only useful from higher
;	level languages.
;
;  Calling Sequence:
;
;	num-args.wl.v = ARGCOUNT()
;
;  Formal Parameters:
;
;	None
;
;  Side Effects:
;
;	Unpredictable results may result if this  routine is called from
;	a main program.
;
;  Revision History:
;
;	\1-002\  24-Jun-1985	added Routine macro for psect compatibility.
;
;	routine	argcount, <>   NOTE: I expanded the "routine" macro here
	.psect	_code, pic, usr, con, rel, lcl, shr, exe, rd, nowrt

	.entry	argcount, ^m<>
                      
	movl	@8(fp), r0		; Put previous call's arg count
	ret				; into R0 and return
	.end
    
324.2One from North of the border!SHEILA::PUCKETTOpen the pod bay doors please HALWed Oct 01 1986 03:3935
Gidday...

Here's one (after the FF)

	.title	NARGS - returns # of arguments & arg supplied
;
;  numargs=NARGS()	returns # of args in arg list to Fortran
;
;  logical argsup
;  flag=ARGSUP(narg)	returns .true. if arg # (narg) was suppiled
;			relies on non-passed args having 0 in arg list
;
	.psect	$code,pic,con,rel,lcl,shr,exe,rd,nowrt,long
;
	.entry	NARGS,0		; dont save anything (r0,r1 temp)
	movl	fp,r1
	addl	s^#8,r1
	movl	(r1),r1		; get old AP
	movzbl	(r1),r0		; return # of args
	ret
;
	.entry	ARGSUP,^m<r2,r3>
	clrl	r0
	movl	@4(ap),r3
	movl	fp,r1
	addl	s^#8,r1
	movl	(r1),r1		; get old AP
	movzbl	(r1),r2		; number of args suppiled is in R2
	cmpl	r3,r2		; is arg off end of list?
	bgtr	10$		; yes, return .false.
	tstl	(r1)[r3]	; no, see if arg pointer zero?
	beql	10$		; yes, return .false.
	incl	r0		; nonzero, return .true.
10$:	ret
	.end
324.3Be a software engineer, not a hacker...TLE::BRETTWed Oct 01 1986 12:3747
    Do it PROPERLY and don't let these crocks annoy the people who are
    going to have to be maintaining this stuff for the next twenty years
    get stuck with your cleverness.
    
    So what is PROPERLY here.
    
    FORTRAN does NOT support optional parameters, and what it does before
    it calls some "clever" hacker's messy .MAR subroutine is its business
    and not yours.  For example, it is quite entitled to move ALL of
    the arguments into registers...
    
    Since your subroutine must support optional parameters, you have
    a choice of two languages, namely MACRO and BLISS.  (Maybe PASCAL????).
    
    Since your algorithm must be written in FORTRAN, it stands to reason
    you need a JACKET ROUTINE, written in BLISS or MACRO, surrounding
    your FORTRAN routine.
    
    
    So, the proper solution is
    
    
    		routine JACKET(P1, P2, P3, P4,...) =
    		begin
    		builtin nullparameter;
    		local
    		    REAL_P1, REAL_P2, ...;
    
    		REAL_P1 = default_p1_value;
    		if not nullparameter(P1) then REAL_P1 = .P1;
    		...
    
    		return FORTRAN_ROUTINE(.REAL_P1,...)
    		end;
                                             
    
    Yes, this gets you an extra layer of CALL/RET.  Yes, that is slower.
    But does it *really* matter, or are you going to try and squeeze
    an extra 0.01% performance out by putting some not-quaranteed-to-work
    kludge in your product?
    
    Furthermore, if performance is really that critical, look at providing
    more than one FORTRAN subroutine offering the different combinations
    of arguments.
    
    
    /Bevin
324.4C Overlooked Yet AgainVAXUUM::DYERWorking For The Yankee DollarWed Oct 01 1986 23:1710
	> Since your subroutine must support optional parameters, you
	> have a choice of two languages, namely MACRO and BLISS.
	> (Maybe PASCAL????)

	    Once again, something is alleged to be feasible only with
	MACRO and BLISS when C has no problem doing it.  C's had varargs
	capabilities for quite some time.
	    I believe VAX Pascal has default values for optional param-
	eters.  I don't know if it's standard Pascal or not . . .
			<_Jym_>
324.5Give 'em what they ask for...ANYWAY::GORDONWhat happens after the fire?Thu Oct 02 1986 11:038
    re: .3
    
    	.0 asked for a hack.... ;-}
    
    		... and I supplied one...
    
    --Doug_who_used_to_be_a_customer_with_only_a_FORTRAN_compiler_and_who_-
      did_many_perverse_and_hackish_things_in_FORTRAN_and_a_handful_of_MACRO.
324.6AP is just another registerSTAR::BRANDENBERGCivilization is the progress toward a society of privacy.Tue Oct 07 1986 19:447
    There is another dangerous aspect of using variable arguments in
    VAX Fortran and that is that the optimizer will, believe it or not,
    grab the argument pointer if it thinks it is no longer needed (observed
    on a VMS 3.5 system compiler version unknown).  So, the best way
    to avoid this is to compile /nooptimize.

    					Monty
324.7Tail between legs...SHEILA::PUCKETTOpen the pod bay doors please HALWed Oct 08 1986 22:143
I have seen this behaviour on V4.5-219. So my hack won't work any more...

= Giles =