strm_string strm_to_str(strm_value v) { char buf[32]; int n; strm_state* ns = strm_value_ns(v); if (ns) { strm_value m; n = strm_var_get(ns, strm_str_intern_lit("string"), &m); if (n == STRM_OK) { n = strm_funcall(NULL, m, 1, &v, &m); if (n == STRM_OK && strm_string_p(m)) return m; } } switch (strm_value_tag(v)) { case STRM_TAG_INT: n = sprintf(buf, "%d", strm_to_int(v)); return strm_str_new(buf, n); case STRM_TAG_BOOL: n = sprintf(buf, strm_to_int(v) ? "true" : "false"); return strm_str_new(buf, n); case STRM_TAG_CFUNC: n = sprintf(buf, "<cfunc:%p>", (void*)strm_value_cfunc(v)); return strm_str_new(buf, n); case STRM_TAG_STRING_I: case STRM_TAG_STRING_6: case STRM_TAG_STRING_O: case STRM_TAG_STRING_F: return strm_value_str(v); case STRM_TAG_ARRAY: case STRM_TAG_STRUCT: return strm_inspect(v); case STRM_TAG_PTR: if (strm_value_val(v) == 0) return strm_str_lit("nil"); else { void *p = strm_ptr(v); switch (strm_ptr_type(p)) { case STRM_PTR_STREAM: n = sprintf(buf, "<stream:%p>", p); break; case STRM_PTR_IO: { strm_io io = (strm_io)p; char *mode; switch (io->mode & 3) { case STRM_IO_READ: mode = "r"; break; case STRM_IO_WRITE: mode = "w"; break; case STRM_IO_READ|STRM_IO_WRITE: mode = "rw"; break; default: mode = "?"; break; } n = sprintf(buf, "<io: fd=%d mode=%s>", io->fd, mode); break; } case STRM_PTR_LAMBDA: n = sprintf(buf, "<lambda:%p>", p); break; case STRM_PTR_AUX: n = sprintf(buf, "<obj:%p>", p); break; } return strm_str_new(buf, n); } default: if (strm_flt_p(v)) { n = sprintf(buf, "%.14g", strm_to_flt(v)); return strm_str_new(buf, n); } n = sprintf(buf, "<%p>", strm_value_vptr(v)); return strm_str_new(buf, n); } /* not reached */ return strm_str_null; }
static int str_split(strm_stream* strm, int argc, strm_value* args, strm_value* ret) { strm_string str; strm_string sep; const char* s; strm_int slen; const char* t; const char* p; const char* pend; char c; strm_int n = 0; strm_array ary; strm_value* sps; strm_int i; switch (argc) { case 1: str = args[0]; sep = strm_str_lit(" "); break; case 2: str = args[0]; if (!strm_string_p(args[1])) { strm_raise(strm, "need string separator"); return STRM_NG; } sep = strm_value_str(args[1]); break; default: strm_raise(strm, "wrong number of arguments"); return STRM_NG; } /* count number of split strings */ s = strm_str_ptr(sep); slen = strm_str_len(sep); c = s[0]; t = p = strm_str_ptr(str); pend = p + strm_str_len(str) - slen; n = 0; while (p<pend) { if (*p == c) { if (memcmp(p, s, slen) == 0) { if (!(slen == 1 && c == ' ' && (p-t) == 0)) { n++; } t = p + slen; } } p++; } n++; /* actual split */ ary = strm_ary_new(NULL, n); sps = strm_ary_ptr(ary); s = strm_str_ptr(sep); slen = strm_str_len(sep); c = s[0]; t = p = strm_str_ptr(str); pend = p + strm_str_len(str) - slen; i = 0; while (p<pend) { if (*p == c) { if (memcmp(p, s, slen) == 0) { if (!(slen == 1 && c == ' ' && (p-t) == 0)) { sps[i++] = strm_str_new(t, p-t); } t = p + slen; } } p++; } pend = strm_str_ptr(str) + strm_str_len(str); sps[i++] = strm_str_new(t, pend-t); *ret = strm_ary_value(ary); return STRM_OK; }