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)
|