Allow variable labels longer than 255 bytes.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 16 Mar 2014 17:22:34 +0000 (10:22 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 16 Mar 2014 17:22:34 +0000 (10:22 -0700)
Reported by Andre Müller.
Bug #41863.

14 files changed:
NEWS
doc/dev/system-file-format.texi
perl-module/PSPP.xs
src/data/por-file-reader.c
src/data/sys-file-reader.c
src/data/variable.c
src/data/variable.h
src/language/data-io/combine-files.c
src/language/dictionary/apply-dictionary.c
src/language/dictionary/variable-label.c
src/language/stats/aggregate.c
src/language/stats/descriptives.c
src/language/stats/rank.c
src/ui/gui/psppire-var-sheet.c

diff --git a/NEWS b/NEWS
index fba979bee65c64f26e2e7c81f0fb6923289009de..5a0202d84402be3dd5341ae0af794713950aca03 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -31,6 +31,9 @@ Changes since 0.8.2:
    - SYSFILE INFO now accepts an ENCODING subcommand to specify the
      character encoding of string data in the system file.
 
+   - Variable labels over 255 bytes long are now accepted without
+     truncation (bug #41863).
+
    - System files that contain duplicate variable names may now be
      read successfully (bug #41475).
 
index 2d576733081d3018e402bf7072fae9a3ca63eb6d..0f0940b58f88a2bfe9d13c0678dc52343be14982 100644 (file)
@@ -328,7 +328,7 @@ This field is present only if @code{has_var_label} is set to 1.  It is
 set to the length, in characters, of the variable label.  The
 documented maximum length varies from 120 to 255 based on SPSS
 version, but some files have been seen with longer labels.  PSPP
-accepts longer labels and truncates them to 255 bytes on input.
+accepts labels of any length.
 
 @item char label[];
 This field is present only if @code{has_var_label} is set to 1.  It has
index 0f0d16b34321cc8d05165725a75be1455f1c31ae..e600f7b45d4e271d1d381e087349ec017a5f7831 100644 (file)
@@ -424,7 +424,7 @@ set_label (var, label)
  struct variable *var;
  char *label
 CODE:
-  var_set_label (var, label, false);
+  var_set_label (var, label);
 
 
 void
index a4d13ec7bc4b927c88cac19a3d9920db08da7ece..0897d77aa2e30a4520f645c9fa9a647ed7fde652 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -750,7 +750,7 @@ read_variables (struct pfm_reader *r, struct dictionary *dict)
         {
           char label[256];
           read_string (r, label);
-          var_set_label (v, label, false); /* XXX */
+          var_set_label (v, label); /* XXX */
         }
     }
 
index 98af30031248f68c5837d025d06428600823f5e6..99e8caa6a78d8bc2ccbc8fa4709de4b235fca55a 100644 (file)
@@ -1439,7 +1439,7 @@ parse_variable_records (struct sfm_reader *r, struct dictionary *dict,
 
           utf8_label = recode_string_pool ("UTF-8", dict_encoding,
                                            rec->label, -1, r->pool);
-          var_set_label (var, utf8_label, false);
+          var_set_label (var, utf8_label);
         }
 
       /* Set missing values. */
index c4bab00fc36081b15aa368ec5b57dc89b7088dfe..8758af35b429b6cc026aead9db207aeb283fc339 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -80,7 +80,7 @@ struct variable
 
 static void var_set_print_format_quiet (struct variable *v, const struct fmt_spec *print);
 static void var_set_write_format_quiet (struct variable *v, const struct fmt_spec *write);
-static bool var_set_label_quiet (struct variable *v, const char *label, bool issue_warning);
+static void var_set_label_quiet (struct variable *v, const char *label);
 static void var_set_name_quiet (struct variable *v, const char *name);
 
 /* Creates and returns a new variable with the given NAME and
@@ -124,7 +124,7 @@ var_destroy (struct variable *v)
       mv_destroy (&v->miss);
       var_clear_short_names (v);
       val_labs_destroy (v->val_labs);
-      var_set_label_quiet (v, NULL, false);
+      var_set_label_quiet (v, NULL);
       attrset_destroy (var_get_attributes (v));
       free (v->name);
       ds_destroy (&v->name_and_label);
@@ -715,49 +715,18 @@ var_get_label (const struct variable *v)
 /* Sets V's variable label to UTF-8 encoded string LABEL, stripping off leading
    and trailing white space.  If LABEL is a null pointer or if LABEL is an
    empty string (after stripping white space), then V's variable label (if any)
-   is removed.
-
-   Variable labels are limited to 255 bytes in V's encoding (as returned by
-   var_get_encoding()).  If LABEL fits within this limit, this function returns
-   true.  Otherwise, the variable label is set to a truncated value, this
-   function returns false and, if ISSUE_WARNING is true, issues a warning.  */
-static bool
-var_set_label_quiet (struct variable *v, const char *label, bool issue_warning)
+   is removed. */
+static void
+var_set_label_quiet (struct variable *v, const char *label)
 {
-  bool truncated = false;
-
   free (v->label);
   v->label = NULL;
 
   if (label != NULL && label[strspn (label, CC_SPACES)])
-    {
-      const char *dict_encoding = var_get_encoding (v);
-      struct substring s = ss_cstr (label);
-      size_t trunc_len;
-
-      if (dict_encoding != NULL)
-        {
-          enum { MAX_LABEL_LEN = 255 };
-
-          trunc_len = utf8_encoding_trunc_len (label, dict_encoding,
-                                               MAX_LABEL_LEN);
-          if (ss_length (s) > trunc_len)
-            {
-              if (issue_warning)
-                msg (SW, _("Truncating variable label for variable `%s' to %d "
-                           "bytes."), var_get_name (v), MAX_LABEL_LEN);
-              ss_truncate (&s, trunc_len);
-              truncated = true;
-            }
-        }
-
-        v->label = ss_xstrdup (s);
-    }
+    v->label = xstrdup (label);
 
   ds_destroy (&v->name_and_label);
   ds_init_empty (&v->name_and_label);
-
-  return truncated;
 }
 
 
@@ -765,21 +734,13 @@ var_set_label_quiet (struct variable *v, const char *label, bool issue_warning)
 /* Sets V's variable label to UTF-8 encoded string LABEL, stripping off leading
    and trailing white space.  If LABEL is a null pointer or if LABEL is an
    empty string (after stripping white space), then V's variable label (if any)
-   is removed.
-
-   Variable labels are limited to 255 bytes in V's encoding (as returned by
-   var_get_encoding()).  If LABEL fits within this limit, this function returns
-   true.  Otherwise, the variable label is set to a truncated value, this
-   function returns false and, if ISSUE_WARNING is true, issues a warning.  */
-bool
-var_set_label (struct variable *v, const char *label, bool issue_warning)
+   is removed. */
+void
+var_set_label (struct variable *v, const char *label)
 {
   struct variable *ov = var_clone (v);
-  bool truncated = var_set_label_quiet (v, label, issue_warning);
-
+  var_set_label_quiet (v, label);
   dict_var_changed (v, VAR_TRAIT_LABEL, ov);
-
-  return truncated;
 }
 
 
@@ -787,7 +748,7 @@ var_set_label (struct variable *v, const char *label, bool issue_warning)
 void
 var_clear_label (struct variable *v)
 {
-  var_set_label (v, NULL, false);
+  var_set_label (v, NULL);
 }
 
 /* Returns true if V has a variable V,
@@ -1298,7 +1259,7 @@ var_clone (const struct variable *old_var)
   var_set_print_format_quiet (new_var, var_get_print_format (old_var));
   var_set_write_format_quiet (new_var, var_get_write_format (old_var));
   var_set_value_labels_quiet (new_var, var_get_value_labels (old_var));
-  var_set_label_quiet (new_var, var_get_label (old_var), false);
+  var_set_label_quiet (new_var, var_get_label (old_var));
   var_set_measure_quiet (new_var, var_get_measure (old_var));
   var_set_role_quiet (new_var, var_get_role (old_var));
   var_set_display_width_quiet (new_var, var_get_display_width (old_var));
index d77a289afaefe897c0ef7ffcffffd4691c628a67..25596ad368beac821803ef074bdd3eaea3e8938d 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -120,7 +120,7 @@ struct fmt_spec var_default_formats (int width);
 /* Variable labels. */
 const char *var_to_string (const struct variable *);
 const char *var_get_label (const struct variable *);
-bool var_set_label (struct variable *, const char *label, bool issue_warning);
+void var_set_label (struct variable *, const char *label);
 void var_clear_label (struct variable *);
 bool var_has_label (const struct variable *);
 
index 9d353c81a112488aa9db988f43f65e0c0ddad8c0..6eb9a3181a5f741281f480e9254baf4e48111130 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -590,7 +590,7 @@ merge_dictionary (struct dictionary *const m, struct comb_file *f)
           if (var_has_missing_values (dv) && !var_has_missing_values (mv))
             var_set_missing_values (mv, var_get_missing_values (dv));
           if (var_get_label (dv) && !var_get_label (mv))
-            var_set_label (mv, var_get_label (dv), false);
+            var_set_label (mv, var_get_label (dv));
         }
       else
         mv = dict_clone_var_assert (m, dv);
index 8531ba56d2d257d30e3cc085ab42fafa91bca19c..05143fcd580cf034c1ebce3006e932ca456eb843 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010, 2011, 2012, 2014 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -80,7 +80,7 @@ cmd_apply_dictionary (struct lexer *lexer, struct dataset *ds)
        }
 
       if (var_has_label (s))
-        var_set_label (t, var_get_label (s), false);
+        var_set_label (t, var_get_label (s));
 
       if (var_has_value_labels (s))
         {
index bceb84994eeacf5e678f97e3e212b9df213e9f37..c4e0df69fede265294c84ea60650e3fc14426145 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2010, 2011, 2014 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -54,7 +54,7 @@ cmd_variable_labels (struct lexer *lexer, struct dataset *ds)
        }
 
       for (i = 0; i < nv; i++)
-        var_set_label (v[i], lex_tokcstr (lexer), i == 0);
+        var_set_label (v[i], lex_tokcstr (lexer));
 
       lex_get (lexer);
       while (lex_token (lexer) == T_SLASH)
index 4d95e62e64f6ea098bad20b7e181927a6a0271a2..678ea5334afd6e7c9692252fe0f049468cda30d4 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2008, 2009, 2010, 2011, 2012, 2014 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -639,7 +639,7 @@ parse_aggregate_functions (struct lexer *lexer, const struct dictionary *dict,
 
            free (dest[i]);
            if (dest_label[i])
-              var_set_label (destvar, dest_label[i], true);
+              var_set_label (destvar, dest_label[i]);
 
            v->dest = destvar;
          }
index f80965616f0c1f5fc29b04a9a788440d8471f676..a35878b75ad326add482f986e5336ea46f041254 100644 (file)
@@ -748,7 +748,7 @@ setup_z_trns (struct dsc_proc *dsc, struct dataset *ds)
          dst_var = dict_create_var_assert (dataset_dict (ds), dv->z_name, 0);
 
           label = xasprintf (_("Z-score of %s"),var_to_string (dv->v));
-          var_set_label (dst_var, label, false);
+          var_set_label (dst_var, label);
           free (label);
 
           z = &t->z_scores[cnt++];
index 5a849b8cf889cce5b45b5af08dd8d190c5f54a8f..cef51df08c69453055420bf80e2e57eafbd25bbe 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2005, 2006, 2007, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc
+   Copyright (C) 2005, 2006, 2007, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -1123,7 +1123,7 @@ rank_cmd (struct dataset *ds, const struct rank *cmd)
 
           var = dict_create_var_assert (d, rs->dest_names[i], 0);
           var_set_both_formats (var, &dest_format[rs->rfunc]);
-          var_set_label (var, rs->dest_labels[i], false);
+          var_set_label (var, rs->dest_labels[i]);
 
           iv->output_vars[j] = var;
         }
index 6fc42c1a36922e8df114c6c6a181ca2f3e4e61ba..733a6450c614b3b983162eea439d8ca8ac995991 100644 (file)
@@ -252,7 +252,7 @@ on_var_column_edited (GtkCellRendererText *cell,
       break;
 
     case VS_LABEL:
-      var_set_label (var, new_text, false);
+      var_set_label (var, new_text);
       break;
 
     case VS_VALUES: