lrg7030@uxa.cso.uiuc.edu (Loren Rittle) (12/10/90)
OK, a few people have asked about !.rexx. It is still rough, I mean it works great for me, but there is no documentation yet and all the system dependencies have been removed yet! (Most of the more major ones are listed in a new section of the ARexx comment at the top of !.rexx.) I will add the CSH-style history in a few weeks and repost. Any user submitted changes will be incorporated at that point. (Sorry, but my sig will be attached to the bottom of this, I don't know how to override that action!) Here it is: /* * !.rexx ... processes '?', '[]', '*', '.', '..', '~', '/', '!*' * and `backtick` evaluation. * Does filename globbing, minimal UNIX file system emulation and * CSH-style history management (soon). * Requires WShell v1.2, ConMan v1.3c, ARexx v1.1, RexxArpLib, and * ARP (possibly more!) * Started: LJR 9/4/89 * Updates: LJR 10/22/89 1/9/90 2/20/90 * Last update: LJR Sun Dec 09 10:13:09 1990 * Version 5.0 * Copyright (C) 1990 Loren J. Rittle * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 5.0, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * I can be reached at the following address: * Loren J. Rittle * lrg7030@uxa.cso.uiuc.edu */ /* * READ ALL OF THIS BEFORE USING, PLEASE! * You may delete this comment from the version you run from. * You must keep it intact (or updated) on versions you give out. * * I *want* as much user feedback on this as possible, send me * mail if you love it or hate it. Tell me how it crashes your * machine (Yea, it's ARexx, but during the process of building * this thing, I found a few ARexx bugs (all reported to WSH of * course!) that *crashed* the machine!) SEND ANY UPDATES YOU * MAKE TO THIS THING SO I CAN USE THEM IN NEW VERSIONS! * This thing has many system dependencies, * some of the more important ones are listed below: * 1) There *MUST* be a logical device root: assigned! * 2) FindTask returns, via stdout, the ID of the WShell process, I don't * think that this can be found within ARexx, thus you need FindTask * (a quick little program I wrote) in your path, given below * in source form: * --> FindTask.c <-- * #include <proto/all.h> * * void main(void) * { * char buffer[32]; * sprintf(buffer, "%08x", FindTask(NULL)); * puts(buffer); * } * --> END OF INSERTED FILE <-- * 3) I assume that you have local env's, the way I kludge it under * 1.3 AmigaOS is to make a directory for each user WShell. It is * located in env: with a name of the form env:004b0d48, where * 004b0d48 is the process ID of the WShell, found with the above * program. Local env, HOME, is the only one looked at in !.rexx. * I have a login program that sets all this up: env:????????/HOME * and env:????????/USER are the only two local env's I set (other * programs need USER, RCS to name one). When !.rexx notices * eof while it is trying to read a line it closes the WShell (ala * csh) and deletes all local env's. * I believe that local env's are supported under 2.0, so * this will be fixed up, some day in the future when I have 2.0. * 4) Some things will work a bit differently than you would expect * under a plain AmigaOS system: * a) / now refers to root: (so, echo /c/dir will print root:c/dir) * b) . refers to the current directory * c) .. refers to the parent directory * d) ~ refers to your home directory as set in local env USER. * If none of this makes sense to you, then you (most likely) * don't use UNIX and should (unless you want to learn a bit) * stay away from this package, it will only confuse the hell * out of you! :-) :-) :-) * 5) Unlike UNIX we don't pattern match directories. * There are some good reasons for this, I just can't remember * them right at the moment :-). * * Put the following line into your s:startup-wshell file: * prompt "R(%3%r%1);T(%3%E%1)> %[!.rexx]" * Put FindTask in your c: directory (after making it!) * Put !.rexx in your Rexx: directory * * A bit of history, this thing is named !.rexx because WSH had * an example called $.rexx that did `backtick` evaluation. */ signal on BREAK_C signal on ERROR signal on SYNTAX parse pull comm if eof(stdin) then do arexxid = pragma('id') 'findtask >t:'||arexxid 'execio <t:'arexxid||' for 1 var id' 'delete t:'arexxid 'delete env:'||id||' all >nil:' queue "endcli <nil: >nil:" exit end curdotpos = 0 do forever curdotpos=pos('/',comm, curdotpos+1) if curdotpos == 0 then break if curdotpos == 1 then comm = 'root:'||substr(comm, 2) if curdotpos == 1 then iterate if substr(comm, curdotpos-1, 1) == ' ' then do comm = substr(comm, 1, curdotpos-1)||'root:'||substr(comm, curdotpos+1) end end do forever parse var comm first "~" last if first == comm then break arexxid = pragma('id') 'findtask >t:'||arexxid 'execio <t:'arexxid||' for 1 var id' 'delete t:'arexxid home = getenv(id || '/' || home) if home == "" then home = "root:" comm = first||home||last end do forever parse var comm first ".." last if first == comm then break lastspace=lastpos(' ',first) second = substr(first,lastspace+1) first = left(first,lastspace) if second == "" then second = pragma(Directory) say second curdir = pragma('Directory', second) second = pragma('Directory', curdir) lastslash=lastpos('/',second) if lastslash=0 then lastslash=lastpos(':',second) path=left(second,lastslash) if substr(last, 1, 1) == "/" then last = substr(last, 2) comm = first||path||last end curdotpos = 0 do forever curdotpos=pos('.',comm, curdotpos+1) if curdotpos == 0 then break if curdotpos == 1 then comm = pragma(Directory)||substr(comm, 2) if curdotpos == 1 then iterate if substr(comm, curdotpos-1, 1) == ' ' then do if substr(comm, curdotpos+1, 1) == ' ' then comm = substr(comm, 1, curdotpos-1)||pragma(Directory)||substr(comm, curdotpos+1) if substr(comm, curdotpos+1, 1) == '/' then comm = substr(comm, 1, curdotpos-1)||pragma(Directory)||substr(comm, curdotpos+1) end end do i = words(comm) to 2 by -1 ithsubword = subword(comm, i, 1) count = 0 bracketcount = 0 curpos = 0 do forever curpos=pos('*',ithsubword, curpos+1) if curpos == 0 then break count = count + 1 end do forever curpos=pos('?',ithsubword, curpos+1) if curpos == 0 then break count = count + 1 end do forever curpos=pos('\*',ithsubword, curpos+1) if curpos == 0 then break count = count - 1 end do forever curpos=pos('\?',ithsubword, curpos+1) if curpos == 0 then break count = count - 1 end do forever curpos=pos('[',ithsubword, curpos+1) if curpos == 0 then break bracketcount = bracketcount + 1 end do forever curpos=pos(']',ithsubword, curpos+1) if curpos == 0 then break bracketcount = bracketcount + 1 end do forever curpos=pos('\[',ithsubword, curpos+1) if curpos == 0 then break bracketcount = bracketcount - 1 end do forever curpos=pos('\]',ithsubword, curpos+1) if curpos == 0 then break bracketcount = bracketcount - 1 end if (count == 0 & bracketcount == 0) then do do forever curpos=pos('\*',ithsubword, curpos+1) if curpos == 0 then break ithsubword = substr(ithsubword, 1, curpos-1)||substr(ithsubword, curpos+1) end do forever curpos=pos('\?',ithsubword, curpos+1) if curpos == 0 then break ithsubword = substr(ithsubword, 1, curpos-1)||substr(ithsubword, curpos+1) end do forever curpos=pos('\[',ithsubword, curpos+1) if curpos == 0 then break ithsubword = substr(ithsubword, 1, curpos-1)||substr(ithsubword, curpos+1) end do forever curpos=pos('\]',ithsubword, curpos+1) if curpos == 0 then break ithsubword = substr(ithsubword, 1, curpos-1)||substr(ithsubword, curpos+1) end comm = subword(comm, 1, i-1) ithsubword subword(comm, i+1) iterate i end temp = subword(comm, 1, i-1) if filelist(ithsubword, myfilelist, 'F') == 0 then do call open(stderr, '*', 'Write') call writeln(stderr, 'No match.') call close(stderr) queue ' ' exit (5) end do j = 1 to myfilelist.0 temp = temp myfilelist.j end comm = temp subword(comm, i+1) end parse var comm first "`" middle "`" last rc = 0 if middle ~= "" then do middle '| execio stem middle.' middle = "" do j = 1 to middle.0 middle = middle middle.j end if rc = 0 then comm = first middle last else exit rc end queue comm exit BREAK_C: call open(stderr, '*', 'Write') call writeln(stderr, '!.rexx: Break') call close(stderr) queue ' ' exit (5) ERROR: call open(stderr, '*', 'Write') call writeln(stderr, '!.rexx: External error' RC 'on line' SIGL) call close(stderr) queue ' ' exit (5) SYNTAX: call open(stderr, '*', 'Write') call writeln(stderr, '!.rexx: ARexx error' RC 'on line' SIGL) call close(stderr) queue ' ' exit (5) -- ``In short, this is the absolute coolest computer device ever invented!'' -Tom Denbo speaking about The VideoToaster by NewTek ``Think about NewTek's VideoToaster! Now think about the Amiga!'' Loren J. Rittle lrg7030@uxa.cso.uiuc.edu
lrg7030@uxa.cso.uiuc.edu (Loren Rittle) (12/10/90)
A quick correction: * 5) Unlike UNIX we don't pattern match directories. * There are some good reasons for this, I just can't remember * them right at the moment :-). Should say: * 5) Unlike UNIX we don't allow patterns to match directories. * E.g. work:adventure/advent.f is a valid file on our system. * echo work:ad*re/ad*f would print work:adventure/advent.f, * whereas, echo work:ad*re would print (!.rexx would print, BTW) * No match. * There are some good reasons for this, I just can't remember * them right at the moment :-). -- ``In short, this is the absolute coolest computer device ever invented!'' -Tom Denbo speaking about The VideoToaster by NewTek ``Think about NewTek's VideoToaster! Now think about the Amiga!'' Loren J. Rittle lrg7030@uxa.cso.uiuc.edu