diff --git a/stix/kernel/Apex.st b/stix/kernel/Apex.st index e59b0b1..a9babee 100644 --- a/stix/kernel/Apex.st +++ b/stix/kernel/Apex.st @@ -239,7 +239,6 @@ ^(self isMemberOf: aClass) or: [self class inheritsFrom: aClass]. } - ## ------------------------------------------------------- ## ------------------------------------------------------- " diff --git a/stix/kernel/Collect.st b/stix/kernel/Collect.st index 390caec..52105cb 100644 --- a/stix/kernel/Collect.st +++ b/stix/kernel/Collect.st @@ -108,8 +108,10 @@ #pooldic Log { ## ----------------------------------------------------------- + ## defines log levels ## these items must follow defintions in stix.h ## ----------------------------------------------------------- + #DEBUG := 1. #INFO := 2. #WARN := 4. @@ -127,27 +129,50 @@ #dcl(#pooldic) Log. - #method log: message level: level + #method atLevel: level log: message { ## do nothing upon logging failure } - #method logNl: message level: level + #method atLevel: level log: message and: message2 { - self log: message level: level. - self log: S'\n' level: level. - ^self. + + ## do nothing upon logging failure + } + + #method atLevel: level log: message and: message2 and: message3 + { + + ## do nothing upon logging failure + } + + #method atLevel: level logNl: message + { + ## the #_log primitive accepts an array. + ## so the following lines should work also. + ## | x | + ## x := Array new: 2. + ## x at: 0 put: message. + ## x at: 1 put: S'\n'. + ## ^self atLevel: level log: x. + + ^self atLevel: level log: message and: S'\n'. + } + + #method atLevel: level logNl: message and: message2 + { + ^self atLevel: level log: message and: message2 and: S'\n'. } #method log: message { - ^self log: message level: Log.INFO. + ^self atLevel: Log.INFO log: message. } #method logNl: message { - ^self logNl: message level: Log.INFO. + ^self atLevel: Log.INFO logNl: message. } } @@ -164,3 +189,20 @@ } +#extend Apex +{ + ## ------------------------------------------------------- + ## Association has been defined now. let's add association + ## creating methods + ## ------------------------------------------------------- + + #method(#class) -> object + { + ^Association new key: self value: object + } + + #method -> object + { + ^Association new key: self value: object + } +} diff --git a/stix/kernel/Context.st b/stix/kernel/Context.st index 4face29..404bdb3 100644 --- a/stix/kernel/Context.st +++ b/stix/kernel/Context.st @@ -246,6 +246,4 @@ { ip := self.source pc. } - } - diff --git a/stix/kernel/Except.st b/stix/kernel/Except.st index a8a68f7..9595b19 100644 --- a/stix/kernel/Except.st +++ b/stix/kernel/Except.st @@ -165,6 +165,8 @@ ]. stop := (ctx == context). ctx := ctx sender. + + ## stop ifFalse: [ stop := ctx isNil ]. ]. ^retval diff --git a/stix/kernel/Process.st b/stix/kernel/Process.st index 19df57f..1798732 100644 --- a/stix/kernel/Process.st +++ b/stix/kernel/Process.st @@ -37,12 +37,19 @@ ##^Processor resume: self. } - #method terminate + #method _terminate { self primitiveFailed } + #method terminate + { +##search from the top contextof the process down to intial_contextand find ensure blocks and execute them. + self.current_context unwindTo: self.initial_context return: nil. + ^self _terminate + } + #method yield { @@ -58,15 +65,6 @@ { ^self.initial_context } - - #method sleep: seconds - { - | s | - s := Semaphore new. - Processor signal: s after: seconds. - ## Processor activeProcess dump. - s wait. - } } #class Semaphore(Object) @@ -405,4 +403,26 @@ self primitiveFailed. } + + #method sleepFor: secs + { + ## ----------------------------------------------------- + ## put the calling process to sleep for given seconds. + ## ----------------------------------------------------- + | s | + s := Semaphore new. + self signal: s after: secs. + s wait. + } + + #method sleepFor: secs and: nanosecs + { + ## ----------------------------------------------------- + ## put the calling process to sleep for given seconds. + ## ----------------------------------------------------- + | s | + s := Semaphore new. + self signal: s after: secs and: nanosecs + s wait. + } } diff --git a/stix/kernel/Stix.st b/stix/kernel/Stix.st index 3f92fb2..2f5b845 100644 --- a/stix/kernel/Stix.st +++ b/stix/kernel/Stix.st @@ -21,6 +21,22 @@ #class Association(Magnitude) { #dcl key value. + + #method key: key value: value + { + self.key := key. + self.value := value. + } + + #method key + { + ^self.key + } + + #method value + { + ^self.value + } } #class Character(Magnitude) diff --git a/stix/kernel/test-010.st b/stix/kernel/test-010.st index 3514b9c..6ee2bae 100644 --- a/stix/kernel/test-010.st +++ b/stix/kernel/test-010.st @@ -182,11 +182,11 @@ s3 := Semaphore new. t1 := [ - 10 timesRepeat: ['BLOCK #1' dump. Processor activeProcess sleep: 1.]. + 10 timesRepeat: ['BLOCK #1' dump. Processor sleepFor: 1.]. s1 signal ] newProcess. t2 := [ - 5 timesRepeat: ['BLOCK #2' dump. "Processor activeProcess sleep: 1." ]. + 5 timesRepeat: ['BLOCK #2' dump. "Processor sleepFor: 1." ]. 'SIGNALLING S2...' dump. s2 signal. ] newProcess. diff --git a/stix/kernel/test-011.st b/stix/kernel/test-011.st index b7c160c..8718c8f 100644 --- a/stix/kernel/test-011.st +++ b/stix/kernel/test-011.st @@ -221,7 +221,7 @@ ## on: Exception do: [:ex | ex messageText dump]. 'SLEEPING FOR 10 seconds ....' dump. - Processor activeProcess sleep: 10. + Processor sleepFor: 10. '>>>>> END OF MAIN' dump. } diff --git a/stix/kernel/test-013.st b/stix/kernel/test-013.st new file mode 100644 index 0000000..87a8b2c --- /dev/null +++ b/stix/kernel/test-013.st @@ -0,0 +1,101 @@ + +#include 'Stix.st'. + +################################################################# +## MAIN +################################################################# + +## TODO: use #define to define a class or use #class to define a class. +## use #extend to extend a class +## using #class for both feels confusing. + +#extend Apex +{ + +} + +#extend SmallInteger +{ + #method getTrue: anInteger + { + ^anInteger + 9999. + } + + #method inc + { + ^self + 1. + } +} + +#class TestObject(Object) +{ + #dcl(#class) Q R. + #dcl(#classinst) a1 a2. + + #method test999 + { + ^self.Q + } +} + +#class B.TestObject(Object) +{ + #dcl(#class) Q R. + #dcl(#classinst) a1 a2. + + #method test000 + { + ^self.Q + } +} + +#pooldic ABC +{ + #KKK := 20. +} + + +#class MyObject(TestObject) +{ + #method(#class) main + { + | v1 v2 | + System logNl: 'START OF MAIN'. + v2 := [ + [ v1 := [ System logNl: 'xxxxxxxxxxxxxxxxc'. Exception signal: 'qqqqq' ] value. + 'OK OK OK' dump. ] ensure: [ System logNl: 'ENSURE ENSURE ENSURE']. + ] + on: Exception + do: [:ex | + System logNl: ('Exception: ', ex messageText). + ex return: 10. + ##ex retry. + System logNl: '--- THIS MUST NOT BE PRINTED ---'. + ]. + + + System logNl: '---------------------'. + System log: 'v1=>'; log: v1; log: ' v2=>'; logNl: v2. + + v1 := [ + [ + [ + 1 to: 10000 by: 1 do: [:i | System logNl: i asString. Processor sleepFor: 5. ] + ] ensure: [ System logNl: '<<>>' ]. + + ] ensure: [ System logNl: '<<--------------------->>' ]. + ] newProcess. + + System logNl: 'RESUMING v1'. + v1 resume. + v1 terminate. + + ##[ + ## [ Processor activeProcess terminate. ] ensure: [System logNl: '<<>>' ]. + ##] ensure: [ System logNl: '<<--------------------->>' ]. + + System logNl: S'\0\0\0END OF MAIN\0AB\0\0\0C\0\0\0'. + } + +} + diff --git a/stix/lib/comp.c b/stix/lib/comp.c index c6c78a9..f8de4ee 100644 --- a/stix/lib/comp.c +++ b/stix/lib/comp.c @@ -1916,39 +1916,25 @@ static STIX_INLINE int add_class_level_variable (stix_t* stix, var_type_t index, static STIX_INLINE int add_pool_dictionary (stix_t* stix, const stix_oocs_t* name, stix_oop_set_t pooldic_oop) { - int n; - stix_oow_t saved_len; - - saved_len = stix->c->cls.pooldic.len; - - n = copy_string_to (stix, name, &stix->c->cls.pooldic, &stix->c->cls.pooldic_capa, 1, ' '); - if (n >= 0) + if (stix->c->cls.pooldic_count >= stix->c->cls.pooldic_oop_capa) { - if (stix->c->cls.pooldic_count >= stix->c->cls.pooldic_oop_capa) - { - stix_oow_t new_capa; - stix_oop_set_t* tmp; + stix_oow_t new_capa; + stix_oop_set_t* tmp; - new_capa = STIX_ALIGN(stix->c->cls.pooldic_oop_capa + 1, POOLDIC_OOP_BUFFER_ALIGN); - tmp = stix_reallocmem (stix, stix->c->cls.pooldic_oops, new_capa * STIX_SIZEOF(stix_oop_set_t)); - if (!tmp) - { - stix->c->cls.pooldic.len = saved_len; - return -1; - } + new_capa = STIX_ALIGN(stix->c->cls.pooldic_oop_capa + 1, POOLDIC_OOP_BUFFER_ALIGN); + tmp = stix_reallocmem (stix, stix->c->cls.pooldic_oops, new_capa * STIX_SIZEOF(stix_oop_set_t)); + if (!tmp) return -1; - stix->c->cls.pooldic_oop_capa = new_capa; - stix->c->cls.pooldic_oops = tmp; - } - - stix->c->cls.pooldic_oops[stix->c->cls.pooldic_count] = pooldic_oop; - stix->c->cls.pooldic_count++; -/* TODO: check if pooldic_count overflows */ + stix->c->cls.pooldic_oop_capa = new_capa; + stix->c->cls.pooldic_oops = tmp; } - return n; -} + stix->c->cls.pooldic_oops[stix->c->cls.pooldic_count] = pooldic_oop; + stix->c->cls.pooldic_count++; +/* TODO: check if pooldic_count overflows */ + return 0; +} static stix_ooi_t find_class_level_variable (stix_t* stix, stix_oop_class_t self, const stix_oocs_t* name, var_info_t* var) { @@ -2281,6 +2267,46 @@ wrong_name: return -1; } +static int resolve_pooldic (stix_t* stix, int dotted, const stix_oocs_t* name) +{ + stix_oocs_t last; /* the last segment */ + stix_oop_set_t ns_oop; /* name space */ + stix_oop_association_t ass; + stix_oow_t i; + + if (dotted) + { + if (preprocess_dotted_name(stix, 0, 0, name, &stix->c->tok.loc, &last, &ns_oop) <= -1) return -1; + } + else + { + last = *name; + /* it falls back to the name space of the class */ + ns_oop = stix->c->cls.ns_oop; + } + + /* check if the name refers to a pool dictionary */ + ass = stix_lookupdic (stix, ns_oop, &last); + if (!ass || STIX_CLASSOF(stix, ass->value) != stix->_pool_dictionary) + { + set_syntax_error (stix, STIX_SYNERR_POOLDIC, &stix->c->tok.loc, name); + return -1; + } + + /* check if the same dictionary pool has been declared for import */ + for (i = 0; i < stix->c->cls.pooldic_count; i++) + { + if ((stix_oop_set_t)ass->value == stix->c->cls.pooldic_oops[i]) + { + set_syntax_error (stix, STIX_SYNERR_POOLDICDUP, &stix->c->tok.loc, name); + return -1; + } + } + + return 0; +} + + static int compile_class_level_variables (stix_t* stix) { var_type_t dcl_type = VAR_INSTANCE; @@ -2304,7 +2330,7 @@ static int compile_class_level_variables (stix_t* stix) } else if (is_token_symbol(stix, VOCA_POOLDIC)) { - /* #dcl(#pooldic) */ + /* #dcl(#pooldic) - import a pool dictionary */ dcl_type = VAR_GLOBAL; /* this is not a real type. use for branching below */ GET_TOKEN (stix); } @@ -2360,6 +2386,12 @@ static int compile_class_level_variables (stix_t* stix) } if (add_pool_dictionary(stix, &stix->c->tok.name, (stix_oop_set_t)ass->value) <= -1) return -1; + if (copy_string_to (stix, &stix->c->tok.name, &stix->c->cls.pooldic, &stix->c->cls.pooldic_capa, 1, ' ') <= -1) + { + stix->c->cls.pooldic_count--; + return -1; + } + GET_TOKEN (stix); } while (1); @@ -2401,9 +2433,6 @@ static int compile_class_level_variables (stix_t* stix) GET_TOKEN (stix); return 0; - - - } static int compile_unary_method_name (stix_t* stix) @@ -2761,7 +2790,6 @@ static int get_variable_info (stix_t* stix, const stix_oocs_t* name, const stix_ } else { - if (find_class_level_variable(stix, stix->c->cls.self_oop, name, var) >= 0) { class_level_variable: @@ -4881,11 +4909,9 @@ static int __compile_pooldic_definition (stix_t* stix) case STIX_IOTOK_NUMLIT: case STIX_IOTOK_RADNUMLIT: - { lit = string_to_num (stix, &stix->c->tok.name, stix->c->tok.type == STIX_IOTOK_RADNUMLIT); if (!lit) return -1; goto add_literal; - } case STIX_IOTOK_BPAREN: /* #[ */ if (read_byte_array_literal(stix, &lit) <= -1) return -1; @@ -5005,8 +5031,7 @@ static int compile_stream (stix_t* stix) } else if (is_token_symbol(stix, VOCA_POOLDIC)) { -/* TODO: allow #pooldic within #class */ - /* #pooldic SharedPoolDic { #abc := 20. #defg := 'ayz' } */ + /* #pooldic SharedPoolDic { #ABC := 20. #DEFG := 'ayz' } */ GET_TOKEN (stix); if (compile_pooldic_definition(stix) <= -1) return -1; } diff --git a/stix/lib/exec.c b/stix/lib/exec.c index 5052bc6..aad5418 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -557,7 +557,6 @@ static void resume_process (stix_t* stix, stix_oop_process_t proc) /* don't switch to this process. just set the state to RUNNING */ } - #if 0 else if (proc->state == STIX_SMOOI_TO_OOP(PROC_STATE_RUNNABLE)) { @@ -1167,56 +1166,100 @@ static int prim_dump (stix_t* stix, stix_ooi_t nargs) return 1; /* success */ } +static void log_char_object (stix_t* stix, stix_oow_t mask, stix_oop_char_t msg) +{ + stix_ooi_t n; + stix_oow_t rem; + const stix_ooch_t* ptr; + + STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(msg) == STIX_OBJ_TYPE_CHAR); + + rem = STIX_OBJ_GET_SIZE(msg); + ptr = msg->slot; + +start_over: + while (rem > 0) + { + if (*ptr == '\0') + { + n = stix_logbfmt (stix, mask, "%C", *ptr); + STIX_ASSERT (n == 1); + rem -= n; + ptr += n; + goto start_over; + } + + n = stix_logbfmt (stix, mask, "%.*S", rem, ptr); + if (n <= -1) break; + if (n == 0) + { + /* to skip the unprinted character. + * actually, this check is not needed because of '\0' skipping + * at the beginning of the loop */ + n = stix_logbfmt (stix, mask, "%C", *ptr); + STIX_ASSERT (n == 1); + } + rem -= n; + ptr += n; + } +} + static int prim_log (stix_t* stix, stix_ooi_t nargs) { stix_oop_t msg, level; + stix_oow_t mask; + stix_ooi_t k; STIX_ASSERT (nargs >= 2); - level = STIX_STACK_GET(stix, stix->sp); - msg = STIX_STACK_GET(stix, stix->sp - 1); + level = STIX_STACK_GET(stix, stix->sp - nargs + 1); + if (!STIX_OOP_IS_SMOOI(level)) mask = STIX_LOG_APP | STIX_LOG_INFO; + else mask = STIX_LOG_APP | STIX_OOP_TO_SMOOI(level); -/* TODO: SUPPORT ARBITRARY NUMBERS OF MESSAGES */ - if (!STIX_OOP_IS_SMOOI(level)) level = STIX_SMOOI_TO_OOP(STIX_LOG_INFO); - - if (STIX_OOP_IS_POINTER(msg) && STIX_OBJ_GET_FLAGS_TYPE(msg)) + for (k = nargs - 1; k > 0; ) { - stix_ooi_t n; - stix_oow_t rem; - const stix_ooch_t* ptr; + --k; + msg = STIX_STACK_GET(stix, stix->sp - k); - rem = STIX_OBJ_GET_SIZE(msg); - ptr = ((stix_oop_char_t)msg)->slot; - - start_over: - while (rem > 0) + if (msg == stix->_nil || msg == stix->_true || msg == stix->_false) { - if (*ptr == '\0') - { - n = stix_logbfmt (stix, STIX_LOG_APP | STIX_OOP_TO_SMOOI(level), "%C", *ptr); - STIX_ASSERT (n == 1); - rem -= n; - ptr += n; - goto start_over; - } - - n = stix_logbfmt (stix, STIX_LOG_APP | STIX_OOP_TO_SMOOI(level), "%.*S", rem, ptr); - if (n <= -1) break; - if (n == 0) - { - /* to skip the unprinted character. - * actually, this check is not needed because of '\0' skipping - * at the beginning of the loop */ - n = stix_logbfmt (stix, STIX_LOG_APP | STIX_OOP_TO_SMOOI(level), "%C", *ptr); - STIX_ASSERT (n == 1); - } - rem -= n; - ptr += n; + goto dump_object; + } + else if (STIX_OOP_IS_POINTER(msg)) + { + if (STIX_OBJ_GET_FLAGS_TYPE(msg) == STIX_OBJ_TYPE_CHAR) + { + log_char_object (stix, mask, (stix_oop_char_t)msg); + } + else if (STIX_OBJ_GET_FLAGS_TYPE(msg) == STIX_OBJ_TYPE_OOP) + { + /* visit only 1-level down into an array-like object */ + stix_oop_t inner; + stix_oow_t i; + + if (STIX_CLASSOF(stix,msg) == stix->_association) goto dump_object; + + for (i = 0; i < STIX_OBJ_GET_SIZE(msg); i++) + { + inner = ((stix_oop_oop_t)msg)->slot[i]; + if (STIX_OOP_IS_POINTER(inner) && + STIX_OBJ_GET_FLAGS_TYPE(inner) == STIX_OBJ_TYPE_CHAR) + { + log_char_object (stix, mask, (stix_oop_char_t)inner); + } + else + { + stix_logbfmt (stix, mask, "%O", inner); + } + } + } + else goto dump_object; + } + else + { + dump_object: + stix_logbfmt (stix, mask, "%O", msg); } - } - else - { - stix_logbfmt (stix, STIX_LOG_APP | STIX_OOP_TO_SMOOI(level), "%O", msg); } STIX_STACK_POPS (stix, nargs); /* delete arguments, keep self */ @@ -2656,7 +2699,7 @@ typedef struct prim_t prim_t; static prim_t primitives[] = { { 0, MAX_NARGS, prim_dump, "_dump" }, - { 2, 2, prim_log, "_log" }, + { 2, MAX_NARGS, prim_log, "_log" }, { 1, 1, prim_identical, "_identical" }, { 1, 1, prim_not_identical, "_not_identical" }, diff --git a/stix/lib/logfmt.c b/stix/lib/logfmt.c index 9d07940..8a1bcbb 100644 --- a/stix/lib/logfmt.c +++ b/stix/lib/logfmt.c @@ -131,14 +131,14 @@ static stix_bch_t bch_nullstr[] = { '(','n','u','l','l', ')','\0' }; typedef int (*stix_fmtout_putch_t) ( stix_t* stix, - unsigned int mask, + stix_oow_t mask, stix_ooch_t c, stix_oow_t len ); typedef int (*stix_fmtout_putcs_t) ( stix_t* stix, - unsigned int mask, + stix_oow_t mask, const stix_ooch_t* ptr, stix_oow_t len ); @@ -147,7 +147,7 @@ typedef struct stix_fmtout_t stix_fmtout_t; struct stix_fmtout_t { stix_oow_t count; /* out */ - int mask; /* in */ + stix_oow_t mask; /* in */ stix_fmtout_putch_t putch; /* in */ stix_fmtout_putcs_t putcs; /* in */ }; @@ -185,7 +185,7 @@ static stix_bch_t* sprintn_upper (stix_bch_t* nbuf, stix_uintmax_t num, int base } /* ------------------------------------------------------------------------- */ -static int put_ooch (stix_t* stix, unsigned int mask, stix_ooch_t ch, stix_oow_t len) +static int put_ooch (stix_t* stix, stix_oow_t mask, stix_ooch_t ch, stix_oow_t len) { if (len <= 0) return 1; @@ -237,7 +237,7 @@ redo: return 1; /* success */ } -static int put_oocs (stix_t* stix, unsigned int mask, const stix_ooch_t* ptr, stix_oow_t len) +static int put_oocs (stix_t* stix, stix_oow_t mask, const stix_ooch_t* ptr, stix_oow_t len) { if (len <= 0) return 1; @@ -277,7 +277,7 @@ static int put_oocs (stix_t* stix, unsigned int mask, const stix_ooch_t* ptr, st /* ------------------------------------------------------------------------- */ -static void print_object (stix_t* stix, unsigned int mask, stix_oop_t oop) +static void print_object (stix_t* stix, stix_oow_t mask, stix_oop_t oop) { if (oop == stix->_nil) { @@ -365,6 +365,9 @@ static void print_object (stix_t* stix, unsigned int mask, stix_oop_t oop) case '\0': escaped = '0'; break; + case '\n': + escaped = 'n'; + break; case '\r': escaped = 'r'; break; @@ -450,6 +453,10 @@ static void print_object (stix_t* stix, unsigned int mask, stix_oop_t oop) /* print the class name */ stix_logbfmt (stix, mask, "%.*S", STIX_OBJ_GET_SIZE(((stix_oop_class_t)oop)->name), ((stix_oop_class_t)oop)->name->slot); } + else if ((stix_oop_t)c == stix->_association) + { + stix_logbfmt (stix, mask, "%O -> %O", ((stix_oop_association_t)oop)->key, ((stix_oop_association_t)oop)->value); + } else { stix_logbfmt (stix, mask, "instance of %.*S(%p)", STIX_OBJ_GET_SIZE(c->name), ((stix_oop_char_t)c->name)->slot, oop); @@ -473,7 +480,7 @@ static void print_object (stix_t* stix, unsigned int mask, stix_oop_t oop) #define FMTCHAR_IS_OOCH #include "logfmtv.h" -stix_ooi_t stix_logbfmt (stix_t* stix, unsigned int mask, const stix_bch_t* fmt, ...) +stix_ooi_t stix_logbfmt (stix_t* stix, stix_oow_t mask, const stix_bch_t* fmt, ...) { int x; va_list ap; @@ -495,7 +502,7 @@ stix_ooi_t stix_logbfmt (stix_t* stix, unsigned int mask, const stix_bch_t* fmt, return (x <= -1)? -1: fo.count; } -stix_ooi_t stix_logoofmt (stix_t* stix, unsigned int mask, const stix_ooch_t* fmt, ...) +stix_ooi_t stix_logoofmt (stix_t* stix, stix_oow_t mask, const stix_ooch_t* fmt, ...) { int x; va_list ap; diff --git a/stix/lib/main.c b/stix/lib/main.c index f18672a..765e91b 100644 --- a/stix/lib/main.c +++ b/stix/lib/main.c @@ -30,6 +30,7 @@ #include #include #include +#include #if defined(_WIN32) @@ -330,7 +331,7 @@ printf ("MOD_GETSYM [%s]\n", &buf[0]); /* ========================================================================= */ -static void log_write (stix_t* stix, unsigned int mask, const stix_ooch_t* msg, stix_oow_t len) +static void log_write (stix_t* stix, stix_oow_t mask, const stix_ooch_t* msg, stix_oow_t len) { #if defined(_WIN32) # error NOT IMPLEMENTED @@ -340,30 +341,71 @@ static void log_write (stix_t* stix, unsigned int mask, const stix_ooch_t* msg, stix_oow_t ucslen, bcslen, msgidx; int n; - msgidx = 0; + + /*if (mask & STIX_LOG_GC) return;*/ /* don't show gc logs */ /* TODO: beautify the log message. * do classification based on mask. */ +/* +{ + char ts[32]; + struct tm tm; + time_t now; + now = time(NULL); + localtime_r (&now, &tm); + strftime (ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %z ", &tm); + write (1, ts, strlen(ts)); +} +*/ + msgidx = 0; while (len > 0) { ucslen = len; bcslen = STIX_COUNTOF(buf); n = stix_ucstoutf8 (&msg[msgidx], &ucslen, buf, &bcslen); - if (n == 0) - { - write (1, buf, bcslen); /* TODO: write all */ - break; - } - else if (n == -2) + if (n == 0 || n == -2) { + stix_oow_t rem; + const stix_bch_t* ptr; + /* n = 0: + * converted all successfully + * n == -2: + * buffer not sufficient. not all got converted yet. + * write what have been converted this round. */ + STIX_ASSERT (ucslen > 0); /* if this fails, the buffer size must be increased */ - write (1, buf, bcslen); /* TODO: write all */ - msgidx += ucslen; - len -= ucslen; + + /* attempt to write all converted characters */ + rem = bcslen; + ptr = buf; + while (rem > 0) + { + stix_ooi_t wr; + + wr = write (1, ptr, rem); /* TODO: write all */ + if (wr <= -1) + { + /*if (errno == EAGAIN || errno == EWOULDBLOCK) + { + push it to internal buffers? before writing data just converted, need to write buffered data first. + }*/ + break; + } + + ptr += wr; + rem -= wr; + } + + if (n == 0) break; + else + { + msgidx += ucslen; + len -= ucslen; + } } else if (n <= -1) { diff --git a/stix/lib/stix.h b/stix/lib/stix.h index 8595c9d..9d3014e 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -407,7 +407,7 @@ struct stix_class_t stix_oop_char_t classinstvars; /* String */ /* == NEVER CHANGE THE ORDER OF 3 ITEMS ABOVE == */ - stix_oop_char_t pooldics; /* String */ + stix_oop_char_t pooldics; /* String - pool dictionaries imported */ /* [0] - instance methods, MethodDictionary * [1] - class methods, MethodDictionary */ @@ -678,7 +678,7 @@ typedef void* (*stix_mod_open_t) (stix_t* stix, const stix_ooch_t* name); typedef void (*stix_mod_close_t) (stix_t* stix, void* handle); typedef void* (*stix_mod_getsym_t) (stix_t* stix, void* handle, const stix_ooch_t* name); -typedef void (*stix_log_write_t) (stix_t* stix, unsigned int mask, const stix_ooch_t* msg, stix_oow_t len); +typedef void (*stix_log_write_t) (stix_t* stix, stix_oow_t mask, const stix_ooch_t* msg, stix_oow_t len); struct stix_vmprim_t { @@ -1134,14 +1134,14 @@ STIX_EXPORT void stix_freemem ( STIX_EXPORT stix_ooi_t stix_logbfmt ( stix_t* stix, - unsigned int mask, + stix_oow_t mask, const stix_bch_t* fmt, ... ); STIX_EXPORT stix_ooi_t stix_logoofmt ( stix_t* stix, - unsigned int mask, + stix_oow_t mask, const stix_ooch_t* fmt, ... );