format: Make format settings structure smaller and cheaper.
[pspp] / src / data / settings.c
index 47b3f3d5ce6081f58f53afe03a2f1bd1fd381904..37b609dcfb0031aaeb48f9f457c7a13d4d51c3ed 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 2011, 2015 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
 
    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
@@ -29,7 +29,6 @@
 #include "libpspp/integer-format.h"
 #include "libpspp/message.h"
 
 #include "libpspp/integer-format.h"
 #include "libpspp/message.h"
 
-#include "gl/error.h"
 #include "gl/minmax.h"
 #include "gl/xalloc.h"
 
 #include "gl/minmax.h"
 #include "gl/xalloc.h"
 
@@ -67,17 +66,18 @@ struct settings
   size_t workspace;
   struct fmt_spec default_format;
   bool testing_mode;
   size_t workspace;
   struct fmt_spec default_format;
   bool testing_mode;
+  int fuzzbits;
 
   int cmd_algorithm;
   int global_algorithm;
   int syntax;
 
 
   int cmd_algorithm;
   int global_algorithm;
   int syntax;
 
-  struct fmt_settings *styles;
+  struct fmt_settings styles;
 
   enum settings_output_devices output_routing[SETTINGS_N_OUTPUT_TYPES];
 
 
   enum settings_output_devices output_routing[SETTINGS_N_OUTPUT_TYPES];
 
-  enum settings_var_style var_output_style;
-  enum settings_value_style value_output_style;
+  enum settings_value_show show_values;
+  enum settings_value_show show_variables;
 };
 
 static struct settings the_settings = {
 };
 
 static struct settings the_settings = {
@@ -109,10 +109,11 @@ static struct settings the_settings = {
   64L * 1024 * 1024,            /* workspace */
   {FMT_F, 8, 2},                /* default_format */
   false,                        /* testing_mode */
   64L * 1024 * 1024,            /* workspace */
   {FMT_F, 8, 2},                /* default_format */
   false,                        /* testing_mode */
+  6,                            /* fuzzbits */
   ENHANCED,                     /* cmd_algorithm */
   ENHANCED,                     /* global_algorithm */
   ENHANCED,                     /* syntax */
   ENHANCED,                     /* cmd_algorithm */
   ENHANCED,                     /* global_algorithm */
   ENHANCED,                     /* syntax */
-  NULL,                         /* styles */
+  FMT_SETTINGS_INIT,            /* styles */
 
   /* output_routing */
   {SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL,
 
   /* output_routing */
   {SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL,
@@ -120,8 +121,8 @@ static struct settings the_settings = {
    0,
    SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL},
 
    0,
    SETTINGS_DEVICE_LISTING | SETTINGS_DEVICE_TERMINAL},
 
-  SETTINGS_VAR_STYLE_LABELS,
-  SETTINGS_VAL_STYLE_LABELS
+  SETTINGS_VALUE_SHOW_LABEL,
+  SETTINGS_VALUE_SHOW_LABEL
 };
 
 /* Initializes the settings module. */
 };
 
 /* Initializes the settings module. */
@@ -129,8 +130,6 @@ void
 settings_init (void)
 {
   settings_set_epoch (-1);
 settings_init (void)
 {
   settings_set_epoch (-1);
-  the_settings.styles = fmt_settings_create ();
-
   settings_set_decimal_char (get_system_decimal ());
 }
 
   settings_set_decimal_char (get_system_decimal ());
 }
 
@@ -145,7 +144,7 @@ static void
 settings_copy (struct settings *dst, const struct settings *src)
 {
   *dst = *src;
 settings_copy (struct settings *dst, const struct settings *src)
 {
   *dst = *src;
-  dst->styles = fmt_settings_clone (src->styles);
+  fmt_settings_copy (&dst->styles, &src->styles);
 }
 
 /* Returns a copy of the current settings. */
 }
 
 /* Returns a copy of the current settings. */
@@ -172,7 +171,7 @@ settings_destroy (struct settings *s)
 {
   if (s != NULL)
     {
 {
   if (s != NULL)
     {
-      fmt_settings_destroy (s->styles);
+      fmt_settings_uninit (&s->styles);
       if (s != &the_settings)
         free (s);
     }
       if (s != &the_settings)
         free (s);
     }
@@ -189,7 +188,7 @@ settings_get_input_float_format (void)
 /* Sets the floating-point format used for RB and RBHEX input to
    FORMAT. */
 void
 /* Sets the floating-point format used for RB and RBHEX input to
    FORMAT. */
 void
-settings_set_input_float_format ( enum float_format format)
+settings_set_input_float_format (enum float_format format)
 {
   the_settings.input_float_format = format;
 }
 {
   the_settings.input_float_format = format;
 }
@@ -204,7 +203,7 @@ settings_get_input_integer_format (void)
 /* Sets the integer format used for IB and PIB input to
    FORMAT. */
 void
 /* Sets the integer format used for IB and PIB input to
    FORMAT. */
 void
-settings_set_input_integer_format ( enum integer_format format)
+settings_set_input_integer_format (enum integer_format format)
 {
   the_settings.input_integer_format = format;
 }
 {
   the_settings.input_integer_format = format;
 }
@@ -233,7 +232,7 @@ settings_get_output_float_format (void)
 
 /* Sets the output float format to FLOAT_FORMAT. */
 void
 
 /* Sets the output float format to FLOAT_FORMAT. */
 void
-settings_set_output_float_format ( enum float_format float_format)
+settings_set_output_float_format (enum float_format float_format)
 {
   the_settings.output_float_format = float_format;
 }
 {
   the_settings.output_float_format = float_format;
 }
@@ -247,7 +246,7 @@ settings_get_viewlength (void)
 
 /* Sets the view length. */
 void
 
 /* Sets the view length. */
 void
-settings_set_viewlength ( int viewlength_)
+settings_set_viewlength (int viewlength_)
 {
   the_settings.viewlength = viewlength_;
 }
 {
   the_settings.viewlength = viewlength_;
 }
@@ -261,7 +260,7 @@ settings_get_viewwidth(void)
 
 /* Sets the screen width. */
 void
 
 /* Sets the screen width. */
 void
-settings_set_viewwidth ( int viewwidth_)
+settings_set_viewwidth (int viewwidth_)
 {
   the_settings.viewwidth = viewwidth_;
 }
 {
   the_settings.viewwidth = viewwidth_;
 }
@@ -289,7 +288,7 @@ settings_get_include (void)
 
 /* Set include file echo. */
 void
 
 /* Set include file echo. */
 void
-settings_set_include ( bool include)
+settings_set_include (bool include)
 {
   the_settings.include = include;
 }
 {
   the_settings.include = include;
 }
@@ -305,7 +304,7 @@ settings_get_epoch (void)
 
 /* Sets the year that starts the epoch. */
 void
 
 /* Sets the year that starts the epoch. */
 void
-settings_set_epoch ( int epoch)
+settings_set_epoch (int epoch)
 {
   if (epoch < 0)
     {
 {
   if (epoch < 0)
     {
@@ -327,7 +326,7 @@ settings_get_scompression (void)
 
 /* Set system file default compression. */
 void
 
 /* Set system file default compression. */
 void
-settings_set_scompression ( bool scompress)
+settings_set_scompression (bool scompress)
 {
   the_settings.scompress = scompress;
 }
 {
   the_settings.scompress = scompress;
 }
@@ -341,7 +340,7 @@ settings_get_undefined (void)
 
 /* Set whether to warn on undefined values. */
 void
 
 /* Set whether to warn on undefined values. */
 void
-settings_set_undefined ( bool undefined)
+settings_set_undefined (bool undefined)
 {
   the_settings.undefined = undefined;
 }
 {
   the_settings.undefined = undefined;
 }
@@ -356,7 +355,7 @@ settings_get_blanks (void)
 /* Set the value that blank numeric fields are set to when read
    in. */
 void
 /* Set the value that blank numeric fields are set to when read
    in. */
 void
-settings_set_blanks ( double blanks)
+settings_set_blanks (double blanks)
 {
   the_settings.blanks = blanks;
 }
 {
   the_settings.blanks = blanks;
 }
@@ -373,9 +372,9 @@ settings_get_max_messages (enum msg_severity severity)
 
 /* Sets the maximum number of messages to show of the given SEVERITY before
    aborting to MAX.  (The value for MSG_S_WARNING is interpreted as maximum
 
 /* Sets the maximum number of messages to show of the given SEVERITY before
    aborting to MAX.  (The value for MSG_S_WARNING is interpreted as maximum
-   number of warnings and errors combined.)  In addition, in the case of 
+   number of warnings and errors combined.)  In addition, in the case of
    warnings the special value of zero indicates that no warnings are to be
    warnings the special value of zero indicates that no warnings are to be
-   issued. 
+   issued.
 */
 void
 settings_set_max_messages (enum msg_severity severity, int max)
 */
 void
 settings_set_max_messages (enum msg_severity severity, int max)
@@ -384,13 +383,13 @@ settings_set_max_messages (enum msg_severity severity, int max)
 
   if (severity == MSG_S_WARNING)
     {
 
   if (severity == MSG_S_WARNING)
     {
-      if ( max == 0)
+      if (max == 0)
        {
          msg (MW,
               _("MXWARNS set to zero.  No further warnings will be given even when potentially problematic situations are encountered."));
          msg_ui_disable_warnings (true);
        }
        {
          msg (MW,
               _("MXWARNS set to zero.  No further warnings will be given even when potentially problematic situations are encountered."));
          msg_ui_disable_warnings (true);
        }
-      else if ( the_settings.max_messages [MSG_S_WARNING] == 0)
+      else if (the_settings.max_messages [MSG_S_WARNING] == 0)
        {
          msg_ui_disable_warnings (false);
          the_settings.max_messages[MSG_S_WARNING] = max;
        {
          msg_ui_disable_warnings (false);
          the_settings.max_messages[MSG_S_WARNING] = max;
@@ -412,7 +411,7 @@ settings_get_mprint (void)
 /* Sets whether the commands generated by macro invocations are
    displayed. */
 void
 /* Sets whether the commands generated by macro invocations are
    displayed. */
 void
-settings_set_mprint ( bool mprint)
+settings_set_mprint (bool mprint)
 {
   the_settings.mprint = mprint;
 }
 {
   the_settings.mprint = mprint;
 }
@@ -426,7 +425,7 @@ settings_get_mxloops (void)
 
 /* Set implied limit of unbounded loop. */
 void
 
 /* Set implied limit of unbounded loop. */
 void
-settings_set_mxloops ( int mxloops)
+settings_set_mxloops (int mxloops)
 {
   the_settings.mxloops = mxloops;
 }
 {
   the_settings.mxloops = mxloops;
 }
@@ -452,7 +451,7 @@ settings_get_workspace_cases (const struct caseproto *proto)
    bytes. */
 
 void
    bytes. */
 
 void
-settings_set_workspace ( size_t workspace)
+settings_set_workspace (size_t workspace)
 {
   the_settings.workspace = workspace;
 }
 {
   the_settings.workspace = workspace;
 }
@@ -468,7 +467,7 @@ settings_get_format (void)
 /* Set default format for variables created by transformations
    and by DATA LIST {FREE,LIST}. */
 void
 /* Set default format for variables created by transformations
    and by DATA LIST {FREE,LIST}. */
 void
-settings_set_format ( const struct fmt_spec *default_format)
+settings_set_format (const struct fmt_spec *default_format)
 {
   the_settings.default_format = *default_format;
 }
 {
   the_settings.default_format = *default_format;
 }
@@ -483,11 +482,23 @@ settings_get_testing_mode (void)
 
 /* Set testing mode. */
 void
 
 /* Set testing mode. */
 void
-settings_set_testing_mode ( bool testing_mode)
+settings_set_testing_mode (bool testing_mode)
 {
   the_settings.testing_mode = testing_mode;
 }
 
 {
   the_settings.testing_mode = testing_mode;
 }
 
+int
+settings_get_fuzzbits (void)
+{
+  return the_settings.fuzzbits;
+}
+
+void
+settings_set_fuzzbits (int fuzzbits)
+{
+  the_settings.fuzzbits = fuzzbits;
+}
+
 /* Return the current algorithm setting */
 enum behavior_mode
 settings_get_algorithm (void)
 /* Return the current algorithm setting */
 enum behavior_mode
 settings_get_algorithm (void)
@@ -504,7 +515,7 @@ settings_set_algorithm (enum behavior_mode mode)
 
 /* Set the algorithm option for this command only */
 void
 
 /* Set the algorithm option for this command only */
 void
-settings_set_cmd_algorithm ( enum behavior_mode mode)
+settings_set_cmd_algorithm (enum behavior_mode mode)
 {
   the_settings.cmd_algorithm = mode;
 }
 {
   the_settings.cmd_algorithm = mode;
 }
@@ -525,82 +536,19 @@ settings_get_syntax (void)
 
 /* Set the syntax option */
 void
 
 /* Set the syntax option */
 void
-settings_set_syntax ( enum behavior_mode mode)
+settings_set_syntax (enum behavior_mode mode)
 {
   the_settings.syntax = mode;
 }
 
 \f
 {
   the_settings.syntax = mode;
 }
 
 \f
-
-/* Find the grouping characters in CC_STRING and sets *GROUPING and *DECIMAL
-   appropriately.  Returns true if successful, false otherwise. */
-static bool
-find_cc_separators (const char *cc_string, char *decimal, char *grouping)
-{
-  const char *sp;
-  int comma_cnt, dot_cnt;
-
-  /* Count commas and periods.  There must be exactly three of
-     one or the other, except that an apostrophe escapes a
-     following comma or period. */
-  comma_cnt = dot_cnt = 0;
-  for (sp = cc_string; *sp; sp++)
-    if (*sp == ',')
-      comma_cnt++;
-    else if (*sp == '.')
-      dot_cnt++;
-    else if (*sp == '\'' && (sp[1] == '.' || sp[1] == ',' || sp[1] == '\''))
-      sp++;
-
-  if ((comma_cnt == 3) == (dot_cnt == 3))
-    return false;
-
-  if (comma_cnt == 3)
-    {
-      *decimal = '.';
-      *grouping = ',';
-    }
-  else
-    {
-      *decimal = ',';
-      *grouping = '.';
-    }
-  return true;
-}
-
-/* Extracts a token from IN into a newly allocated string AFFIXP.  Tokens are
-   delimited by GROUPING.  Returns the first character following the token. */
-static const char *
-extract_cc_token (const char *in, int grouping, char **affixp)
-{
-  char *out;
-
-  out = *affixp = xmalloc (strlen (in) + 1);
-  for (; *in != '\0' && *in != grouping; in++)
-    {
-      if (*in == '\'' && in[1] == grouping)
-        in++;
-      *out++ = *in;
-    }
-  *out = '\0';
-
-  if (*in == grouping)
-    in++;
-  return in;
-}
-
 /* Sets custom currency specifier CC having name CC_NAME ('A' through
    'E') to correspond to the settings in CC_STRING. */
 bool
 settings_set_cc (const char *cc_string, enum fmt_type type)
 {
 /* Sets custom currency specifier CC having name CC_NAME ('A' through
    'E') to correspond to the settings in CC_STRING. */
 bool
 settings_set_cc (const char *cc_string, enum fmt_type type)
 {
-  char *neg_prefix, *prefix, *suffix, *neg_suffix;
-  char decimal, grouping;
-
-  assert (fmt_get_category (type) == FMT_CAT_CUSTOM);
-
-  /* Determine separators. */
-  if (!find_cc_separators (cc_string, &decimal, &grouping))
+  struct fmt_number_style *style = fmt_number_style_from_string (cc_string);
+  if (!style)
     {
       msg (SE, _("%s: Custom currency string `%s' does not contain "
                  "exactly three periods or commas (or it contains both)."),
     {
       msg (SE, _("%s: Custom currency string `%s' does not contain "
                  "exactly three periods or commas (or it contains both)."),
@@ -608,19 +556,7 @@ settings_set_cc (const char *cc_string, enum fmt_type type)
       return false;
     }
 
       return false;
     }
 
-  cc_string = extract_cc_token (cc_string, grouping, &neg_prefix);
-  cc_string = extract_cc_token (cc_string, grouping, &prefix);
-  cc_string = extract_cc_token (cc_string, grouping, &suffix);
-  cc_string = extract_cc_token (cc_string, grouping, &neg_suffix);
-
-  fmt_settings_set_style (the_settings.styles, type, decimal, grouping,
-                          neg_prefix, prefix, suffix, neg_suffix);
-
-  free (neg_suffix);
-  free (suffix);
-  free (prefix);
-  free (neg_prefix);
-
+  fmt_settings_set_cc (&the_settings.styles, type, style);
   return true;
 }
 
   return true;
 }
 
@@ -628,13 +564,13 @@ settings_set_cc (const char *cc_string, enum fmt_type type)
 int
 settings_get_decimal_char (enum fmt_type type)
 {
 int
 settings_get_decimal_char (enum fmt_type type)
 {
-  return fmt_settings_get_style (the_settings.styles, type)->decimal;
+  return fmt_settings_get_style (&the_settings.styles, type)->decimal;
 }
 
 void
 settings_set_decimal_char (char decimal)
 {
 }
 
 void
 settings_set_decimal_char (char decimal)
 {
-  fmt_settings_set_decimal (the_settings.styles, decimal);
+  the_settings.styles.decimal = decimal;
 }
 
 /* Returns the number formatting style associated with the given
 }
 
 /* Returns the number formatting style associated with the given
@@ -643,7 +579,7 @@ const struct fmt_number_style *
 settings_get_style (enum fmt_type type)
 {
   assert (is_fmt_type (type));
 settings_get_style (enum fmt_type type)
 {
   assert (is_fmt_type (type));
-  return fmt_settings_get_style (the_settings.styles, type);
+  return fmt_settings_get_style (&the_settings.styles, type);
 }
 
 /* Returns a string of the form "$#,###.##" according to FMT,
 }
 
 /* Returns a string of the form "$#,###.##" according to FMT,
@@ -658,10 +594,10 @@ settings_dollar_template (const struct fmt_spec *fmt)
 
   assert (fmt->type == FMT_DOLLAR);
 
 
   assert (fmt->type == FMT_DOLLAR);
 
-  fns = fmt_settings_get_style (the_settings.styles, fmt->type);
+  fns = fmt_settings_get_style (&the_settings.styles, fmt->type);
 
   ds_put_byte (&str, '$');
 
   ds_put_byte (&str, '$');
-  for (c = MAX (fmt->w - fmt->d - 1, 0); c > 0; )
+  for (c = MAX (fmt->w - fmt->d - 1, 0); c > 0;)
     {
       ds_put_byte (&str, '#');
       if (--c % 4 == 0 && c > 0)
     {
       ds_put_byte (&str, '#');
       if (--c % 4 == 0 && c > 0)
@@ -694,29 +630,27 @@ settings_get_output_routing (enum settings_output_type type)
   return the_settings.output_routing[type] | SETTINGS_DEVICE_UNFILTERED;
 }
 
   return the_settings.output_routing[type] | SETTINGS_DEVICE_UNFILTERED;
 }
 
-enum settings_value_style 
-settings_get_value_style (void)
+enum settings_value_show
+settings_get_show_values (void)
 {
 {
-  return the_settings.value_output_style;
+  return the_settings.show_values;
 }
 
 void
 }
 
 void
-settings_set_value_style (enum settings_value_style s)
+settings_set_show_values (enum settings_value_show s)
 {
 {
-  the_settings.value_output_style = s;
+  the_settings.show_values = s;
 }
 
 
 }
 
 
-
-enum settings_var_style
-settings_get_var_style (void)
+enum settings_value_show
+settings_get_show_variables (void)
 {
 {
-  return the_settings.var_output_style;
+  return the_settings.show_variables;
 }
 
 }
 
-
 void
 void
-settings_set_var_style (enum settings_var_style s)
+settings_set_show_variables (enum settings_value_show s)
 {
 {
-  the_settings.var_output_style = s;
+  the_settings.show_variables = s;
 }
 }