From: CSBVAX::MRGATE!SCHUMANN%GRIN1.Bitnet@CUNYVM.CUNY.EDU@SMTP 2-MAR-1988 15:56 To: ARISIA::EVERHART Subj: Thanks for all the fish! Received: from CUNYVM.CUNY.EDU by KL.SRI.COM with TCP; Mon 29 Feb 88 11:57:49-PST Received: from GRIN1.Bitnet by CUNYVM.CUNY.EDU ; Mon, 29 Feb 88 14:53:45 EST Date: Mon, 29 Feb 88 12:54:55 cst From: "Schumann,Mark" To: INFO-VAX@KL.SRI.COM Subject: Thanks for all the fish! Thanks to all those who responded to my query a few weeks ago. As promised, here is the digest of responses. Regards, Mark W. Schumann ========================================================================= DIGEST OF RESPONSES TO MY INFO-VAX QUESTION: HOW DO I PASS SWITCHES FROM A FOREIGN COMMAND VERB INTO A DCL COMMAND PROCEDURE? ========================================================================== From: A. Mahendra Rajah University of Regina Regina, Saskatchewan Canada The most elegant way is to use a program and the command definition language. You can then specify switches in any order and the CLI$ routines will find them. Compilation, linking, etc can then be done using LIB$SPAWN from the program. From: Patrick Martin University of North Carolina Define a .CLD file for valid command syntax/verbage/qualifiers, add routines to handle the different qualifiers, and define the routine as a foreign command with SET COMMAND. From: Jeff E Nelson Virginia Polytechnic Institute and State University Define your CCLGO command as follows: $ CCLGO == "@disk:[dir]cclgo *" This passes "*" to the command procedure as P1. You should start looking for user qualifiers and parameters at P2. For example, $ CCLGO/PRINTER=YMLN03 OUTLINE Passes the following parameters to the command procedure: P1 = "*" P2 = "/PRINTER=YMLN03" P3 = "OUTLINE" From: Tom Vaughan Computer Center Canisius College [sent two examples:] First is mac.com, a real simple command stream that will pull off qualifiers and use them inside to modify the behavior of what is going on. The next is a pascal program that has several qualifiers defined for it, the same as anyother dcl command. It has a command verb defined for it, and then those values are retrieved using a call to cli$getinput. From: Bill Costa University Computing University of New Hampshire I have written command procedures that do this, but only through brute-force methods. There are some tricks to the trade. For example: $ MYPROG == "@somewhere:MYPROG.COM """"" defines the command procedure MYPROG as a DCL command. The trick with all those quote marks is simply to pass a null string as the value for the first parameter. Now this means you only have 7 possible parameters left, but it also means that DCL will now let you say: $ MYPROG/QUAL MYFILE where before it wouldn't. Of course "/QUAL" is the value of P2, "MYFILE" is the value of P3, etc. Now for 'real' programs (i.e. written in your favorite hi-level programming language, Pascal, BASIC, FORTRAN, C, etc.) DEC makes it easy. You create a 'CLD' file which describes the qualifiers and parameters you want, and then at run-time, your program simply asks DCL to hand the values over. [Inconvenient to call system utilites like compiler and linker . . .] There are only two things I can think of doing to solve this problem: 1. Write a 'real' program that uses a CLD definition for all the parameters and qualifiers that you want your procedure to accept. This program, when executed, simply takes the hard-won information supplied by DCL and turns around and executes a DCL command procedure, using the information wanted as parameter values (in some well defined order). 2. Write a general purpose program which is called by the command procedure that needs it. From: Jonathan Borden Yale University School of Medicine yes there is a fairly easy way to do this using the CLI$ routines (Command Line Interface) look this up in the programming support manual From: Bertrand Buclin Computer Support Group Computer Science Department Swiss Federal Institute of Technology CH-1015 Lausanne First in DCL : write a command procedure doing the parsing of your command line, i.e. the parsing of parameters P2 to P8, and define your symbol CLGO as CLGO :== @proc foo where foo is a dummy P1 parameter allowing you to add qualifiers to the pseudo verb CLGO. Second, in a language : you will use the mechanism DEC uses for all its applications. This is documented in the following two manuals : - Vol 7B, command definition (CDU) - Vol 8A, Utilities routines (CLI interface) I think the manuals give enough examples, so I don't send you an example. From: Steve Roseman Lehigh University PROGRAM TEKFILE integer status character file*40, scale*20, xbias*20, ybias*20, param*5 character verb*4, verbs(-1:9)*4 data verbs/'TEKF', 'TEKD', 'DTDR', 'HDSD', 'DEDR', 'SEID', + 'TK1D', 'PCDR', 'PCED', 'HPDR', 'PCMD'/ status = cli$get_value('P1', file, i) ! print *, status, file, i if(status.ne.0 .or. i.le.0) file = 'PLOT.PLT' status = cli$get_value('SCALE', scale, i) ! print *, status, scale, i if(status.ne.0 .or. i.le.0) scale = '1.0' param = 'SCALE' read (scale, '(bn,f20.0)', err=90) ascale status = cli$get_value('XBIAS', xbias, i) ! print *, status, xbias, i if(status.ne.0 .or. i.le.0) xbias = '0.0' param = 'XBIAS' read (XBIAS, '(bn,f20.0)', err=90) axbias status = cli$get_value('YBIAS', ybias, i) ! print *, status, ybias, i if(status.ne.0 .or. i.le.0) ybias = '0.0' param = 'YBIAS' read (YBIAS, '(bn,f20.0)', err=90) aybias status = cli$get_value('$VERB', verb, i) if(status.ne.0 .or. i.le.0) file = 'PLOT.PLT' iprog = -1 do 10 i=-1, 9 if(verb .eq. verbs(i)) iprog = i 10 continue CALL DOTEK(iprog, file, ascale, axbias, aybias) STOP 90 continue print *, param, ' parameter is not numeric.' stop END ------------- ! TEKFILE definitions ! Revised: SGR 01/05/88 define verb TEKFILE image "LU$LIB:[EXE]TEKFILE.EXE" qualifier SCALE, VALUE qualifier XBIAS, VALUE qualifier YBIAS, VALUE parameter P1, VALUE define verb TEKDRAW image "LU$LIB:[EXE]TEKFILE.EXE" qualifier SCALE, VALUE qualifier XBIAS, VALUE qualifier YBIAS, VALUE parameter P1, VALUE define verb DTDRAW image "LU$LIB:[EXE]TEKFILE.EXE" qualifier SCALE, VALUE qualifier XBIAS, VALUE qualifier YBIAS, VALUE parameter P1, VALUE define verb HDSDRAW image "LU$LIB:[EXE]TEKFILE.EXE" qualifier SCALE, VALUE qualifier XBIAS, VALUE qualifier YBIAS, VALUE parameter P1, VALUE define verb DEDRAW image "LU$LIB:[EXE]TEKFILE.EXE" qualifier SCALE, VALUE qualifier XBIAS, VALUE qualifier YBIAS, VALUE parameter P1, VALUE define verb SEIDRAW image "LU$LIB:[EXE]TEKFILE.EXE" qualifier SCALE, VALUE qualifier XBIAS, VALUE qualifier YBIAS, VALUE parameter P1, VALUE define verb TK1DRAW image "LU$LIB:[EXE]TEKFILE.EXE" qualifier SCALE, VALUE qualifier XBIAS, VALUE qualifier YBIAS, VALUE parameter P1, VALUE define verb PCDRAW image "LU$LIB:[EXE]TEKFILE.EXE" qualifier SCALE, VALUE qualifier XBIAS, VALUE qualifier YBIAS, VALUE parameter P1, VALUE define verb PCEDRAW image "LU$LIB:[EXE]TEKFILE.EXE" qualifier SCALE, VALUE qualifier XBIAS, VALUE qualifier YBIAS, VALUE parameter P1, VALUE define verb HPDRAW image "LU$LIB:[EXE]TEKFILE.EXE" qualifier SCALE, VALUE qualifier XBIAS, VALUE qualifier YBIAS, VALUE parameter P1, VALUE define verb PCMDRAW image "LU$LIB:[EXE]TEKFILE.EXE" qualifier SCALE, VALUE qualifier XBIAS, VALUE qualifier YBIAS, VALUE parameter P1, VALUE From: Mike Sieweke Georgia Tech Research Institute Atlanta, Georgia I have come up with a way to do exactly what you want. You have to define your with the first parameter, and then it works. For example: $ test :== @com_dir:test + $ test/bogus In this case, "+" is passed as p1, and "/BOGUS" is passed as p2. There may be other ways to get this to work, but I just found this out a minute ago. I always wanted to do this myself, but couldn't figure out how until now. From: Carlo Mekenkamp For command procedures switches example look at jan_gmail:gmail.com. For languages you can use CLI$-routines. [Also sent samples.] From: Kees DeGroot Wageningen Agricultural University Computer-centre, the Netherlands It can be done. Define a procedure, say test.com to be the following: $! TEST.COM to demonstrate the trick $ WRITE SYS$OUTPUT "P IS: ''P1' ''P2' ''P3' ''P4' ''P5'" $ EXIT And now for the interesting part! Define a symbol test as follows: $ TEST :== @TEST % After that call your test with arguments as in: $ TEST/SWITCH MONKEYS/DONKEYS BLA BLA You will see that you get all arguments passed to P1, P2 etc. The only thing to do in DCL is to remove the %. That will be an exercise for you! From: SUTTON@BRANDEIS.BITNET For switches immediately following the symbol you need to define the symbol with a dummy argument. I've done this with my generic COMPILE command, which takes a file and compiles it according to it's file-type. For instance, I can say: $ COMPILE/LIST THIS It will do a search on file, THIS.*, and compile it with the /LIST qualifier. Since a sequence of qualifiers are always followed by a space when immediately following the verb, you can get such a list in the SECOND parameter if you define your symbol thus: $ COMPILE == "@COM$:COMPILE X" You throw away the first parameter (it'll just be the X). You can then check the first character of P2 to see if it's a slash. If the first parameter is a sequence of qualifiers, I keep it around as global qualifiers to be applied to each file. For those qualifiers coming later in the command line such as the second example, I use F$ELEMENT with a comma as the separator to get a value from the list and parse the qualifiers out with string manipulation. One thing to keep in mind is that if one of the qualifiers takes a list of values or a quoted string containing a comma, F$ELEMENT will pare off the parameter at the wrong comma. [Another thing that COMPILE will do is process TeX and LaTeX files from compiling to printing.] From: Lewis,Pat J To: Schumann,Mark [Pat is a Grinnell student--obviously others on BITNET can't read his files, but I didn't think it fair to leave this contribution out.] For an example of command line parsing, see the files [LEWIS.CLD]LOGOUT.CLD and [LEWIS.PROGRAMMING.C.LOGOUT]FILE_LOGOUT.C. You can get further examples of CLDs by typing @DISK$SYS3:[VERB]VERBSETUP and then typing $ VERB your-favorite-DCL-command. For example, $ VERB LOGOUT would print the LOGOUT.CLD to the screen. To dump it to a file, type $ VERB/OUTPUT=LOGOUT.CLD LOGOUT For further documentation on the CLI$ routines, see manuals 7B and 8A in the resource room. P.S. There are also other examples of my own CLDs that can be found in [LEWIS.CLD], and furthermore many of the files in my account are publicly readable, most notably the .COM files in [LEWIS.COMMAND]. From: McMahon,Brian D If you're working entirely in DCL, the only option I know of is to use a command format like CCLNG FOO.C/, in which case P1 = "FOO.C/", which the DCL routine has to parse. (Using some variant of F$LOCATE("/",P1) perhaps.) Disadvantage: In this case, the switch MUST come after the file, to prevent VMS from gagging on it. This is how the PGO command goes about its business. If you want "real" switches that can go anywhere, then that implies using CLI$ routines, which implies a compiled program. I don't know of any other way to do it. If you get any good ideas that aren't posted to the list, I'd love to see them... From: Joe Meadows You can write a command to do just what you want (either 'foreign' or normal). If it's a general case of having lots of command procedures that you want to run this way, you could write one program that used the CLI$ routines, gets the command line, rewrites it in some such way, and have that call the command procedure. This mess just gives you a general way of getting strange things into DCL, which might really be what you want to do. However, the CLI$ routines (and SET COMMAND) allow you to do fairly complex command parsing, and you should really check it out sometime for its intentioned uses. From: John Hascall Iowa State University Computation Center Ames, Iowa 50011 USA The solution is to define the foreign command as such: $ CCLGO :== @disk:[dir]filename DUMMYARG this will get the slash past DCL's parser. ============================================================================ As you can see, the solution boils down to one of two things: 1. Trick DCL into thinking that the verb switch is actually a parameter by feeding it a dummy P1. 2. Or write a CLD. Thanks again.