Add SET TVARS option. Closes bug #31566 20120515030501/pspp 20120516030503/pspp 20120517030502/pspp 20120518030503/pspp 20120519030503/pspp
authorJohn Darrington <john@darrington.wattle.id.au>
Sun, 13 May 2012 20:25:39 +0000 (22:25 +0200)
committerJohn Darrington <john@darrington.wattle.id.au>
Mon, 14 May 2012 08:25:58 +0000 (10:25 +0200)
doc/utilities.texi
src/data/settings.c
src/data/settings.h
src/data/variable.c
src/language/utilities/set.q
tests/language/dictionary/variable-display.at

index c568acec6c1967f61918cb1a64e30e65855f4069..b20fa24c851e85fb064e09a174dd7f25ef6e0456 100644 (file)
@@ -423,6 +423,7 @@ SET
         /MORE=@{ON,OFF@}
         /WIDTH=@{NARROW,WIDTH,@var{n_characters}@}
         /TNUMBERS=@{VALUES,LABELS,BOTH@}
+        /TVARS=@{NAMES,LABELS,BOTH@}
 
 (logging)
         /JOURNAL=@{ON,OFF@} ['@var{file_name}']
@@ -719,7 +720,16 @@ If @subcmd{TNUMBERS} is set to @subcmd{LABELS}, then values are displayed using
 (@xref{VALUE LABELS}.)
 If the a value has no label, then it will be displayed using its literal value.
 If @subcmd{TNUMBERS} is set to @subcmd{BOTH}, then values will be displayed with both their label
-(if any) and their literal value in parenthesis.
+(if any) and their literal value in parentheses.
+@itemx TVARS
+The @subcmd{TVARS} option sets the way in which variables are displayed in output tables.
+The valid settings are @subcmd{NAMES}, @subcmd{LABELS} and @subcmd{BOTH}.
+If @subcmd{TVARS} is set to @subcmd{NAMES}, then all variables are displayed using their names.
+If @subcmd{TVARS} is set to @subcmd{LABELS}, then variables are displayed using their label if one
+has been set.  If no label has been set, then the name will be used.
+(@xref{VARIABLE LABELS}.)
+If @subcmd{TVARS} is set to @subcmd{BOTH}, then variables will be displayed with both their label
+(if any) and their name in parentheses.
 @end table
 
 @cindex headers
index 95fda576dae5ef61bb24c4c43f52a210b55b083e..47b3f3d5ce6081f58f53afe03a2f1bd1fd381904 100644 (file)
@@ -713,3 +713,10 @@ settings_get_var_style (void)
 {
   return the_settings.var_output_style;
 }
+
+
+void
+settings_set_var_style (enum settings_var_style s)
+{
+  the_settings.var_output_style = s;
+}
index 559f64ebb6d7d3b8d19971b9cceda607c3d3dc54..409b7fe9ebffb690340dc8ebfbc3f0aca2fb442e 100644 (file)
@@ -121,7 +121,7 @@ enum settings_value_style settings_get_value_style (void);
 enum settings_var_style settings_get_var_style (void);
 
 void settings_set_value_style (enum settings_value_style s);
-void settings_set_var_style (enum settings_value_style s);
+void settings_set_var_style (enum settings_var_style s);
 
 
 enum behavior_mode {
index 2ceeecd2717c86212378bc783b0fea293d80d6bc..cc606cc9e77131911727c1e2df85ee8b217189bc 100644 (file)
@@ -54,6 +54,7 @@ struct variable
     struct fmt_spec write;     /* Default format for WRITE. */
     struct val_labs *val_labs;  /* Value labels. */
     char *label;               /* Variable label. */
+    struct string name_and_label; /* The name and label in the same string */
 
     /* GUI information. */
     enum measure measure;       /* Nominal, ordinal, or continuous. */
@@ -91,9 +92,7 @@ var_create (const char *name, int width)
 
   assert (width >= 0 && width <= MAX_STRING);
 
-  v = xmalloc (sizeof *v);
-  v->vardict = NULL;
-  v->name = NULL;
+  v = xzalloc (sizeof *v);
   var_set_name (v, name);
   v->width = width;
   mv_init (&v->miss, width);
@@ -103,13 +102,8 @@ var_create (const char *name, int width)
   v->measure = var_default_measure (type);
   v->display_width = var_default_display_width (width);
   v->print = v->write = var_default_formats (width);
-  v->val_labs = NULL;
-  v->label = NULL;
-  v->short_names = NULL;
-  v->short_name_cnt = 0;
-  v->aux = NULL;
-  v->aux_dtor = NULL;
   attrset_init (&v->attributes);
+  ds_init_empty (&v->name_and_label);
 
   return v;
 }
@@ -160,6 +154,7 @@ var_destroy (struct variable *v)
       var_clear_label (v);
       attrset_destroy (var_get_attributes (v));
       free (v->name);
+      ds_destroy (&v->name_and_label);
       free (v);
     }
 }
@@ -173,6 +168,8 @@ var_get_name (const struct variable *v)
   return v->name;
 }
 
+
+
 /* Sets V's name to NAME, a UTF-8 encoded string.
    Do not use this function for a variable in a dictionary.  Use
    dict_rename_var instead. */
@@ -184,6 +181,8 @@ var_set_name (struct variable *v, const char *name)
 
   free (v->name);
   v->name = xstrdup (name);
+  ds_destroy (&v->name_and_label);
+  ds_init_empty (&v->name_and_label);
   dict_var_changed (v);
 }
 
@@ -582,14 +581,51 @@ var_default_formats (int width)
           ? fmt_for_output (FMT_F, 8, 2)
           : fmt_for_output (FMT_A, width, 0));
 }
+
+
 \f
+
+/* Update the combined name and label string if necessary */
+static void
+update_vl_string (const struct variable *v)
+{
+  /* Cast away const! */
+  struct string *str = (struct string *) &v->name_and_label;
+
+  if (ds_is_empty (str))
+    {
+      if (v->label)
+        ds_put_format (str, _("%s (%s)"), v->label, v->name);
+      else
+        ds_put_cstr (str, v->name);
+    }
+}
+
+
 /* Return a string representing this variable, in the form most
    appropriate from a human factors perspective, that is, its
    variable label if it has one, otherwise its name. */
 const char *
 var_to_string (const struct variable *v)
 {
-  return v->label != NULL ? v->label : v->name;
+  enum settings_var_style style = settings_get_var_style ();
+
+  switch (style)
+  {
+    case SETTINGS_VAR_STYLE_NAMES:
+      return v->name;
+      break;
+    case SETTINGS_VAR_STYLE_LABELS:
+      return v->label != NULL ? v->label : v->name;
+      break;
+    case SETTINGS_VAR_STYLE_BOTH:
+      update_vl_string (v);
+      return ds_cstr (&v->name_and_label);
+      break;
+    default:
+      NOT_REACHED ();
+      break;
+  };
 }
 
 /* Returns V's variable label, or a null pointer if it has none. */
@@ -641,6 +677,9 @@ var_set_label (struct variable *v, const char *label, bool issue_warning)
         v->label = ss_xstrdup (s);
     }
 
+  ds_destroy (&v->name_and_label);
+  ds_init_empty (&v->name_and_label);
+
   dict_var_changed (v);
 
   return truncated;
index dcf7a327be79e2681bbfbe841affb0a02b370592..243de30063c8b12332009d185ed02274c0a5bb06 100644 (file)
@@ -108,6 +108,7 @@ int tgetnum (const char *);
      scripttab=string;
      seed=custom;
      tnumbers=custom;
+     tvars=custom;
      tb1=string;
      tbfonts=string;
      undefined=undef:warn/nowarn;
@@ -357,6 +358,35 @@ stc_custom_tnumbers (struct lexer *lexer,
 }
 
 
+static int
+stc_custom_tvars (struct lexer *lexer,
+                  struct dataset *ds UNUSED,
+                  struct cmd_set *cmd UNUSED, void *aux UNUSED)
+{
+  lex_match (lexer, T_EQUALS);
+
+  if (lex_match_id (lexer, "NAMES"))
+    {
+      settings_set_var_style (SETTINGS_VAR_STYLE_NAMES);
+    }
+  else if (lex_match_id (lexer, "LABELS"))
+    {
+      settings_set_var_style (SETTINGS_VAR_STYLE_LABELS);
+    }
+  else if (lex_match_id (lexer, "BOTH"))
+    {
+      settings_set_var_style (SETTINGS_VAR_STYLE_BOTH);
+    }
+  else
+    {
+      lex_error_expecting (lexer, "NAMES", "LABELS", "BOTH", NULL_SENTINEL);
+      return 0;
+    }
+
+  return 1;
+}
+
+
 /* Parses the EPOCH subcommand, which controls the epoch used for
    parsing 2-digit years. */
 static int
index 6f527a72bbe0e3f21d6625a9022bf0f868a219e1..f4d76eb94b4851675057868ffddf6bb1b2682768 100644 (file)
@@ -25,3 +25,77 @@ z,Format: F8.2,,3
 ,Display Width: 14,,
 ])
 AT_CLEANUP
+
+
+AT_BANNER([VARIABLE LABELS])
+
+AT_SETUP([variable labels])
+
+dnl The following test is to make sure the TVARS command works and that
+dnl variables are displayed accordingly.
+AT_DATA([var-labels.sps], [dnl
+DATA LIST LIST NOTABLE /x * y *.
+BEGIN DATA.
+1 100
+2 200
+3 300
+4 400
+END DATA.
+
+* While no labels have been set, the TVARS is irrelevant.
+SET TVARS=NAMES.
+DESCRIPTIVES ALL.
+
+SET TVARS=LABELS.
+DESCRIPTIVES ALL.
+
+SET TVARS=BOTH.
+DESCRIPTIVES ALL.
+
+VARIABLE LABEL x 'foo' y 'bar'.
+
+* Now, the TVARS setting should have effect
+
+SET TVARS=NAMES.
+DESCRIPTIVES ALL.
+
+SET TVARS=LABELS.
+DESCRIPTIVES ALL.
+
+SET TVARS=BOTH.
+DESCRIPTIVES ALL.
+])
+
+AT_CHECK([pspp -O format=csv var-labels.sps], [0],[dnl
+Table: Valid cases = 4; cases with missing value(s) = 0.
+Variable,N,Mean,Std Dev,Minimum,Maximum
+x,4,2.50,1.29,1.00,4.00
+y,4,250.00,129.10,100.00,400.00
+
+Table: Valid cases = 4; cases with missing value(s) = 0.
+Variable,N,Mean,Std Dev,Minimum,Maximum
+x,4,2.50,1.29,1.00,4.00
+y,4,250.00,129.10,100.00,400.00
+
+Table: Valid cases = 4; cases with missing value(s) = 0.
+Variable,N,Mean,Std Dev,Minimum,Maximum
+x,4,2.50,1.29,1.00,4.00
+y,4,250.00,129.10,100.00,400.00
+
+Table: Valid cases = 4; cases with missing value(s) = 0.
+Variable,N,Mean,Std Dev,Minimum,Maximum
+x,4,2.50,1.29,1.00,4.00
+y,4,250.00,129.10,100.00,400.00
+
+Table: Valid cases = 4; cases with missing value(s) = 0.
+Variable,N,Mean,Std Dev,Minimum,Maximum
+foo,4,2.50,1.29,1.00,4.00
+bar,4,250.00,129.10,100.00,400.00
+
+Table: Valid cases = 4; cases with missing value(s) = 0.
+Variable,N,Mean,Std Dev,Minimum,Maximum
+foo (x),4,2.50,1.29,1.00,4.00
+bar (y),4,250.00,129.10,100.00,400.00
+])
+
+AT_CLEANUP