diff --git a/moo/kernel/test-003.moo b/moo/kernel/test-003.moo index ee82da1..8c51d6c 100644 --- a/moo/kernel/test-003.moo +++ b/moo/kernel/test-003.moo @@ -90,7 +90,11 @@ class MyObject(Object) 0 priorTo: limit by: 1 do: [ :idx | | tb | tb := tc at: idx. - System log(System.Log.INFO, idx asString, (if (tb value) { ' PASS' } else { ' FAIL' }), S'\n'). + System log(System.Log.INFO, idx asString, (if (tb value) { ' PASS' } else { ' FAIL' }), "\n"). ]. + + ## TODO: + String format('%s', " 나 는\\\"") dump. + #"a b\nc" dump. } } diff --git a/moo/kernel/test-004.moo b/moo/kernel/test-004.moo index 74e6b8f..4d1be0f 100644 --- a/moo/kernel/test-004.moo +++ b/moo/kernel/test-004.moo @@ -39,7 +39,7 @@ class MyObject(Object) sg addSemaphore: s3. s1 signalOnInput: 0. - s2 signalOnInput: 0. ## this should raise an exception. + s2 signalOnInput: 0. ## this should raise an exception as the same file descriptor is added to a different semaphore s3 signalOnInput: 0. [ sg wait. ] fork. @@ -69,7 +69,7 @@ sg removeSemaphore: s1. tb := tc at: idx. System log(System.Log.INFO, idx asString, (if (tb value) { ' PASS' } else { ' FAIL' }), S'\n'). ]. - + '********** END OF MAIN PROGRAM *************' dump. } } diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 1ba10fb..0cef937 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -2019,11 +2019,19 @@ retry: break; case '\'': - /* quoted symbol literal */ + /* #'XXXX' - quoted symbol literal */ if (get_strlit(moo) <= -1) return -1; /* reuse the string literal tokenizer */ SET_TOKEN_TYPE (moo, MOO_IOTOK_SYMLIT); /* change the symbol type to symbol */ break; + case '"': + /* #"XXXX" - quoted symbol literal with C-style escape sequences. + * if MOO_PRAGMA_QC is set, this part should never be reached */ + MOO_ASSERT (moo, !(moo->c->pragma_flags & MOO_PRAGMA_QC)); + if (get_string(moo, '"', '\\', 0, 0) <= -1) return -1; + SET_TOKEN_TYPE (moo, MOO_IOTOK_SYMLIT); /* change the symbol type to symbol */ + break; + case '\\': ADD_TOKEN_CHAR (moo, c); GET_CHAR_TO (moo, c); diff --git a/moo/lib/fmt.c b/moo/lib/fmt.c index 6d31f1a..bbb9725 100644 --- a/moo/lib/fmt.c +++ b/moo/lib/fmt.c @@ -1431,87 +1431,79 @@ int moo_fmt_object_ (moo_fmtout_t* fmtout, moo_oop_t oop) } else if (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_CHAR) { - if (c == moo->_symbol) - { - if (moo_bfmt_out(fmtout, "#%.*js", MOO_OBJ_GET_SIZE(oop), MOO_OBJ_GET_CHAR_SLOT(oop)) <= -1) return -1; - } - else /*if ((moo_oop_t)c == moo->_string)*/ - { - moo_ooch_t ch; - int escape = 0; + moo_ooch_t ch; + int escape = 0; + for (i = 0; i < MOO_OBJ_GET_SIZE(oop); i++) + { + ch = MOO_OBJ_GET_CHAR_SLOT(oop)[i]; + if ((ch >= '\0' && ch < ' ') || ch == '\\' || ch == '\"') + { + escape = 1; + break; + } + } + + if (escape) + { + moo_ooch_t escaped; + + if (moo_bfmt_out(fmtout, ((c == moo->_symbol)? "#\"": "\"")) <= -1) return -1; for (i = 0; i < MOO_OBJ_GET_SIZE(oop); i++) { ch = MOO_OBJ_GET_CHAR_SLOT(oop)[i]; - if (ch < ' ') + if (ch >= '\0' && ch < ' ') { - escape = 1; - break; + switch (ch) + { + case '\0': + escaped = '0'; + break; + case '\n': + escaped = 'n'; + break; + case '\r': + escaped = 'r'; + break; + case '\t': + escaped = 't'; + break; + case '\f': + escaped = 'f'; + break; + case '\b': + escaped = 'b'; + break; + case '\v': + escaped = 'v'; + break; + case '\a': + escaped = 'a'; + break; + default: + /* since it's less than ' ' and greater than or equal to '\0' , + * it should not exceed 0xFF regardless of character mode. %02X should be good enough */ + if (moo_bfmt_out(fmtout, "\\x%02X", (moo_oochu_t)ch) <= -1) return -1; + continue; + } + + if (moo_bfmt_out(fmtout, "\\%jc", escaped) <= -1) return -1; + } + else if (ch == '\\' || ch == '\"') + { + if (moo_bfmt_out(fmtout, "\\%jc", ch) <= -1) return -1; + } + else + { + if (moo_bfmt_out(fmtout, "%jc", ch) <= -1) return -1; } } - if (escape) - { - moo_ooch_t escaped; - - if (moo_bfmt_out(fmtout, "S'") <= -1) return -1; - for (i = 0; i < MOO_OBJ_GET_SIZE(oop); i++) - { - ch = MOO_OBJ_GET_CHAR_SLOT(oop)[i]; - if (ch < ' ') - { - switch (ch) - { - case '\0': - escaped = '0'; - break; - case '\n': - escaped = 'n'; - break; - case '\r': - escaped = 'r'; - break; - case '\t': - escaped = 't'; - break; - case '\f': - escaped = 'f'; - break; - case '\b': - escaped = 'b'; - break; - case '\v': - escaped = 'v'; - break; - case '\a': - escaped = 'a'; - break; - default: - escaped = ch; - break; - } - - if (escaped == ch) - { - if (moo_bfmt_out(fmtout, "\\x%X", ch) <= -1) return -1; - } - else - { - if (moo_bfmt_out(fmtout, "\\%jc", escaped) <= -1) return -1; - } - } - else - { - if (moo_bfmt_out(fmtout, "%jc", ch) <= -1) return -1; - } - } - - if (moo_bfmt_out(fmtout, "'") <= -1) return -1; - } - else - { - if (moo_bfmt_out(fmtout, "'%.*js'", MOO_OBJ_GET_SIZE(oop), MOO_OBJ_GET_CHAR_SLOT(oop)) <= -1) return -1; - } + if (moo_bfmt_out(fmtout, "\"") <= -1) return -1; + } + else + { + if (moo_bfmt_out(fmtout, ((c == moo->_symbol)? "#%.*js": "'%.%js'"), MOO_OBJ_GET_SIZE(oop), MOO_OBJ_GET_CHAR_SLOT(oop)) <= -1) return -1; } } else if (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_BYTE) diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index a041519..476860a 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -419,7 +419,7 @@ struct moo_initv_t enum moo_pragma_flag_t { - MOO_PRAGMA_QC = (1 << 0) + MOO_PRAGMA_QC = (1 << 0) /* quoted commented. treat a double quoted text as a comment */ }; enum moo_cunit_type_t diff --git a/moo/mod/_con.c b/moo/mod/_con.c index c367b17..d0e0135 100644 --- a/moo/mod/_con.c +++ b/moo/mod/_con.c @@ -180,7 +180,7 @@ static moo_pfrc_t pf_write (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) { ucslen = ucsrem; bcslen = MOO_COUNTOF(bcs); - if ((n = moo_convootobchars (moo, &msg->slot[ucspos], &ucslen, bcs, &bcslen)) <= -1) + if ((n = moo_convootobchars(moo, &msg->slot[ucspos], &ucslen, bcs, &bcslen)) <= -1) { if (n != -2 || ucslen <= 0) return MOO_PF_HARD_FAILURE; } @@ -191,7 +191,7 @@ static moo_pfrc_t pf_write (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) ucsrem -= ucslen; } #else - write (con->fd, MOO_GET_OBJ_CHAR_SLOT(msg), MOO_OBJ_GET_SIZE(msg)); /* TODO: error handling. incomplete write handling */ + write (con->fd, MOO_OBJ_GET_CHAR_SLOT(msg), MOO_OBJ_GET_SIZE(msg)); /* TODO: error handling. incomplete write handling */ #endif MOO_STACK_SETRETTORCV (moo, nargs); /* TODO: change return code */ diff --git a/moo/mod/x11.c b/moo/mod/x11.c index 8e536a4..d730771 100644 --- a/moo/mod/x11.c +++ b/moo/mod/x11.c @@ -45,7 +45,7 @@ static XChar2b* uchars_to_xchar2bstr (moo_t* moo, const moo_uch_t* inptr, moo_oo const moo_uch_t* endptr; XChar2b* outbuf, * outptr; - outbuf = moo_allocmem (moo, (inlen + 1) * MOO_SIZEOF(*outptr)); + outbuf = moo_allocmem(moo, (inlen + 1) * MOO_SIZEOF(*outptr)); if (!outbuf) return MOO_NULL; outptr = outbuf; @@ -99,17 +99,21 @@ static moo_pfrc_t pf_open_display (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) } bl = MOO_OBJ_GET_SIZE(np); - dispname = moo_dupootobcstr (moo, MOO_OBJ_GET_CHAR_SLOT(np), &bl); + #if defined(MOO_OOCH_IS_UCH) + dispname = moo_dupootobcstr(moo, MOO_OBJ_GET_CHAR_SLOT(np), &bl); if (!dispname) { MOO_DEBUG2 (moo, " Cannot convert display name %.*js\n", MOO_OBJ_GET_SIZE(np), MOO_OBJ_GET_CHAR_SLOT(np)); MOO_STACK_SETRETTOERRNUM (moo, nargs); goto oops; } + #else + dispname = MOO_OBJ_GET_CHAR_SLOT(np); + #endif } } - event = moo_allocmem (moo, MOO_SIZEOF(*event)); + event = moo_allocmem(moo, MOO_SIZEOF(*event)); if (!event) { MOO_STACK_SETRETTOERRNUM (moo, nargs); @@ -150,13 +154,17 @@ static moo_pfrc_t pf_open_display (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) x11->display = MOO_SMPTR_TO_OOP(disp); MOO_STACK_SETRETTORCV (moo, nargs); +#if defined(MOO_OOCH_IS_UCH) if (dispname) moo_freemem (moo, dispname); +#endif return MOO_PF_SUCCESS; oops: if (disp) XCloseDisplay (disp); if (event) moo_freemem (moo, event); +#if defined(MOO_OOCH_IS_UCH) if (dispname) moo_freemem (moo, dispname); +#endif return MOO_PF_SUCCESS; } @@ -714,8 +722,8 @@ static moo_pfrc_t pf_draw_string (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) moo_oow_t oocslen; oocslen = MOO_OBJ_GET_SIZE(a3); - if (moo_convootobchars (moo, MOO_OBJ_GET_CHAR_SLOT(a3), &oocslen, MOO_NULL, &bcslen) <= -1 || - !(bb = moo_allocmem (moo, MOO_SIZEOF(moo_bch_t) * bcslen))) + if (moo_convootobchars(moo, MOO_OBJ_GET_CHAR_SLOT(a3), &oocslen, MOO_NULL, &bcslen) <= -1 || + !(bb = moo_allocmem(moo, MOO_SIZEOF(moo_bch_t) * bcslen))) { MOO_DEBUG0 (moo, " Error in converting a string\n"); MOO_STACK_SETRETTOERRNUM (moo, nargs); @@ -724,7 +732,7 @@ static moo_pfrc_t pf_draw_string (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) moo_convootobchars (moo, MOO_OBJ_GET_CHAR_SLOT(a3), &oocslen, bb, &bcslen); #else bb = MOO_OBJ_GET_CHAR_SLOT(a3); - bcslen = oocslen; + bcslen = MOO_OBJ_GET_SIZE(a3); #endif XmbTextExtents(MOO_OOP_TO_SMPTR(gc->font_set), bb, bcslen, MOO_NULL, &r); @@ -741,12 +749,13 @@ static moo_pfrc_t pf_draw_string (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) } else { + #if defined(MOO_OOCH_IS_UCH) XChar2b* stptr; moo_oow_t stlen; int ascent = 0; /* TODO: draw string chunk by chunk to avoid memory allocation in uchars_to_xchars2bstr */ - stptr = uchars_to_xchar2bstr (moo, MOO_OBJ_GET_CHAR_SLOT(a3), MOO_OBJ_GET_SIZE(a3), &stlen); + stptr = uchars_to_xchar2bstr(moo, MOO_OBJ_GET_CHAR_SLOT(a3), MOO_OBJ_GET_SIZE(a3), &stlen); if (!stptr) { MOO_DEBUG0 (moo, " Error in converting a string\n"); @@ -765,6 +774,19 @@ static moo_pfrc_t pf_draw_string (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) MOO_OOP_TO_SMOOI(a1), MOO_OOP_TO_SMOOI(a2) + ascent, stptr, stlen); moo_freemem (moo, stptr); + #else + int ascent = 0; + + if (MOO_OOP_IS_SMPTR(gc->font_ptr)) + { + int direction, descent; + XCharStruct overall; + XTextExtents16 (MOO_OOP_TO_SMPTR(gc->font_ptr), MOO_OBJ_GET_CHAR_SLOT(a3), MOO_OBJ_GET_SIZE(a3), &direction, &ascent, &descent, &overall); + } + + XDrawString (disp, (Window)MOO_OOP_TO_SMOOI(((oop_x11_widget_t)gc->widget)->window_handle), MOO_OOP_TO_SMPTR(gc->gc_handle), + MOO_OOP_TO_SMOOI(a1), MOO_OOP_TO_SMOOI(a2) + ascent, MOO_OBJ_GET_CHAR_SLOT(a3), MOO_OBJ_GET_SIZE(a3)); + #endif } MOO_STACK_SETRETTORCV (moo, nargs);