Dr. Rx

Hello again, Gentle Readers,

Time for another column.  As you will remember, last month (two months ago, really) I was stumped by a base64 mime decoder.  Still am.  Maybe next month.

In the meantime, I heard from Steven Bacher (seb@draper.com) who wrote:

    Dr. Rx - good problem application, that Base-64 decoder, but what I would really like to see right away would be a quoted-printable decoder.  That is probably easier to get working, and doesn't involve the creation of binary files that might not work on a given OS....

    Ever get those mail messages with "=3D" scattered throughout the text, because someone sent a mail message that had at least one "funny" character in it?  You would see it that way only with a "dumb" mailer (ask Scott Ophof).  That's "quoted printable", where you need to convert every sequence of equal-sign plus two hex characters to the representative ASCII character.  Also, [an] equal sign at the end of a line seems to indicate a trailing space.

Well, that I can handle.  Pass this function a quoted-printable string, and it will pass back the string with the "funny" characters stuck back in.  Put a shell around it which reads and writes a file, and you're done.  I'm kinda pleased with the second Parse statement.

    qpdec: procedure
      parse arg string
      pos = 0
      do forever
        /* Find an equals sign */
        pos = pos("=", string, pos + 1)

        /* All done? Pass string back.  But first.... */
        if pos = 0 then do
          /* If trailing "=", replace with " " */
          if substr(string, length(string)) = "=" ,
            then string = substr(string, 1, length(string) - 1) || " "
          return string

        /* Winkle out the putative hex value */
        parse var string front =(pos) +1 hex +2 back

        /* If it's really hex, replace it and its "=" with the char */
        if hex <> "" then ,
          if datatype(hex, "X") = 1 then ,
            string = front || x2c(hex) || back

A word about that second parse statement.  An unsigned number in a parsing template tells Rexx to break the string at that position.  But pos is a variable, and when Rexx finds variables in a parsing
template, it expects to put output from the parsing into them.  That's why pos is enclosed in parentheses--that tells Rexx to interpret the variable before doing the parsing.

Unfortunately, even though it's now a number, Rexx treats it as a delimiter--that is, if the equals sign is at position 6, Rexx looks for a "6" in the string, instead of breaking the string at position 6.  The "=" prefix reminds Rexx that I want it used as an index, so the string does get broken at position 6.  Then, the "+1" jumps forward over the "=", hex gets the next two chars, and the remainder of the string goes in back.

Paul Raulerson (paulr@axs2000.net) asked about designing screens, like in ISPF.  I think this will be the subject of a future column, but I am checking out Object Rexx, which has a screen builder.  So far, all my Rexxes just run in a DOS window.  Inelegant, but effective.

After reading last month's newsletter column The Scriptor's Maid, I think I better try MAID out too.  It's got to be easier to use than OREXX.

Les Greenwood (GreenwoodL@tsb.co.za) writes,

    it hurts, when Microsoft supplies Regina REXX without documentation....and I cant seem to find any anywhere....I used REXX extensively when I ran a VM mainframe, and have been running Quercus' Personal Rexx on my PC....now I want to use REXX for my WEB, and general tools and utilities, so I need to know nore about Regina REXX...Please prescribe web sites or books.

I rushed a prescription to Les (visit Mark's site at http://www.lightlink.com/hessling/ for the latest Regina, complete with documentation).  I should also have suggested that he check out NetRexx at    http://www2.hursley.ibm.com/netrexx/

Now don't get me wrong, I love what Mark has done, and he's right, I can't think of another free language with a two-pound manual--but I want searchable documentation!  I'm convinced that there's a way to convert a MS Word document directly into a MS .hlp file.  I'm on the case...but if anyone knows the answer, I'd appreciate a quick post--it might save me enough time to do the base64 codec.

Also (get off that hobbyhorse, Doctor!  No!! I wont!!), the documentation is not complete.  For example, Regina knows about the index() function, but there's nary a mention of it in the documentation.  And, while parsing templates are mentioned, it's with a reference to a still-to-be-written chapter.

But-it's too much to ask Mark to be doing the documentation work (at least the pretty part of it) and still expect him to keep making Regina better and better.  Does anyone want to volunteer to take it on?  (Maybe I should first ask Mark if he is interested in this....Mark?)

Aram J. Agajanian (agajan@ibm.net) writes,

    I have a C program that sends its output to stdout. This is a complicated program that cannot be rewritten without a lot of effort.  I want to call this program from Rexx and then process the output. Is there any way to do this without storing the data into a temporary file?  I am using OS/2 Warp 4.

Why yes, Aram, there are a couple of ways.  You could call your program within the Rexx, pipe the output to rxqueue, and then pull it into an array.

    "your_pgm | RXQEUEUE"
    do i = 1 to queued()
       parse pull line.i
    line.0 = i - 1

Even cuter, you could receive the data within your Rexx as it is being written by your program, by piping the stdout (and stderr, if you want) from the program to your Rexx:

    your_pgm 2>&1 | YOUR_REXX

The weird syntax (2>&1) is the way DOS signals that both stderr (the second standard output stream) and stdout (the first standard output stream) are to be redirected.  Your Rexx gets started and runs alongside your_pgm, receiving each line as it is written to either output stream.  In your Rexx, you would treat stderr and stdin as though they were files, for example:

    do i = 1 while lines(stdin)
       line.i = linein(stdin)
    line.0 = i - 1

I believe that what's written to stderr is read from stderr, while what's written to stdout must be picked up from stdin. Consistent, huh? (Anyone?  Is this right?)

I received a long missive from Donald E. Johnson (djohnson@crystal.palace.net) about coding style.  I think that'll be another future column, unless one of my cohorts beats me to it (maybe even then--imagine the Rexx Style Wars!).
And finally, Bob Hamilton (mail@bobh.to) asked,

    Do you know of anyone who has ever tried to write a decoder for Clarion files... These were used in some old DOS-PC systems and I need to convert them to something more modern.

Ah, Clarion!  I remember the ads - the rough, rocky road on the left, and the gleaming highway on the right, leading to a Maxfield Parrish castle in the distance.  Setting sun illuminating the Clarion Road, the other in shadow.  I just knew that if I could get that product, I'd never have to work again.  Fortunately, I couldn't persuade anyone to buy it for me.  Poor Bob.

Well!  Imagine my surprise when +clarion +programming turned up over 15000 hits at Altavista!  Apparently, the language still lives! (Quick, get the stake!).  And +clarion +programming +converter +Rexx gets 15 hits.  Doesn't mean anything, Bob, but surely worth checking out. Good luck!

That's the bottom of the mailbag for this month.  Or at least, I think it is.  If I forgot someone, please poke me.  So, until next month, stay healthy!  And don't eat too much over the holidays!

Dr. Rx, Dr_Rx@Hotmail.com