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.edulrg7030@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