static GnmValue * gnumeric_not (GnmFuncEvalInfo *ei, GnmValue const * const *argv) { gboolean err, val = value_get_as_bool (argv [0], &err); if (err) return value_new_error (ei->pos, _("Type Mismatch")); return value_new_bool (!val); }
static GnmValue * callback_function_and (GnmEvalPos const *ep, GnmValue const *value, void *closure) { int *result = closure; if (!VALUE_IS_STRING (value)) { gboolean err; *result = value_get_as_bool (value, &err) && *result; if (err) return value_new_error_VALUE (ep); } return NULL; }
gboolean go_conf_set_value_from_str (GOConfNode *node, gchar const *key, gchar const *val_str) { switch (go_conf_node_get_key_type (node, key)) { case G_TYPE_STRING: go_conf_set_string (node, key, val_str); break; case G_TYPE_FLOAT: { GODateConventions const *conv = NULL; /* workbook_date_conv (state->wb); */ GnmValue *value = format_match_number (val_str, NULL, conv); if (value != NULL) { gnm_float the_float = value_get_as_float (value); go_conf_set_double (node, key, the_float); } value_release (value); break; } case G_TYPE_INT: { GODateConventions const *conv = NULL; /* workbook_date_conv (state->wb); */ GnmValue *value = format_match_number (val_str, NULL, conv); if (value != NULL) { gint the_int = value_get_as_int (value); go_conf_set_int (node, key, the_int); } value_release (value); break; } case G_TYPE_BOOLEAN: { GODateConventions const *conv = NULL; /* workbook_date_conv (state->wb); */ GnmValue *value = format_match_number (val_str, NULL, conv); gboolean err, the_bool; if (value != NULL) { err = FALSE; the_bool = value_get_as_bool (value, &err); go_conf_set_bool (node, key, the_bool); } value_release (value); break; } default: g_warning ("Unsupported gconf type in preference dialog"); } return TRUE; }
G_MODULE_EXPORT void paradox_file_save (GOFileSaver const *fs, GOIOContext *io_context, WorkbookView const *wb_view, GsfOutput *output) { Sheet *sheet; GnmRange r; gint row, col, i; pxdoc_t *pxdoc = NULL; pxfield_t *pxf; char *data; char *tmpfilename; sheet = wb_view_cur_sheet (wb_view); if (sheet == NULL) { go_io_error_string (io_context, _("Cannot get default sheet.")); return; } r = sheet_get_extent (sheet, FALSE, TRUE); #ifdef PX_MEMORY_DEBUGGING pxdoc = PX_new2 (gn_errorhandler, PX_mp_malloc, PX_mp_realloc, PX_mp_free); #else pxdoc = PX_new2 (gn_errorhandler, gn_malloc, gn_realloc, gn_free); #endif /* Read the field specification and build the field array for * PX_create_fp(). The memory is freed by PX_delete() including * the memory for the field name. */ if ((pxf = (pxfield_t *) pxdoc->malloc (pxdoc, (r.end.col+1)*sizeof (pxfield_t), _("Allocate memory for field definitions."))) == NULL){ go_io_error_string (io_context, _("Cannot allocate memory for field definitions.")); PX_delete (pxdoc); return; } for (col = r.start.col; col <= r.end.col; col++) { GnmCell *cell = sheet_cell_get (sheet, col, 0); if (gnm_cell_is_empty (cell)) { go_io_error_string (io_context, _("First line of sheet must contain database specification.")); PX_delete (pxdoc); return; } else { gchar *fieldstr, *tmp; int len, needsize, needprecision; i = col; fieldstr = gnm_cell_get_rendered_text (cell); needsize = 0; needprecision = 0; /* Search for the first comma which is the end of the field name. */ tmp = strchr (fieldstr, ','); if (NULL == tmp) { g_warning (_("Field specification must be a comma separated value (Name,Type,Size,Prec).")); PX_delete (pxdoc); return; } len = tmp-fieldstr; if (NULL == (pxf[i].px_fname = pxdoc->malloc (pxdoc, len+1, _("Allocate memory for column name.")))) { g_warning (_("Could not allocate memory for %d. field name."), i); PX_delete (pxdoc); return; } strncpy (pxf[i].px_fname, fieldstr, len); pxf[i].px_fname[len] = '\0'; /* Get the field Type */ fieldstr = tmp+1; if (*fieldstr == '\0') { g_warning (_("%d. field specification ended unexpectedly."), i); PX_delete (pxdoc); return; } if (*fieldstr == ',') { g_warning (_("%d. field specification misses type."), i); PX_delete (pxdoc); return; } switch ((int) *fieldstr) { case 'S': pxf[i].px_ftype = pxfShort; pxf[i].px_flen = 2; break; case 'I': pxf[i].px_ftype = pxfLong; pxf[i].px_flen = 4; break; case 'A': case 'C': pxf[i].px_ftype = pxfAlpha; needsize = 1; break; case 'N': pxf[i].px_ftype = pxfNumber; pxf[i].px_flen = 8; break; case '$': pxf[i].px_ftype = pxfCurrency; pxf[i].px_flen = 8; break; case 'L': pxf[i].px_ftype = pxfLogical; pxf[i].px_flen = 1; break; case 'D': pxf[i].px_ftype = pxfDate; pxf[i].px_flen = 4; break; case '+': pxf[i].px_ftype = pxfAutoInc; pxf[i].px_flen = 4; break; case '@': pxf[i].px_ftype = pxfTimestamp; pxf[i].px_flen = 8; break; case 'T': pxf[i].px_ftype = pxfTime; pxf[i].px_flen = 4; break; case '#': pxf[i].px_ftype = pxfBCD; pxf[i].px_flen = 17; needprecision = 1; break; case 'M': pxf[i].px_ftype = pxfMemoBLOb; needsize = 1; break; case 'B': pxf[i].px_ftype = pxfBLOb; needsize = 1; break; case 'F': pxf[i].px_ftype = pxfFmtMemoBLOb; needsize = 1; break; case 'Y': pxf[i].px_ftype = pxfBytes; needsize = 1; break; default: g_warning (_("%d. field type '%c' is unknown."), i, *fieldstr); pxdoc->free (pxdoc, pxf); PX_delete (pxdoc); return; } if (needsize || needprecision) { char *endptr; /* find end of type definition */ tmp = strchr (fieldstr, ','); if (NULL == tmp || *(tmp+1) == '\0') { g_warning (_("Field specification misses the column size.")); PX_delete (pxdoc); return; } fieldstr = tmp+1; if (needsize) pxf[i].px_flen = strtol (fieldstr, &endptr, 10); else pxf[i].px_fdc = strtol (fieldstr, &endptr, 10); if ((endptr == NULL) || (fieldstr == endptr)) { g_warning (_("Field specification misses the column size.")); PX_delete (pxdoc); return; } if (*endptr != '\0') { /* There is also precision which we do not care about. */ fieldstr = endptr+1; g_warning (_("The remainder '%s' of the specification for field %d is being disregarded."), fieldstr, i+1); } } } } /* Create the paradox file */ tmpfilename = tempnam ("/tmp", NULL); if (0 > PX_create_file (pxdoc, pxf, r.end.col+1, tmpfilename, pxfFileTypNonIndexDB)) { g_warning (_("Could not create output file.")); PX_delete (pxdoc); return; } PX_set_inputencoding (pxdoc, "UTF-8"); PX_set_parameter (pxdoc, "targetencoding", "CP1252"); PX_set_tablename (pxdoc, sheet->name_unquoted); if ((data = (char *) pxdoc->malloc (pxdoc, pxdoc->px_head->px_recordsize, _("Allocate memory for record data."))) == NULL) { g_warning (_("Could not allocate memory for record data.")); PX_close (pxdoc); PX_delete (pxdoc); return; } /* Process all cells */ for (row = r.start.row+1; row <= r.end.row; row++) { int i; int offset; offset = 0; memset (data, 0, pxdoc->px_head->px_recordsize); for (col = r.start.col, i = 0; col <= r.end.col; col++) { GnmCell *cell = sheet_cell_get (sheet, col, row); if (!gnm_cell_is_empty (cell)) { char *fieldstr = gnm_cell_get_rendered_text (cell); switch (pxf[i].px_ftype) { case pxfShort: { int value = value_get_as_int (cell->value); PX_put_data_short (pxdoc, &data[offset], 2, (short int) value); break; } case pxfLong: case pxfAutoInc: { int value = value_get_as_int (cell->value); PX_put_data_long (pxdoc, &data[offset], 4, value); break; } case pxfTimestamp: { double value = value_get_as_float (cell->value); /* 60 would be 29.2.1900 which didn't exist. */ if (value < 60) value += 1.0; value += 693594; value *= 86400000.0; PX_put_data_double (pxdoc, &data[offset], 8, value); break; } case pxfCurrency: case pxfNumber: { double value = value_get_as_float (cell->value); PX_put_data_double(pxdoc, &data[offset], 8, value); break; } case pxfAlpha: { char *value = fieldstr; int nlen = strlen (value); if (nlen > pxf[i].px_flen) /* xgettext : last %d gives the number of characters.*/ /* This is input to ngettext. */ g_warning (ngettext ("Field %d in line %d has possibly " "been cut off. Data has %d character.", "Field %d in line %d has possibly " "been cut off. Data has %d characters.", nlen), i+1, row+1, nlen); PX_put_data_alpha (pxdoc, &data[offset], pxf[i].px_flen, value); break; } case pxfMemoBLOb: case pxfFmtMemoBLOb: { char *value = fieldstr; if (0 > PX_put_data_blob (pxdoc, &data[offset], pxf[i].px_flen, value, strlen (value))) { g_warning (_("Field %d in row %d could not be written."), i+1, row+1); } break; } case pxfDate: { long value = value_get_as_int (cell->value); /* 60 would be 29.2.1900 which didn't exist. */ if (value < 60) value++; value += 693594; PX_put_data_long (pxdoc, &data[offset], 4, value); break; } case pxfTime: { double dtmp; int value; dtmp = value_get_as_float (cell->value); dtmp -= ((int) dtmp); value = (int) (dtmp * 86400000.0); PX_put_data_long (pxdoc, &data[offset], 4, value); break; } case pxfLogical: { gboolean err; /* Ignored */ gboolean value = value_get_as_bool (cell->value, &err); PX_put_data_byte (pxdoc, &data[offset], 1, value ? 1 : 0); break; } case pxfBCD: PX_put_data_bcd (pxdoc, &data[offset], pxf[i].px_fdc, fieldstr); break; } } offset += pxf[i].px_flen; i++; } if ((i > 0) && (0 > PX_put_record (pxdoc, data))) { g_warning (_("Could not write record number %d."), i+1); pxdoc->free (pxdoc, data); PX_close (pxdoc); PX_delete (pxdoc); return; } } pxdoc->free (pxdoc, data); PX_close (pxdoc); PX_delete (pxdoc); #ifdef PX_MEMORY_DEBUGGING PX_mp_list_unfreed (); #endif { FILE *fp; size_t size; fp = fopen (tmpfilename, "r"); if (fp) { data = g_malloc (8192); while (0 != (size = fread (data, 1, 8192, fp))) gsf_output_write (output, size, data); fclose (fp); g_free (data); } else g_warning ("Cannot open %s\n", tmpfilename); unlink (tmpfilename); } }
/** * gnm_validation_eval: * @wbc: * @mstyle: * @sheet: * * validation set in the GnmStyle if applicable. **/ ValidationStatus gnm_validation_eval (WorkbookControl *wbc, GnmStyle const *mstyle, Sheet *sheet, GnmCellPos const *pos, gboolean *showed_dialog) { GnmValidation const *v; GnmCell *cell; GnmValue *val; gnm_float x; int nok, i; GnmEvalPos ep; if (showed_dialog) *showed_dialog = FALSE; v = gnm_style_get_validation (mstyle); if (v == NULL) return GNM_VALIDATION_STATUS_VALID; if (v->type == GNM_VALIDATION_TYPE_ANY) return GNM_VALIDATION_STATUS_VALID; cell = sheet_cell_get (sheet, pos->col, pos->row); if (cell != NULL) gnm_cell_eval (cell); if (gnm_cell_is_empty (cell)) { if (v->allow_blank) return GNM_VALIDATION_STATUS_VALID; BARF (g_strdup_printf (_("Cell %s is not permitted to be blank"), cell_name (cell))); } val = cell->value; switch (val->type) { case VALUE_ERROR: if (typeinfo[v->type].errors_not_allowed) BARF (g_strdup_printf (_("Cell %s is not permitted to contain error values"), cell_name (cell))); break; case VALUE_BOOLEAN: if (typeinfo[v->type].bool_always_ok) return GNM_VALIDATION_STATUS_VALID; break; case VALUE_STRING: if (typeinfo[v->type].strings_not_allowed) BARF (g_strdup_printf (_("Cell %s is not permitted to contain strings"), cell_name (cell))); break; default: break; } eval_pos_init_cell (&ep, cell); switch (v->type) { case GNM_VALIDATION_TYPE_AS_INT: x = value_get_as_float (val); if (gnm_fake_floor (x) == gnm_fake_ceil (x)) break; else BARF (g_strdup_printf (_("'%s' is not an integer"), value_peek_string (val))); case GNM_VALIDATION_TYPE_AS_NUMBER: x = value_get_as_float (val); break; case GNM_VALIDATION_TYPE_AS_DATE: /* What the hell does this do? */ x = value_get_as_float (val); if (x < 0) BARF (g_strdup_printf (_("'%s' is not a valid date"), value_peek_string (val))); break; case GNM_VALIDATION_TYPE_AS_TIME: /* What the hell does this do? */ x = value_get_as_float (val); break; case GNM_VALIDATION_TYPE_IN_LIST: { GnmExprTop const *texpr = v->deps[0].texpr; if (texpr) { GnmValue *list = gnm_expr_top_eval (texpr, &ep, GNM_EXPR_EVAL_PERMIT_NON_SCALAR | GNM_EXPR_EVAL_PERMIT_EMPTY); GnmValue *res = value_area_foreach (list, &ep, CELL_ITER_IGNORE_BLANK, (GnmValueIterFunc) cb_validate_custom, val); value_release (list); if (res == NULL) { GnmParsePos pp; char *expr_str = gnm_expr_top_as_string (texpr, parse_pos_init_evalpos (&pp, &ep), ep.sheet->convs); char *msg = g_strdup_printf (_("%s does not contain the new value."), expr_str); g_free (expr_str); BARF (msg); } } return GNM_VALIDATION_STATUS_VALID; } case GNM_VALIDATION_TYPE_TEXT_LENGTH: /* XL appears to use a very basic value->string mapping that * ignores formatting. * eg len (12/13/01) == len (37238) = 5 * This seems wrong for */ x = g_utf8_strlen (value_peek_string (val), -1); break; case GNM_VALIDATION_TYPE_CUSTOM: { gboolean valid; GnmExprTop const *texpr = v->deps[0].texpr; if (!texpr) return GNM_VALIDATION_STATUS_VALID; val = gnm_expr_top_eval (texpr, &ep, GNM_EXPR_EVAL_SCALAR_NON_EMPTY); valid = value_get_as_bool (val, NULL); value_release (val); if (valid) return GNM_VALIDATION_STATUS_VALID; else { GnmParsePos pp; char *expr_str = gnm_expr_top_as_string (texpr, parse_pos_init_evalpos (&pp, &ep), ep.sheet->convs); char *msg = g_strdup_printf (_("%s is not true."), expr_str); g_free (expr_str); BARF (msg); } } default: g_assert_not_reached (); return GNM_VALIDATION_STATUS_VALID; } if (v->op == GNM_VALIDATION_OP_NONE) return GNM_VALIDATION_STATUS_VALID; nok = 0; for (i = 0; i < opinfo[v->op].nops; i++) { GnmExprTop const *texpr_i = v->deps[i].texpr; GnmExprTop const *texpr; GnmValue *cres; if (!texpr_i) { nok++; continue; } texpr = gnm_expr_top_new (gnm_expr_new_binary (gnm_expr_new_constant (value_new_float (x)), opinfo[v->op].ops[i], gnm_expr_copy (texpr_i->expr))); cres = gnm_expr_top_eval (texpr, &ep, GNM_EXPR_EVAL_SCALAR_NON_EMPTY); if (value_get_as_bool (cres, NULL)) nok++; value_release (cres); gnm_expr_top_unref (texpr); } if (nok < opinfo[v->op].ntrue) BARF (g_strdup_printf (_("%s is out of permitted range"), value_peek_string (val))); return GNM_VALIDATION_STATUS_VALID; }