- add a socket timeout\r
-- don't allow multiple reads on the same port\r
- (and don't hang when this happends!)\r
- >lower, >upper for strings\r
- telnetd should use multitasking\r
- accept multi-line input in listener\r
+ listener/plugin:\r
\r
- plugin should not exit jEdit on fatal errors\r
-- make inferior.factor nicer to use\r
- auto insert USE:\r
- balance needs USE:\r
- fedit broken with listener\r
IN: inferior
USE: combinators
USE: errors
+USE: interpreter
USE: kernel
USE: lists
+USE: logic
USE: namespaces
USE: parser
USE: prettyprint
dup str-length write-big-endian-32
write ;
+: inferior-server-flush ( -- )
+ CHAR: f write flush ;
+
: <inferior-server-stream> ( stream -- stream )
<extend-stream> [
( -- str )
[
"\n" cat2 default-style inferior-server-write-attr
] "fprint" set
+ ( -- )
+ [ inferior-server-flush ] "fflush" set
] extend ;
: inferior-client-read ( stream -- ? )
: inferior-client-packet ( stream -- ? )
#! Read from an inferior client socket and print attributed
#! strings that were read to standard output.
- read1 dup CHAR: r = [
- drop inferior-client-read
- ] [
- dup CHAR: w = [
- drop inferior-client-write
- ] [
- "Invalid packet type: " swap cat2 throw
- ] ifte
- ] ifte ;
+ read1 [
+ [ not ] [ 2drop f ( EOF ) ]
+ [ CHAR: r = ] [ drop inferior-client-read ]
+ [ CHAR: w = ] [ drop inferior-client-write ]
+ [ CHAR: f = ] [ drop fflush t ]
+ [ drop t ] [ "Invalid packet type: " swap cat2 throw ]
+ ] cond ;
: inferior-client-loop ( stream -- )
#! The stream is the stream to write to.
drop
] ifte ;
+: inferior-server ( -- )
+ #! Execute this in the inferior Factor.
+ terpri
+ "inferior-ack" print flush
+ "stdio" get <inferior-server-stream> "stdio" set ;
+
+: inferior-read-ack ( -- )
+ read [
+ "inferior-ack" = [ inferior-read-ack ] unless
+ ] when* ;
+
: inferior-client ( from -- )
- "stdio" get swap [ inferior-client-loop ] with-stream ;
+ #! Execute this in the superior Factor, with a socket to
+ #! the inferior Factor as a parameter.
+ "stdio" get swap [
+ "USE: inferior inferior-server" print flush
+ inferior-read-ack
+ inferior-client-loop
+ ] with-stream ;
"quit-flag" on ;
: eval-catch ( str -- )
- [ eval ] [ default-error-handler ] catch ;
+ [ eval ] [ [ default-error-handler drop ] when* ] catch ;
: interpret ( -- )
print-prompt read dup [
[ ] "java.io.EOFException" jnew ;
: >char/eof ( ch -- ch )
- dup -1 = [ <eof-exception> throw ] [ >char ] ifte ;
+ dup -1 = [ drop f ] [ >char ] ifte ;
: <byte-stream>/fread1 ( -- string )
"in" get [ ] "java.io.InputStream" "read" jinvoke
: expired-port-error ( obj -- )
"Expired port: " write . ;
+: io-task-twice-error ( obj -- )
+ "Attempting to perform two simultaneous I/O operations on "
+ write . ;
+
+: no-io-tasks-error ( obj -- )
+ "No I/O tasks" print ;
+
: undefined-word-error ( obj -- )
"Undefined word: " write . ;
+: incompatible-port-error ( obj -- )
+ "Unsuitable port for operation: " write . ;
+
+: io-error ( list -- )
+ "I/O error in kernel function " write
+ unswons write ": " write car print ;
+
: type-check-error ( list -- )
"Type check error" print
uncons car dup "Object: " write .
uncons car "Maximum index: " write .
"Requested index: " write . ;
-: io-error ( list -- )
- "I/O error in kernel function " write
- unswons write ": " write car print ;
-
: numerical-comparison-error ( list -- )
"Cannot compare " write unswons unparse write
" with " write unparse print ;
: signal-error ( obj -- )
"Operating system signal " write . ;
-: io-task-twice-error ( obj -- )
- "Attempting to perform two simulatenous I/O operations on "
- write . ;
-
-: no-io-tasks-error ( obj -- )
- "No I/O tasks" print ;
-
: profiling-disabled-error ( obj -- )
drop "Recompile with the EXTRA_CALL_INFO flag." print ;
: kernel-error. ( obj n -- str )
{
expired-port-error
+ io-task-twice-error
+ no-io-tasks-error
+ incompatible-port-error
+ io-error
undefined-word-error
type-check-error
array-range-error
- io-error
numerical-comparison-error
float-format-error
signal-error
- io-task-twice-error
- no-io-tasks-error
profiling-disabled-error
} vector-nth execute ;
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
IN: streams
+USE: combinators
USE: errors
USE: kernel
USE: namespaces
( -- string )
[ "freadln not implemented." throw ] "freadln" set
( -- string )
- [ 1 namespace fread# 0 swap str-nth ] "fread1" set
+ [
+ 1 namespace fread# dup f-or-"" [
+ 0 swap str-nth
+ ] unless
+ ] "fread1" set
( count -- string )
[ "fread# not implemented." throw ] "fread#" set
( string -- )
#define ERROR_PORT_EXPIRED (0<<3)
-#define ERROR_UNDEFINED_WORD (1<<3)
-#define ERROR_TYPE (2<<3)
-#define ERROR_RANGE (3<<3)
+#define ERROR_IO_TASK_TWICE (1<<3)
+#define ERROR_IO_TASK_NONE (2<<3)
+#define ERROR_INCOMPATIBLE_PORT (3<<3)
#define ERROR_IO (4<<3)
-#define ERROR_INCOMPARABLE (5<<3)
-#define ERROR_FLOAT_FORMAT (6<<3)
-#define ERROR_SIGNAL (7<<3)
-#define ERROR_IO_TASK_TWICE (8<<3)
-#define ERROR_IO_TASK_NONE (9<<3)
-#define ERROR_PROFILING_DISABLED (10<<3)
+#define ERROR_UNDEFINED_WORD (5<<3)
+#define ERROR_TYPE (6<<3)
+#define ERROR_RANGE (7<<3)
+#define ERROR_INCOMPARABLE (8<<3)
+#define ERROR_FLOAT_FORMAT (9<<3)
+#define ERROR_SIGNAL (10<<3)
+#define ERROR_PROFILING_DISABLED (11<<3)
void fatal_error(char* msg, CELL tagged);
void critical_error(char* msg, CELL tagged);
{
pending_io_error(port);
+ if(port->type != PORT_READ && port->type != PORT_RECV)
+ general_error(ERROR_INCOMPATIBLE_PORT,port);
+
if(port->line_ready)
return true;
else
{
pending_io_error(port);
+ if(port->type != PORT_READ && port->type != PORT_RECV)
+ general_error(ERROR_INCOMPATIBLE_PORT,port);
+
if(port->line != F && CAN_READ_COUNT(port,count))
return true;
else
pending_io_error(port);
+ if(port->type != PORT_WRITE)
+ general_error(ERROR_INCOMPATIBLE_PORT,tag_object(port));
+
switch(port->type)
{
case PORT_READ: