Operating System - OpenVMS
Showing results for 
Search instead for 
Did you mean: 

DCL Scripting

Occasional Contributor

DCL Scripting

I currently have a job scheduler that passes 8 parameters to a command procedure, which assigns the values as symbols to eliminate any hard coding. The problem is that I need to increase the number of parameters being passed to the command procedure, which exceeds the limit of the job scheduler.

What I would like to do is modify the command procedure to initially read in a static file that contains parameter information (12 records) and then use the values within the command procedure.
Example of existing command procedure:
$ username = P1
$ business_model_instance = P2
$ warehouse_model_instance = P3
$ bit_string = P4
$ environment = P5
$ ods_admin = P6
$ warehouse_admin = P7

! Production or Development?
$ @wipdss_base_root:[config]wipdss_env.com 'environment

An example of how to accomplish would be great! Thanks, Brett
Honored Contributor

Re: DCL Scripting

Aaron Sakovich
Super Advisor

Re: DCL Scripting

One alternative would be to pass a single string to the command procedure with all of your parameters enclosed in quotes, e.g.,

@myproc "p1 p2 p3 ... pn"

This would result in a list of parameters only limited by the string variable length (typically 1024 characters).

Then, inside your routine, you would need to parse all the parameters out. The easiest way to do that would be to use the lexical f$element.

$ n = 0
$ loop:
$ parm'n' = f$element(n," ",p1)
$ if parm'n' .nes. ""
$ then
$ n = n + 1
$ goto loop
$ endif
: fall through...

This can be problematic, esp. if you want to pass blank parameters (" "), or strings with embedded spaces as single parameters.

But, this should give you the general idea as to what's involved.
Honored Contributor

Re: DCL Scripting

Define a logical name (in the group table for example), and translate this logical in the beginning of your procedure
You can use any separator between your parameters (here I use /)

Basic example

$ define/group a "1/2/43/ZZ/aa/123/ghh/jkjk/opop"
$ wr sys$output f$elem(0,"/",f$trn("a","lnm$group"))
$ wr sys$output f$elem(7,"/",f$trn("a","lnm$group"))
Robert Gezelter
Honored Contributor

Re: DCL Scripting


In similar situations, I have implemented something along the lines of "toy" version of TPARSE for DCL, for example:

$ @XYZ parm1=1/parm2=2/parm3=3

You can verify this for yourself with the toy command file:

$ write sys$output p1

- Bob Gezelter, http://www.rlgsc.com
Honored Contributor

Re: DCL Scripting

A group logical will be visible to all processes in the group, and easily prone to collisions.

Logical names are not reentrant; what happens if two runs of FOO define the logical name BAR in parallel? Last DEFINE wins...

Further, the translation will be static; these logical names do not go way until directly deleted, or the system reboots.

The group table is also fairly far along in the sequence of logical name translations, as the process and job tables are checked first. It's easily feasible to end up with several translations, one in each of the tables. So you can look at the group table, and something else left a value in another table. Confusion ensues.

I don't recommend using global symbols or (particularly) logical names to pass contextual information or data around among procedures. If you follow this approach (and some do), you can easily end up with a forest of logical names and knobs akin to what has happened with DEC C (and its increasingly large forest of DECC$* logical names), and then things really get interesting as these values get tangled up, or conflict, or get defined somewhere visible to a process that is not expecting the definition.

This doesn't scale, and it's a monster to debug the transients and race conditions that can arise from such a simple construct.

I still have the scars from when I used logical names for this sort of thing.

(No, I don't like the DECC$* logical names.)

See the other thread for other discussions and suggestions.