Esempio n. 1
0
static GlpkFileVersion
gnm_glpk_detect_version (GnmGlpk *lp,
			 GsfInputTextline *tl)
{
	GnmSubSolver *subsol = lp->parent;
	gsf_off_t cur = gsf_input_tell (GSF_INPUT (tl));
	GlpkFileVersion ver = GLPK_UNKNOWN;
	const char *line;
	unsigned cols, rows;

	if ((line = gsf_input_textline_utf8_gets (tl)) == NULL)
		goto out;
	if (sscanf (line, "%u %u", &rows, &cols) == 2 &&
	    cols == g_hash_table_size (subsol->cell_from_name)) {
		ver = GLPK_457;
		if (gnm_solver_debug ())
			g_printerr ("Detected version 4.57 file format\n");
		goto out;
	}

	if ((line[0] == 'c' || line[0] == 's') && line[1] == ' ') {
		ver = GLPK_458;
		if (gnm_solver_debug ())
			g_printerr ("Detected version 4.58 file format\n");
		goto out;
	}	

out:
	// Extra seek due to gsf bug
	gsf_input_seek (GSF_INPUT (tl), cur + 1, G_SEEK_SET);
	gsf_input_seek (GSF_INPUT (tl), cur, G_SEEK_SET);
	return ver;
}
Esempio n. 2
0
static void
go_help_display (CBHelpPaths const *paths)
{
#ifdef GOFFICE_WITH_GNOME
	gnome_help_display (paths->app, paths->link, NULL);
#elif defined(G_OS_WIN32)
	static GHashTable* context_help_map = NULL;
	guint id;

	if (!context_help_map) {
		GsfInput *input;
		GsfInputTextline *textline;
		GError *err = NULL;
		gchar *mapfile = g_strconcat (paths->app, ".hhmap", NULL);
		gchar *path = g_build_filename (paths->data_dir, "doc", "C", mapfile, NULL);

		g_free (mapfile);

		if (!(input = gsf_input_stdio_new (path, &err)) ||
		    !(textline = (GsfInputTextline *) gsf_input_textline_new (input)))
			go_gtk_notice_dialog (NULL, GTK_MESSAGE_ERROR, "Cannot open '%s': %s",
					      path, err ? err->message :
							  "failed to create gsf-input-textline");
		else {
			gchar *line, *topic;
			gulong id, i = 1;
			context_help_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

			while ((line = gsf_input_textline_utf8_gets (textline)) != NULL) {
				if (!(id = strtoul (line, &topic, 10))) {
					go_gtk_notice_dialog (NULL, GTK_MESSAGE_ERROR,
							      "Invalid topic id at line %lu in %s: '%s'",
							      i, path, line);
					continue;
				}
				for (; *topic == ' '; ++topic);
				g_hash_table_insert (context_help_map, g_strdup (topic),
					(gpointer)id);
			}
			g_object_unref (G_OBJECT (textline));
		}
		if (input)
			g_object_unref (G_OBJECT (input));
		g_free (path);
	}

	if (!(id = (guint) g_hash_table_lookup (context_help_map, paths->link)))
		go_gtk_notice_dialog (NULL, GTK_MESSAGE_ERROR, "Topic '%s' not found.",
				      paths->link);
	else {
		gchar *chmfile = g_strconcat (paths->app, ".chm", NULL);
		gchar *path = g_build_filename (paths->data_dir, "doc", "C", chmfile, NULL);

		g_free (chmfile);
		if (!HtmlHelp (GetDesktopWindow (), path, HH_HELP_CONTEXT, id))
			go_gtk_notice_dialog (NULL, GTK_MESSAGE_ERROR, "Failed to spawn HtmlHelp");
		g_free (path);
	}
#else
	go_gtk_notice_dialog (NULL, GTK_MESSAGE_ERROR,
			      "TODO : launch help browser for %s", paths->link);
#endif
}
Esempio n. 3
0
/**
 * gsf_input_textline_ascii_gets:
 * @textline: #GsfInputTextline
 *
 * A utility routine to read things line by line from the underlying source.
 * Trailing newlines and carriage returns are stripped, and the resultant buffer
 * can be edited.
 *
 * Returns: (transfer none): the string read, or %NULL on eof.
 **/
unsigned char *
gsf_input_textline_ascii_gets (GsfInputTextline *textline)
{
	return gsf_input_textline_utf8_gets (textline);
}
Esempio n. 4
0
static void
gnm_glpk_read_solution (GnmGlpk *lp)
{
	GnmSubSolver *subsol = lp->parent;
	GnmSolver *sol = GNM_SOLVER (subsol);
	GsfInput *input;
	GsfInputTextline *tl = NULL;
	const char *line;
	GnmSolverResult *result = NULL;
	GnmSolverSensitivity *sensitivity = NULL;
	enum { SEC_UNKNOWN, SEC_ROWS, SEC_COLUMNS } state;
	gboolean has_integer;
	GSList *l;

	input = gsf_input_stdio_new (lp->result_filename, NULL);
	if (!input)
		goto fail;
	tl = GSF_INPUT_TEXTLINE (gsf_input_textline_new (input));
	g_object_unref (input);

	result = g_object_new (GNM_SOLVER_RESULT_TYPE, NULL);
	result->solution = g_new0 (gnm_float, sol->input_cells->len);

	sensitivity = gnm_solver_sensitivity_new (sol);

	/*
	 * glpsol's output format is different if there are any integer
	 * constraint.  Go figure.
	 */
	has_integer = sol->params->options.assume_discrete;
	for (l = sol->params->constraints; !has_integer && l; l = l->next) {
		GnmSolverConstraint *c = l->data;
		has_integer = (c->type == GNM_SOLVER_INTEGER ||
			       c->type == GNM_SOLVER_BOOLEAN);
	}

	switch (gnm_glpk_detect_version (lp, tl)) {
	case GLPK_457:
		if (gnm_glpk_read_solution_457 (lp, tl, result, sensitivity,
						has_integer))
			goto fail;
		break;
	case GLPK_458:
		if (gnm_glpk_read_solution_458 (lp, tl, result, sensitivity,
						has_integer))
			goto fail;
		break;
	default:
		goto fail;
	}

	g_object_unref (tl);
	tl = NULL;

	// ----------------------------------------

	if (!lp->ranges_filename)
		goto done;

	input = gsf_input_stdio_new (lp->ranges_filename, NULL);
	if (!input)
		goto fail;
	tl = GSF_INPUT_TEXTLINE (gsf_input_textline_new (input));
	g_object_unref (input);

	state = SEC_UNKNOWN;
	// We are reading a file intended for human consumption.
	// That is unfortunately because it implies rounding, for example.
	// The information does not appear to be available elsewhere.

	while ((line = gsf_input_textline_utf8_gets (tl)) != NULL) {
		gchar **items, **items2 = NULL;
		int len, len2 = 0;

		if (g_str_has_prefix (line, "   No. Row name")) {
			state = SEC_ROWS;
			continue;
		} else if (g_str_has_prefix (line, "   No. Column name")) {
			state = SEC_COLUMNS;
			continue;
		} else if (g_ascii_isalpha (line[0])) {
			state = SEC_UNKNOWN;
			continue;
		}

		if (state == SEC_UNKNOWN)
			continue;

		items = my_strsplit (line);
		len = g_strv_length (items);

		if (len == 10 && g_ascii_isdigit (items[0][0])) {
			line = gsf_input_textline_utf8_gets (tl);
			if (line) {
				items2 = my_strsplit (line);
				len2 = g_strv_length (items2);
			}
		}

		if (len == 10 && len2 == 6 && state == SEC_COLUMNS) {
			gnm_float low = parse_number (items[7]);
			gnm_float high = parse_number (items2[3]);
			GnmCell const *cell = gnm_sub_solver_find_cell (lp->parent, items[1]);
			int idx = gnm_solver_cell_index (sol, cell);
			if (idx >= 0) {
				sensitivity->vars[idx].low = low;
				sensitivity->vars[idx].high = high;
			}
		}

		if (len == 10 && len2 == 6 && state == SEC_ROWS) {
			gnm_float low = parse_number (items[6]);
			gnm_float high = parse_number (items2[2]);
			int cidx = gnm_sub_solver_find_constraint (lp->parent, items[1]);
			if (cidx >= 0) {
				sensitivity->constraints[cidx].low = low;
				sensitivity->constraints[cidx].high = high;
			}
		}
		
		g_strfreev (items);
		g_strfreev (items2);

	}

	g_object_unref (tl);

	// ----------------------------------------
done:
	gnm_solver_set_status (sol, GNM_SOLVER_STATUS_DONE);
	g_object_set (subsol, "result", result, NULL);
	g_object_unref (result);
	g_object_set (subsol, "sensitivity", sensitivity, NULL);
	g_object_unref (sensitivity);

	return;

fail:
	if (tl)
		g_object_unref (tl);
	if (result)
		g_object_unref (result);
	if (sensitivity)
		g_object_unref (sensitivity);
	gnm_solver_set_status (sol, GNM_SOLVER_STATUS_ERROR);
}
Esempio n. 5
0
static gboolean
gnm_glpk_read_solution_457 (GnmGlpk *lp,
			    GsfInputTextline *tl,
			    GnmSolverResult *result,
			    GnmSolverSensitivity *sensitivity,
			    gboolean has_integer)
{
	GnmSubSolver *subsol = lp->parent;
	const char *line;
	unsigned cols, rows, c, r;
	int pstat, dstat;
	gnm_float val;

	if ((line = gsf_input_textline_utf8_gets (tl)) == NULL)
		goto fail;
	if (sscanf (line, "%u %u", &rows, &cols) != 2 ||
	    cols != g_hash_table_size (subsol->cell_from_name))
		goto fail;

	if ((line = gsf_input_textline_utf8_gets (tl)) == NULL)
		goto fail;

	if (has_integer
	    ? sscanf (line, "%d %" GNM_SCANF_g, &pstat, &val) != 2
	    : sscanf (line, "%d %d %" GNM_SCANF_g, &pstat, &dstat, &val) != 3)
		goto fail;

	result->value = val;
	switch (pstat) {
	case 2:
	case 5:
		result->quality = GNM_SOLVER_RESULT_OPTIMAL;
		break;
	case 1: /* "Undefined" -- see #611407 */
	case 3:
	case 4:
		result->quality = GNM_SOLVER_RESULT_INFEASIBLE;
		break;
	case 6:
		result->quality = GNM_SOLVER_RESULT_UNBOUNDED;
		break;
	default:
		goto fail;
	}

	for (r = 0; r < rows; r++) {
		gnm_float pval, dval;
		unsigned rstat;
		unsigned cidx = r;

		if ((line = gsf_input_textline_utf8_gets (tl)) == NULL)
			goto fail;

		if (has_integer)
			continue;

		if (sscanf (line, "%u %" GNM_SCANF_g " %" GNM_SCANF_g,
			    &rstat, &pval, &dval) != 3)
			goto fail;

		sensitivity->constraints[cidx].shadow_price = dval;
	}

	for (c = 0; c < cols; c++) {
		gnm_float pval, dval;
		unsigned cstat;
		unsigned idx = c;

		if ((line = gsf_input_textline_utf8_gets (tl)) == NULL)
			goto fail;

		if (has_integer
		    ? sscanf (line, "%" GNM_SCANF_g, &pval) != 1
		    : sscanf (line, "%u %" GNM_SCANF_g " %" GNM_SCANF_g,
			      &cstat, &pval, &dval) != 3)
			goto fail;

		result->solution[idx] = pval;
		if (!has_integer)
			sensitivity->vars[idx].reduced_cost = dval;
	}

	// Success
	return FALSE;

fail:
	return TRUE;
}