From 2c5413cec5f5db73c6976a48cc0ee86a9dfc2ae1 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sat, 21 Aug 2004 01:16:47 +0000 Subject: [PATCH] fix redirect headers, postpone i/o errors until calling operation recovers them --- TODO.FACTOR.txt | 7 +---- actions.xml | 4 +-- factor/jedit/FactorCompletion.java | 4 +-- factor/jedit/FactorPlugin.props | 4 +-- factor/jedit/FactorSideKickParser.java | 13 ++++++++++ factor/jedit/factor.bsh | 2 +- library/httpd/responder.factor | 4 ++- library/platform/native/debugger.factor | 2 ++ library/test/crashes.factor | 6 +++-- native/error.c | 11 -------- native/error.h | 3 ++- native/io.c | 4 +-- native/port.c | 34 +++++++++++++++++++++++++ native/port.h | 6 +++++ native/read.c | 20 ++++++++++++--- native/run.c | 3 +++ native/write.c | 12 +++++++-- 17 files changed, 104 insertions(+), 35 deletions(-) diff --git a/TODO.FACTOR.txt b/TODO.FACTOR.txt index 7026b3f722..8ca9c38729 100644 --- a/TODO.FACTOR.txt +++ b/TODO.FACTOR.txt @@ -3,18 +3,13 @@ - maple-like: press enter at old commands to evaluate there - standalone listener input style - add a socket timeout -- drop test in http server - jedit bug? +line doesn't always work when switching into an existing buffer with a remembered first line -- jedit bug? ' in noWordSep ignored -- word names containing ' not quoted properly -- completion: enter no good -- completion: don't show automatically - balance needs USE: -- postpone errors until actual read/write op - command line arguments - socket protocol - irc: stack underflow? +- ignore SIGPIPE + docs: diff --git a/actions.xml b/actions.xml index ab3a1339a8..fd4a7f20a3 100644 --- a/actions.xml +++ b/actions.xml @@ -18,7 +18,7 @@ VFSManager.waitForRequests(); factorEval(view, "\"" - + MiscUtilities.charsToEscapes(buffer.path) + + factor.FactorReader.charsToEscapes(buffer.path) + "\" run-file"); @@ -28,7 +28,7 @@ textArea.selectWord(); factorEval(view, "\"" - + MiscUtilities.charsToEscapes( + + factor.FactorReader.charsToEscapes( textArea.selectedText) + "\" apropos."); diff --git a/factor/jedit/FactorCompletion.java b/factor/jedit/FactorCompletion.java index 2e4bd35898..0b025a13f7 100644 --- a/factor/jedit/FactorCompletion.java +++ b/factor/jedit/FactorCompletion.java @@ -56,7 +56,7 @@ public class FactorCompletion extends SideKickCompletion public String getLongestPrefix() { - return ""; + return MiscUtilities.getLongestPrefix(items,false); } public void insert(int index) @@ -78,7 +78,7 @@ public class FactorCompletion extends SideKickCompletion public boolean handleKeystroke(int selectedIndex, char keyChar) { - if(keyChar == '\t') + if(keyChar == '\t' || keyChar == '\n') insert(selectedIndex); else { diff --git a/factor/jedit/FactorPlugin.props b/factor/jedit/FactorPlugin.props index 435a991019..b981d27ab8 100644 --- a/factor/jedit/FactorPlugin.props +++ b/factor/jedit/FactorPlugin.props @@ -3,13 +3,13 @@ plugin.factor.jedit.FactorPlugin.activate=defer plugin.factor.jedit.FactorPlugin.name=Factor -plugin.factor.jedit.FactorPlugin.version=0.63 +plugin.factor.jedit.FactorPlugin.version=0.64 plugin.factor.jedit.FactorPlugin.author=Slava Pestov plugin.factor.jedit.FactorPlugin.docs=/doc/plugin.html plugin.factor.jedit.FactorPlugin.depend.0=jedit 04.02.15.00 plugin.factor.jedit.FactorPlugin.depend.1=plugin errorlist.ErrorListPlugin 1.3.2 -plugin.factor.jedit.FactorPlugin.depend.2=plugin sidekick.SideKickPlugin 0.3 +plugin.factor.jedit.FactorPlugin.depend.2=plugin sidekick.SideKickPlugin 0.3.1 plugin.factor.jedit.FactorPlugin.menu=factor \ - \ diff --git a/factor/jedit/FactorSideKickParser.java b/factor/jedit/FactorSideKickParser.java index 6988cf0b1a..4528798779 100644 --- a/factor/jedit/FactorSideKickParser.java +++ b/factor/jedit/FactorSideKickParser.java @@ -168,6 +168,19 @@ public class FactorSideKickParser extends SideKickParser == ReadTable.WHITESPACE); } //}}} + //{{{ canCompleteAnywhere() method + /** + * Returns if completion popups should be shown after any period of + * inactivity. Otherwise, they are only shown if explicitly requested + * by the user. + * + * Returns false by default. + */ + public boolean canCompleteAnywhere() + { + return false; + } //}}} + //{{{ complete() method /** * Returns completions suitable for insertion at the specified position. diff --git a/factor/jedit/factor.bsh b/factor/jedit/factor.bsh index da21364190..3dc16a461d 100644 --- a/factor/jedit/factor.bsh +++ b/factor/jedit/factor.bsh @@ -13,7 +13,7 @@ factorWord(view) if(textArea.selectionCount == 0) textArea.selectWord(); return "\"" - + MiscUtilities.charsToEscapes(textArea.selectedText) + + factor.FactorReader.charsToEscapes(textArea.selectedText) + "\" " + factor.FactorReader.unparseObject(data.use) + " search"; } diff --git a/library/httpd/responder.factor b/library/httpd/responder.factor index 51431fb425..70cc47e354 100644 --- a/library/httpd/responder.factor +++ b/library/httpd/responder.factor @@ -60,7 +60,9 @@ USE: httpd : redirect ( to -- ) "301 Moved Permanently" "text/plain" response write - "Location: " write print ; + "Location: " write write + terpri terpri + "The resource has moved." print ; : get-responder ( name -- responder ) "httpd-responders" get get* ; diff --git a/library/platform/native/debugger.factor b/library/platform/native/debugger.factor index 5396d3e8f3..150dda66af 100644 --- a/library/platform/native/debugger.factor +++ b/library/platform/native/debugger.factor @@ -62,6 +62,8 @@ USE: vectors "Incomparable types: " "Float format: " "Signal " + "Adding I/O task twice on port: " + "No I/O tasks" } ?vector-nth ; : ?kernel-error ( cons -- error# param ) diff --git a/library/test/crashes.factor b/library/test/crashes.factor index c0148bf29a..d32f00ad01 100644 --- a/library/test/crashes.factor +++ b/library/test/crashes.factor @@ -14,5 +14,7 @@ USE: test "20 \"foo\" set" eval "garbage-collection" eval -[ drop ] [ drop ] catch -[ drop ] [ drop ] catch +[ + [ drop ] [ drop ] catch + [ drop ] [ drop ] catch +] keep-datastack diff --git a/native/error.c b/native/error.c index 1a827b3a29..faf68fdf62 100644 --- a/native/error.c +++ b/native/error.c @@ -59,14 +59,3 @@ void range_error(CELL tagged, CELL index, CELL max) tag_cons(cons(tag_fixnum(max),F))))); general_error(ERROR_RANGE,tag_cons(c)); } - -void io_error(const char* func) -{ - STRING* function = from_c_string(func); - STRING* error = from_c_string(strerror(errno)); - - CONS* c = cons(tag_object(function),tag_cons( - cons(tag_object(error),F))); - - general_error(ERROR_IO,tag_cons(c)); -} diff --git a/native/error.h b/native/error.h index ffd90b7e3d..5d6b0878b9 100644 --- a/native/error.h +++ b/native/error.h @@ -8,6 +8,8 @@ #define ERROR_INCOMPARABLE (7<<3) #define ERROR_FLOAT_FORMAT (8<<3) #define ERROR_SIGNAL (9<<3) +#define ERROR_IO_TASK_TWICE (10<<3) +#define ERROR_IO_TASK_NONE (11<<3) void fatal_error(char* msg, CELL tagged); void critical_error(char* msg, CELL tagged); @@ -16,4 +18,3 @@ void throw_error(CELL object); void general_error(CELL error, CELL tagged); void type_error(CELL type, CELL tagged); void range_error(CELL tagged, CELL index, CELL max); -void io_error(const char* func); diff --git a/native/io.c b/native/io.c index d432c1c9b9..52efb1694b 100644 --- a/native/io.c +++ b/native/io.c @@ -34,7 +34,7 @@ IO_TASK* add_io_task( int fd = port->fd; if(io_tasks[fd].port != F) - critical_error("Adding I/O task twice",fd); + general_error(ERROR_IO_TASK_TWICE,tag_object(port)); io_tasks[fd].type = type; io_tasks[fd].port = tag_object(port); @@ -193,7 +193,7 @@ CELL next_io_task(void) write_fd_count,write_io_tasks); if(!reading && !writing) - critical_error("next_io_task() called with no IO tasks",0); + general_error(ERROR_IO_TASK_NONE,F); set_up_fd_set(&except_fd_set, read_fd_count,read_io_tasks); diff --git a/native/port.c b/native/port.c index 61a7f41bb5..242976adef 100644 --- a/native/port.c +++ b/native/port.c @@ -25,6 +25,7 @@ PORT* port(PORT_MODE type, CELL fd) port->line_ready = false; port->buf_fill = 0; port->buf_pos = 0; + port->io_error = F; if(type == PORT_SPECIAL) port->buffer = NULL; @@ -58,6 +59,7 @@ void fixup_port(PORT* port) fixup(&port->line); fixup(&port->client_host); fixup(&port->client_port); + fixup(&port->io_error); } void collect_port(PORT* port) @@ -67,4 +69,36 @@ void collect_port(PORT* port) copy_object(&port->line); copy_object(&port->client_host); copy_object(&port->client_port); + copy_object(&port->io_error); +} + +CELL make_io_error(const char* func) +{ + STRING* function = from_c_string(func); + STRING* error = from_c_string(strerror(errno)); + + CONS* c = cons(tag_object(function),tag_cons( + cons(tag_object(error),F))); + + return tag_cons(c); +} + +void postpone_io_error(PORT* port, const char* func) +{ + port->io_error = make_io_error(func); +} + +void io_error(const char* func) +{ + general_error(ERROR_IO,make_io_error(func)); +} + +void pending_io_error(PORT* port) +{ + CELL io_error = port->io_error; + if(io_error != F) + { + port->io_error = F; + general_error(ERROR_IO,io_error); + } } diff --git a/native/port.h b/native/port.h index b0ea0c3ded..3553a037aa 100644 --- a/native/port.h +++ b/native/port.h @@ -28,6 +28,9 @@ typedef struct { CELL client_port; /* untagged fd of accepted connection */ CELL client_socket; + + /* a pending I/O error or F */ + CELL io_error; } PORT; PORT* untag_port(CELL tagged); @@ -36,3 +39,6 @@ void init_line_buffer(PORT* port, FIXNUM count); void primitive_portp(void); void fixup_port(PORT* port); void collect_port(PORT* port); +void postpone_io_error(PORT* port, const char* func); +void io_error(const char* func); +void pending_io_error(PORT* port); diff --git a/native/read.c b/native/read.c index 0229f06d27..fce806544b 100644 --- a/native/read.c +++ b/native/read.c @@ -3,7 +3,7 @@ /* Return true if something was read */ bool read_step(PORT* port) { - FIXNUM amount = 0; + FIXNUM amount = 0; if(port->type == PORT_RECV) { @@ -24,8 +24,12 @@ bool read_step(PORT* port) if(amount < 0) { if(errno != EAGAIN) - io_error(__FUNCTION__); - return false; + { + postpone_io_error(port,__FUNCTION__); + return true; + } + else + return false; } else { @@ -76,6 +80,8 @@ bool read_line_step(PORT* port) bool can_read_line(PORT* port) { + pending_io_error(port); + if(port->line_ready) return true; else @@ -133,6 +139,9 @@ bool perform_read_line_io_task(PORT* port) void primitive_read_line_8(void) { PORT* port = untag_port(dpeek()); + + pending_io_error(port); + if(port->line_ready) { drepl(port->line); @@ -170,6 +179,8 @@ bool read_count_step(PORT* port) bool can_read_count(PORT* port, FIXNUM count) { + pending_io_error(port); + if(port->line != F && CAN_READ_COUNT(port,count)) return true; else @@ -222,6 +233,9 @@ void primitive_read_count_8(void) FIXNUM len = to_fixnum(dpop()); if(port->count != len) critical_error("read# counts don't match",port); + + pending_io_error(port); + dpush(port->line); port->line = F; port->line_ready = false; diff --git a/native/run.c b/native/run.c index 8fdffdd4ab..5c2544cb8c 100644 --- a/native/run.c +++ b/native/run.c @@ -8,8 +8,11 @@ void signal_handler(int signal, siginfo_t* siginfo, void* uap) void init_signals(void) { struct sigaction custom_sigaction; + struct sigaction ign_sigaction; custom_sigaction.sa_sigaction = signal_handler; custom_sigaction.sa_flags = SA_SIGINFO; + ign_sigaction.sa_handler = SIG_IGN; + ign_sigaction.sa_flags = 0; sigaction(SIGABRT,&custom_sigaction,NULL); sigaction(SIGFPE,&custom_sigaction,NULL); sigaction(SIGBUS,&custom_sigaction,NULL); diff --git a/native/write.c b/native/write.c index 4e9a40f6e9..ec0d7ad905 100644 --- a/native/write.c +++ b/native/write.c @@ -11,8 +11,12 @@ bool write_step(PORT* port) if(amount == -1) { if(errno != EAGAIN) - io_error(__FUNCTION__); - return false; + { + postpone_io_error(port,__FUNCTION__); + return true; + } + else + return false; } else { @@ -25,6 +29,8 @@ bool can_write(PORT* port, FIXNUM len) { CELL buf_capacity; + pending_io_error(port); + switch(port->type) { case PORT_READ: @@ -111,6 +117,8 @@ void primitive_write_8(void) CELL text = dpop(); CELL type = type_of(text); + pending_io_error(port); + switch(type) { case FIXNUM_TYPE: