The REXX Files | - by Dr. Dirk Terrell |
Well, my trusty old 486/50 finally bit the dust the other day. It has served me well in 5 years of heavy use, running every version of OS/2 since 2.0 came out. Unfortunately, its death came just a couple of days before the deadline for this column, and the column I had been working on dealt with using REXX to start DOS applications with certain DOS settings (like memory, priority, etc.). With that work sitting on an inaccessible hard drive, I will have to delay that column until next month. But I thought a column on using queues in REXX might be useful, so here goes.
There are times when you need to take the output of one program and have a REXX program do something with it. One way to do this is to write the output of the first program to a temporary file on the hard disk and then read the temporary file with the REXX program. There are situations, however, where you might not want to do that, and queues are an attractive alternative. Queues can also be used as a means of communicating between REXX programs.
Queues are basically areas in memory that can hold data and allow multiple processes to access those data. REXX creates a queue called "SESSION" for use by processes (REXX or otherwise) in that particular OS/2 session. You can also create queues for your own use, and processes from multiple sessions can access these so-called "private"or "named" queues.
The first thing to do is to decide whether you will use the session queue or create a private one. If you are going to access a queue from only one REXX program to do simple processing, the session queue will probably suffice. As an example, let's just put some numbers and strings in the session queue, and pull them back off.
Since the session queue is created by REXX, we don't have to worry about it. There are two ways of getting data onto a queue, depending on whether you wish to put it at the top of the queue (last-in, first-out, or LIFO) or at the bottom of the queue (first-in, first-out, or FIFO). If you use the PUSH instruction, data will be placed at the top of the queue (LIFO). The QUEUE instruction will place data at the bottom of the queue (FIFO). The following code shows the use of QUEUE and PUSH to place data onto the session queue and PULL to retrieve the data.
/* Test of PUSH and QUEUE */ push 1 push 2 push 3 Say "Result of PUSH with 1 2 3" Do While Queued()>0 Pull a Say a End queue "A" queue "B" queue "C" Say "Result of QUEUE with A B C" Do While Queued()>0 Pull a Say a End ExitNotice that using PUSH caused the numbers to come off the queue in the reverse order that they were placed onto the queue, whereas QUEUE kept the order the same. You will also notice a function I haven't yet mentioned, the QUEUED() function. QUEUED simply returns the number of lines in the active queue.
Now suppose we don't want to use the session queue for some reason. In the next example, we will create a named queue, and perform the same operations as before. We need only add a couple lines to create the new queue and destroy it when we are done. The RXQUEUE() function is used to create, destroy, and switch queues.
/* Test of PUSH and QUEUE with a named queue */ /* The following line creates a new queue and makes it the active queue. */ old_queue=RXQUEUE("Create","new_queue") push 1 push 2 push 3 Say "Result of PUSH with 1 2 3" Do While Queued()>0 Parse Pull a Say a End queue "A" queue "B" queue "C" Say "Result of QUEUE with A B C" Do While Queued()>0 Parse Pull a Say a End /* The following deletes the new queue and sets the session queue as the active queue. */ rc=RXQUEUE("Delete","new_queue") ExitOne thing you have to be careful to do with named queues is delete them when you are done. They are not deleted when the REXX program completes or when the OS/2 session that created them is terminated. These queues are active until they are explicitly deleted, which can be very useful in certain situations, but could cause problems if you create too many of them.
Queues can be very handy within and amongst REXX programs, but what about other applications? How do you get the output of a non-REXX program into a REXX queue? The answer lies in the RXQUEUE program (not to be confused with the RXQUEUE() function used above). If your non-REXX application writes its output to the screen (standard output), then you can redirect that output into the RXQUEUE program. To redirect the output of the OS/2 DIR command, for example, you would issue the DIR command from within your REXX program:
"dir | rxqueue"using the "|" standard pipe symbol to do the redirection. In this case, the output would be redirected to the session queue.
Then you could read in the results from your REXX program. The following is a full example of using the RXQUEUE program to redirect the output of the DIR command.
/* Redirect the output of the OS/2 DIR command to a REXX queue */ "dir | rxqueue" Do While Queued()>0 Parse Pull a /* Using PARSE PULL preserves case */ Say a EndHere we have used the built-in OS/2 DIR command, but any program that writes to standard output can be redirected to RXQUEUE, making it very easy to process the output with a REXX program. I frequently use FORTRAN or C to do numerically intensive calculations and then feed the output into a REXX program via a queue.
Next month, we'll get back on track with that REXX program to start a Virtual DOS Machine with particular settings.
[Our Sponsor: Perez Computing Services - Makers of Ctrl-Alt-Del Commander and IPF Editor.]
Copyright © 1996 - Falcon Networking
This page is maintained by Falcon Networking. We welcome your suggestions.