cancel
Showing results for 
Search instead for 
Did you mean: 

DCL Coding

SOLVED
Go to solution
mira123456
Occasional Visitor

DCL Coding

I am workimg on a code to to check if queue is still stopped? If yes, I want to proceed with the original code. If no, I want to skip over the messages and warnings and go on to whatever the next section of code . Here is the section of the code I wrote . Does this look right?



$ qname = "SYS$PRINT"
$ qstopped = f$getqui("display_queue","queue_stopped","''qname'")
$ qstoppend = f$getqui("display_queue","queue_stop_pending","''qname'")
$ if (qstopped .or. qstoppend)
$ then
$ qclosed = f$getqui("display_queue","queue_closed","''qname'")
$ if (.not. qclosed) .and. (.not. sys$print_warning)
$ then
$ wait 00:05:00
$ goto nomessage_loop
$ log_mess1 = "Queue ''qname' is STOPPED on " + -
"Node ''node' at ''f$cvtime()'!"
$ sys$print_warning = "TRUE"
$ say "''log_mess1'"
$ endif
$ else
$ nomessage_loop:
$ sys$batch_warning = "FALSE"
$ endif
8 REPLIES
Duncan Morris
Honored Contributor
Solution

Re: DCL Coding

From a quick glance at your source, you have unreachable code following "goto nomessage_loop". Should there be a line with "$ else" there???

sys$print_warning is undefined on the first iteration, so gives

%DCL-W-UNDSYM, undefined symbol - check validity and spelling
\SYS$PRINT_WARNING\

Please add

$ SYS$PRINT_WARNING = "FALSE" towards the start of the procedure.

nomessage_loop label is defined in the middle of an "else" clause!

$ if (.not. qclosed) .and. (.not. sys$print_warning)
$ then
$ wait 00:00:02
$ goto nomessage_loop
%DCL-W-USGOTO, target of GOTO not found - check spelling and presence of label
\NOMESSAGE_LOOP\


I presume that "say" is a global symbol defined in SYLOGIN.COM or your own LOGIN.COM.



Hoff
Honored Contributor

Re: DCL Coding

Jumping around inside an IF-THEN-ELSE structure (use of labels and GOTO commands) would not be my choice. That generally doesn't work all that well. But I'm guessing you knew that. Using a GOTO to exit out of the IF-THEN-ELSE structure does work.

"say" is usually a shorthand for write sys$output, but site specific.

Don't use the "sys$" prefix for your stuff. Unless you are at HP and working on OpenVMS itself, you don't own that prefix.

I see what looks like an un-initialized variable with the sys$print_warning test. That means you could pick up something from a previous invocation.

What other errors did you get when you invoked this?

There are some examples of using f$getqui around, such as in the old (and retired) Ask The Wizard area:

http://www.hp.com/go/openvms/wizard

there's a zip archive of everything:

http://mvb.saic.com/freeware/freewarev70/ask_the_wizard/

and there are examples in the HP OpenVMS documentation and elsewhere in the ITRC forums. It's among the toughest of all the lexical functions around.

ps: mixing the f$getqui lexical function and queue operations can be interesting, as the queue commands and queue operations can (and variously will) change the context underneath the f$getqui lexical function.

mira123456
Occasional Visitor

Re: DCL Coding

$ qname = "SYS$PRINT"
$ qstopped = f$getqui("display_queue","queue_stopped","''qname'")
$ qstoppend = f$getqui("display_queue","queue_stop_pending","''qname'")
$ if (qstopped .or. qstoppend)
$ then
$ qclosed = f$getqui("display_queue","queue_closed","''qname'")
$ if (.not. qclosed) .and. (.not. sys$print_warning)
$ then
$ wait 00:05:00
$ goto nomessage_loop
$ else
$ log_mess1 = "Queue ''qname' is STOPPED on " + -
"Node ''node' at ''f$cvtime()'!"
$ sys$print_warning = "TRUE"
$ say "''log_mess1'"
$ endif
$ else
$ nomessage_loop:
$ sys$print_warning = "FALSE"
$ endif
John Gillings
Honored Contributor

Re: DCL Coding

>$ else
>$ nomessage_loop:
>$ sys$print_warning = "FALSE"
>$ endif

Maybe it's just superstition, but I avoid ever having a label anywhere inside an IF-THEN-ELSE. A label inside may not be visible from a scope outside the conditional.

If I need a loop inside a THEN or ELSE block (usually the only reason for a label)I use GOSUB

$ IF condition
$ THEN
$ GOSUB ThenLoop
$ ELSE
$ GOSUB ElseLoop
$ ENDIF
...
$ ThenLoop:
$ IF WhileTrue
$ THEN
$ Loop Body
$ GOTO ThenLoop
$ ENDIF
$ RETURN
$
$ ElseLoop:
$ Loop Body
$ IF .NOT.UntilTrue THEN GOTO ElseLoop
$ RETURN


When playing with F$GETQUI, make sure you clear the context first with

$ TEMP = F$GETQUI("")

If you need to execute any other commands which touch queues (SUBMIT, PRINT, SHOW QUEUE, SHOW ENTRY etc...), SPAWN them to preserve the queue context of the current process.
A crucible of informative mistakes
Hoff
Honored Contributor

Re: DCL Coding

Eh?

That's very similar code, if not identical?

I have not gone to DIFFERENCES the new DCL with the original DCL code to see what changed here, this given that several of the same problems mentioned earlier replies remain present in this new code.

1: Labels located inside of an IF-THEN-ELSE-ENDIF structure are a very bad idea.

2: Use of sys$print_warning and sys$batch_warning outside of an HP OpenVMS operating system module is a bad idea; the SYS$ prefix is registered, and (unless you're working in OpenVMS Engineering) you shouldn't use symbols or logical names or files with that prefix.

3: Use of a local SAY symbol should either be specifically implemented here, or WRITE SYS$OUTPUT should be used.

4: I don't see the log_mess1 symbol established, either.

5: There's no error handing here; that would usually be an ON or a SET NOON command at the top of the DCL sequence.

I'm not at all sure what you're trying to do -- this looks like a smaller wad of DCL extricated from within a larger wad -- nor hat error(s) or problems you're seeing -- but here's some DCL code that does mostly what it appears is the goal:

$ set noon
$ qname = "SYS$PRINT"
$ qstopped = 0
$ qpending = 0
$ qclosed = 0
$ if f$getqui("display_queue","queue_stopped",qname) then qstopped = 1
$ if f$getqui("display_queue","queue_stop_pending",qname) then qpending = 1
$ if f$getqui("display_queue","queue_closed",qname) then qclosed = 1
$ if (qstopped .or. qpending) .and. .not. qclosed
$ then
$ write sys$output "Queue ''qname' stalled"
$ endif

If you can locate a copy, the book I wrote a while back Writing Real Programs in DCL (currently out of print, but with copies occasionally available used via eBay) might be useful. Failing access to that book, do skim through the OpenVMS User's Guide manual for some DCL details.

Ian Miller.
Honored Contributor

Re: DCL Coding

lots of examples of using f$getqui can be found at http://dcl.openvms.org
____________________
Purely Personal Opinion
Gregg Parmentier
Frequent Advisor

Re: DCL Coding


I find that using indentation to highlight my if-then-else blocks and logical loops makes parsing these DCL errors a lot easier.

Leaving it all left justified just reminds me of the old fortran 66 code I had to support back in the 80's.

ugh.
John Gillings
Honored Contributor

Re: DCL Coding

Gregg,

> Leaving it all left justified just
>reminds me of the old fortran 66 code I
>had to support back in the 80's.
>
>ugh.

Of course, you're correct, but in this case the blame is probably on ITRC rather than the poster. ITRC collapses multiple spaces. I know my code was nicely indented before posting it here, I'd guess mira123456's was too. Clicking the "retain format(spacing)" button before posting will preserve indentation, but you have to remember to do it, and it breaks other things.

With proper indentation I find the command:

$ SEARCH myprocedure.COM "IF","THEN","ELSE","ENDIF"

will help highlight structural errors.
A crucible of informative mistakes