home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga MA Magazine 1998 #6
/
amigamamagazinepolishissue1998.iso
/
coders
/
jËzyki_programowania
/
amigae
/
moremodules
/
rexxc
/
rexxc.e
< prev
next >
Wrap
Text File
|
1977-12-31
|
40KB
|
1,702 lines
->
-> rexxC.e
->
-> version 0.25
->
-> ARexx port handling class in E v3.2a
->
-> Piotr Obminski (piotr@augs.se)
->
-> last compilation 29-Jul-95
->
-> 1 TAB = 4 spaces <--------------------- see this? -----<<
->
-> -------------------------------------------------------------------
-> BUGS, QUIRKS & LIMITATIONS:
->
-> 1. I have not had any big success with functions, there must be
-> something I don't quite understand about them...
->
-> 2. No inline assembler or any serious optimization, some string
-> operation pretty elementary (but safe & easy to understand). But
-> ARexx itself is no lightning ;-)
->
-> 3. Very little testing for this version (but I'm moving in a few days)
->
-> 4. The code is formatted in an unusual style that reminds one of Ada,
-> but I REALLY BELIEVE THAT CODE MUST BE AS READABLE AS POSSIBLE!
-> Baby, that's my style!
->
-> -------------------------------------------------------------------
OPT MODULE, PREPROCESS
OPT REG = 5
MODULE 'exec/ports', 'exec/nodes', 'exec/lists', 'rexxsyslib',
'rexx/rexxio', 'rexx/rxslib', 'rexx/errors', 'rexx/storage',
'dos/dos'
-> ---------------------------------------------------------------
#define DEBUG
-> ---------------------------------------------------------------
#define NEED_getUnconfirmedCount
#define NEED_commandList -> always needed for receiving
#define NEED_loopReceive
#define NEED_waitReceive -> will be used by loopReceive()
#define NEED_get
#define NEED_isLastTokenized
#define NEED_getArgStr
#define NEED_longToStr
#define NEED_charToStr
#define NEED_version
#define NEED_passPort
#define NEED_defaultIn
#define NEED_defaultOut
#define NEED_brutal
#define NEED_command
#define NEED_commandFile
#define NEED_commandString
#define NEED_commandQuick
#define NEED_commandFileQuick
#define NEED_function
#define NEED_functionQuick
#define NEED_do_send_function
#define NEED_commandStringQuick
#define NEED_commandToken
#define NEED_commandFileToken
#define NEED_commandstringToken
#define NEED_commandQuickToken
#define NEED_commandFileQuickToken
#define NEED_commandStringQuickToken
#define NEED_addServer
#define NEED_addServerQuick
#define NEED_addLibrary
#define NEED_addLibraryQuick
#define NEED_removeLibrary
#define NEED_removeLibraryQuick
#define NEED_addClip
#define NEED_addClipQuick
#define NEED_removeClip
#define NEED_removeClipQuick
#define NEED_functionString
#define NEED_functionStringQuick
#define NEED_openGlobalConsole
#define NEED_openGlobalConsoleQuick
#define NEED_closeGlobalConsole
#define NEED_closeGlobalConsoleQuick
-> PRIVATE --------------------------------------------------
#define NEED_swallowReplies
#define NEED_swallowRepliesQuick
#define NEED_handle_reply
#define NEED_do_send_command
#define NEED_do_send_command_quick
#define NEED_do_send_misc
#define NEED_do_function_string
#define NEED_free_message_all
#define NEED_checkCBList
#define NEED_handle_incoming
#define NEED_command_executor
#define NEED_reply_message
#define NEED_find_command
#define NEED_we_want_reply
-> automatic -----------------------------------------------
#ifdef NEED_loopReceive
#ifndef NEED_waitReceive
#define NEED_waitReceive
#endif
#endif
-> ---------------------------------------------------------------
CONST VERSION_NUM = 0,
REVISION_NUM = 25
-> ---------------------------------------------------------------
->
-> values for state_flags
->
SET ST_DOSPIN, ST_SHUTDOWN
-> ---------------------------------------------------------------
->
-> values for settings_flags
->
EXPORT SET SE_RECEIVING_PORT, -> public port for receiving commands etc.
SE_SENDING_PORT, -> private port with no name (for sending)
SE_BRUTAL, -> don't wait for replies in end()
SE_LIST_SORTED -> callback-list (still not used)
-> ---------------------------------------------------------------
->
-> exceptioninfo values (our exception value is 'rexx'):
->
-> all are 'user' errors ;)
->
EXPORT ENUM EXI_BAD_CALLBACKS, -> bad callback-list
EXI_PORT_NOT_UNIQUE -> port-name not unique
-> ---------------------------------------------------------------
EXPORT OBJECT rexxC
PRIVATE
receiving_port : PTR TO mp
sending_port : PTR TO mp
unconfirmed_count : LONG -> how many answers we want
last_reply_argstr : PTR TO rexxarg
last_args : PTR TO CHAR -> arguments after command-name
remaining_arg_len : LONG
fLastTokenized : LONG
-> ---------------------------------------------
com_callback_list : PTR TO LONG -> command-names & callbacks
default_extension : PTR TO CHAR
pass_port : LONG
default_input : LONG
default_output : LONG
state_flags : LONG -> managed by the class itself
settings_flags : LONG -> set by the user
rec_signal_mask : LONG
send_signal_mask : LONG
break_mask : LONG
ENDOBJECT
-> ---------------------------------------------------------------
RAISE "REXX" IF OpenLibrary() = NIL,
"MEM" IF String() = NIL,
"PORT" IF CreateMsgPort() = NIL
-> ---------------------------------------------------------------
CONST DEFAULT_SETTIGS = SE_SENDING_PORT OR SE_RECEIVING_PORT
-> ---------------------------------------------------------------
->
-> error-values for do_send... routines
->
EXPORT CONST DCC_NO_ERROR = 0,
DCC_GOT_NO_REPLY = 1,
DCC_HOST_NOT_FOUND = 2,
DCC_MSG_NOT_CREATED = 3,
DCC_ABORTED_SWALLOWING = 4,
DCC_NO_FILE = 5 -> for file-commands
-> ---------------------------------------------------------------
->
-> what a speed-gain!
->
CONST MY_RXFF_NOIO = $10000 -> it is: 1 << 16
-> ---------------------------------------------------------------
->
-> is 0 the best thing as default priority?
->
-> also needs: I/O, pass-port
->
EXPORT PROC rexxC( port_name = NIL : PTR TO CHAR,
callbacks = NIL : PTR TO LONG,
priority = 0,
default_ext = NIL : PTR TO CHAR,
passPort = NIL,
defaultIn = NIL,
defaultOut = NIL,
break_mask = 0,
fCtrlC = TRUE,
settings = DEFAULT_SETTIGS ) OF rexxC
rexxsysbase := OpenLibrary( 'rexxsyslib.library', 0 )
self.fileExtension( default_ext )
IF callbacks <> NIL THEN self.commandList( callbacks )
IF settings AND SE_RECEIVING_PORT
IF port_name = NIL THEN port_name := self.fix_port_name()
self.receiving_port := self.create_port( port_name, priority )
ENDIF
self.rec_signal_mask := Shl( 1, self.receiving_port.sigbit )
IF settings AND SE_SENDING_PORT THEN
self.sending_port := self.create_port( NIL, 0 )
self.send_signal_mask := Shl( 1, self.sending_port.sigbit )
self.settings_flags := settings
self.breakMask( break_mask, fCtrlC )
self.pass_port := passPort
self.default_input := defaultIn
self.default_output := defaultOut
ENDPROC
-> ---------------------------------------------------------------
->
->
->
EXPORT PROC end() OF rexxC
DEF msg : PTR TO rexxmsg,
signal_mask
IF self.receiving_port <> NIL
RemPort( self.receiving_port )
Forbid()
WHILE msg := GetMsg( self.receiving_port )
IF IsRexxMsg( msg ) THEN msg.result1 := RC_FATAL
ReplyMsg( msg )
ENDWHILE
DeleteMsgPort( self.receiving_port )
Permit()
ENDIF
IF self.sending_port <> NIL
IF self.last_reply_argstr <> NIL THEN
DeleteArgstring( self.last_reply_argstr )
IF ( self.settings_flags AND SE_BRUTAL ) = FALSE
WHILE self.unconfirmed_count > 0
signal_mask := Wait( self.send_signal_mask OR self.break_mask )
IF signal_mask AND self.break_mask THEN JUMP delete_port
msg := GetMsg( self.sending_port )
IF msg.mn::mn.ln::ln.type = NT_REPLYMSG
IF self.we_want_reply( msg.args[ 15 ] )
self.unconfirmed_count := self.unconfirmed_count - 1
ENDIF
self.free_message_all( msg )
ENDIF
ENDWHILE
ELSE
WHILE msg := GetMsg( self.sending_port )
IF msg.mn::mn.ln::ln.type = NT_REPLYMSG
IF self.we_want_reply( msg.args[ 15 ] )
self.unconfirmed_count := self.unconfirmed_count - 1
ENDIF
self.free_message_all( msg )
ENDIF
ENDWHILE
ENDIF
delete_port:
DeleteMsgPort( self.sending_port )
ENDIF
self.fileExtension( NIL )
CloseLibrary( rexxsysbase )
ENDPROC
-> =================================================================
->
->
->
#ifdef NEED_unconfirmedCount
EXPORT PROC unconfirmedCount() OF rexxC IS self.unconfirmed_count
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_commandList
EXPORT PROC commandList( cblist : PTR TO LONG ) OF rexxC
IF self.checkCBList( cblist ) = FALSE THEN
Throw( "rexx", EXI_BAD_CALLBACKS )
self.com_callback_list := cblist
ENDPROC
#endif
-> ---------------------------------------------------------------
->
-> check validity of non-NIL callback-list
->
#ifdef NEED_checkCBList
EXPORT PROC checkCBList( list : PTR TO LONG ) OF rexxC
DEF len
IF list = NIL THEN RETURN TRUE -> YES!
len := ListLen( list )
IF ( len < 2 ) OR ( Mod( len, 2 ) <> 0 ) THEN RETURN FALSE
ENDPROC TRUE
#endif
-> ---------------------------------------------------------------
->
-> breaks looping & Wait()'ing for INCOMING messages
->
EXPORT PROC break() OF rexxC
self.state_flags := self.state_flags AND Not( ST_DOSPIN )
ENDPROC
-> ---------------------------------------------------------------
->
-> LOOP waiting for message, EXECUTE & answer them if possible
->
-> should it RETURN anything?
->
#ifdef NEED_loopReceive
EXPORT PROC loopReceive() OF rexxC
self.state_flags := self.state_flags OR ST_DOSPIN
LOOP
IF ( self.state_flags AND ST_DOSPIN ) = FALSE THEN RETURN
self.waitReceive()
ENDLOOP
ENDPROC
#endif
-> ---------------------------------------------------------------
->
-> wait for a message, EXECUTE them if possible, then answer it
->
-> should it RETURN anything?
->
#ifdef NEED_waitReceive
EXPORT PROC waitReceive() OF rexxC
DEF signal_mask
signal_mask := Wait( self.rec_signal_mask OR self.break_mask )
IF signal_mask AND self.break_mask THEN
self.break() ELSE self.handle_incoming()
ENDPROC
#endif
-> ---------------------------------------------------------------
->
-> get (if already present) message, EXECUTE it if possible & answer
->
-> should it RETURN anything?
->
#ifdef NEED_get
EXPORT PROC get() OF rexxC
DEF rexx_msg : PTR TO rexxmsg,
rexx_args : PTR TO LONG,
result_1 = RC_ERROR : LONG,
result_2 = NIL : PTR TO CHAR
IF self.receiving_port = NIL THEN RETURN
rexx_msg := GetMsg( self.receiving_port )
IF ( rexx_msg = NIL ) OR ( IsRexxMsg( rexx_msg ) = FALSE ) THEN RETURN
IF ( rexx_msg.action AND RXCODEMASK ) = RXCOMM
rexx_args := rexx_msg.args
result_1, result_2 := self.command_executor( rexx_args[ 0 ] )
ELSE
IF rexx_msg.action AND RXFF_NONRET THEN JUMP reset_it
ENDIF
self.reply_message( rexx_msg, result_1, result_2 )
reset_it:
self.last_args := NIL
self.remaining_arg_len := 0
ENDPROC
#endif
-> ---------------------------------------------------------------
->
-> to be used ONLY ONCE for every message!
->
#ifdef NEED_isLastTokenized
EXPORT PROC isLastTokenized() OF rexxC IS self.fLastTokenized
#endif
-> ---------------------------------------------------------------
->
-> to be used ONLY ONCE for every message!
->
#ifdef NEED_getArgStr
EXPORT PROC getArgStr() OF rexxC
DEF last_args, remaining_arg_len
last_args := self.last_args
remaining_arg_len := self.remaining_arg_len
self.last_args := NIL
self.remaining_arg_len := 0
ENDPROC last_args, remaining_arg_len, self.fLastTokenized
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_version
EXPORT PROC version() OF rexxC IS VERSION_NUM, REVISION_NUM
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_passPort
EXPORT PROC passPort( port_address ) OF rexxC
self.pass_port := port_address
ENDPROC
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_defaultIn
EXPORT PROC defaultIn( file ) OF rexxC
self.default_input := file
ENDPROC
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_defaultOut
EXPORT PROC defaultOut( file ) OF rexxC
self.default_output := file
ENDPROC
#endif
-> ---------------------------------------------------------------
->
->
->
EXPORT PROC breakMask( new_mask, fCtrlC ) OF rexxC
DEF ctrl_c = 0
IF fCtrlC THEN ctrl_c := SIGBREAKF_CTRL_C
self.break_mask := new_mask OR ctrl_c
ENDPROC
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_brutal
EXPORT PROC brutal( fBbrutal ) OF rexxC
IF fBbrutal = TRUE
self.settings_flags := self.settings_flags OR SE_BRUTAL
ELSE
self.settings_flags := self.settings_flags AND Not( SE_BRUTAL )
ENDIF
ENDPROC
#endif
-> ---------------------------------------------------------------
->
->
->
EXPORT PROC fileExtension( ext = NIL : PTR TO CHAR ) OF rexxC
DEF temp
IF self.default_extension <> NIL THEN Dispose( self.default_extension )
IF ext <> NIL
temp := String( StrLen( ext ) )
StrCopy( temp, ext )
self.default_extension := temp
ENDIF
ENDPROC TRUE
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_command
EXPORT PROC command( host_name : PTR TO CHAR,
cmd_to_send : PTR TO CHAR ) OF rexxC
ENDPROC self.do_send_command( host_name, cmd_to_send, RXCOMM )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_commandFile
EXPORT PROC commandFile( file_name : PTR TO CHAR ) OF rexxC
ENDPROC self.do_send_command( 'REXX', file_name, RXCOMM )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_commandString
EXPORT PROC commandString( string : PTR TO CHAR ) OF rexxC
ENDPROC self.do_send_command( 'REXX', string, RXCOMM OR RXFF_STRING )
#endif
-> ---------------------------------------------------------------
->
-> sends command without swallowing any replies or waiting for anything
->
#ifdef NEED_commandQuick
EXPORT PROC commandQuick( host_name : PTR TO CHAR,
cmd_to_send : PTR TO CHAR ) OF rexxC
ENDPROC self.do_send_command_quick( host_name, cmd_to_send, RXCOMM )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_commandFileQuick
EXPORT PROC commandFileQuick( file_name : PTR TO CHAR ) OF rexxC
ENDPROC self.do_send_command_quick( 'AREXX', file_name, RXCOMM )
#endif
-> ---------------------------------------------------------------
->
-> executes 'string-file' without swallowing or waiting for reply
->
#ifdef NEED_commandStringQuick
EXPORT PROC commandStringQuick( string : PTR TO CHAR ) OF rexxC
ENDPROC self.do_send_command( 'AREXX', string, RXCOMM OR RXFF_STRING )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_commandToken
EXPORT PROC commandToken( host_name : PTR TO CHAR,
cmd_to_send : PTR TO CHAR ) OF rexxC
ENDPROC self.do_send_command( host_name, cmd_to_send, RXCOMM OR RXFF_TOKEN )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_commandFileToken
EXPORT PROC commandFileToken( file_name : PTR TO CHAR ) OF rexxC
DEF ret_val1,
ret_val2 : PTR TO CHAR,
ret_val3,
lock
lock := Lock( file_name, ACCESS_READ )
IF lock = NIL THEN RETURN RC_FATAL, NIL, DCC_NO_FILE
ret_val1, ret_val2, ret_val3 :=
self.do_send_command( 'REXX', file_name, RXCOMM OR RXFF_TOKEN )
UnLock( lock )
ENDPROC ret_val1, ret_val2, ret_val3
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_commandStringToken
EXPORT PROC stringToken( string : PTR TO CHAR ) OF rexxC
ENDPROC self.do_send_command( 'REXX', string,
RXCOMM OR RXFF_STRING OR RXFF_TOKEN )
#endif
-> ---------------------------------------------------------------
->
-> sends command without swallowing any replies or waiting for anything
->
#ifdef NEED_commandQuickToken
EXPORT PROC commandQuickToken( host_name : PTR TO CHAR,
cmd_to_send : PTR TO CHAR ) OF rexxC
ENDPROC self.do_send_command_quick( host_name,
cmd_to_send, RXCOMM OR RXFF_TOKEN )
#endif
-> ---------------------------------------------------------------
->
->
->
->
#ifdef NEED_fileQuickToken
EXPORT PROC fileQuickToken( file_name : PTR TO CHAR ) OF rexxC
DEF ret_val, lock
lock := Lock( file_name, ACCESS_READ )
IF lock = NIL THEN RETURN RC_FATAL, NIL, DCC_NO_FILE
ret_val :=
self.do_send_command_quick( 'AREXX', file_name, RXCOMM OR RXFF_TOKEN )
UnLock( lock )
ENDPROC ret_val
#endif
-> ---------------------------------------------------------------
->
-> executes 'string-file' without swallowing or waiting for reply
->
#ifdef NEED_commandStringQuickToken
EXPORT PROC commandStringQuickToken( string : PTR TO CHAR ) OF rexxC
ENDPROC self.do_send_command( 'AREXX', string,
RXCOMM OR RXFF_STRING OR RXFF_TOKEN )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_addServer
EXPORT PROC addServer( port_name, priority ) OF rexxC
ENDPROC self.do_send_misc( port_name, Bounds( priority, -100, 100 ),
0, 0, RXADDFH )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_addServerQuick
EXPORT PROC addServerQuick( port_name, priority ) OF rexxC
ENDPROC self.do_send_misc( port_name, Bounds( priority, -100, 100 ),
0, 0, RXADDFH OR RXFF_NONRET )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_addLibrary
EXPORT PROC addLibrary( library_name,
priority,
entry_point,
version_num ) OF rexxC IS
self.do_send_misc( library_name, Bounds( priority, -100, 100 ),
entry_point, version_num, RXADDLIB )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_addLibraryQuick
EXPORT PROC addLibraryQuick( library_name,
priority,
entry_point,
version_num ) OF rexxC IS
self.do_send_misc( library_name, Bounds( priority, -100, 100 ),
entry_point, version_num, RXADDLIB OR RXFF_NONRET )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_removeLibrary
EXPORT PROC removeLibrary( library_name ) OF rexxC IS
self.do_send_misc( library_name, 0, 0, 0, RXREMLIB )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_removeLibraryQuick
EXPORT PROC removeLibraryQuick( library_name ) OF rexxC IS
self.do_send_misc( library_name, 0, 0, 0, RXREMLIB )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_addClip
EXPORT PROC addClip( clip_name : PTR TO CHAR,
clip_value : PTR TO CHAR ) OF rexxC IS
self.do_send_misc( clip_name, clip_value, StrLen( clip_value), 0, RXADDFH )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_addClipQuick
EXPORT PROC addClipQuick( clip_name : PTR TO CHAR,
clip_value : PTR TO CHAR ) OF rexxC IS
self.do_send_misc( clip_name, clip_value, StrLen( clip_value),
0, RXADDCON OR RXFF_NONRET )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_removeClip
EXPORT PROC removeClip( clip_name : PTR TO CHAR ) OF rexxC IS
self.do_send_misc( clip_name, 0, 0, 0, RXREMCON )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_removeClipQuick
EXPORT PROC removeClipQuick( clip_name : PTR TO CHAR ) OF rexxC IS
self.do_send_misc( clip_name, 0, 0, 0, RXREMCON OR RXFF_NONRET )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_functionString
EXPORT PROC functionString( string : PTR TO CHAR ) OF rexxC IS
self.do_function_string( string, RXFF_RESULT OR RXFF_STRING )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_functionStringQuick
EXPORT PROC functionStringQuick( string : PTR TO CHAR ) OF rexxC IS
self.do_function_string( string, RXFF_STRING OR RXFF_NONRET )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_openGlobalConsole
EXPORT PROC openGlobalConsole() OF rexxC IS
self.do_send_misc( 0, 0, 0, 0, RXTCOPN )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_openGlobalConsoleQuick
EXPORT PROC openGlobalConsoleQuick() OF rexxC IS
self.do_send_misc( 0, 0, 0, 0, RXTCOPN OR RXFF_NONRET )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_closeGlobalConsole
EXPORT PROC closeGlobalConsole() OF rexxC IS
self.do_send_misc( 0, 0, 0, 0, RXTCCLS )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_closeGlobalConsoleQuick
EXPORT PROC closeGlobalConsoleQuick() OF rexxC IS
self.do_send_misc( 0, 0, 0, 0, RXTCCLS OR RXFF_NONRET )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_function
EXPORT PROC function( name : PTR TO CHAR,
arg_list = NIL : PTR TO LONG ) OF rexxC IS
self.do_send_function( name, arg_list, RXFF_RESULT )
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_functionQuick
EXPORT PROC functionQuick( name : PTR TO CHAR,
arg_list = NIL : PTR TO LONG ) OF rexxC IS
self.do_send_function( name, arg_list, RXFF_NONRET )
#endif
-> ====================== PRIVATE PROC'esses =======================
->
-> maybe someday it will produce a name based on task-name; but in fact
-> it's user's problem...
->
PROC fix_port_name() OF rexxC IS 'rexx_port'
-> ---------------------------------------------------------------
->
-> still should RETURN return-values for answers?!
->
#ifdef NEED_handle_incoming
PROC handle_incoming() OF rexxC
DEF rexx_msg : PTR TO rexxmsg,
rexx_args : PTR TO LONG,
result_1 = RC_FATAL : LONG,
result_2 = NIL : PTR TO CHAR
IF self.receiving_port = NIL THEN RETURN
WHILE rexx_msg := GetMsg( self.receiving_port )
IF IsRexxMsg( rexx_msg ) = FALSE THEN JUMP reset_them
rexx_args := rexx_msg.args
IF ( rexx_msg.action AND RXCODEMASK ) = RXCOMM
self.fLastTokenized := ( rexx_msg.action AND RXFF_TOKEN )
result_1, result_2 := self.command_executor( rexx_args[ 0 ] )
ELSE
IF rexx_msg.action AND RXFF_NONRET
self.free_message_all( rexx_msg )
JUMP reset_them
ENDIF
ENDIF
self.reply_message( rexx_msg, result_1, result_2 )
reset_them:
self.last_args := NIL
self.remaining_arg_len := 0
ENDWHILE
ENDPROC
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_reply_message
PROC reply_message( rexx_msg : PTR TO rexxmsg,
rc1 : LONG,
rc2 : PTR TO CHAR ) OF rexxC
rexx_msg.result1 := rc1
IF rexx_msg.action AND RXFF_RESULT
IF rc1 = RC_OK
IF rc2 <> NIL
rexx_msg.result2 := CreateArgstring( rc2, StrLen( rc2 ) )
IF rexx_msg.result2 = NIL
rexx_msg.result1 := RC_ERROR
rexx_msg.result2 := ERR10_003 -> 'no memory available'
ENDIF
ENDIF
ENDIF
ENDIF
ReplyMsg( rexx_msg )
ENDPROC
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_free_message_all
PROC free_message_all( rexx_msg : PTR TO rexxmsg ) OF rexxC
DEF rexx_args : PTR TO LONG
rexx_args := rexx_msg.args
IF rexx_args[ 0 ] <> NIL THEN DeleteArgstring( rexx_args[ 0 ] )
DeleteRexxMsg( rexx_msg )
ENDPROC
#endif
-> ---------------------------------------------------------------
->
-> calls appropriate callback if command matches argument
->
#ifdef NEED_command_executor
PROC command_executor( what : PTR TO CHAR ) OF rexxC
DEF ptr : PTR TO LONG,
callback_ptr : PTR TO LONG,
cb_ret_val = NIL : PTR TO LONG,
len,
top_addres,
command_len,
temp_ptr : PTR TO CHAR,
i = 0
ptr := self.com_callback_list
IF ptr = NIL THEN JUMP not_found
len := ListLen( ptr )
top_addres := ptr[ len ]
WHILE i < len
command_len := self.find_command( ^ptr, what )
IF command_len <> 0
ptr++
IF ptr > top_addres THEN JUMP not_found
IF ( callback_ptr := ^ptr ) = NIL THEN JUMP not_found
temp_ptr := what + command_len
TrimStr( temp_ptr )
self.last_args := TrimStr( temp_ptr )
self.remaining_arg_len := temp_ptr - what
cb_ret_val := callback_ptr()
RETURN RC_OK, cb_ret_val
ENDIF
ptr := ptr + 8 -> it is: 2 * ( SIZEOF LONG )
INC i; INC i
ENDWHILE
not_found:
ENDPROC RC_WARN, NIL
#endif
-> ---------------------------------------------------------------
->
-> compares arg 'command' (things like 'BEEP') with arg, returns
-> command-string-length
->
#ifdef NEED_find_command
PROC find_command( command : PTR TO CHAR,
string : PTR TO CHAR ) OF rexxC
DEF len
len := StrLen( command )
IF StrCmp( command, string, len ) THEN
RETURN len -> command FOUND OK! -- RETURN command-name length
ENDPROC 0 -> command NOT found! -- RETURN 0
#endif
-> ---------------------------------------------------------------
->
->
->
PROC create_port( port_name : PTR TO CHAR, priority ) OF rexxC
DEF port = NIL : PTR TO mp,
node = NIL : PTR TO ln
IF port_name = NIL THEN RETURN CreateMsgPort()
-> -----------------------------------------------------------
Forbid()
->
-> is the name of our port (in spe) unique?
->
IF FindPort( port_name ) = NIL
IF port := CreateMsgPort() -> could we create the port?
node := port.ln
node.name := port_name -> fill in the name
node.pri := priority -> public port priority
AddPort( port ) -> make this port public
ENDIF
ENDIF
Permit()
->
-> if no port at this point, it must be NOT-UNIQUE!
->
IF port = NIL THEN Throw( "rexx", EXI_PORT_NOT_UNIQUE )
ENDPROC port
-> ---------------------------------------------------------------
-> ---------------------------------------------------------------
-> ---------------------------------------------------------------
->
-> WAIT & swallow ALL replies; RETURN's self.unconfirmed_count;
-> breakable with ^C
->
#ifdef NEED_swallowReplies
PROC swallowReplies() OF rexxC
DEF rexx_msg = NIL : PTR TO rexxmsg,
signal_mask
IF self.unconfirmed_count = 0 THEN RETURN 0
WHILE self.unconfirmed_count > 0
signal_mask := Wait( self.send_signal_mask OR self.break_mask )
IF signal_mask AND self.break_mask THEN JUMP the_end
WHILE rexx_msg := GetMsg( self.sending_port )
IF rexx_msg.mn::mn.ln::ln.type = NT_REPLYMSG
IF self.we_want_reply( rexx_msg.args[ 15 ] )
self.unconfirmed_count := self.unconfirmed_count - 1
ENDIF
self.free_message_all( rexx_msg )
ENDIF
ENDWHILE
ENDWHILE
the_end:
ENDPROC self.unconfirmed_count
#endif
-> ---------------------------------------------------------------
->
-> swallows all replies that are ALREADY PRESENT;
-> RETURN's self.unconfirmed_count
->
#ifdef NEED_swallowRepliesQuick
PROC swallowRepliesQuick() OF rexxC
DEF rexx_msg = NIL : PTR TO rexxmsg
IF self.unconfirmed_count = 0 THEN RETURN 0
WHILE rexx_msg := GetMsg( self.sending_port )
IF rexx_msg.mn::mn.ln::ln.type = NT_REPLYMSG
IF self.we_want_reply( rexx_msg.args[ 15 ] )
self.unconfirmed_count := self.unconfirmed_count - 1
ENDIF
self.free_message_all( rexx_msg )
ENDIF
ENDWHILE
ENDPROC self.unconfirmed_count
#endif
-> ---------------------------------------------------------------
->
-> wait for ONLY ONE reply, and RETURN return-values
->
#ifdef NEED_handle_reply
PROC handle_reply() OF rexxC
DEF rexx_msg : PTR TO rexxmsg,
signal_mask, result_1
IF self.last_reply_argstr <> NIL THEN
DeleteArgstring( self.last_reply_argstr )
self.last_reply_argstr := NIL
signal_mask := Wait( self.send_signal_mask OR self.break_mask )
IF signal_mask AND self.break_mask THEN JUMP the_end_here
rexx_msg := GetMsg( self.sending_port )
IF rexx_msg.mn::mn.ln::ln.type = NT_REPLYMSG
result_1 := rexx_msg.result1
->
-> store reply-string only if it is really present!
->
IF ( rexx_msg.action AND RXFF_RESULT ) AND ( result_1 = RC_OK )
self.last_reply_argstr := rexx_msg.result2
ENDIF
IF self.we_want_reply( rexx_msg.args[ 15 ] )
self.unconfirmed_count := self.unconfirmed_count - 1
ENDIF
self.free_message_all( rexx_msg )
ENDIF
the_end_here:
ENDPROC result_1, self.last_reply_argstr
#endif
-> =================================================================
-> =================================================================
-> =================================================================
->
-> the error_value should be something like 0 for 'no error',
-> 1 for 'broken before reply come', 2 for 'not even sent', 3 for
-> 'host not found', 4 for 'not even all replies swallowed before sending'
->
#ifdef NEED_do_send_command
PROC do_send_command( host_name : PTR TO CHAR,
cmd_to_send : PTR TO CHAR,
my_actions ) OF rexxC
DEF arexx_port = NIL : PTR TO mp,
rexx_msg = NIL : PTR TO rexxmsg,
rexx_args : PTR TO LONG,
list_node = NIL : PTR TO ln,
temp_arg_str = NIL : PTR TO CHAR,
result_1 = RC_FATAL : LONG,
result_2 = NIL : PTR TO CHAR,
error_value = DCC_ABORTED_SWALLOWING
list_node := self.sending_port.ln
VOID self.swallowReplies()
IF self.unconfirmed_count > 0 THEN RETURN RC_FATAL, NIL, error_value
error_value := DCC_MSG_NOT_CREATED
rexx_msg := CreateRexxMsg( self.sending_port,
self.default_extension,
list_node.name )
IF rexx_msg = NIL THEN JUMP clean_up
rexx_args := rexx_msg.args
temp_arg_str := CreateArgstring( cmd_to_send, StrLen( cmd_to_send ) )
IF temp_arg_str = NIL THEN JUMP clean_up
rexx_args[ 0 ] := temp_arg_str
rexx_msg.action := RXFF_RESULT OR my_actions
rexx_msg.passport := self.pass_port
IF ( self.default_input <> NIL ) OR ( self.default_output <> NIL )
rexx_msg.stdin := self.default_input
rexx_msg.stdout := self.default_output
rexx_msg.action := rexx_msg.action OR MY_RXFF_NOIO
ENDIF
error_value := DCC_HOST_NOT_FOUND
Forbid()
->
-> send our message to the port if it exists
->
arexx_port := FindPort( host_name )
IF arexx_port <> NIL THEN PutMsg( arexx_port, rexx_msg )
Permit()
->
-> this is written in this way in order to have Permit() earlier
->
IF arexx_port <> NIL
error_value := DCC_GOT_NO_REPLY
self.unconfirmed_count := self.unconfirmed_count + 1
result_1, result_2 := self.handle_reply()
RETURN result_1, result_2, DCC_NO_ERROR
ENDIF
clean_up:
IF temp_arg_str <> NIL THEN DeleteArgstring( temp_arg_str )
DeleteRexxMsg( rexx_msg )
ENDPROC RC_FATAL, NIL, error_value
#endif
-> ---------------------------------------------------------------
->
-> the error_value probably should be something like 0 for 'no error',
-> 2 for 'not sent', 1 for 'broken before reply come'
->
#ifdef NEED_do_send_command_quick
PROC do_send_command_quick( host_name : PTR TO CHAR,
cmd_to_send : PTR TO CHAR,
my_actions ) OF rexxC
DEF arexx_port = NIL : PTR TO mp,
rexx_msg = NIL : PTR TO rexxmsg,
rexx_args : PTR TO LONG,
list_node = NIL : PTR TO ln,
temp_arg_str = NIL : PTR TO CHAR
list_node := self.sending_port.ln
rexx_msg := CreateRexxMsg( self.sending_port,
self.default_extension,
list_node.name )
IF rexx_msg = NIL THEN JUMP clean_after_error
rexx_args := rexx_msg.args
temp_arg_str := CreateArgstring( cmd_to_send, StrLen( cmd_to_send ) )
IF temp_arg_str = NIL THEN JUMP clean_after_error
rexx_args[ 0 ] := temp_arg_str
rexx_args[ 15 ] := { no_reply_string }
rexx_msg.action := my_actions
rexx_msg.passport := self.pass_port
IF ( self.default_input <> NIL ) OR ( self.default_output <> NIL )
rexx_msg.stdin := self.default_input
rexx_msg.stdout := self.default_output
rexx_msg.action := rexx_msg.action OR MY_RXFF_NOIO
ENDIF
self.swallowRepliesQuick()
Forbid()
->
-> send our message to the port if it exists
->
IF ( arexx_port := FindPort( host_name ) ) <> NIL THEN
PutMsg( arexx_port, rexx_msg )
Permit()
IF arexx_port <> NIL THEN RETURN RC_OK
clean_after_error:
IF temp_arg_str <> NIL THEN DeleteArgstring( temp_arg_str )
DeleteRexxMsg( rexx_msg )
ENDPROC RC_FATAL
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_do_send_misc
PROC do_send_misc( arg_0, arg_1, arg_2, arg_3, my_action ) OF rexxC
DEF arexx_port = NIL : PTR TO mp,
rexx_msg = NIL : PTR TO rexxmsg,
rexx_args : PTR TO LONG,
list_node = NIL : PTR TO ln,
temp_arg_str = NIL : PTR TO CHAR,
result_1 = RC_FATAL : LONG,
result_2 = NIL : PTR TO CHAR,
error_value = DCC_ABORTED_SWALLOWING
list_node := self.sending_port.ln
IF my_action AND RXFF_NONRET
self.swallowRepliesQuick()
ELSE
VOID self.swallowReplies()
IF self.unconfirmed_count > 0 THEN RETURN RC_FATAL, NIL, error_value
ENDIF
error_value := DCC_MSG_NOT_CREATED
rexx_msg := CreateRexxMsg( self.sending_port,
self.default_extension,
list_node.name )
IF rexx_msg = NIL THEN JUMP clean_me_up
rexx_args := rexx_msg.args
temp_arg_str := CreateArgstring( arg_0, StrLen( arg_0 ) )
IF temp_arg_str = NIL THEN JUMP clean_me_up
rexx_args[ 0 ] := temp_arg_str
rexx_msg.action := my_action
rexx_args[ 1 ] := arg_1
rexx_args[ 2 ] := arg_2
rexx_args[ 3 ] := arg_3
IF my_action AND RXFF_NONRET THEN
rexx_args[ 15 ] := CreateArgstring( { no_reply_string },
StrLen( { no_reply_string } ) )
error_value := DCC_HOST_NOT_FOUND
Forbid()
->
-> send our message to the port if it exists
->
arexx_port := FindPort( 'REXX' )
IF arexx_port <> NIL THEN PutMsg( arexx_port, rexx_msg )
Permit()
->
-> this is written in this way in order to have Permit() earlier
->
IF arexx_port <> NIL
error_value := DCC_GOT_NO_REPLY
IF ( my_action AND RXFF_NONRET ) = FALSE
self.unconfirmed_count := self.unconfirmed_count + 1
result_1, result_2 := self.handle_reply()
RETURN result_1, result_2, DCC_NO_ERROR
ELSE
DeleteArgstring( temp_arg_str )
RETURN RC_OK, NIL, DCC_NO_ERROR -> but nothing replied
ENDIF
ENDIF
clean_me_up:
DeleteRexxMsg( rexx_msg )
ENDPROC result_1, NIL, error_value
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_do_send_function
PROC do_send_function( func_name : PTR TO CHAR,
func_args : PTR TO LONG,
modifiers ) OF rexxC
DEF arexx_port = NIL : PTR TO mp,
rexx_msg = NIL : PTR TO rexxmsg,
rexx_args : PTR TO LONG,
list_node = NIL : PTR TO ln,
result_1 = RC_FATAL : LONG,
result_2 = NIL : PTR TO CHAR,
error_value = DCC_ABORTED_SWALLOWING,
list_len = 0,
temp_str = NIL : PTR TO CHAR,
i
list_node := self.sending_port.ln
IF modifiers AND RXFF_NONRET
self.swallowRepliesQuick()
ELSE
VOID self.swallowReplies()
IF self.unconfirmed_count > 0 THEN RETURN RC_FATAL, NIL, error_value
ENDIF
error_value := DCC_MSG_NOT_CREATED
rexx_msg := CreateRexxMsg( self.sending_port,
self.default_extension,
list_node.name )
IF rexx_msg = NIL THEN JUMP clean_me_please
rexx_args := rexx_msg.args
-> -------------------------------------------------
rexx_args[ 0 ] := CreateArgstring( func_name, StrLen( func_name ) )
IF modifiers AND RXFF_NONRET THEN rexx_args[ 15 ] :=
CreateArgstring( { no_reply_string },
StrLen( { no_reply_string } ) )
IF func_args <> NIL
list_len := Bounds( ListLen( func_args ), 0, 13 )
FOR i := 0 TO list_len - 1
temp_str := func_args[ i ]
rexx_args[ i + 1 ] := CreateArgstring( temp_str, StrLen( temp_str ) )
ENDFOR
ENDIF
rexx_msg.action := ( modifiers OR RXFUNC ) AND Not( $FF )
IF modifiers AND RXFF_NONRET
rexx_msg.action := rexx_msg.action OR 15
ELSE
rexx_msg.action := rexx_msg.action OR list_len -> arg # into low byte
ENDIF
IF FillRexxMsg( rexx_msg, 16, 0 ) = FALSE THEN JUMP clean_me_please
->
-> fix I/O
->
IF ( self.default_input <> NIL ) OR ( self.default_output <> NIL )
rexx_msg.stdin := self.default_input
rexx_msg.stdout := self.default_output
rexx_msg.action := rexx_msg.action OR MY_RXFF_NOIO
ENDIF
error_value := DCC_HOST_NOT_FOUND
Forbid()
->
-> send our message to the port if it exists
->
arexx_port := FindPort( 'REXX' )
IF arexx_port <> NIL THEN PutMsg( arexx_port, rexx_msg )
Permit()
->
-> this is written in this way in order to have Permit() earlier
->
IF arexx_port <> NIL
error_value := DCC_GOT_NO_REPLY
IF ( modifiers AND RXFF_NONRET ) = FALSE
self.unconfirmed_count := self.unconfirmed_count + 1
result_1, result_2 := self.handle_reply()
RETURN result_1, result_2, DCC_NO_ERROR
ELSE -> it's RXFF_NONRET
RETURN RC_OK, NIL, DCC_NO_ERROR -> but nothing replied
ENDIF
ENDIF
ClearRexxMsg( rexx_msg, 16 )
DeleteRexxMsg( rexx_msg )
ENDPROC result_1, result_2, error_value
#endif
-> ---------------------------------------------------------------
->
->
->
#ifdef NEED_do_function_string
PROC do_function_string( string : PTR TO CHAR, modifiers ) OF rexxC
DEF arexx_port = NIL : PTR TO mp,
rexx_msg = NIL : PTR TO rexxmsg,
rexx_args : PTR TO LONG,
list_node = NIL : PTR TO ln,
result_1 = RC_FATAL : LONG,
result_2 = NIL : PTR TO CHAR,
error_value = DCC_ABORTED_SWALLOWING
list_node := self.sending_port.ln
IF modifiers AND RXFF_NONRET
self.swallowRepliesQuick()
ELSE
VOID self.swallowReplies()
IF self.unconfirmed_count > 0 THEN RETURN RC_FATAL, NIL, error_value
ENDIF
error_value := DCC_MSG_NOT_CREATED
rexx_msg := CreateRexxMsg( self.sending_port,
self.default_extension,
list_node.name )
IF rexx_msg = NIL THEN JUMP clean_me_please
rexx_args := rexx_msg.args
-> -------------------------------------------------
rexx_args[ 0 ] := CreateArgstring( string, StrLen( string ) )
IF modifiers AND RXFF_NONRET THEN
rexx_args[ 15 ] := CreateArgstring( { no_reply_string },
StrLen( { no_reply_string } ) )
->
-> put 0 as # of arguments in the lowest byte of rexx_msg.action
->
rexx_msg.action := ( modifiers OR RXFUNC ) AND Not( $FF )
IF FillRexxMsg( rexx_msg, 1, 0 ) = FALSE THEN JUMP clean_me_please
->
-> fix default I/O
->
IF ( self.default_input <> NIL ) OR ( self.default_output <> NIL )
rexx_msg.stdin := self.default_input
rexx_msg.stdout := self.default_output
rexx_msg.action := rexx_msg.action OR MY_RXFF_NOIO
ENDIF
error_value := DCC_HOST_NOT_FOUND
Forbid()
->
-> send our message to the port if it exists
->
arexx_port := FindPort( 'REXX' )
IF arexx_port <> NIL THEN PutMsg( arexx_port, rexx_msg )
Permit()
->
-> this is written in this way in order to have Permit() earlier
->
IF arexx_port <> NIL
error_value := DCC_GOT_NO_REPLY
IF ( modifiers AND RXFF_NONRET ) = FALSE
self.unconfirmed_count := self.unconfirmed_count + 1
result_1, result_2 := self.handle_reply()
RETURN result_1, result_2, DCC_NO_ERROR
ELSE
RETURN RC_OK, NIL, DCC_NO_ERROR -> but nothing replied
ENDIF
ENDIF
clean_me_please:
ClearRexxMsg( rexx_msg, 16 )
DeleteRexxMsg( rexx_msg )
ENDPROC result_1, result_2, error_value
#endif
-> ---------------------------------------------------------------
->
-> takes args[ 15 ] ! ! ! !
->
#ifdef NEED_we_want_reply
PROC we_want_reply( str : PTR TO CHAR ) OF rexxC IS
Not( StrCmp( str, { no_reply_string } ) )
#endif
-> ---------------------------------------------------------------
no_reply_string:
CHAR '« NO REPLY! »'
-> =============== the is the end ================