BASIC problem calling LIB$ RTL

  • Follow


I'm not a BASIC programmer.  Can somebody take a look at this and tell me
why calling LIB$RENAME_FILE returns %BAS-F-TOOFEWARG.  The equivalent code
in Macro works.


=== Begin: DESCRIP.MMS ==================================
..IFDEF	DEBUG
MFLAGS = $(MFLAGS)/NOOPTIMIZE/DEBUG
BASFLAGS = $(BASFLAGS)/NOOPTIMIZE/DEBUG
LINKFLAGS = $(LINKFLAGS)/DEBUG
..ENDIF

RF.EXE : MAIN.OBJ,RF.OBJ
	LINK$(LINKFLAGS)/EXECUTABLE=$(MMS$TARGET) $(MMS$SOURCE_LIST)

MAIN.OBJ : MAIN.MAR

..IFDEF	MAC
RF.OBJ : RF.MAR
..ELSE
RF.OBJ : RF.BAS
..ENDIF
=== End: DESCRIP.MMS ====================================


=== Begin: MAIN.MAR =====================================
	$DSCDEF
	$LIB$ROUTINESDEF

	.PSECT	DATA,WRT,NOEXE,5
FROM:	.ASCID	"OLDFILE.TXT"
	.ALIGN	LONG
TO:	.ASCID	"NEWFILE.TXT"
	.ALIGN	LONG
RESULT:	.LONG	<DSC$K_CLASS_D@<DSC$B_CLASS@3>>!-
		<DSC$K_DTYPE_T@<DSC$B_DTYPE@3>>,0

	.PSECT	CODE,NOWRT,EXE,5
	.ENTRY	GO,0
	PUSHAB	RESULT
	PUSHAB	TO
	PUSHAB	FROM
	CALLS	#3,RENAME_FILE

	$LIB_PUT_OUTPUT_S -
		MESSAGE_STRING=RESULT

	RET
	.END	GO
=== End: MAIN.MAR =======================================

=== Begin: RF.BAS =======================================
	%TITLE 'DEMO'
	%IDENT 'V1.0'

	SUB RENAME_FILE(STRING FROM$,TO$,RESULT$)
	EXTERNAL LONG FUNCTION LIB$RENAME_FILE
	EXTERNAL LONG FUNCTION RENAME_ERROR
	DECLARE LONG S%
	S%=LIB$RENAME_FILE(FROM$,TO$, , , , ,RENAME_ERROR, , , ,RESULT$, )
	RESULT$=FROM$ UNLESS S% AND 1%
	END SUB

	FUNCTION LONG RENAME_ERROR(STRING OLD$,NEW$,LONG STS%,STV%,SOURCE%,USER%)
	RENAME_ERROR=STS%
	END FUNCTION
=== End: RF.BAS =========================================

=== Begin: RF.MAR =======================================
	$LIB$ROUTINESDEF

;++
..SBTTL	Primitive program datum definitions
;--
	ZERO = 0		; |_ 
	BYTE = 1@0		; |_|_ 
	WORD = 1@1		; |___|___ 
	LONG = 1@2		; |_______|_______
	QUAD = 1@3		; |_______________|_______________
	OCTA = 1@4		; |_______________|_______________|
	PAGE = 1@9		; VAX page ; Alpha & IA64 Pagelet
	BLOCK= 1@9		; Standard disk block size


	$OFFSET	0,POSITIVE,<-
		<ARGCNT,LONG>,-
		<OLDNAM,LONG>,-
		<NEWNAM,LONG>,-
		<DEFSPC,LONG>,-
		<RELSPC,LONG>,-
		<FLAGS,LONG>,-
		<SUCRTN,LONG>,-
		<ERRRTN,LONG>,-
		<CONRTN,LONG>,-
		<USRARG,LONG>,-
		<OLDRES,LONG>,-
		<NEWRES,LONG>,-
		<CONTXT,LONG>,-
		<LENGTH,ZERO>,-
		>

	$OFFSET	LONG,POSITIVE,<-
		<FROM,LONG>,-
		<TO,LONG>,-
		<RESULT,LONG>,-
		>

	.ENTRY	RENAME_FILE,^M<R2,R3,R4,R5>
	SUBL2	#LENGTH,SP
	MOVC5	#0,#0,#0,#LENGTH,(SP)	
	MOVL	#<LENGTH/LONG>-1,ARGCNT(SP)
	MOVL	FROM(AP),OLDNAM(SP)
	MOVL	TO(AP),NEWNAM(SP)
	MOVL	RESULT(AP),NEWRES(SP)
	CALLG	(SP),LIB$RENAME_FILE
	RET


	$OFFSET	LONG,POSITIVE,<-
		<OLD,LONG>,-
		<NEW,LONG>,-
		<STS,LONG>,-
		<STV,LONG>,-
		<SOURCE,LONG>,-
		<USER,LONG>,-
		>

	.ENTRY	RENAME_ERROR,0
	MOVL	STS(AP),R0
	RET
	.END
=== End: RF.MAR =========================================

-- 
VAXman- A Bored Certified VMS Kernel Mode Hacker   VAXman(at)TMESIS(dot)COM
           
  "Well my son, life is like a beanstalk, isn't it?" 
0
Reply VAXman 5/2/2007 4:52:41 PM

Well, I'm not a Macro-32 programmer, but I did write the VAX BASIC
run-time library (in Bliss) and it still occupies a warm place in my
heart, 30 years later, so I will try to answer.

The error message you saw is from the VAX BASIC run-time library,
in particular the part that sets up the frame.  It has detected that 
the number of arguments passed to the VAX BASIC subroutine
is not equal to the number that the subroutine was expecting to
receive.

Now I realize that you have declared the subroutine to have three
arguments, and the caller is passing three arguments.  I can only
conclude that there must be a hidden argment, such as a return
value.  Fire up your debugger and step into the VAX BASIC code,
including the part where it calls the run-time library to set up its 
frame.  The code isn't very complex.
    John Sauter (J_Sauter@Empire.Net)

0
Reply J_Sauter (46) 5/2/2007 10:25:15 PM


VAXman- @SendSpamHere.ORG wrote:
> I'm not a BASIC programmer.  Can somebody take a look at this and tell me
> why calling LIB$RENAME_FILE returns %BAS-F-TOOFEWARG.  The equivalent code
> in Macro works.
> 
> 
> === Begin: DESCRIP.MMS ==================================
> .IFDEF	DEBUG
> MFLAGS = $(MFLAGS)/NOOPTIMIZE/DEBUG
> BASFLAGS = $(BASFLAGS)/NOOPTIMIZE/DEBUG
> LINKFLAGS = $(LINKFLAGS)/DEBUG
> .ENDIF
> 
> RF.EXE : MAIN.OBJ,RF.OBJ
> 	LINK$(LINKFLAGS)/EXECUTABLE=$(MMS$TARGET) $(MMS$SOURCE_LIST)
> 
> MAIN.OBJ : MAIN.MAR
> 
> .IFDEF	MAC
> RF.OBJ : RF.MAR
> .ELSE
> RF.OBJ : RF.BAS
> .ENDIF
> === End: DESCRIP.MMS ====================================
> 
> 
> === Begin: MAIN.MAR =====================================
> 	$DSCDEF
> 	$LIB$ROUTINESDEF
> 
> 	.PSECT	DATA,WRT,NOEXE,5
> FROM:	.ASCID	"OLDFILE.TXT"
> 	.ALIGN	LONG
> TO:	.ASCID	"NEWFILE.TXT"
> 	.ALIGN	LONG
> RESULT:	.LONG	<DSC$K_CLASS_D@<DSC$B_CLASS@3>>!-
> 		<DSC$K_DTYPE_T@<DSC$B_DTYPE@3>>,0
> 
> 	.PSECT	CODE,NOWRT,EXE,5
> 	.ENTRY	GO,0
> 	PUSHAB	RESULT
> 	PUSHAB	TO
> 	PUSHAB	FROM
> 	CALLS	#3,RENAME_FILE
> 
> 	$LIB_PUT_OUTPUT_S -
> 		MESSAGE_STRING=RESULT
> 
> 	RET
> 	.END	GO
> === End: MAIN.MAR =======================================
> 
> === Begin: RF.BAS =======================================
> 	%TITLE 'DEMO'
> 	%IDENT 'V1.0'
> 
> 	SUB RENAME_FILE(STRING FROM$,TO$,RESULT$)
> 	EXTERNAL LONG FUNCTION LIB$RENAME_FILE
> 	EXTERNAL LONG FUNCTION RENAME_ERROR
> 	DECLARE LONG S%
> 	S%=LIB$RENAME_FILE(FROM$,TO$, , , , ,RENAME_ERROR, , , ,RESULT$, )
> 	RESULT$=FROM$ UNLESS S% AND 1%
> 	END SUB
> 
> 	FUNCTION LONG RENAME_ERROR(STRING OLD$,NEW$,LONG STS%,STV%,SOURCE%,USER%)
> 	RENAME_ERROR=STS%
> 	END FUNCTION
> === End: RF.BAS =========================================
> 
> === Begin: RF.MAR =======================================
> 	$LIB$ROUTINESDEF
> 
> ;++
> .SBTTL	Primitive program datum definitions
> ;--
> 	ZERO = 0		; |_ 
> 	BYTE = 1@0		; |_|_ 
> 	WORD = 1@1		; |___|___ 
> 	LONG = 1@2		; |_______|_______
> 	QUAD = 1@3		; |_______________|_______________
> 	OCTA = 1@4		; |_______________|_______________|
> 	PAGE = 1@9		; VAX page ; Alpha & IA64 Pagelet
> 	BLOCK= 1@9		; Standard disk block size
> 
> 
> 	$OFFSET	0,POSITIVE,<-
> 		<ARGCNT,LONG>,-
> 		<OLDNAM,LONG>,-
> 		<NEWNAM,LONG>,-
> 		<DEFSPC,LONG>,-
> 		<RELSPC,LONG>,-
> 		<FLAGS,LONG>,-
> 		<SUCRTN,LONG>,-
> 		<ERRRTN,LONG>,-
> 		<CONRTN,LONG>,-
> 		<USRARG,LONG>,-
> 		<OLDRES,LONG>,-
> 		<NEWRES,LONG>,-
> 		<CONTXT,LONG>,-
> 		<LENGTH,ZERO>,-
> 		>
> 
> 	$OFFSET	LONG,POSITIVE,<-
> 		<FROM,LONG>,-
> 		<TO,LONG>,-
> 		<RESULT,LONG>,-
> 		>
> 
> 	.ENTRY	RENAME_FILE,^M<R2,R3,R4,R5>
> 	SUBL2	#LENGTH,SP
> 	MOVC5	#0,#0,#0,#LENGTH,(SP)	
> 	MOVL	#<LENGTH/LONG>-1,ARGCNT(SP)
> 	MOVL	FROM(AP),OLDNAM(SP)
> 	MOVL	TO(AP),NEWNAM(SP)
> 	MOVL	RESULT(AP),NEWRES(SP)
> 	CALLG	(SP),LIB$RENAME_FILE
> 	RET
> 
> 
> 	$OFFSET	LONG,POSITIVE,<-
> 		<OLD,LONG>,-
> 		<NEW,LONG>,-
> 		<STS,LONG>,-
> 		<STV,LONG>,-
> 		<SOURCE,LONG>,-
> 		<USER,LONG>,-
> 		>
> 
> 	.ENTRY	RENAME_ERROR,0
> 	MOVL	STS(AP),R0
> 	RET
> 	.END
> === End: RF.MAR =========================================
> 

You need to change the call to LIB$RENAME_FILE to look like:

 S%=LIB$RENAME_FILE(FROM$,TO$, , , , ,LOC(RENAME_ERROR), , , ,RESULT$, )

Just as an aside, I'd add an OPTION TYPE=EXPLICIT into the BASIC code as
well and include lib$routines like so:

 %INCLUDE "LIB$ROUTINES" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET.TLB"

Cheers,
Jim.
-- 
www.eight-cubed.com
0
Reply Jim 5/3/2007 12:11:24 AM

VAXman- @SendSpamHere.ORG wrote:
> I'm not a BASIC programmer.  Can somebody take a look at this and tell me
> why calling LIB$RENAME_FILE returns %BAS-F-TOOFEWARG.  The equivalent code
> in Macro works.
> 

Why not this?

	NAME FROM$ AS TO$

Also declaring all variables and compiling with /TYPE:EXPLICIT will 
catch a lot of problems.

Jeff Coffield
0
Reply Jeffrey 5/3/2007 1:07:51 AM

In article <og3i339qqtuamc42j941t3hruqicmdsfhl@4ax.com>, John Sauter <J_Sauter@Empire.Net> writes:
>
>
>Well, I'm not a Macro-32 programmer, but I did write the VAX BASIC
>run-time library (in Bliss) and it still occupies a warm place in my
>heart, 30 years later, so I will try to answer.
>
>The error message you saw is from the VAX BASIC run-time library,
>in particular the part that sets up the frame.  It has detected that 
>the number of arguments passed to the VAX BASIC subroutine
>is not equal to the number that the subroutine was expecting to
>receive.
>
>Now I realize that you have declared the subroutine to have three
>arguments, and the caller is passing three arguments.  I can only
>conclude that there must be a hidden argment, such as a return
>value.  Fire up your debugger and step into the VAX BASIC code,
>including the part where it calls the run-time library to set up its 
>frame.  The code isn't very complex.
>    John Sauter (J_Sauter@Empire.Net)

Not.  The error was most definitely on the call to LIB$RENAME_FILE.

What I did was to boil the code I posted down to the bare essentials.

I found the problem later today when I started paring down the argument
list passed to LIB$RENAME_FILE.  This is code I was handed and apparently
has worked for eons or the customer just never exercised this particular
part of the code.

The RENAME_ERROR routine needed to be passed using the LOC() function.

-- 
VAXman- A Bored Certified VMS Kernel Mode Hacker   VAXman(at)TMESIS(dot)COM
           
  "Well my son, life is like a beanstalk, isn't it?" 
0
Reply VAXman 5/3/2007 1:19:40 AM

In article <HBa_h.7038$rO7.6300@newssvr25.news.prodigy.net>, "Jeffrey H. Coffield" <jeffrey@digitalsynergyinc.com> writes:
>
>
>VAXman- @SendSpamHere.ORG wrote:
>> I'm not a BASIC programmer.  Can somebody take a look at this and tell me
>> why calling LIB$RENAME_FILE returns %BAS-F-TOOFEWARG.  The equivalent code
>> in Macro works.
>> 
>
>Why not this?
>
>	NAME FROM$ AS TO$
>
>Also declaring all variables and compiling with /TYPE:EXPLICIT will 
>catch a lot of problems.
>
>Jeff Coffield

Again, I'm not a BASIC programmer and, as you have pointed out, neither
was the person that authored this code.

The %BAS-F-TOOFEWARG is misleading error.  The problem was that a routine
entry point was improperly passed to the LIB$RENAME_FILE RTL.  I used the
LOC() and fixed the problem.

-- 
VAXman- A Bored Certified VMS Kernel Mode Hacker   VAXman(at)TMESIS(dot)COM
           
  "Well my son, life is like a beanstalk, isn't it?" 
0
Reply VAXman 5/3/2007 1:21:47 AM

In article <463928ac$1@dnews.tpgi.com.au>, Jim Duff <spam.this@127.0.0.1> writes:
{...snip...}

> S%=LIB$RENAME_FILE(FROM$,TO$, , , , ,LOC(RENAME_ERROR), , , ,RESULT$, )

Thanks Jim, I figured this out after I made my original post.  The BASIC
error code was misleading.

How have you been?  I hope you haven't had any more bicycle mishaps since
our last meetup.

-- 
VAXman- A Bored Certified VMS Kernel Mode Hacker   VAXman(at)TMESIS(dot)COM
           
  "Well my son, life is like a beanstalk, isn't it?" 
0
Reply VAXman 5/3/2007 1:23:51 AM

VAXman- @SendSpamHere.ORG wrote:
> In article <463928ac$1@dnews.tpgi.com.au>, Jim Duff <spam.this@127.0.0.1> writes:
> {...snip...}
> 
>> S%=LIB$RENAME_FILE(FROM$,TO$, , , , ,LOC(RENAME_ERROR), , , ,RESULT$, )
> 
> Thanks Jim, I figured this out after I made my original post.  The BASIC
> error code was misleading.
> 
> How have you been?  I hope you haven't had any more bicycle mishaps since
> our last meetup.
> 

I've been good, thanks.  And thank you no, no bike mishaps :-)

Cheers,
Jim.
-- 
www.eight-cubed.com
0
Reply Jim 5/3/2007 3:00:00 AM

VAXman-, @SendSpamHere.ORG wrote:
> 
> In article <HBa_h.7038$rO7.6300@newssvr25.news.prodigy.net>, "Jeffrey H. Coffield" <jeffrey@digitalsynergyinc.com> writes:
> >
> >
> >VAXman- @SendSpamHere.ORG wrote:
> >> I'm not a BASIC programmer.  Can somebody take a look at this and tell me
> >> why calling LIB$RENAME_FILE returns %BAS-F-TOOFEWARG.  The equivalent code
> >> in Macro works.
> >>
> >
> >Why not this?
> >
> >       NAME FROM$ AS TO$
> >
> >Also declaring all variables and compiling with /TYPE:EXPLICIT will
> >catch a lot of problems.
> >
> >Jeff Coffield
> 
> Again, I'm not a BASIC programmer and, as you have pointed out, neither
> was the person that authored this code.
> 
> The %BAS-F-TOOFEWARG is misleading error.  The problem was that a routine
> entry point was improperly passed to the LIB$RENAME_FILE RTL.  I used the
> LOC() and fixed the problem.

I think I see what may have happened.

TYPE=EXPLICIT was not in force at compile time, leaving TYPE=IMPLICIT in 
force.

RENAME_ERROR was not explicitly declared as a variable at compile time 
and the name does not contain a dollar sign ("$"); so, RENAME_ERROR was 
implicitly declared as a numeric variable of the default type and size. The
implicitly declared variable was initialized to zero at runtime.

Now consider the calling standard. It is very likely that this leaves 
two consecutive zero longwords on the stack at just the right alignment 
- thus signifying the end of the argument list. Thus, the RTL routine 
likely interpreted that as TOOFEWARG since the apparent end of the 
argument list occurred before it was expected.

Had RENAME_ERROR also been a previously used variable with a non-zero value, the
result would likely have been an ACCVIO when the RTL routine tried to use its
contents as an address. That would have been equally or even more misleading,
and perhaps a bit more difficult to troubleshoot.

-- 
David J Dachtera
dba DJE Systems
http://www.djesys.com/

Unofficial OpenVMS Marketing Home Page
http://www.djesys.com/vms/market/

Unofficial Affordable OpenVMS Home Page:
http://www.djesys.com/vms/soho/

Unofficial OpenVMS-IA32 Home Page:
http://www.djesys.com/vms/ia32/

Unofficial OpenVMS Hobbyist Support Page:
http://www.djesys.com/vms/support/
0
Reply djesys.no (1536) 5/5/2007 2:18:11 AM

David J Dachtera wrote:
> VAXman-, @SendSpamHere.ORG wrote:
[snip]
>> Again, I'm not a BASIC programmer and, as you have pointed out, neither
>> was the person that authored this code.
>>
>> The %BAS-F-TOOFEWARG is misleading error.  The problem was that a routine
>> entry point was improperly passed to the LIB$RENAME_FILE RTL.  I used the
>> LOC() and fixed the problem.
> 
> I think I see what may have happened.
> 
> TYPE=EXPLICIT was not in force at compile time, leaving TYPE=IMPLICIT in 
> force.
> 
> RENAME_ERROR was not explicitly declared as a variable at compile time 
> and the name does not contain a dollar sign ("$"); so, RENAME_ERROR was 
> implicitly declared as a numeric variable of the default type and size. The
> implicitly declared variable was initialized to zero at runtime.

Actually, it was.  See the line that says:

EXTERNAL LONG FUNCTION RENAME_ERROR

> 
> Now consider the calling standard. It is very likely that this leaves 
> two consecutive zero longwords on the stack at just the right alignment 
> - thus signifying the end of the argument list. Thus, the RTL routine 
> likely interpreted that as TOOFEWARG since the apparent end of the 
> argument list occurred before it was expected.
> 
> Had RENAME_ERROR also been a previously used variable with a non-zero value, the
> result would likely have been an ACCVIO when the RTL routine tried to use its
> contents as an address. That would have been equally or even more misleading,
> and perhaps a bit more difficult to troubleshoot.
> 

Applying Occam's Razor (and compiling /list/machine) you will find that
the bare reference to RENAME_ERROR is treated by the compiler as a
function invocation.  Because RENAME_ERROR requires six arguments, and
none are supplied, the runtime error results.

Jim.
-- 
www.eight-cubed.com
0
Reply Jim 5/5/2007 2:36:09 AM

In article <463bed99$1@dnews.tpgi.com.au>, Jim Duff <spam.this@127.0.0.1> writes:
>
>
>David J Dachtera wrote:
>> VAXman-, @SendSpamHere.ORG wrote:
>[snip]
>>> Again, I'm not a BASIC programmer and, as you have pointed out, neither
>>> was the person that authored this code.
>>>
>>> The %BAS-F-TOOFEWARG is misleading error.  The problem was that a routine
>>> entry point was improperly passed to the LIB$RENAME_FILE RTL.  I used the
>>> LOC() and fixed the problem.
>> 
>> I think I see what may have happened.
>> 
>> TYPE=EXPLICIT was not in force at compile time, leaving TYPE=IMPLICIT in 
>> force.
>> 
>> RENAME_ERROR was not explicitly declared as a variable at compile time 
>> and the name does not contain a dollar sign ("$"); so, RENAME_ERROR was 
>> implicitly declared as a numeric variable of the default type and size. The
>> implicitly declared variable was initialized to zero at runtime.
>
>Actually, it was.  See the line that says:
>
>EXTERNAL LONG FUNCTION RENAME_ERROR
>
>> 
>> Now consider the calling standard. It is very likely that this leaves 
>> two consecutive zero longwords on the stack at just the right alignment 
>> - thus signifying the end of the argument list. Thus, the RTL routine 
>> likely interpreted that as TOOFEWARG since the apparent end of the 
>> argument list occurred before it was expected.
>> 
>> Had RENAME_ERROR also been a previously used variable with a non-zero value, the
>> result would likely have been an ACCVIO when the RTL routine tried to use its
>> contents as an address. That would have been equally or even more misleading,
>> and perhaps a bit more difficult to troubleshoot.
>> 
>
>Applying Occam's Razor (and compiling /list/machine) you will find that
>the bare reference to RENAME_ERROR is treated by the compiler as a
>function invocation.  Because RENAME_ERROR requires six arguments, and
>none are supplied, the runtime error results.

I didn't write this software; I was only asked to right it.  Strangely,
the problem didn't rear its ugly head until it was run on V8.3.  Most of
the code was Macro32.  Why the small bit of code calling it was written
in BASIC is beyond me.  The problem has been corrected with LOC().

-- 
VAXman- A Bored Certified VMS Kernel Mode Hacker   VAXman(at)TMESIS(dot)COM
           
  "Well my son, life is like a beanstalk, isn't it?" 
0
Reply VAXman 5/5/2007 12:40:40 PM

In article <463bed99$1@dnews.tpgi.com.au>, spam.this@127.0.0.1 says...
> David J Dachtera wrote:
> > VAXman-, @SendSpamHere.ORG wrote:
> [snip]
> >> Again, I'm not a BASIC programmer and, as you have pointed out, neither
> >> was the person that authored this code.
> >>
> >> The %BAS-F-TOOFEWARG is misleading error.  The problem was that a routine
> >> entry point was improperly passed to the LIB$RENAME_FILE RTL.  I used the
> >> LOC() and fixed the problem.
> > 
> > I think I see what may have happened.
> > 
> > TYPE=EXPLICIT was not in force at compile time, leaving TYPE=IMPLICIT in 
> > force.
> > 
> > RENAME_ERROR was not explicitly declared as a variable at compile time 
> > and the name does not contain a dollar sign ("$"); so, RENAME_ERROR was 
> > implicitly declared as a numeric variable of the default type and size. The
> > implicitly declared variable was initialized to zero at runtime.
> 
> Actually, it was.  See the line that says:
> 
> EXTERNAL LONG FUNCTION RENAME_ERROR
> 
> > 
> > Now consider the calling standard. It is very likely that this leaves 
> > two consecutive zero longwords on the stack at just the right alignment 
> > - thus signifying the end of the argument list. Thus, the RTL routine 
> > likely interpreted that as TOOFEWARG since the apparent end of the 
> > argument list occurred before it was expected.
> > 

You're thinking of itemlists.  This is an arg list, there is an arg 
count at the beginning.  It doesn't matter how many of the args are
0 or in what order.


> > Had RENAME_ERROR also been a previously used variable with a non-zero value, the
> > result would likely have been an ACCVIO when the RTL routine tried to use its
> > contents as an address. That would have been equally or even more misleading,
> > and perhaps a bit more difficult to troubleshoot.
> > 
> 
> Applying Occam's Razor (and compiling /list/machine) you will find that
> the bare reference to RENAME_ERROR is treated by the compiler as a
> function invocation.  Because RENAME_ERROR requires six arguments, and
> none are supplied, the runtime error results.

Just to clarify, it is treated as a function invocation while setting up
the call to LIB$RENAME_FILE.  So the compiler creates a call block for
LIB$RENAME_FILE (probably by pushing the args on the stack in reverse 
order) evaluating the args as it goes.  RENAME_ERROR is defined as a
long function, so the compiled code calls it directly (with no args,
since none are declared), intending to store the result as the nth
arg to LIB$RENAME_FILE.  But RENAME_ERROR blows up at run time with
"too few args", so LIB$RENAME_FILE never actually gets called.

LOC() solves the problem because the arg is supposed to be the address
of an error routine, not some random longword, which LIB$RENAME_FILE
knows, but the compiler doesn't.  AFAIK, there is no way to prototype
a function in BASIC specifying that an arg is the address of a function,
so you have to use tricks like LOC() when calling routines that use
callbacks.


> 
> Jim.
> 

-- 
John
0
Reply john.santos (100) 5/5/2007 10:46:52 PM

On May 2, 9:21 pm, VAXman-  @SendSpamHere.ORG wrote:

>> LIB$RENAME_FILE returns %BAS-F-TOOFEWARG

No it did not. LIB$RENAME_FILE was never called.

> The %BAS-F-TOOFEWARG is misleading error.  The problem was that a routine
> entry point was improperly passed to the LIB$RENAME_FILE RTL.  I used the
> LOC() and fixed the problem.

I realize it is pretty much a moot point, but that explanation is
bullshit.

The error message was most accurate.

The basic program was just plain wrong.

>>>        S%=LIB$RENAME_FILE(FROM$,TO$, , , , ,RENAME_ERROR, , , ,RESULT$, )

Compare this to for example this slightly contrived example.

 S%=LIB$RENAME_FILE(EDIT$(FROM$,2%),TO
$, , , , ,RENAME_ERROR, , , ,RESULT$, )

What do you expect the compile to do?
Pass the address of the edit function or the  result of calling it?

Ditto for RENAME_ERROR...
It is a function, so the result of calling it is passed as an argument
to LIB$RENAME_FILE. However, it is called with 0 arguments so the code
in RENAME_ERROR signals/traps with TOOFEWARG, like it should, BEFORE
LIB$RENAME_FILE is even called.
How is that error message misleading?
If one were to chage the rename_error function to have "OPTION
INACTIVE = SETUP" then it will just (try to) use the non-provided
arguments and crap out with a Memory management violation.

Cheers,
Hein.

0
Reply heinvandenheuvel2 (578) 5/6/2007 2:29:32 AM

In article <1178418572.462196.151280@n76g2000hsh.googlegroups.com>, Hein RMS van den Heuvel <heinvandenheuvel@gmail.com> writes:
>
>
>On May 2, 9:21 pm, VAXman-  @SendSpamHere.ORG wrote:
>
>>> LIB$RENAME_FILE returns %BAS-F-TOOFEWARG
>
>No it did not. LIB$RENAME_FILE was never called.
>
>> The %BAS-F-TOOFEWARG is misleading error.  The problem was that a routine
>> entry point was improperly passed to the LIB$RENAME_FILE RTL.  I used the
>> LOC() and fixed the problem.
>
>I realize it is pretty much a moot point, but that explanation is
>bullshit.

Just reporting what was displayed in the symbolic editor.  I prefer seeing
what is really being executed (machine instructions) and usually debug in
DELTA.



>The error message was most accurate.
>
>The basic program was just plain wrong.
>
>>>>        S%=LIB$RENAME_FILE(FROM$,TO$, , , , ,RENAME_ERROR, , , ,RESULT$, )
>
>Compare this to for example this slightly contrived example.
>
> S%=LIB$RENAME_FILE(EDIT$(FROM$,2%),TO
>$, , , , ,RENAME_ERROR, , , ,RESULT$, )
>
>What do you expect the compile to do?
>Pass the address of the edit function or the  result of calling it?
>
>Ditto for RENAME_ERROR...
>It is a function, so the result of calling it is passed as an argument
>to LIB$RENAME_FILE. However, it is called with 0 arguments so the code
>in RENAME_ERROR signals/traps with TOOFEWARG, like it should, BEFORE
>LIB$RENAME_FILE is even called.
>How is that error message misleading?
>If one were to chage the rename_error function to have "OPTION
>INACTIVE = SETUP" then it will just (try to) use the non-provided
>arguments and crap out with a Memory management violation.
>
>Cheers,
>Hein.

Too much knowledge about BASIC for a simple error.

I was more interested in this not being MY supplied code (which is was
not) and finding what was wrong when the customer invoked my code.  As
it turned out, wasn't my code at all.

-- 
VAXman- A Bored Certified VMS Kernel Mode Hacker   VAXman(at)TMESIS(dot)COM
           
  "Well my son, life is like a beanstalk, isn't it?" 
0
Reply VAXman 5/6/2007 11:59:36 AM

On May 6, 7:59 am, VAXman-  @SendSpamHere.ORG wrote:
> In article <1178418572.462196.151...@n76g2000hsh.googlegroups.com>, Hein RMS van den Heuvel <heinvandenheu...@gmail.com> writes:
>> Too much knowledge about BASIC for a simple error.

I still beg to differ.The error would be exactly the same whether the
code was written in cobol or fortran or any other HLL. The only thing
that would have saved the bad code was a strong function prototype
which explicitly declared that argument as address of function.

>> Just reporting what was displayed in the symbolic editor.
>>I prefer seeing what is really being executed (machine instructions)

Same here, same here.
That's why before replying I triple checked with BAS/LIST/MACHINE
output. Here is that slightly condensed and annotated listing:

0130       RENAME_FILE::
0134               AND     R25, 255, R25
:
016C               CMPLT   R25, 3, R16    ; Enough arguments?
:
0194               JSR     R26, DBASIC$INIT ; active = setup
:
01A4               CLR     R25
01A8               JSR     R26, RENAME_ERROR
01B8               LDA     R21, 172(FP)   ; argument 7 points to
result
01B8               LDQ     R16, 184(FP)  ; argument 1
01C0               STL     R0, 172(FP)     ; store rename_error result
:
01E4               MOV     12, R25        ; argument count
:
01F4               JSR     R26, LIB$RENAME_FILE  ; never get here.
:

:-)

Hein.

0
Reply heinvandenheuvel2 (578) 5/6/2007 12:37:30 PM

"Hein RMS van den Heuvel" <heinvandenheuvel@gmail.com> wrote in message
news:1178418572.462196.151280@n76g2000hsh.googlegroups.com...
> On May 2, 9:21 pm, VAXman-  @SendSpamHere.ORG wrote:
>
[...snip...]
>
> S%=LIB$RENAME_FILE(FROM$,TO$, , , , ,RENAME_ERROR, , , ,RESULT$, )
>
> Compare this to for example this slightly contrived example.
>
> S%=LIB$RENAME_FILE(EDIT$(FROM$,2%),TO
> $, , , , ,RENAME_ERROR, , , ,RESULT$, )
>
> What do you expect the compile to do?
> Pass the address of the edit function or the  result of calling it?
>

The complier will always attempt to evaluate all expressions before
attempting to prepare for the call. The main problem with the original
program was that the author did not use a formal method to declare
LIB$RENAME_FILE. I've seen tons of code like this (almost always written by
less disciplined programmers) and the only way to fix it is to replace all
the home grown declarations with something like this:

 %include "starlet" %from %library "sys$library:basic$starlet" ! sys$
 %include "$ssdef" %from %library "sys$library:basic$starlet" ! ss$
 %include "lib$routines" %from %library "sys$library:basic$starlet" ! lib$
 %include "$libclidef" %from %library "sys$library:basic$starlet" ! lib$ cli

I took the liberty of peeking into starlet for LIB$RENAME_FILE and this is
what I found:

!     LIB$RENAME_FILE
!
!     Rename One or More Files
!
!     The Rename One or More Files routine changes the names of one or more
!     files. The specification of the files to be renamed may include
!     wildcards.  LIB$RENAME_FILE is similar in function to the DCL command
!     RENAME.
!
EXTERNAL LONG FUNCTION  lib$rename_file &
( STRING  BY DESC, &
  STRING  BY DESC, &
  OPTIONAL STRING  BY DESC, &
  STRING  BY DESC, &
  LONG  BY REF, &
  LONG  BY VALUE, &
  LONG  BY VALUE, &
  LONG  BY VALUE, &
  LONG  BY VALUE, &
  STRING  BY DESC, &
  STRING  BY DESC, &
  LONG  BY REF &
)

Click the following link if you want to see how I peeked into the starlet
library.
http://www3.sympatico.ca/n.rieck/docs/hacking_OpenVMS_starlet.html

Neil Rieck
Kitchener/Waterloo/Cambridge,
Ontario, Canada.
http://www3.sympatico.ca/n.rieck/


-- 
Posted via a free Usenet account from http://www.teranews.com

0
Reply n.rieck (1986) 5/6/2007 1:21:21 PM

In article <463dc9da$0$16320$88260bb3@free.teranews.com>, 
n.rieck@sympatico.ca says...
> "Hein RMS van den Heuvel" <heinvandenheuvel@gmail.com> wrote in message
> news:1178418572.462196.151280@n76g2000hsh.googlegroups.com...
> > On May 2, 9:21 pm, VAXman-  @SendSpamHere.ORG wrote:
> >
> [...snip...]
> >
> > S%=LIB$RENAME_FILE(FROM$,TO$, , , , ,RENAME_ERROR, , , ,RESULT$, )
> >
> > Compare this to for example this slightly contrived example.
> >
> > S%=LIB$RENAME_FILE(EDIT$(FROM$,2%),TO
> > $, , , , ,RENAME_ERROR, , , ,RESULT$, )
> >
> > What do you expect the compile to do?
> > Pass the address of the edit function or the  result of calling it?
> >
> 
> The complier will always attempt to evaluate all expressions before
> attempting to prepare for the call. The main problem with the original
> program was that the author did not use a formal method to declare
> LIB$RENAME_FILE. I've seen tons of code like this (almost always written by
> less disciplined programmers) and the only way to fix it is to replace all
> the home grown declarations with something like this:
> 
>  %include "starlet" %from %library "sys$library:basic$starlet" ! sys$
>  %include "$ssdef" %from %library "sys$library:basic$starlet" ! ss$
>  %include "lib$routines" %from %library "sys$library:basic$starlet" ! lib$
>  %include "$libclidef" %from %library "sys$library:basic$starlet" ! lib$ cli
> 
> I took the liberty of peeking into starlet for LIB$RENAME_FILE and this is
> what I found:
> 
> !     LIB$RENAME_FILE
> !
> !     Rename One or More Files
> !
> !     The Rename One or More Files routine changes the names of one or more
> !     files. The specification of the files to be renamed may include
> !     wildcards.  LIB$RENAME_FILE is similar in function to the DCL command
> !     RENAME.
> !
> EXTERNAL LONG FUNCTION  lib$rename_file &
> ( STRING  BY DESC, &
>   STRING  BY DESC, &
>   OPTIONAL STRING  BY DESC, &
>   STRING  BY DESC, &
>   LONG  BY REF, &
>   LONG  BY VALUE, &
>   LONG  BY VALUE, &
>   LONG  BY VALUE, &
>   LONG  BY VALUE, &
>   STRING  BY DESC, &
>   STRING  BY DESC, &
>   LONG  BY REF &
> )
> 

Unfortunately, using this prototype wouldn't have detected the problem.

RENAME_ERROR (IIRC) was declared as a long function, so the compiler
would be happy to evaluate it and pass the result as a longword to
LIB$RENAME_FILE.

The problem is there is no way (that I know of) in BASIC to declare
a function argument as the address of a procedure, so the prototype
has to declare it as a long by ref, and the caller has to provide the
LOC() of the procedure as the argument.  So the compiler can't detect
various coding errors such as passing a constant or a variable or a 
temporary longword on the stack containing the result of a function 
instead of the address of a procedure.

I wonder how much work it would be to add procedures to BASIC as a
pseudo datatype, and fix all the prototypes without breaking all
existing programs that use the current prototypes?  :-)


> Click the following link if you want to see how I peeked into the starlet
> library.
> http://www3.sympatico.ca/n.rieck/docs/hacking_OpenVMS_starlet.html
> 
> Neil Rieck
> Kitchener/Waterloo/Cambridge,
> Ontario, Canada.
> http://www3.sympatico.ca/n.rieck/
> 
> 
> 

-- 
John
0
Reply john.santos (100) 5/7/2007 9:24:20 AM

"John Santos" <john.santos@post.harvard.edu> wrote in message 
news:MPG.20a8ba4bc357bb3f989752@news.bellatlantic.net...
>
[...snip...]
>
> Unfortunately, using this prototype wouldn't have detected the problem.
>
> RENAME_ERROR (IIRC) was declared as a long function, so the compiler
> would be happy to evaluate it and pass the result as a longword to
> LIB$RENAME_FILE.
>

I was only attempting to show the correct way to call OpenVMS functions from 
within OpenVMS-BASIC (which many people do not do based upon stuff I've 
fixed over the past 20 years)

The error in the original posting was caused when the complier say this line 
of code:
S%=LIB$RENAME_FILE(FROM$,TO$, , , , ,RENAME_ERROR, , , ,RESULT$, )

The original program declared RENAME_ERROR with 6 parameters but none are 
present in the call on the offending line.

   ###

In my previous post I showed how to look at the declarations found inside 
"BASIC$STARLET.TLB" but I'd like to stress that we still rely on the 
official documentation ROMs. Here is the official definition of LIB$RENAME 
as published by HP:

LIB$RENAME_FILE old-filespec ,new-filespec [,default-filespec] 
[,related-filespec] [,flags] [,user-success-procedure] 
[,user-error-procedure] [,user-confirm-procedure] [,user-specified-argument] 
[,old-resultant-name] [,new-resultant-name] [,file-scan-context]

Here we can see that RENAME_ERROR will be called as part of 
USER-ERROR-PROCEDURE.

Neil Rieck
Kitchener/Waterloo/Cambridge,
Ontario, Canada.
http://www3.sympatico.ca/n.rieck/links/cool_openvms.html
http://www3.sympatico.ca/n.rieck/links/openvms_demos.html


-- 
Posted via a free Usenet account from http://www.teranews.com

0
Reply n.rieck (1986) 5/11/2007 11:26:17 AM

17 Replies
256 Views

(page loaded in 0.17 seconds)

Similiar Articles:


















7/23/2012 3:36:45 PM


Reply: