[gnumeric] SubSolvers: fix crash on plain ssconvert to solver formats.



commit 9220ae972759b082b18528ac5725e8402aa48cf6
Author: Morten Welinder <terra gnome org>
Date:   Wed Feb 10 11:29:41 2016 -0500

    SubSolvers: fix crash on plain ssconvert to solver formats.

 NEWS                            |    1 +
 plugins/glpk/ChangeLog          |    6 +++++
 plugins/glpk/boot.h             |   11 +++++++++
 plugins/glpk/glpk-write.c       |   12 ++++++++++
 plugins/glpk/gnm-glpk.c         |   44 +++++++++++++++++-------------------
 plugins/lpsolve/ChangeLog       |    6 +++++
 plugins/lpsolve/boot.h          |    9 +++++++
 plugins/lpsolve/gnm-lpsolve.c   |   47 +++++++++++++++++++--------------------
 plugins/lpsolve/lpsolve-write.c |   12 ++++++++++
 9 files changed, 101 insertions(+), 47 deletions(-)
---
diff --git a/NEWS b/NEWS
index 8ac27e1..167b1af 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ Gnumeric 1.12.28
 Morten:
        * Fuzzed file fixes.  [#761663] [#761727]
        * Plug leak.
+       * Fix problems with ssconvert to lp/cplex formats.
 
 --------------------------------------------------------------------------
 Gnumeric 1.12.27
diff --git a/plugins/glpk/ChangeLog b/plugins/glpk/ChangeLog
index 3040385..4e07967 100644
--- a/plugins/glpk/ChangeLog
+++ b/plugins/glpk/ChangeLog
@@ -1,3 +1,9 @@
+2016-02-10  Morten Welinder  <terra gnome org>
+
+       * glpk-write.c (glpk_file_save):  Handle the situation where
+       there is no assigned solver -- i.e., plain ssconvert -- by
+       creating a temporary.
+
 2016-02-06  Morten Welinder <terra gnome org>
 
        * Release 1.12.27
diff --git a/plugins/glpk/boot.h b/plugins/glpk/boot.h
index a40468a..85142c5 100644
--- a/plugins/glpk/boot.h
+++ b/plugins/glpk/boot.h
@@ -4,9 +4,20 @@
 #include "gnumeric.h"
 #include <goffice/goffice.h>
 #include <gsf/gsf-output.h>
+#include <tools/gnm-solver.h>
 
 void
 glpk_file_save (GOFileSaver const *fs, GOIOContext *io_context,
                WorkbookView const *wb_view, GsfOutput *output);
 
+
+GnmSolver *glpk_solver_create (GnmSolverParameters *params);
+
+gboolean glpk_solver_factory_functional (GnmSolverFactory *factory,
+                                        WBCGtk *wbcg);
+
+GnmSolver * glpk_solver_factory (GnmSolverFactory *factory,
+                                GnmSolverParameters *params);
+
+
 #endif
diff --git a/plugins/glpk/glpk-write.c b/plugins/glpk/glpk-write.c
index 49fe084..aa9b981 100644
--- a/plugins/glpk/glpk-write.c
+++ b/plugins/glpk/glpk-write.c
@@ -323,8 +323,17 @@ glpk_file_save (GOFileSaver const *fs, GOIOContext *io_context,
        GError *err = NULL;
        GString *prg;
        GnmLocale *locale;
+       GnmSolver *sol = NULL;
        GnmSubSolver *ssol = g_object_get_data (G_OBJECT (fs), "solver");
 
+       if (!ssol) {
+               // Create a temporary solver just functional enough to
+               // write the program
+               Sheet *sheet = wb_view_cur_sheet (wb_view);
+               sol = glpk_solver_create (sheet->solver_parameters);
+               ssol = GNM_SUB_SOLVER (sol);
+       }
+
        go_io_progress_message (io_context,
                                _("Writing glpk file..."));
 
@@ -347,4 +356,7 @@ fail:
        go_io_progress_unset (io_context);
        if (err)
                g_error_free (err);
+
+       if (sol)
+               g_object_unref (sol);
 }
diff --git a/plugins/glpk/gnm-glpk.c b/plugins/glpk/gnm-glpk.c
index ff5bd53..a774cff 100644
--- a/plugins/glpk/gnm-glpk.c
+++ b/plugins/glpk/gnm-glpk.c
@@ -304,9 +304,26 @@ gnm_glpk_stop (GnmSolver *sol, GError *err, GnmGlpk *lp)
        return TRUE;
 }
 
-gboolean
-glpk_solver_factory_functional (GnmSolverFactory *factory,
-                               WBCGtk *wbcg);
+GnmSolver *
+glpk_solver_create (GnmSolverParameters *params)
+{
+       GnmSolver *res = g_object_new (GNM_SUB_SOLVER_TYPE,
+                                      "params", params,
+                                      NULL);
+       GnmGlpk *lp = g_new0 (GnmGlpk, 1);
+
+       lp->parent = GNM_SUB_SOLVER (res);
+
+       g_signal_connect (res, "prepare", G_CALLBACK (gnm_glpk_prepare), lp);
+       g_signal_connect (res, "start", G_CALLBACK (gnm_glpk_start), lp);
+       g_signal_connect (res, "stop", G_CALLBACK (gnm_glpk_stop), lp);
+       g_signal_connect (res, "child-exit", G_CALLBACK (gnm_glpk_child_exit), lp);
+
+       g_object_set_data_full (G_OBJECT (res), PRIVATE_KEY, lp,
+                               (GDestroyNotify)gnm_glpk_final);
+
+       return res;
+}
 
 gboolean
 glpk_solver_factory_functional (GnmSolverFactory *factory,
@@ -340,27 +357,8 @@ glpk_solver_factory_functional (GnmSolverFactory *factory,
        return FALSE;
 }
 
-
-GnmSolver *
-glpk_solver_factory (GnmSolverFactory *factory, GnmSolverParameters *params);
-
 GnmSolver *
 glpk_solver_factory (GnmSolverFactory *factory, GnmSolverParameters *params)
 {
-       GnmSolver *res = g_object_new (GNM_SUB_SOLVER_TYPE,
-                                      "params", params,
-                                      NULL);
-       GnmGlpk *lp = g_new0 (GnmGlpk, 1);
-
-       lp->parent = GNM_SUB_SOLVER (res);
-
-       g_signal_connect (res, "prepare", G_CALLBACK (gnm_glpk_prepare), lp);
-       g_signal_connect (res, "start", G_CALLBACK (gnm_glpk_start), lp);
-       g_signal_connect (res, "stop", G_CALLBACK (gnm_glpk_stop), lp);
-       g_signal_connect (res, "child-exit", G_CALLBACK (gnm_glpk_child_exit), lp);
-
-       g_object_set_data_full (G_OBJECT (res), PRIVATE_KEY, lp,
-                               (GDestroyNotify)gnm_glpk_final);
-
-       return res;
+       return glpk_solver_create (params);
 }
diff --git a/plugins/lpsolve/ChangeLog b/plugins/lpsolve/ChangeLog
index cc36035..e5f8e1f 100644
--- a/plugins/lpsolve/ChangeLog
+++ b/plugins/lpsolve/ChangeLog
@@ -1,3 +1,9 @@
+2016-02-10  Morten Welinder  <terra gnome org>
+
+       * lpsolve-write.c (lpsolve_file_save): Handle the situation where
+       there is no assigned solver -- i.e., plain ssconvert -- by
+       creating a temporary.
+
 2016-02-06  Morten Welinder <terra gnome org>
 
        * Release 1.12.27
diff --git a/plugins/lpsolve/boot.h b/plugins/lpsolve/boot.h
index 5c99ae5..f8f3642 100644
--- a/plugins/lpsolve/boot.h
+++ b/plugins/lpsolve/boot.h
@@ -4,9 +4,18 @@
 #include "gnumeric.h"
 #include <goffice/goffice.h>
 #include <gsf/gsf-output.h>
+#include <tools/gnm-solver.h>
 
 void
 lpsolve_file_save (GOFileSaver const *fs, GOIOContext *io_context,
                   WorkbookView const *wb_view, GsfOutput *output);
 
+GnmSolver *lpsolve_solver_create (GnmSolverParameters *params);
+
+gboolean lpsolve_solver_factory_functional (GnmSolverFactory *factory,
+                                           WBCGtk *wbcg);
+
+GnmSolver *lpsolve_solver_factory (GnmSolverFactory *factory,
+                                  GnmSolverParameters *params);
+
 #endif
diff --git a/plugins/lpsolve/gnm-lpsolve.c b/plugins/lpsolve/gnm-lpsolve.c
index 16f45e8..3210d02 100644
--- a/plugins/lpsolve/gnm-lpsolve.c
+++ b/plugins/lpsolve/gnm-lpsolve.c
@@ -1,6 +1,6 @@
 #include <gnumeric-config.h>
 #include "gnumeric.h"
-#include <tools/gnm-solver.h>
+#include "boot.h"
 #include "cell.h"
 #include "sheet.h"
 #include "value.h"
@@ -301,9 +301,27 @@ gnm_lpsolve_stop (GnmSolver *sol, GError *err, GnmLPSolve *lp)
        return TRUE;
 }
 
-gboolean
-lpsolve_solver_factory_functional (GnmSolverFactory *factory,
-                                  WBCGtk *wbcg);
+GnmSolver *
+lpsolve_solver_create (GnmSolverParameters *params)
+{
+       GnmSolver *res = g_object_new (GNM_SUB_SOLVER_TYPE,
+                                      "params", params,
+                                      NULL);
+       GnmLPSolve *lp = g_new0 (GnmLPSolve, 1);
+
+       lp->parent = GNM_SUB_SOLVER (res);
+
+       g_signal_connect (res, "prepare", G_CALLBACK (gnm_lpsolve_prepare), lp);
+       g_signal_connect (res, "start", G_CALLBACK (gnm_lpsolve_start), lp);
+       g_signal_connect (res, "stop", G_CALLBACK (gnm_lpsolve_stop), lp);
+       g_signal_connect (res, "child-exit", G_CALLBACK (gnm_lpsolve_child_exit), lp);
+
+       g_object_set_data_full (G_OBJECT (res), PRIVATE_KEY, lp,
+                               (GDestroyNotify)gnm_lpsolve_final);
+
+       return res;
+}
+
 
 gboolean
 lpsolve_solver_factory_functional (GnmSolverFactory *factory,
@@ -337,27 +355,8 @@ lpsolve_solver_factory_functional (GnmSolverFactory *factory,
        return FALSE;
 }
 
-
-GnmSolver *
-lpsolve_solver_factory (GnmSolverFactory *factory, GnmSolverParameters *params);
-
 GnmSolver *
 lpsolve_solver_factory (GnmSolverFactory *factory, GnmSolverParameters *params)
 {
-       GnmSolver *res = g_object_new (GNM_SUB_SOLVER_TYPE,
-                                      "params", params,
-                                      NULL);
-       GnmLPSolve *lp = g_new0 (GnmLPSolve, 1);
-
-       lp->parent = GNM_SUB_SOLVER (res);
-
-       g_signal_connect (res, "prepare", G_CALLBACK (gnm_lpsolve_prepare), lp);
-       g_signal_connect (res, "start", G_CALLBACK (gnm_lpsolve_start), lp);
-       g_signal_connect (res, "stop", G_CALLBACK (gnm_lpsolve_stop), lp);
-       g_signal_connect (res, "child-exit", G_CALLBACK (gnm_lpsolve_child_exit), lp);
-
-       g_object_set_data_full (G_OBJECT (res), PRIVATE_KEY, lp,
-                               (GDestroyNotify)gnm_lpsolve_final);
-
-       return res;
+       return lpsolve_solver_create (params);
 }
diff --git a/plugins/lpsolve/lpsolve-write.c b/plugins/lpsolve/lpsolve-write.c
index c440169..06f8681 100644
--- a/plugins/lpsolve/lpsolve-write.c
+++ b/plugins/lpsolve/lpsolve-write.c
@@ -308,8 +308,17 @@ lpsolve_file_save (GOFileSaver const *fs, GOIOContext *io_context,
        GError *err = NULL;
        GString *prg;
        GnmLocale *locale;
+       GnmSolver *sol = NULL;
        GnmSubSolver *ssol = g_object_get_data (G_OBJECT (fs), "solver");
 
+       if (!ssol) {
+               // Create a temporary solver just functional enough to
+               // write the program
+               Sheet *sheet = wb_view_cur_sheet (wb_view);
+               sol = lpsolve_solver_create (sheet->solver_parameters);
+               ssol = GNM_SUB_SOLVER (sol);
+       }
+
        go_io_progress_message (io_context,
                                _("Writing lpsolve file..."));
 
@@ -332,4 +341,7 @@ fail:
        go_io_progress_unset (io_context);
        if (err)
                g_error_free (err);
+
+       if (sol)
+               g_object_unref (sol);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]