/* * Coalesce two SSDs. fromq will be deleted, preceded by transferring of all * its children to toq */ int ssd_coalesce(Quark *toq, Quark *fromq) { unsigned int nrows, ncols, i, j; ss_data *ssd; AMem *amem = toq->amem; coalesce_hook_t p; nrows = ssd_get_nrows(fromq); if (nrows > ssd_get_nrows(toq)) { if (ssd_set_nrows(toq, nrows) != RETURN_SUCCESS) { return RETURN_FAILURE; } } /* original number of columns */ ncols = ssd_get_ncols(toq); ssd = ssd_get_data(fromq); for (i = 0; i < ssd->ncols; i++) { ss_column *col = &ssd->cols[i]; ss_column *col_new = ssd_add_col(toq, col->format); if (!col_new) { return RETURN_FAILURE; } col_new->label = amem_strdup(amem, col->label); if (col->format == FFORMAT_STRING) { for (j = 0; j < nrows; j++) { ((char **) col_new->data)[j] = amem_strdup(amem, ((char **) col->data)[j]); } } else { memcpy(col_new->data, col->data, nrows*SIZEOF_DOUBLE); } } p.toq = toq; p.nshift = ncols; quark_traverse(fromq, coalesce_hook, &p); quark_free(fromq); return RETURN_SUCCESS; }
int ssd_transpose(Quark *q) { ss_data *ssd_new, *ssd_old; unsigned int ncols, nrows, i, j; if (!ssd_is_numeric(q)) { return RETURN_FAILURE; } ncols = ssd_get_ncols(q); nrows = ssd_get_nrows(q); if (!ncols || !nrows) { return RETURN_FAILURE; } ssd_new = ssd_data_new(q->amem); if (!ssd_new) { return RETURN_FAILURE; } /* swap the data */ ssd_old = q->data; q->data = ssd_new; if (ssd_set_ncols(q, nrows, NULL) != RETURN_SUCCESS || ssd_set_nrows(q, ncols) != RETURN_SUCCESS) { ssd_data_free(q->amem, ssd_new); q->data = ssd_old; return RETURN_FAILURE; } for (i = 0; i < ncols; i++) { for (j = 0; j < nrows; j++) { ssd_set_value(q, i, j, ((double *)ssd_old->cols[i].data)[j]); } } quark_dirtystate_set(q, TRUE); ssd_data_free(q->amem, ssd_old); return RETURN_SUCCESS; }
/* * drop rows */ int ssd_delete_rows(Quark *q, unsigned int startno, unsigned int endno) { ss_data *ssd = ssd_get_data(q); unsigned int i, j, dist; if (!ssd || startno >= ssd->nrows || endno >= ssd->nrows) { return RETURN_FAILURE; } if (endno < startno) { uswap(&endno, &startno); } if (endno == ssd->nrows - 1) { /* trivial case */ return ssd_set_nrows(q, startno); } dist = endno - startno + 1; for (j = 0; j < ssd->ncols; j++) { ss_column *col = &ssd->cols[j]; if (col->format == FFORMAT_STRING) { char **s = col->data; for (i = startno; i <= endno; i++) { amem_free(q->amem, s[i]); } memmove(s + startno, s + endno + 1, (ssd->nrows - endno - 1)*SIZEOF_VOID_P); } else { double *x = col->data; memmove(x + startno, x + endno + 1, (ssd->nrows - endno - 1)*SIZEOF_DOUBLE); } } ssd->nrows -= dist; quark_dirtystate_set(q, TRUE); return RETURN_SUCCESS; }
static int leaveCB(TableEvent *event) { SSDataUI *ui = (SSDataUI *) event->anydata; int nrows = ssd_get_nrows(ui->q); int ncols = ssd_get_ncols(ui->q); int format; double value; int changed = FALSE; GraceApp *gapp = gapp_from_quark(ui->q); if (event->row < 0 || event->col < 0 || event->col > ncols) { return TRUE; } if (event->row >= nrows && !string_is_empty(event->value)) { if (ssd_set_nrows(ui->q, event->row + 1) == RETURN_SUCCESS) { changed = TRUE; } } if (event->col == ncols && !string_is_empty(event->value)) { if (parse_date_or_number(get_parent_project(ui->q), event->value, FALSE, get_date_hint(gapp), &value) == RETURN_SUCCESS) { format = FFORMAT_NUMBER; } else { format = FFORMAT_STRING; } if (ssd_add_col(ui->q, format)) { ncols++; changed = TRUE; } } if (event->col < ncols) { char *old_value = get_cell_content(ui, event->row, event->col, &format); if (!strings_are_equal(old_value, event->value)) { switch (format) { case FFORMAT_STRING: if (ssd_set_string(ui->q, event->row, event->col, event->value) == RETURN_SUCCESS) { quark_dirtystate_set(ui->q, TRUE); changed = TRUE; } break; default: if (graal_eval_expr(grace_get_graal(gapp->grace), event->value, &value, gproject_get_top(gapp->gp)) == RETURN_SUCCESS) { unsigned int prec; char buf[32]; double val; prec = project_get_prec(get_parent_project(ui->q)); sprintf(buf, "%.*g", prec, value); if (parse_date_or_number(get_parent_project(ui->q), buf, FALSE, get_date_hint(gapp), &val) == RETURN_SUCCESS) { if (ssd_set_value(ui->q, event->row, event->col, val) == RETURN_SUCCESS) { quark_dirtystate_set(ui->q, TRUE); changed = TRUE; } } } else { errmsg("Can't parse input value"); return FALSE; } break; } } } if (changed) { snapshot_and_update(gapp->gp, FALSE); } return TRUE; }
int uniread(Quark *pr, FILE *fp, DataParser parse_cb, DataStore store_cb, void *udata) { int nrows, nrows_allocated; int ok, readerror; Quark *q = NULL; char *linebuf = NULL; int linebuflen = 0; int linecount; linecount = 0; readerror = 0; nrows = 0; nrows_allocated = 0; ok = TRUE; while (ok) { char *s; int maybe_data; int ncols, nncols, nscols; int *formats; if (read_long_line(fp, &linebuf, &linebuflen) == RETURN_SUCCESS) { linecount++; s = linebuf; /* skip leading whitespaces */ while (*s == ' ' || *s == '\t') { s++; } /* skip comments */ if (*s == '#') { continue; } /* EOL EOD */ if (*s == '\n' || *s == '\0') { maybe_data = FALSE; } else if (parse_cb && parse_cb(s, udata) == RETURN_SUCCESS) { maybe_data = FALSE; } else { maybe_data = TRUE; } } else { ok = FALSE; maybe_data = FALSE; } if (maybe_data) { if (!nrows) { /* parse the data line */ if (parse_ss_row(pr, s, &nncols, &nscols, &formats) != RETURN_SUCCESS) { errmsg("Can't parse data"); xfree(linebuf); return RETURN_FAILURE; } ncols = nncols + nscols; /* init the SSD */ q = gapp_ssd_new(pr); if (!q || ssd_set_ncols(q, ncols, formats) != RETURN_SUCCESS) { errmsg("Malloc failed in uniread()"); quark_free(q); xfree(formats); xfree(linebuf); return RETURN_FAILURE; } xfree(formats); } if (nrows >= nrows_allocated) { if (!nrows_allocated) { nrows_allocated = BUFSIZE; } else { nrows_allocated *= 2; } if (ssd_set_nrows(q, nrows_allocated) != RETURN_SUCCESS) { errmsg("Malloc failed in uniread()"); quark_free(q); xfree(linebuf); return RETURN_FAILURE; } } if (insert_data_row(q, nrows, s) != RETURN_SUCCESS) { char tbuf[128]; sprintf(tbuf, "Error parsing line %d, skipped", linecount); errmsg(tbuf); readerror++; if (readerror > MAXERR) { if (yesno("Lots of errors, abort?", NULL, NULL, NULL)) { quark_free(q); xfree(linebuf); return RETURN_FAILURE; } else { readerror = 0; } } } else { nrows++; } } else if (nrows) { /* free excessive storage */ ssd_set_nrows(q, nrows); /* store accumulated data */ if (store_cb && store_cb(q, udata) != RETURN_SUCCESS) { quark_free(q); xfree(linebuf); return RETURN_FAILURE; } /* reset state registers */ nrows = 0; nrows_allocated = 0; readerror = 0; } } xfree(linebuf); return RETURN_SUCCESS; }