From a979e6ffcf76ab2ed71a66d3bb32a12cbb3f312e Mon Sep 17 00:00:00 2001 From: Alex Shinn Date: Sat, 19 May 2012 07:52:17 +0900 Subject: [PATCH] bugfix for reading non-ascii chars --- include/chibi/sexp.h | 2 +- lib/chibi/io/port.c | 40 ++++++++++++++++++++++++---------------- lib/srfi/18/threads.c | 2 +- sexp.c | 8 ++++---- 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/include/chibi/sexp.h b/include/chibi/sexp.h index e6693076..9b1e16a3 100755 --- a/include/chibi/sexp.h +++ b/include/chibi/sexp.h @@ -1239,7 +1239,7 @@ enum sexp_context_globals { #else -#define sexp_read_char(x, p) (sexp_port_buf(p) ? ((sexp_port_offset(p) < sexp_port_size(p)) ? sexp_port_buf(p)[sexp_port_offset(p)++] : sexp_buffered_read_char(x, p)) : getc(sexp_port_stream(p))) +#define sexp_read_char(x, p) (sexp_port_buf(p) ? ((sexp_port_offset(p) < sexp_port_size(p)) ? ((unsigned char*)sexp_port_buf(p))[sexp_port_offset(p)++] : sexp_buffered_read_char(x, p)) : getc(sexp_port_stream(p))) #define sexp_push_char(x, c, p) ((c!=EOF) && (sexp_port_buf(p) ? (sexp_port_buf(p)[--sexp_port_offset(p)] = ((char)(c))) : ungetc(c, sexp_port_stream(p)))) #define sexp_write_char(x, c, p) (sexp_port_buf(p) ? ((sexp_port_offset(p) < sexp_port_size(p)) ? ((((sexp_port_buf(p))[sexp_port_offset(p)++]) = (char)(c)), 0) : sexp_buffered_write_char(x, c, p)) : putc(c, sexp_port_stream(p))) #define sexp_write_string(x, s, p) (sexp_port_buf(p) ? sexp_buffered_write_string(x, s, p) : fputs(s, sexp_port_stream(p))) diff --git a/lib/chibi/io/port.c b/lib/chibi/io/port.c index 4f546053..53b57f19 100644 --- a/lib/chibi/io/port.c +++ b/lib/chibi/io/port.c @@ -329,8 +329,20 @@ sexp sexp_write_u8 (sexp ctx, sexp self, sexp u8, sexp out) { sexp_assert_type(ctx, sexp_oportp, SEXP_OPORT, out); if (!sexp_port_binaryp(out)) return sexp_xtype_exception(ctx, self, "not a binary port", out); - if (sexp_write_char(ctx, sexp_unbox_fixnum(u8), out) == EOF) - return sexp_global(ctx, SEXP_G_IO_BLOCK_ERROR); +#if SEXP_USE_GREEN_THREADS + errno = 0; +#endif + if (sexp_write_char(ctx, sexp_unbox_fixnum(u8), out) == EOF) { + if (sexp_port_stream(out)) + clearerr(sexp_port_stream(out)); +#if SEXP_USE_GREEN_THREADS + if ((errno == EAGAIN) + && sexp_applicablep(sexp_global(ctx, SEXP_G_THREADS_BLOCKER))) { + sexp_apply1(ctx, sexp_global(ctx, SEXP_G_THREADS_BLOCKER), out); + return sexp_global(ctx, SEXP_G_IO_BLOCK_ERROR); + } +#endif + } return SEXP_VOID; } @@ -343,27 +355,23 @@ sexp sexp_read_u8 (sexp ctx, sexp self, sexp in) { errno = 0; #endif c = sexp_read_char(ctx, in); - if (c == EOF) { #if SEXP_USE_GREEN_THREADS - if ((sexp_port_stream(in) ? ferror(sexp_port_stream(in)) : 1) - && (errno == EAGAIN) - && sexp_applicablep(sexp_global(ctx, SEXP_G_THREADS_BLOCKER))) { - if (sexp_port_stream(in)) - clearerr(sexp_port_stream(in)); - sexp_apply1(ctx, sexp_global(ctx, SEXP_G_THREADS_BLOCKER), in); - return sexp_global(ctx, SEXP_G_IO_BLOCK_ERROR); - } -#endif - return SEXP_EOF; + if ((c == EOF) + && (errno == EAGAIN) + && sexp_applicablep(sexp_global(ctx, SEXP_G_THREADS_BLOCKER))) { + if (sexp_port_stream(in)) + clearerr(sexp_port_stream(in)); + sexp_apply1(ctx, sexp_global(ctx, SEXP_G_THREADS_BLOCKER), in); + return sexp_global(ctx, SEXP_G_IO_BLOCK_ERROR); } +#endif if (c == '\n') sexp_port_line(in)++; - else if (c < 0) c += 128; return sexp_make_fixnum(c); } sexp sexp_peek_u8 (sexp ctx, sexp self, sexp in) { sexp res = sexp_read_u8(ctx, self, in); - if (sexp_charp(res)) - sexp_push_char(ctx, sexp_unbox_character(res), in); + if (sexp_fixnump(res)) + sexp_push_char(ctx, sexp_unbox_fixnum(res), in); return res; } diff --git a/lib/srfi/18/threads.c b/lib/srfi/18/threads.c index 23d97a97..4cee606b 100644 --- a/lib/srfi/18/threads.c +++ b/lib/srfi/18/threads.c @@ -546,7 +546,7 @@ sexp sexp_scheduler (sexp ctx, sexp self, sexp_sint_t n, sexp root_thread) { if ((sexp_context_timeval(res).tv_sec == 0) && (sexp_context_timeval(res).tv_usec == 0)) { /* no timeout, wait for default 10ms */ - usecs = 10*1000; + usecs = 10*1000 *100; /* 1s */ } else { /* wait until the next timeout */ gettimeofday(&tval, NULL); diff --git a/sexp.c b/sexp.c index d3df8449..0c44a881 100644 --- a/sexp.c +++ b/sexp.c @@ -1365,14 +1365,14 @@ int sexp_buffered_read_char (sexp ctx, sexp p) { sexp_gc_var1(tmp); int res = 0; if (sexp_port_offset(p) < sexp_port_size(p)) { - return sexp_port_buf(p)[sexp_port_offset(p)++]; + return ((unsigned char*)sexp_port_buf(p))[sexp_port_offset(p)++]; } else if (sexp_port_stream(p)) { res = fread(sexp_port_buf(p), 1, SEXP_PORT_BUFFER_SIZE, sexp_port_stream(p)); if (res >= 0) { sexp_port_offset(p) = 0; sexp_port_size(p) = res; res = ((sexp_port_offset(p) < sexp_port_size(p)) - ? sexp_port_buf(p)[sexp_port_offset(p)++] : EOF); + ? ((unsigned char*)sexp_port_buf(p))[sexp_port_offset(p)++] : EOF); } } else if (sexp_filenop(sexp_port_fd(p))) { res = read(sexp_port_fileno(p), sexp_port_buf(p), SEXP_PORT_BUFFER_SIZE); @@ -1380,7 +1380,7 @@ int sexp_buffered_read_char (sexp ctx, sexp p) { sexp_port_offset(p) = 0; sexp_port_size(p) = res; res = ((sexp_port_offset(p) < sexp_port_size(p)) - ? sexp_port_buf(p)[sexp_port_offset(p)++] : EOF); + ? ((unsigned char*)sexp_port_buf(p))[sexp_port_offset(p)++] : EOF); } } else if (sexp_port_customp(p)) { sexp_gc_preserve1(ctx, tmp); @@ -1391,7 +1391,7 @@ int sexp_buffered_read_char (sexp ctx, sexp p) { sexp_port_offset(p) = 0; sexp_port_size(p) = sexp_unbox_fixnum(tmp); res = ((sexp_port_offset(p) < sexp_port_size(p)) - ? sexp_port_buf(p)[sexp_port_offset(p)++] : EOF); + ? ((unsigned char*)sexp_port_buf(p))[sexp_port_offset(p)++] : EOF); } else { res = EOF; sexp_port_size(p) = 0;