Пример #1
0
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;
}
Пример #2
0
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);
  }
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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);
  }
}