const char* strm_p(strm_value val) { char buf[7]; strm_string str = strm_to_str(val); const char* p = strm_str_cstr(str, buf); fputs(p, stdout); fputs("\n", stdout); return p; }
strm_string strm_inspect(strm_value v) { if (strm_string_p(v)) { strm_string str = strm_value_str(v); return str_dump(str, str_dump_len(str)); } else if (strm_array_p(v)) { char *buf = malloc(32); strm_int i, bi = 0, capa = 32; strm_array a = strm_value_ary(v); for (i=0; i<strm_ary_len(a); i++) { strm_string str = strm_inspect(strm_ary_ptr(a)[i]); strm_string key = (strm_ary_headers(a) && strm_string_p(strm_ary_ptr(strm_ary_headers(a))[i])) ? strm_value_str(strm_ary_ptr(strm_ary_headers(a))[i]) : strm_str_null; strm_int slen = (key ? (strm_str_len(key)+1) : 0) + strm_str_len(str) + 3; if (bi+slen > capa) { capa *= 2; buf = realloc(buf, capa); } if (bi == 0) { buf[bi++] = '['; } else { buf[bi++] = ','; buf[bi++] = ' '; } if (key) { if (!str_symbol_p(key)) { key = str_dump(key, str_dump_len(key)); } memcpy(buf+bi, strm_str_ptr(key), strm_str_len(key)); bi += strm_str_len(key); buf[bi++] = ':'; } memcpy(buf+bi, strm_str_ptr(str), strm_str_len(str)); bi += strm_str_len(str); } buf[bi++] = ']'; return strm_str_new(buf, bi); } else { return strm_to_str(v); } }
static int exec_cputs(strm_stream* strm, FILE* out, int argc, strm_value* args, strm_value* ret) { int i; for (i = 0; i < argc; i++) { strm_string s; if (i != 0) fputs(", ", out); s = strm_to_str(args[i]); fwrite(strm_str_ptr(s), strm_str_len(s), 1, out); } fputs("\n", out); return STRM_OK; }
static int exec_cputs(strm_state* state, FILE* out, int argc, strm_value* args, strm_value* ret) { int i; for (i = 0; i < argc; i++) { strm_string *s; if (i != 0) fputs(", ", out); s = strm_to_str(args[i]); fwrite(s->ptr, s->len, 1, out); } fputs("\n", out); return STRM_OK; }
static void csv_accept(strm_task* task, strm_value data) { strm_array *ary; strm_string *line = strm_value_str(data); strm_value *bp; char *tmp, *tptr; const char *ptr; const char *pend; int fieldcnt, len; int in_quote = 0, quoted = 0, all_str = 1;; struct csv_data *cd = task->data; if (cd->prev) { strm_string *str = strm_str_new(NULL, cd->prev->len+line->len+1); tmp = (char*)str->ptr; memcpy(tmp, cd->prev->ptr, cd->prev->len); *(tmp+cd->prev->len) = '\n'; memcpy(tmp+cd->prev->len+1, line->ptr, line->len); line = str; cd->prev = NULL; } fieldcnt = count_fields(line); if (fieldcnt == -1) { cd->prev = line; return; } if (cd->n > 0 && fieldcnt != cd->n) return; ptr = line->ptr; pend = ptr + line->len; ary = strm_ary_new(NULL, fieldcnt); if (!ary) return; bp = (strm_value*)ary->ptr; len = line->len; tmp = malloc(len+1); if (!tmp) return; *tmp='\0'; ptr=line->ptr; tptr=tmp; for (;ptr<pend; ptr++) { if (in_quote) { if (*ptr == '\"') { if (ptr[1] == '\"') { *tptr++ = '\"'; ptr++; continue; } in_quote = 0; } else *tptr++ = *ptr; continue; } switch(*ptr) { case '\"': in_quote = 1; quoted = 1; continue; case ',': if (quoted) { *bp = strm_str_value(tmp, tptr-tmp); } else { *bp = csv_value(tmp, tptr-tmp); } if (!strm_str_p(*bp)) all_str = 0; bp++; tptr = tmp; quoted = 0; break; default: *tptr++ = *ptr; continue; } } /* trim newline at the end */ if (tptr > tmp && tptr[-1] == '\n') { tptr--; } /* trim carriage return at the end */ if (tptr > tmp && tptr[-1] == '\r') { tptr--; } *bp = csv_value(tmp, tptr-tmp); if (!strm_str_p(*bp)) all_str = 0; free(tmp); /* check headers */ if (!cd->headers && !cd->types) { if (all_str) { cd->headers = ary; ary = NULL; } cd->n = fieldcnt; } if (ary) { int i; /* set headers if any */ if (cd->headers) ary->headers = cd->headers; if (!cd->types) { /* first data line (after optinal header line) */ if (cd->headers) { if (all_str) { /* data line is all string; emit header line */ strm_emit(task, strm_ptr_value(cd->headers), NULL); cd->headers = NULL; } else { /* intern header strings */ strm_array *h = cd->headers; strm_value *p = (strm_value*)h->ptr; int i; for (i=0; i<h->len; i++) { strm_string *str = strm_value_str(p[i]); p[i] = strm_ptr_value(strm_str_intern_str(str)); } } } /* initialize types (determined by first data line) */ cd->types = malloc(sizeof(enum csv_type)*fieldcnt); if (!cd->types) return; for (i=0; i<fieldcnt; i++) { cd->types[i] = csv_type(ary->ptr[i]); } } else { /* type check */ for (i=0; i<fieldcnt; i++) { if (cd->types[i] != csv_type(ary->ptr[i])) { if (cd->types[i] == STRING_TYPE) { /* convert value to string */ ((strm_value*)ary->ptr)[i] = strm_ptr_value(strm_to_str(ary->ptr[i])); } else { /* type mismatch (error); skip this line */ return; } } } } strm_emit(task, strm_ptr_value(ary), NULL); } }