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;
}
Beispiel #4
0
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);
	}
}
Beispiel #5
0
/**
 * 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;
}