Plugged memory leaks in GUI, and converted most of the strings to UTF8, so that
authorJohn Darrington <john@darrington.wattle.id.au>
Thu, 25 May 2006 10:29:14 +0000 (10:29 +0000)
committerJohn Darrington <john@darrington.wattle.id.au>
Thu, 25 May 2006 10:29:14 +0000 (10:29 +0000)
internationalised data files are now rendered OK.
Fixed a buglet in PRINT command.

17 files changed:
lib/gtksheet/ChangeLog
lib/gtksheet/gsheet-column-iface.c
lib/gtksheet/gsheet-column-iface.h
lib/gtksheet/gsheet-hetero-column.c
lib/gtksheet/gsheet-row-iface.c
lib/gtksheet/gsheet-row-iface.h
lib/gtksheet/gsheet-uniform-row.c
lib/gtksheet/gtkextra-sheet.h
lib/gtksheet/gtksheet.c
src/language/data-io/ChangeLog
src/language/data-io/print.c
src/output/ChangeLog
src/output/table.h
src/ui/gui/ChangeLog
src/ui/gui/psppire-var-store.c
tests/automake.mk
tests/bugs/print-crash.sh [new file with mode: 0755]

index b4a99709e52ad5e775315b3a20f4c429d7c8af14..8c2a073d7e18ff3699fcc77caa24b42d24d905ba 100644 (file)
@@ -1,3 +1,10 @@
+Thu May 25 17:58:51 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+    * gsheet-column-iface.c gsheet-column-iface.h gsheet-hetero-column.c
+    gsheet-row-iface.c gsheet-row-iface.h gsheet-uniform-row.c
+    gtksheet-extra.h gtksheet.c:  Plugged memory leaks.  Rationalised the way
+    that GtkSheetButtons are created.
+
 Sat May 20 21:02:03 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
     * gsheetmodel.c gsheetmodel.h: Added columns-inserted and columns-deleted 
index a4cc9f36b3a54359eae56bba396f152c34b08141..5abd21bc2ab99669a1bc4cbf3bfc5811106210b9 100644 (file)
@@ -25,7 +25,7 @@
 #include <gobject/gvaluecollector.h>
 #include "gsheet-column-iface.h"
 #include "gtkextra-marshal.h"
-
+#include "gtkextra-sheet.h"
 
 enum {
   COLUMNS_CHANGED,
@@ -73,8 +73,6 @@ g_sheet_column_get_type (void)
 }
 
 
-static GtkSheetButton default_button;
-
 static void
 g_sheet_column_base_init (gpointer g_class)
 {
@@ -95,12 +93,6 @@ g_sheet_column_base_init (gpointer g_class)
                      G_TYPE_INT);
 
 
-      default_button.state = GTK_STATE_NORMAL;
-      default_button.label = NULL;
-      default_button.label_visible = TRUE;
-      default_button.child = NULL;
-      default_button.justification = GTK_JUSTIFY_FILL;
-
       initialized = TRUE;
     }
 }
@@ -159,21 +151,20 @@ g_sheet_column_get_sensitivity(const GSheetColumn *column,
 }
 
 
-inline const GtkSheetButton *
+inline GtkSheetButton *
 g_sheet_column_get_button(const GSheetColumn *column,
                              gint col, const GtkSheet *sheet)
 {
-  static GtkSheetButton button ;
+  GtkSheetButton *button = gtk_sheet_button_new();
+
   GSheetColumnIface *iface = G_SHEET_COLUMN_GET_IFACE (column);
 
   g_return_val_if_fail (G_IS_SHEET_COLUMN (column), FALSE);
 
-  memcpy(&button, &default_button, sizeof (button));
-
   if ( iface->get_button_label)
-    button.label = iface->get_button_label(column, col, sheet);
+    button->label = iface->get_button_label(column, col, sheet);
 
-  return &button;
+  return button;
 }
 
 inline GtkJustification 
index 4e3e5a1b9d39622fe458e9eb728a215d5ffe733a..6c9970806b90561ee5196d67cde36ab68fc1cc9f 100644 (file)
@@ -71,7 +71,7 @@ struct _GSheetColumnIface
 
 
   GtkStateType  (*get_button_state)(const GSheetColumn *geo, gint col, const GtkSheet *);
-  const gchar * (*get_button_label)(const GSheetColumn *geo, gint col, const GtkSheet *);
+  gchar * (*get_button_label)(const GSheetColumn *geo, gint col, const GtkSheet *);
   gboolean      (*get_button_visibility)(const GSheetColumn *geo, 
                                        gint col, const GtkSheet *);
   const GtkSheetChild * (*get_button_child)(const GSheetColumn *geo, 
@@ -99,7 +99,7 @@ inline gboolean  g_sheet_column_get_sensitivity(const GSheetColumn *gcolumn,
                                             gint col, const GtkSheet *sheet);
 
 
-inline const GtkSheetButton *g_sheet_column_get_button(const GSheetColumn *gcolumn,
+inline GtkSheetButton *g_sheet_column_get_button(const GSheetColumn *gcolumn,
                                             gint col, const GtkSheet *sheet);
 
 inline GtkJustification g_sheet_column_get_justification(const GSheetColumn *gcolumn, gint col, const GtkSheet *sheet);
index e4235656bbad76708a1235cd458b8b2ccce93d7e..1285e9f237c16be56d468754273e252c64e5fcbc 100644 (file)
@@ -128,12 +128,12 @@ g_sheet_hetero_column_get_visibility(const GSheetColumn *geom, gint u)
 
 
 
-static const gchar *
+static gchar *
 g_sheet_hetero_column_get_button_label(const GSheetColumn *geom, gint u)
 {
   GSheetHeteroColumn *hg = G_SHEET_HETERO_COLUMN(geom);
 
-  return hg->col[u].button.label;
+  return g_locale_to_utf8(hg->col[u].button.label, -1, 0, 0, 0);
 }
 
 
index 01a96afe88b66a9630b1153c96daabb8f54f5e04..7c716d858810ce63109500200114065739fa5bb4 100644 (file)
@@ -154,22 +154,20 @@ g_sheet_row_get_sensitivity(const GSheetRow *row_geo,
 }
 
 
-const GtkSheetButton *
+GtkSheetButton *
 g_sheet_row_get_button(const GSheetRow *row_geo,
                              gint row, const GtkSheet *sheet)
 {
-  static GtkSheetButton button ;
+  GtkSheetButton *button  = gtk_sheet_button_new();
 
   GSheetRowIface *iface = G_SHEET_ROW_GET_IFACE (row_geo);
 
   g_return_val_if_fail (G_IS_SHEET_ROW (row_geo), FALSE);
 
-  memcpy(&button, &default_button, sizeof (button));
-
   if ( iface->get_button_label)
-    button.label = iface->get_button_label(row_geo, row, sheet);
+    button->label = iface->get_button_label(row_geo, row, sheet);
 
-  return &button;
+  return button;
 }
 
 
index a6a62b2702c85152cf1d1a4b5cad1f0b961865ba..8575620a9bc55721e484adcbe9c493d7f467bb07 100644 (file)
@@ -69,8 +69,8 @@ struct _GSheetRowIface
   GtkStateType  (*get_button_state)(const GSheetRow *geo, gint row, 
                                    const GtkSheet *);
 
-  const gchar * (*get_button_label)(const GSheetRow *geo, gint row, 
-                                   const GtkSheet *);
+  gchar * (*get_button_label)(const GSheetRow *geo, gint row, 
+                             const GtkSheet *);
 
   gboolean      (*get_button_visibility)(const GSheetRow *geo, 
                                        gint row, const GtkSheet *);
@@ -101,7 +101,7 @@ gboolean  g_sheet_row_get_sensitivity(const GSheetRow *grow,
                                             gint row, const GtkSheet *sheet);
 
 
-const GtkSheetButton *g_sheet_row_get_button(const GSheetRow *grow,
+GtkSheetButton *g_sheet_row_get_button(const GSheetRow *grow,
                                             gint row, const GtkSheet *sheet);
 
 
index 6ab1c8ff11f196824d4a3feb4392024b43d2463b..f25480fbed733ed396ff3947df89e05171999b11 100644 (file)
@@ -123,9 +123,7 @@ g_sheet_uniform_row_get_visibility(const GSheetRow *geom, gint u)
 static const gchar *
 g_sheet_uniform_row_get_button_label(const GSheetRow *geom, gint u)
 {
-  static gchar *label; 
-  g_free(label);
-  label = g_strdup_printf("%d", u);
+  gchar *label = g_strdup_printf("%d", u);
 
   return label;
 }
index bfc714ca340fe0f74c61095840b385838e523b06..0bd573c8a0242c2f752996303854e3f9558214a7 100644 (file)
@@ -68,6 +68,9 @@ typedef struct _GtkSheetButton GtkSheetButton;
 
 
 
+GtkSheetButton * gtk_sheet_button_new(void);
+
+inline void gtk_sheet_button_free(GtkSheetButton *button);
 
 
 #endif /* __GTK_EXTRA_SHEET_H__ */
index caed10ba12c53e814a385a446cf0963cc3af93af..bd506728db70e1f04c4a9a3c344f1507c972c1e6 100644 (file)
@@ -260,7 +260,7 @@ ROW_FROM_YPIXEL(GtkSheet *sheet, gint y)
   return (yyy_row_ypixel_to_row(sheet, y));
 }
 
-static inline const GtkSheetButton *
+static inline GtkSheetButton *
 xxx_column_button(GtkSheet *sheet, gint col)
 {
   GSheetColumn *col_geo = sheet->column_geometry;
@@ -408,7 +408,7 @@ static inline gint SHEET_HEIGHT(GtkSheet *sheet)
 }
 
 
-static inline const GtkSheetButton *
+static inline GtkSheetButton *
 yyy_row_button(GtkSheet *sheet, gint row)
 {
   GSheetRow *row_geo = sheet->row_geometry;
@@ -1807,10 +1807,11 @@ gtk_sheet_show_column_titles(GtkSheet *sheet)
       col <= MAX_VISIBLE_COLUMN(sheet); 
       col++)
     {
-      const GtkSheetButton *button = xxx_column_button(sheet, col);
+      GtkSheetButton *button = xxx_column_button(sheet, col);
       GtkSheetChild *child = button->child;
       if(child)
         gtk_sheet_child_show(child);
+      gtk_sheet_button_free(button);
     }
   adjust_scrollbars(sheet);
  } 
@@ -1881,10 +1882,11 @@ gtk_sheet_hide_column_titles(GtkSheet *sheet)
       col <= MAX_VISIBLE_COLUMN(sheet); 
       col++)
     {
-      const GtkSheetButton *button = xxx_column_button(sheet, col);
+      GtkSheetButton *button = xxx_column_button(sheet, col);
       GtkSheetChild *child = button->child;
       if(child)
         gtk_sheet_child_hide(child);
+      gtk_sheet_button_free(button);
   }
   adjust_scrollbars(sheet);
  }
@@ -6248,6 +6250,7 @@ gtk_sheet_entry_set_max_size(GtkSheet *sheet)
  gint sizel=0, sizer=0;
  gint row,col;
  GtkJustification justification;
+ gchar *s = NULL;
 
  row=sheet->active_cell.row;
  col=sheet->active_cell.col;
@@ -6260,34 +6263,52 @@ gtk_sheet_entry_set_max_size(GtkSheet *sheet)
   case GTK_JUSTIFY_FILL:
   case GTK_JUSTIFY_LEFT:
     for(i=col+1; i<=MAX_VISIBLE_COLUMN(sheet); i++){
-     if(gtk_sheet_cell_get_text(sheet, row, i)) break;
+      if((s = gtk_sheet_cell_get_text(sheet, row, i)))
+       {
+         g_free(s);
+         break;
+       }
      size+=xxx_column_width(sheet, i);
     }
     size = MIN(size, sheet->sheet_window_width - COLUMN_LEFT_XPIXEL(sheet, col));
     break;
-  case GTK_JUSTIFY_RIGHT:
-    for(i=col-1; i>=MIN_VISIBLE_COLUMN(sheet); i--){
-     if(gtk_sheet_cell_get_text(sheet, row, i)) break;
-     size+=xxx_column_width(sheet, i);
-    }
+ case GTK_JUSTIFY_RIGHT:
+   for(i=col-1; i>=MIN_VISIBLE_COLUMN(sheet); i--)
+     {
+       if((s = gtk_sheet_cell_get_text(sheet, row, i)))
+        {
+          g_free(s);
+          break;
+        }
+       size+=xxx_column_width(sheet, i);
+     }
     break;
   case GTK_JUSTIFY_CENTER:
     for(i=col+1; i<=MAX_VISIBLE_COLUMN(sheet); i++){
-/*     if(gtk_sheet_cell_get_text(sheet, row, i)) break;
+/*     if((s = gtk_sheet_cell_get_text(sheet, row, i)))
+            {
+            g_free(s);
+            break;
+            }
 */
      sizer+=xxx_column_width(sheet, i);
     }
-    for(i=col-1; i>=MIN_VISIBLE_COLUMN(sheet); i--){
-     if(gtk_sheet_cell_get_text(sheet, row, i)) break;
-     sizel+=xxx_column_width(sheet, i);
-    }
+    for(i=col-1; i>=MIN_VISIBLE_COLUMN(sheet); i--)
+      {
+       if((s = gtk_sheet_cell_get_text(sheet, row, i)))
+         {
+           g_free(s);
+           break;
+         }
+       sizel+=xxx_column_width(sheet, i);
+      }
     size=2*MIN(sizel, sizer);
     break;
  }
 
- if(size!=0) size+=xxx_column_width(sheet, col);
GTK_ITEM_ENTRY(sheet->sheet_entry)->text_max_size=size;
-
+ if(size != 0) 
  size += xxx_column_width(sheet, col);
+ GTK_ITEM_ENTRY(sheet->sheet_entry)->text_max_size = size;
 }
 
 static void
@@ -6467,7 +6488,7 @@ gtk_sheet_button_draw (GtkSheet *sheet, gint row, gint column)
   gint x = 0, y = 0;
   gint index = 0;
   gint text_width = 0, text_height = 0;
-  const GtkSheetButton *button = NULL;
+  GtkSheetButton *button = NULL;
   GtkSheetChild *child = NULL;
   GdkRectangle allocation;
   gboolean is_sensitive = FALSE;
@@ -6642,6 +6663,8 @@ gtk_sheet_button_draw (GtkSheet *sheet, gint row, gint column)
               gtk_widget_queue_draw(child->widget);
             }
   }
+
+  gtk_sheet_button_free(button);
    
 }
 
@@ -7886,3 +7909,25 @@ gtk_sheet_get_model(const GtkSheet *sheet)
   return sheet->model;
 }
 
+
+GtkSheetButton *
+gtk_sheet_button_new(void)
+{
+  GtkSheetButton *button = g_slice_new(GtkSheetButton);
+  
+  button->state = GTK_STATE_NORMAL;
+  button->label = NULL;
+  button->label_visible = TRUE;
+  button->child = NULL;
+  button->justification = GTK_JUSTIFY_FILL;
+
+  return button;
+}
+
+
+inline void
+gtk_sheet_button_free(GtkSheetButton *button)
+{
+  g_free(button->label);
+  g_slice_free(GtkSheetButton, button);
+}
index 21b2ed3cb376fc9f21ee1e5856a9332dec279b55..23f215cfb4e6f6c9f7d6d0ac91b59165518caab3 100644 (file)
@@ -1,3 +1,9 @@
+Thu May 25 18:26:26 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * print.c (print_trns_free): Made the code agree with the comment, by
+       not freeing PRT.  Has the side effect that the command no longer
+       crashes on invalid syntax.
+
 Tue May  9 20:55:46 2006  Ben Pfaff  <blp@gnu.org>
 
        * get.c (cmd_match_files): Fix memory leak replacing default_dict.
index 63270160d949dd9654776fd13ffa4e8572415cd0..b96ee13be3a4a11105aaef959b9c8a621a850a2e 100644 (file)
@@ -141,7 +141,7 @@ static int
 internal_cmd_print (int f)
 {
   int table = 0;                /* Print table? */
-  struct print_trns *trns;      /* malloc()'d transformation. */
+  struct print_trns *trns = NULL; /* malloc()'d transformation. */
   struct file_handle *fh = NULL;
 
   /* Fill in prt to facilitate error-handling. */
@@ -966,7 +966,7 @@ print_trns_proc (void *trns_, struct ccase *c, int case_num UNUSED)
   return TRNS_CONTINUE;
 }
 
-/* Frees all the data inside print_trns T.  Does not free T. */
+/* Frees all the data inside print_trns PRT.  Does not free PRT. */
 static bool
 print_trns_free (void *prt_)
 {
@@ -996,7 +996,6 @@ print_trns_free (void *prt_)
   if (prt->writer != NULL)
     ok = dfm_close_writer (prt->writer);
   free (prt->line);
-  free (prt);
   return ok;
 }
 \f
index e4f21a0074f07f6db428fa4b7390a1a7fcb32820..04d1dd1ae78bfc0905aea72a3f4bc4ae3d33b2c8 100644 (file)
@@ -1,3 +1,7 @@
+Thu May 25 18:02:53 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * table.c: Removed redundant extern declaration.
+
 Sun May 14 14:03:56 2006  Ben Pfaff  <blp@gnu.org>
 
        * output.c (outp_eject_page): Always make sure that a page is open
index 51031da23c0e45c11299b8a8393b8f3dd56b032d..6245d12bdb7687f671a04bcfb626be031956a1f7 100644 (file)
@@ -102,8 +102,6 @@ struct tab_table
     int col_ofs, row_ofs;      /* X and Y offsets. */
   };
 
-extern int tab_hit;
-
 /* Number of rows in TABLE. */
 #define tab_nr(TABLE) ((TABLE)->nr)
 
index 4fe6e3f37cafd113a93351a8d1d5e9224f05b83a..5782b9b5d312953d48b4900dae7698b0f50113b6 100644 (file)
@@ -1,3 +1,8 @@
+Thu May 25 18:01:17 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+   * psppire-var-store.c: Converted strings to utf8 and returned them on the
+   heap.
+
 Sat May 20 21:08:18 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
    * data-sheet.c, menu-actions.c menu-actions: Fixed data sheet so that
index 09e1e716c82a37c0f29b9410998f643460f53541..aba2703452cc40e9af454986e1ef42b1e44ee0f6 100644 (file)
@@ -49,7 +49,7 @@ static void         psppire_var_store_class_init      (PsppireVarStoreClass *cla
 static void         psppire_var_store_sheet_model_init (GSheetModelIface *iface);
 static void         psppire_var_store_finalize        (GObject           *object);
 
-static const gchar *psppire_var_store_get_string(GSheetModel *sheet_model, gint row, gint column);
+static gchar *psppire_var_store_get_string(GSheetModel *sheet_model, gint row, gint column);
 
 static gboolean  psppire_var_store_clear(GSheetModel *model,  gint row, gint col);
 
@@ -58,7 +58,7 @@ static gboolean psppire_var_store_set_string(GSheetModel *model,
                                          const gchar *text, gint row, gint column);
 
 
-static const gchar *text_for_column(const struct PsppireVariable *pv, gint c);
+static gchar *text_for_column(const struct PsppireVariable *pv, gint c, GError **err);
 
 
 static GObjectClass *parent_class = NULL;
@@ -297,11 +297,9 @@ psppire_var_store_finalize (GObject *object)
   (* parent_class->finalize) (object);
 }
 
-static const gchar *
+static gchar *
 psppire_var_store_get_string(GSheetModel *model, gint row, gint column)
 {
-  const gchar *s ;
-
   PsppireVarStore *store = PSPPIRE_VAR_STORE(model);
 
   struct PsppireVariable *pv;
@@ -311,9 +309,7 @@ psppire_var_store_get_string(GSheetModel *model, gint row, gint column)
   
   pv = psppire_dict_get_variable (store->dict, row);
   
-  s = text_for_column(pv, column);
-
-  return pspp_locale_to_utf8(s, -1, 0);
+  return text_for_column(pv, column, 0);
 }
 
 
@@ -416,13 +412,9 @@ psppire_var_store_set_string(GSheetModel *model,
 }
 
 
-#define MAX_CELL_TEXT_LEN 255
-
-static const gchar *
-text_for_column(const struct PsppireVariable *pv, gint c)
+static  gchar *
+text_for_column(const struct PsppireVariable *pv, gint c, GError **err)
 {
-  static gchar buf[MAX_CELL_TEXT_LEN];
-
   static gchar none[]=_("None");
 
   static const gchar *const type_label[] = 
@@ -444,23 +436,23 @@ text_for_column(const struct PsppireVariable *pv, gint c)
   switch (c)
     {
     case COL_NAME:
-      return psppire_variable_get_name(pv);
+      return pspp_locale_to_utf8(psppire_variable_get_name(pv), -1, err);
       break;
     case COL_TYPE:
       {
        switch ( write_spec->type ) 
          {
          case FMT_F:
-           return type_label[VT_NUMERIC];
+           return g_locale_to_utf8(type_label[VT_NUMERIC], -1, 0, 0, err);
            break;
          case FMT_COMMA:
-           return type_label[VT_COMMA];
+           return g_locale_to_utf8(type_label[VT_COMMA], -1, 0, 0, err);
            break;
          case FMT_DOT:
-           return type_label[VT_DOT];
+           return g_locale_to_utf8(type_label[VT_DOT], -1, 0, 0, err);
            break;
          case FMT_E:
-           return type_label[VT_SCIENTIFIC];
+           return g_locale_to_utf8(type_label[VT_SCIENTIFIC], -1, 0, 0, err);
            break;
          case FMT_DATE:        
          case FMT_EDATE:       
@@ -475,20 +467,20 @@ text_for_column(const struct PsppireVariable *pv, gint c)
          case FMT_DTIME:       
          case FMT_WKDAY:       
          case FMT_MONTH:       
-           return type_label[VT_DATE];
+           return g_locale_to_utf8(type_label[VT_DATE], -1, 0, 0, err);
            break;
          case FMT_DOLLAR:
-           return type_label[VT_DOLLAR];
+           return g_locale_to_utf8(type_label[VT_DOLLAR], -1, 0, 0, err);
            break;
          case FMT_CCA:
          case FMT_CCB:
          case FMT_CCC:
          case FMT_CCD:
          case FMT_CCE:
-           return type_label[VT_CUSTOM];
+           return g_locale_to_utf8(type_label[VT_CUSTOM], -1, 0, 0, err);
            break;
          case FMT_A:
-           return type_label[VT_STRING];
+           return g_locale_to_utf8(type_label[VT_STRING], -1, 0, 0, err);
            break;
          default:
            g_warning("Unknown format: \"%s\"\n", 
@@ -499,93 +491,109 @@ text_for_column(const struct PsppireVariable *pv, gint c)
       break;
     case COL_WIDTH:
       {
-       g_snprintf(buf, MAX_CELL_TEXT_LEN, "%d", write_spec->w);
-       return buf;
+       gchar *s;
+       GString *gstr = g_string_sized_new(10);
+       g_string_printf(gstr, "%d", write_spec->w);
+       s = g_locale_to_utf8(gstr->str, gstr->len, 0, 0, err);
+       g_string_free(gstr, TRUE);
+       return s;
       }
       break;
     case COL_DECIMALS:
       {
-       g_snprintf(buf, MAX_CELL_TEXT_LEN, "%d", write_spec->d);
-       return buf;
+       gchar *s;
+       GString *gstr = g_string_sized_new(10);
+       g_string_printf(gstr, "%d", write_spec->d);
+       s = g_locale_to_utf8(gstr->str, gstr->len, 0, 0, err);
+       g_string_free(gstr, TRUE);
+       return s;
       }
       break;
     case COL_COLUMNS:
       {
-       g_snprintf(buf, MAX_CELL_TEXT_LEN, 
-                  "%d", psppire_variable_get_columns(pv));
-       return buf;
+       gchar *s;
+       GString *gstr = g_string_sized_new(10);
+       g_string_printf(gstr, "%d", psppire_variable_get_columns(pv));
+       s = g_locale_to_utf8(gstr->str, gstr->len, 0, 0, err);
+       g_string_free(gstr, TRUE);
+       return s;
       }
       break;
     case COL_LABEL:
-      return psppire_variable_get_label(pv);
+      return g_locale_to_utf8(psppire_variable_get_label(pv), -1, 0, 0, err);
       break;
+
     case COL_MISSING:
       {
-      const struct missing_values *miss = psppire_variable_get_missing(pv);
-      if ( mv_is_empty(miss)) 
-       return none;
-      else
-       {
-         if ( ! mv_has_range (miss))
-           {
-             const int n = mv_n_values(miss);
-             gchar *mv[4] = {0,0,0,0};
-             gint i;
-             for(i = 0 ; i < n; ++i ) 
-               {
-                 union value v;
-                 mv_peek_value(miss, &v, i);
-                 mv[i] = value_to_text(v, *write_spec);
-               }
-             g_stpcpy(buf, "");
-             for(i = 0 ; i < n; ++i ) 
-               {
-                 if ( i > 0) 
-                   g_strlcat(buf, ", ", MAX_CELL_TEXT_LEN);
-                 g_strlcat(buf, mv[i], MAX_CELL_TEXT_LEN);
-                 g_free(mv[i]);
-               }
-           }
-         else
-           {
-             gchar *l, *h;
-             union value low, high;
-             mv_peek_range(miss, &low.f, &high.f);
+       gchar *s;
+       const struct missing_values *miss = psppire_variable_get_missing(pv);
+       if ( mv_is_empty(miss)) 
+         return g_locale_to_utf8(none, -1, 0, 0, err);
+       else
+         {
+           if ( ! mv_has_range (miss))
+             {
+               GString *gstr = g_string_sized_new(10);
+               const int n = mv_n_values(miss);
+               gchar *mv[4] = {0,0,0,0};
+               gint i;
+               for(i = 0 ; i < n; ++i ) 
+                 {
+                   union value v;
+                   mv_peek_value(miss, &v, i);
+                   mv[i] = value_to_text(v, *write_spec);
+                   if ( i > 0 ) 
+                     g_string_append(gstr, ", ");
+                   g_string_append(gstr, mv[i]);
+                   g_free(mv[i]);
+                 }
+               s = pspp_locale_to_utf8(gstr->str, gstr->len, err);
+               g_string_free(gstr, TRUE);
+             }
+           else
+             {
+               GString *gstr = g_string_sized_new(10);
+               gchar *l, *h;
+               union value low, high;
+               mv_peek_range(miss, &low.f, &high.f);
                  
-             l = value_to_text(low, *write_spec);
-             h = value_to_text(high, *write_spec);
-
-             g_snprintf(buf, MAX_CELL_TEXT_LEN, "%s - %s", l, h);
-             g_free(l);
-             g_free(h);
-
-             if ( mv_has_value(miss)) 
-               {
-                 gchar buf2[MAX_CELL_TEXT_LEN];
-                 gchar *s = 0;
-                 union value v;
-                 mv_peek_value(miss, &v, 0);
-
-                 s = value_to_text(v, *write_spec);
-
-                 g_snprintf(buf2, MAX_CELL_TEXT_LEN, "%s, %s", buf, s);
-                 free(s);
-                 g_stpcpy(buf, buf2);
-               }
-           }
-
-         return buf;
-       }
+               l = value_to_text(low, *write_spec);
+               h = value_to_text(high, *write_spec);
+
+               g_string_printf(gstr, "%s - %s", l, h);
+               g_free(l);
+               g_free(h);
+
+               if ( mv_has_value(miss)) 
+                 {
+                   gchar *ss = 0;
+                   union value v;
+                   mv_peek_value(miss, &v, 0);
+
+                   ss = value_to_text(v, *write_spec);
+
+                   g_string_append(gstr, ", ");
+                   g_string_append(gstr, ss);
+                   free(ss);
+                 }
+               s = pspp_locale_to_utf8(gstr->str, gstr->len, err);
+               g_string_free(gstr, TRUE);
+             }
+
+           return s;
+         }
       }
       break;
     case COL_VALUES:
       {
        const struct val_labs *vls = psppire_variable_get_value_labels(pv);
-       if ( ! vls || 0 == val_labs_count(vls)) 
-         return none;
+       if ( ! vls || 0 == val_labs_count(vls) 
+         return g_locale_to_utf8(none, -1, 0, 0, err);
        else
          {
-           struct val_labs_iterator *ip=0;
+           gchar *ss;
+           GString *gstr = g_string_sized_new(10);
+           struct val_labs_iterator *ip = 0;
            struct val_lab *vl = val_labs_first_sorted (vls, &ip);
 
            g_assert(vl);
@@ -593,22 +601,27 @@ text_for_column(const struct PsppireVariable *pv, gint c)
            {
              gchar *const vstr = value_to_text(vl->value, *write_spec);
 
-             g_snprintf(buf, MAX_CELL_TEXT_LEN, "{%s,\"%s\"}_", vstr, vl->label);
+             g_string_printf(gstr, "{%s,\"%s\"}_", vstr, vl->label);
              g_free(vstr);
            }
 
            val_labs_done(&ip);
-
-           return buf;
+           
+           ss = pspp_locale_to_utf8(gstr->str, gstr->len, err);
+           g_string_free(gstr, TRUE);
+           return ss;
          }
       }
       break;
     case COL_ALIGN:
-      return alignments[psppire_variable_get_alignment(pv)];
+      return g_locale_to_utf8(alignments[psppire_variable_get_alignment(pv)], 
+                                        -1, -0, 0, err);
       break;
     case COL_MEASURE:
-      return measures[psppire_variable_get_measure(pv)];
+      return g_locale_to_utf8(measures[psppire_variable_get_measure(pv)], 
+                                        -1, -0, 0, err);
       break;
+
     }
   return 0;
 }
@@ -636,3 +649,4 @@ psppire_var_store_set_font(PsppireVarStore *store, PangoFontDescription *fd)
 
 
 
+
index e8094484239d1bd7b16f0e42496b8e977bb32dba..033785961e384485195b0a0bfd49c7bde099d0f6 100644 (file)
@@ -91,6 +91,7 @@ TESTS = \
        tests/bugs/computebug.sh \
        tests/bugs/compute-lv.sh \
        tests/bugs/temp-freq.sh \
+       tests/bugs/print-crash.sh \
        tests/xforms/casefile.sh \
        tests/stats/descript-basic.sh \
        tests/stats/descript-missing.sh \
diff --git a/tests/bugs/print-crash.sh b/tests/bugs/print-crash.sh
new file mode 100755 (executable)
index 0000000..d362ede
--- /dev/null
@@ -0,0 +1,75 @@
+#!/bin/sh
+
+# This program tests for a bug which crashed when deallocating after a bad 
+# PRINT command.
+
+TEMPDIR=/tmp/pspp-tst-$$
+TESTFILE=$TEMPDIR/`basename $0`.sps
+
+# ensure that top_srcdir and top_builddir  are absolute
+if [ -z "$top_srcdir" ] ; then top_srcdir=. ; fi
+if [ -z "$top_builddir" ] ; then top_builddir=. ; fi
+top_srcdir=`cd $top_srcdir; pwd`
+top_builddir=`cd $top_builddir; pwd`
+
+PSPP=$top_builddir/src/ui/terminal/pspp
+
+export STAT_CONFIG_PATH=$top_srcdir/config
+
+
+cleanup()
+{
+     if [ x"$PSPP_TEST_NO_CLEANUP" != x ] ; then 
+       echo "NOT cleaning $TEMPDIR"
+       return ; 
+     fi
+     rm -rf $TEMPDIR
+}
+
+
+fail()
+{
+    echo $activity
+    echo FAILED
+    cleanup;
+    exit 1;
+}
+
+
+no_result()
+{
+    echo $activity
+    echo NO RESULT;
+    cleanup;
+    exit 2;
+}
+
+pass()
+{
+    cleanup;
+    exit 0;
+}
+
+mkdir -p $TEMPDIR
+
+cd $TEMPDIR
+
+cat > $TESTFILE << EOF
+DATA LIST LIST /a * b *.
+BEGIN DATA.
+1 2
+3 4
+END DATA.
+
+PRINT F8.2
+LIST.
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+
+activity="run program"
+$SUPERVISOR $PSPP --testing-mode -o raw-ascii $TESTFILE > /dev/null
+if [ $? -ne 1 ] ; then fail ; fi
+
+
+pass;