i would like to check the amount of arguments are on a universe program before i call it, to build the action before calling it.
------------------------------
Daniel Conradie
Rocket Forum Shared Account
------------------------------
i would like to check the amount of arguments are on a universe program before i call it, to build the action before calling it.
i would like to check the amount of arguments are on a universe program before i call it, to build the action before calling it.
Under Prime INFORMATION and PI/open, one could call !EXIST, and, if cataloged, status() would be set to the number of arguments. The implementation for UniVerse, whose source you can find in uv/APP.PROGS/EXIST, is broken, and I never got around to filing a Rocket case to get it fixed. The root cause is that it needs to be sensitive to endian-ness and is not, as the argument count is a sixteen bit integer.
Here is how you can change the code to fix it, albeit only if there are less than 256 arguments.
Replace:
ASSIGN seq(foobar[52,1]) TO STATUS()
with:
b1 = seq(foobar[51, 1])b2 = seq(foobar[52, 1])ASSIGN if b1 then b1 else b2 TO STATUS()
Compile and catalog it as !EXIST using "CATALOG APP.PROGS !EXIST FORCE".
Then, you can do something like this:
sentence = convert(' ', @FM, trim(@SENTENCE))remove verb from sentence setting dremove subr from sentence setting d
if len(subr) then call !EXIST(subr, cataloged) args = status() if cataloged then crt 'Args: ' : args end else crt 'Not cataloged.' endend
end
Enjoy!
Under Prime INFORMATION and PI/open, one could call !EXIST, and, if cataloged, status() would be set to the number of arguments. The implementation for UniVerse, whose source you can find in uv/APP.PROGS/EXIST, is broken, and I never got around to filing a Rocket case to get it fixed. The root cause is that it needs to be sensitive to endian-ness and is not, as the argument count is a sixteen bit integer.
Here is how you can change the code to fix it, albeit only if there are less than 256 arguments.
Replace:
ASSIGN seq(foobar[52,1]) TO STATUS()
with:
b1 = seq(foobar[51, 1])b2 = seq(foobar[52, 1])ASSIGN if b1 then b1 else b2 TO STATUS()
Compile and catalog it as !EXIST using "CATALOG APP.PROGS !EXIST FORCE".
Then, you can do something like this:
sentence = convert(' ', @FM, trim(@SENTENCE))remove verb from sentence setting dremove subr from sentence setting d
if len(subr) then call !EXIST(subr, cataloged) args = status() if cataloged then crt 'Args: ' : args end else crt 'Not cataloged.' endend
end
Enjoy!
Hi Henry Unger,
Thanks for that, i can try use the exists command,
just want to make it clear.
in Universe pgms we call another program by means of CALL (programname) (ARGU1,ARGU2,ARGU3)
before i call the program, i would like to see how many ARGU there is, so i can dynamically change the argument length?

Hi Henry Unger,
Thanks for that, i can try use the exists command,
just want to make it clear.
in Universe pgms we call another program by means of CALL (programname) (ARGU1,ARGU2,ARGU3)
before i call the program, i would like to see how many ARGU there is, so i can dynamically change the argument length?

Assuming your program is called MYPROGRAM and is cataloged as *MYACCOUNT*MYPROGRAM, you can do this:
subr = '*MYACCOUNT*MYPROGRAM"call !EXIST(subr, cataloged)if cataloged then args = status() begin case case args = 1 call MYPROGRAM(arg1) case args = 2 call MYPROGRAM(arg1, arg2) case args = 3 call MYPROGRAM(arg1, arg2, arg3) case @TRUE crt subr : ' called with unhandled number of arguments ' : args : '.' end caseend else crt subr : ' not cataloged.'end
Assuming your program is called MYPROGRAM and is cataloged as *MYACCOUNT*MYPROGRAM, you can do this:
subr = '*MYACCOUNT*MYPROGRAM"call !EXIST(subr, cataloged)if cataloged then args = status() begin case case args = 1 call MYPROGRAM(arg1) case args = 2 call MYPROGRAM(arg1, arg2) case args = 3 call MYPROGRAM(arg1, arg2, arg3) case @TRUE crt subr : ' called with unhandled number of arguments ' : args : '.' end caseend else crt subr : ' not cataloged.'end
awesome, thanks very much Henry.
going to try that now.
i would like to check the amount of arguments are on a universe program before i call it, to build the action before calling it.
Daniel,
Another alternative is use the &MAP& file. To populate this file use the MAKE.MAP.FILE command and you can then list the &MAP& file and the ARGS dictionary will report the number of the arguements. This will only work for entries in the system catalog space.
LIST &MAP& ARGS 04:26:28am 21 Aug 2023 PAGE 2Catalog Name.................. Args
-MOD.DICT 2!GET.DEVICES 2!SPLICE 4$0192 8*AE_HELP 2*AE_PATCHECK 2*HS.OLEDBKEYS 3
Thanks,
------------------------------
Jonathan Smith
UniData ATS
Rocket Support
------------------------------
i would like to check the amount of arguments are on a universe program before i call it, to build the action before calling it.
Ooooooo dont' get me started on relaunching programs that recompile themselves
Daniel,
Another alternative is use the &MAP& file. To populate this file use the MAKE.MAP.FILE command and you can then list the &MAP& file and the ARGS dictionary will report the number of the arguements. This will only work for entries in the system catalog space.
LIST &MAP& ARGS 04:26:28am 21 Aug 2023 PAGE 2Catalog Name.................. Args
-MOD.DICT 2!GET.DEVICES 2!SPLICE 4$0192 8*AE_HELP 2*AE_PATCHECK 2*HS.OLEDBKEYS 3
Thanks,
------------------------------
Jonathan Smith
UniData ATS
Rocket Support
------------------------------
Hi Jonathan,
Thanks for this, this would work alot better, but i cant seem to get the programs that i have cataloged intoo the &MAP& file.
i cataloged the pgms in the UV account and still nothing.
not sure how else to get the list of my pgms in there?

Assuming your program is called MYPROGRAM and is cataloged as *MYACCOUNT*MYPROGRAM, you can do this:
subr = '*MYACCOUNT*MYPROGRAM"call !EXIST(subr, cataloged)if cataloged then args = status() begin case case args = 1 call MYPROGRAM(arg1) case args = 2 call MYPROGRAM(arg1, arg2) case args = 3 call MYPROGRAM(arg1, arg2, arg3) case @TRUE crt subr : ' called with unhandled number of arguments ' : args : '.' end caseend else crt subr : ' not cataloged.'end
i tried this in the main UV account and in my programming account and it does not work, am i missing something?

Hi Jonathan,
Thanks for this, this would work alot better, but i cant seem to get the programs that i have cataloged intoo the &MAP& file.
i cataloged the pgms in the UV account and still nothing.
not sure how else to get the list of my pgms in there?

How are you cataloging? We used to use CATALOG but switched to ICATALOG (see the documentation on the options) because it's consistent and creates the proper VOC entry for MAKE.MAPFILE.
(we're using it to get information from the system on when programs are last used.. though of course you need to have this in place for months/years before that info is useful for pruning unused programs etc).
How are you cataloging? We used to use CATALOG but switched to ICATALOG (see the documentation on the options) because it's consistent and creates the proper VOC entry for MAKE.MAPFILE.
(we're using it to get information from the system on when programs are last used.. though of course you need to have this in place for months/years before that info is useful for pruning unused programs etc).
i tried CATALOG and ICATALOG and still nothing
ICATALOG PGM.SUITE * LOCAL FORCE
it creates the voc entry, but not in the &MAP&
i tried CATALOG and ICATALOG and still nothing
ICATALOG PGM.SUITE * LOCAL FORCE
it creates the voc entry, but not in the &MAP&
The &MAP& file is built by the MAKE.MAP.FILE command, and that command only works on globally/system cataloged programs.
Programs that are only locally cataloged in the current account VOC will not be picked up by the MAKE.MAP.FILE.
So if, after running your ICATALOG verb, there is no entry in the GLOBAL.CATDIR file (which is a remote pointer to the system catalog directory in the UV account) then the MAKE.MAP.FILE command will not work for your program.
i tried CATALOG and ICATALOG and still nothing
ICATALOG PGM.SUITE * LOCAL FORCE
it creates the voc entry, but not in the &MAP&
See Gregor Scott's comment: basically you do NOT want to use 'LOCAL'.
See Gregor Scott's comment: basically you do NOT want to use 'LOCAL'.
Thanks everyone, that does work now and can use it.
Awesome
Ooooooo dont' get me started on relaunching programs that recompile themselves
Hi Daniel,
If you read an object in .o file and convert it to hex string, the first char must be E0 or E1.
If is E0 is a program, otherwise is E1 , is a subroutine.
if you move the pointer forward to position 10 (offset 0), this char represent the number of arguments that the subroutine contain.
I hope that information will be useful.
Hi Daniel,
If you read an object in .o file and convert it to hex string, the first char must be E0 or E1.
If is E0 is a program, otherwise is E1 , is a subroutine.
if you move the pointer forward to position 10 (offset 0), this char represent the number of arguments that the subroutine contain.
I hope that information will be useful.
The position of these values change depending on the byte order of the machine, so if you where to write a program to do this you would need to workout what byte order your machine is. When I get a couple of free cycles I'll send in some code to show you how to work this out for both a high byte and low byte machine.
Thanks,
------------------------------
Jonathan Smith
UniData ATS
Rocket Support
------------------------------
Already have an account? Login
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.