home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
forth
/
compiler
/
fpc
/
source
/
zz.seq
< prev
Wrap
Text File
|
1990-07-24
|
10KB
|
259 lines
\\ ZZ.SEQ Mini Shell Tom Zimmer
A very small program that just processes commands from the file
ZZ.CFG which contains programs and parameters passed between shelled
programs.
Compile as follows: TCOM ZZ /OPT /NOINIT enter
{
\ ***************************************************************************
\ the next few lines define immediate words that allow definitions to
\ select what will be compiled from source lines for either F-PC or TCOM.
DEFINED TARGET-INIT NIP 0= #IF \ Test for NOT target compiling
' noop alias \F immediate \ create \F as a NOOP while in F-PC
' \ alias \T immediate \ create \T as "\" while in F-PC
only forth also definitions hidden also
: DS:ALLOC ( n1 -- a1 ) \ allocate n1 bytes of ram at runtime,
\ returning a1 the address of the ram
HERE SWAP ALLOT ;
: SET_MEMORY drop ;
: DOS_TO_TIB ; immediate
: COMSPEC_INIT ; immediate
: +PLACE DUP>R COUNT + SWAP DUP>R CMOVE R> R> C+! ;
#ELSE
' \ alias \F immediate \ create \F as "\" while TCOMing
' noop alias \T immediate \ create \T as a NOOP while TCOMing
#ENDIF
CHECK_/NOINIT
\ ***************************************************************************
\ now start the Mini Shell program
handle mshndl
256 constant cmd_max
64 constant cmd_item
4096 constant cfg_max
50 constant cfg_max_lines
0 value cfg_len
0 value cfg_#lines
0 value cfg_buf
0 value cmd_buf
0 value cmx_buf
0 value nam_buf
0 value na2_buf
0 value cfg_row
0 value cfg_col
cfg_max_lines 2* array cfg_lines
\ ***************************************************************************
\ When the editor returns, it "may", place a command in the file ZZ.CMD to
\ pass back to Mini-Shell. If MS gets a command, it will try to process
\ it. If no command is received, then it will quit.
: cmd_set ( -- )
" ZZ.CMD" ">$ mshndl $>handle ;
: read_item ( a1 -- )
bl word count cmd_item min rot place ;
: read_cmd ( -- n1 ) \ read the command byte
cmd_set
mshndl hopen
if 0 exit
then
pad 'tib ! \ make sure there is room for 256 bytes
tib cmd_max mshndl hread #tib ! >in off
bl word c@
if here 1+ c@
nam_buf read_item
cfg_row read_item
cfg_col read_item
na2_buf read_item
else 0
nam_buf off
na2_buf off
cfg_row off
cfg_col off
then mshndl hclose drop
sp0 @ 2+ 'tib ! ;
: del_cmd ( -- ) \ delete the command byte file
cmd_set
mshndl hdelete drop ;
\ ***************************************************************************
\ read the configuration file into memory
: no_cfg ( -- )
." Cannot find ZZ.CFG, creating.."
mshndl hcreate
if cr ." Can't create ZZ.CFG, quitting."
bye
else " NEWZ %1 %2 %3 /cmd||" mshndl hwrite drop
2573 sp@ 2 mshndl hwrite 2drop
mshndl hclose drop
mshndl hopen drop
then ;
: read_cfg ( -- ) \ read the configuration file
" ZZ.CFG" ">$ mshndl $>handle
mshndl hopen if no_cfg then
cfg_buf cfg_max mshndl hread =: cfg_len
mshndl hclose drop
cfg_len 0=
if cr ." ZZ.CFG has invalid length=0, quitting"
bye
then ;
: cfg_next_lf ( a1 -- a2 f1 ) \ find next LF in CFG file
begin 1+ dup c@ $0A = \ an LF
over cfg_buf cfg_len + u>= or \ or buf end
until dup cfg_buf cfg_len + u>= ;
: cfg_lcalc ( -- ) \ calculate the line starts
off> cfg_#lines
cfg_buf
cfg_max_lines 2 - 0
do dup cfg_lines i 2* + !
cfg_next_lf ?leave 1+
incr> cfg_#lines
loop drop ;
: >cmd_buf ( c1 -- )
cmd_buf count + c! cmd_buf incr ;
: ">cmd_buf ( a1 n1 -- )
cmd_buf +place ;
: params>cmd_buf ( n1 a1 -- n2 ) \ prompt for parameters for command line
0 rows 1- at cols 1- spaces
0 rows 1- at \ set start of line
1+ dup c@
dup $20 = swap '|' = or 0= \ if not blank or "|"
if 40 2dup '"' scan nip - \ scan for " delimited $
dup 1+ >r ?dup 0=
else true 0 >r
then
if drop " Command line: "
then
type
r> + \ adjust offset for next char
tib 40 expect \ get the command line
tib span @ ">cmd_buf ; \ append it to command buffer
: do_esc ( n1 a1 -- n2 ) \ test char at a1, process then return n2,
\ an adjusted n1 the number of characters
\ to skip.
>r
r@ c@ '1' = if nam_buf count ">cmd_buf then
r@ c@ '2' = if cfg_row count ">cmd_buf then
r@ c@ '3' = if cfg_col count ">cmd_buf then
r@ c@ '4' = if na2_buf count ">cmd_buf then
r@ c@ 'P' = if r@ params>cmd_buf then
r@ c@ 'F' = if nam_buf count 2dup '.' scan nip - \ no EXT
">cmd_buf then
r>drop ;
: to_cmd_buf ( a1 n1 -- )
2dup $0D scan nip - \ strip off CRLF
cmd_buf off
bounds
?do i c@ '%' =
if 2 i 1+ do_esc \ process 7 skip ESC strng
else i c@ >cmd_buf 1 \ do next char
then
+loop ;
: >cfg_line" ( n1 -- a1 n2 ) \ get addr & len of line n1
2* cfg_lines + dup @ swap 2+ @ over - ;
comment:
: "sys ( a1 n1 a2 n2 --- f1 ) \ spawn a program
exec.param 16 erase
dup
if exec.buf place
exec.buf count + off
else 2drop exec.buf off
then ?CS: 44 @L exec.param ! \ environment segmnt
?ds: exec.param 4 + ! \ command line seg
exec.buf exec.param 2 + ! \ and offset
$0D exec.buf count + c! \ append a carraige return
cmdpath place
cmdpath count + off
cmdpath 1+ exec.param execf ;
comment;
: run_cmd_buf ( -- ) \ process multiple commands seperated by '|' chars
cmd_buf count
begin 2dup '|' scan 2dup 2>r nip - dup
while cmx_buf place
cmx_buf count + 1- c@ $0A =
if -2 cmx_buf c+!
then
cmx_buf $sys drop \ process DOS command
2r> 1 /string
repeat 2drop 2r> 2drop ;
: do_cfgline ( n1 -- )
dup cfg_#lines <
if >cfg_line" 255 min to_cmd_buf space
run_cmd_buf
else drop \ ignore greater than lines
then ;
: do_cmd ( c1 -- )
upc
dup 'Q' = if drop bye then
dup '1' '9' between if dup '0' - do_cfgline then
dup '0' = if 10 do_cfgline then
dup 'A' 'H' between if dup 'A' - 11 + do_cfgline then
drop ;
: main ( -- )
DECIMAL \ always select decimal
cfg_max 1+ ds:alloc =: cfg_buf \ allocate buffer space
cmd_max 1+ ds:alloc =: cmd_buf
cmd_max 1+ ds:alloc =: cmx_buf
cmd_item 1+ ds:alloc =: nam_buf
cmd_item 1+ ds:alloc =: na2_buf
cmd_item 1+ ds:alloc =: cfg_row
cmd_item 1+ ds:alloc =: cfg_col
?DS: SSEG ! \ set search segment
0 SET_MEMORY \ reduce memory usage
dosio_init \ init DOS I/O for DEBUGGING
DOS_TO_TIB \ move command tail to TIB
COMSPEC_INIT \ init command specification
read_cfg \ read configuration file
cfg_lcalc \ calculate line starts
bl word count cmd_item min nam_buf place \ get filename
bl word count cmd_item min cfg_row place \ starting row and
bl word count cmd_item min cfg_col place \ starting column
bl word count cmd_item min na2_buf place \ second filename
nam_buf c@ 0= \ if no cmdline parameters
if read_cmd drop \ then use most recent
then
begin del_cmd
0 do_cfgline
read_cfg
cfg_lcalc
read_cmd ?dup
while do_cmd
repeat ;