              <<< VAXAXP::NOTES$:[NOTES$LIBRARY]VMSNOTES.NOTE;1 >>>
               -< VAX and Alpha VMS - Digital Internal Use Only >-
================================================================================
Note 2434.14      SYS$PUBLIC_VECTORS accvio VA 6B60 PC 80457044         14 of 14
EPS::VANDENHEUVEL "Things that make you think, Hmm" 152 lines  22-DEC-1995 00:44
                       -< sample 'call_by_name' module >-
--------------------------------------------------------------------------------
  .11>	So all they have is an ASCII string of the SYS$xxxx service
  .11>	they want to call... So they can infact not know what System
  .11>	Service is about to be called. He has a work around for the moment
  .11>	of creating a shareable image which just calls the real System
  .11>	Service, but is not happy with hand maintaining this code given 
  .11>	the amount of change that has happened to the System Services 
  .11>	over the years.
    
    	As Derk also suggest, it's easy enough to generate a module
    	to perform the name-to-address translation from an exe.
    	I'll include an example that I tested to work on FDLSHR on VAX,
    	and should work on alpha for sys$library:sys$public_vectors
    
    	(I tried the library trick earlier, so that's fine.
    	 But have no easy access to an Alpha running VMS from home 
    	 to verify that the macro code I slapped together ports as is)
    
    	They could include a similar command file with their distribution
    	and allow their customer to re-generate on demand (VMS upgrade).
    	I suggest to use Macro because it'll always be there. VAX & Alpha.
    	My sample code is just that... I'm sure it can be done nicer
    	(binary search or hash table come to mind). 
    
    	Check it out...
    
    		CHeers,
    			hein.
    
$close/nolog temp
$close/nolog list
$!libr/create/share temp sys$library:fdlshr
$libr/create/share temp sys$library:sys$public_vectors
$libr/list=temp/name temp
$crea call_by_name.mar
; call_by_name.mar 			Hein van den Heuvel, Dec 1995
; Usage: calls call_by_name, name_desc, p1, p2, p3,...
;		name_desc is string descriptor with library routine name.
;		p1, p2, p3,... normal params for the library routine.
;
	.psect	address_data,noexe,nowrt
address_data:
	.psect  name_data,noexe,nowrt
name_data:
;
	.macro	define_entry name
	.psect	address_data,noexe,nowrt
	.address name
	.psect  name_data,noexe,nowrt
	x=.
	.ascii	"name"
	.=x+32
	.endm	define_entry 
;
$open/read temp temp.lis
$open/appen list call_by_name.mar
$list_loop:
$read/end=list_end temp record
$if "SYS$".nes.f$extra(0,4,record) then goto list_loop
$!if "FDL$".nes.f$extra(0,4,record) then goto list_loop
$record = f$edit(record,"compress")
$name = f$elem(0," ",record)
$if name.nes." " then write list "      define_entry       ",name
$name = f$elem(1," ",record)
$if name.nes." " then write list "      define_entry       ",name
$name = f$elem(2," ",record)
$if name.nes." " then write list "      define_entry       ",name
$goto list_loop
$list_end:
$close temp
$close list
$!delete temp.*.*
$append sys$input: call_by_name.mar
	.PSECT	name_data,noexe,nowrt
end_of_names:
	.PSECT  code,EXE,NOWRT
	.ENTRY	call_by_name,0
	MOVAQ	@4(AP),R0
	MOVZWL	(R0),R6
	MOVL	4(R0),R7
	MOVAB	name_data,R8
name_loop:
	CMPC3	R6,(R7),(R8)
	BEQL	copy_args
	ADDL2	#32, R8			; next name
	CMPL	R8, #end_of_names
	BLSSU	name_loop
	MOVL	#1409788, R0            ; not found
	RET
copy_args:
	SUBL3	#1,(AP),R0              ; adjusted arg count
arg_loop:
	BEQL	call_it
	PUSHL	4(ap)[R0]
	SOBGEQ	R0,arg_loop
call_it:
	SUBL3	#1,(AP),R0
	SUBL3	#name_data,R8,R6        ; offset in name table
	ASHL	#-3,R6,R6               ; divive by (32/4) -> address offset
	MOVL	address_data(R6),R7	; grab corresponding routine address
	CALLS	R0,(R7)                 
	RET
	.end
$MACRO  call_by_name
$exit
    
    I'll include my test program for the FDL case and a symbol sorting hint.
    
a:	.long
b:	.long
x:	.ascid	"FDL$CREATE"
y:	.ascid	"FDL$PARSE"
f:	.ascid  "TMP.FDL"
	.entry	start,0
	pushaq	f
	pushaq	x
	calls	#2, call_by_name
	pushal	a
	pushal	b
	pushaq	f
	pushaq	y
	calls	#4, call_by_name
	ret
	.end start
 
   And here is roughly how you could get symbols in the same order as original.
   This could be usefull if a shareable images is made with all the entry points

$libr/create/share temp sys$library:sys$public_vectors
$libr/list=temp/name temp
$close/nolog temp
$close/nolog list
$open/read temp temp.lis
$open/writ list temp.mar
$list_loop:
$read/end=list_end temp record
$if "SYS$".nes.f$extra(0,4,record) then goto list_loop
$record = f$edit(record,"compress")
$name = f$elem(0," ",record)
$if name.nes." " then write list "      .external       ",name
$name = f$elem(1," ",record)
$if name.nes." " then write list "      .external       ",name
$name = f$elem(2," ",record)
$if name.nes." " then write list "      .external       ",name
$goto list_loop
$list_end:
$write list "   .end"
$close temp
$close list
$macro temp
$link/share/map/cross temp
$sear/out=temp.lis temp.map "-RX"
$sort temp.lis/key=(pos:33,siz:9) temp.lis
