Example #1
0
/* Callback which occurs when the OK button is clicked */
static void
missing_val_dialog_accept (GtkWidget *w, gpointer data)
{
  struct missing_val_dialog *dialog = data;

  if ( gtk_toggle_button_get_active (dialog->button_discrete))
    {
      gint nvals = 0;
      gint badvals = 0;
      gint i;
      mv_clear(&dialog->mvl);
      for(i = 0 ; i < 3 ; ++i )
	{
	  gchar *text =
	    g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->mv[i])));

	  union value v;
	  if ( !text || strlen (g_strstrip (text)) == 0 )
	    {
	      g_free (text);
	      continue;
	    }

	  if ( text_to_value (text, dialog->pv, &v))
	    {
	      nvals++;
	      mv_add_value (&dialog->mvl, &v);
	    }
	  else
	      badvals++;
	  g_free (text);
	  value_destroy (&v, var_get_width (dialog->pv));
	}
      if ( nvals == 0 || badvals > 0 )
	{
	  err_dialog (_("Incorrect value for variable type"),
		     GTK_WINDOW (dialog->window));
	  return ;
	}
    }

  if (gtk_toggle_button_get_active (dialog->button_range))
    {
      gchar *discrete_text ;

      union value low_val ;
      union value high_val;
      const gchar *low_text = gtk_entry_get_text (GTK_ENTRY (dialog->low));
      const gchar *high_text = gtk_entry_get_text (GTK_ENTRY (dialog->high));

      if ( text_to_value (low_text, dialog->pv, &low_val)
	   &&
	   text_to_value (high_text, dialog->pv, &high_val))
	{
	  if ( low_val.f > high_val.f )
	    {
	      err_dialog (_("Incorrect range specification"),
			  GTK_WINDOW (dialog->window));
	      value_destroy (&low_val, var_get_width (dialog->pv));
	      value_destroy (&high_val, var_get_width (dialog->pv));
	      return ;
	    }
	}
      else
	{
	  err_dialog (_("Incorrect range specification"),
		      GTK_WINDOW (dialog->window));
	  value_destroy (&low_val, var_get_width (dialog->pv));
	  value_destroy (&high_val, var_get_width (dialog->pv));
	  return;
	}

      discrete_text =
	g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->discrete)));

      mv_clear (&dialog->mvl);
      mv_add_range (&dialog->mvl, low_val.f, high_val.f);

      value_destroy (&low_val, var_get_width (dialog->pv));
      value_destroy (&high_val, var_get_width (dialog->pv));

      if ( discrete_text && strlen (g_strstrip (discrete_text)) > 0 )
	{
	  union value discrete_val;
	  if ( !text_to_value (discrete_text, 
			       dialog->pv,
			       &discrete_val))
	    {
	      err_dialog (_("Incorrect value for variable type"),
			 GTK_WINDOW (dialog->window) );
	      g_free (discrete_text);
	      value_destroy (&discrete_val, var_get_width (dialog->pv));
	      return;
	    }
	  mv_add_value (&dialog->mvl, &discrete_val);
	  value_destroy (&discrete_val, var_get_width (dialog->pv));
	}
      g_free (discrete_text);
    }


  if (gtk_toggle_button_get_active (dialog->button_none))
    mv_clear (&dialog->mvl);

  var_set_missing_values (dialog->pv, &dialog->mvl);

  gtk_widget_hide (dialog->window);
}
Example #2
0
int
cmd_missing_values (struct lexer *lexer, struct dataset *ds)
{
  struct dictionary *dict = dataset_dict (ds);
  struct variable **v = NULL;
  size_t nv;

  bool ok = true;

  while (lex_token (lexer) != T_ENDCMD)
    {
      size_t i;

      if (!parse_variables (lexer, dict, &v, &nv, PV_NONE))
        goto error;

      if (!lex_force_match (lexer, T_LPAREN))
        goto error;

      for (i = 0; i < nv; i++)
        var_clear_missing_values (v[i]);

      if (!lex_match (lexer, T_RPAREN))
        {
          struct missing_values mv;

          for (i = 0; i < nv; i++)
            if (var_get_type (v[i]) != var_get_type (v[0]))
              {
                const struct variable *n = var_is_numeric (v[0]) ? v[0] : v[i];
                const struct variable *s = var_is_numeric (v[0]) ? v[i] : v[0];
                msg (SE, _("Cannot mix numeric variables (e.g. %s) and "
                           "string variables (e.g. %s) within a single list."),
                     var_get_name (n), var_get_name (s));
                goto error;
              }

          if (var_is_numeric (v[0]))
            {
              mv_init (&mv, 0);
              while (!lex_match (lexer, T_RPAREN))
                {
                  enum fmt_type type = var_get_print_format (v[0])->type;
                  double x, y;
                  bool ok;

                  if (!parse_num_range (lexer, &x, &y, &type))
                    goto error;

                  ok = (x == y
                        ? mv_add_num (&mv, x)
                        : mv_add_range (&mv, x, y));
                  if (!ok)
                    ok = false;

                  lex_match (lexer, T_COMMA);
                }
            }
          else
            {
              mv_init (&mv, MV_MAX_STRING);
              while (!lex_match (lexer, T_RPAREN))
                {
                  uint8_t value[MV_MAX_STRING];
                  char *dict_mv;
                  size_t length;

                  if (!lex_force_string (lexer))
                    {
                      ok = false;
                      break;
                    }

                  dict_mv = recode_string (dict_get_encoding (dict), "UTF-8",
                                           lex_tokcstr (lexer),
                                           ss_length (lex_tokss (lexer)));
                  length = strlen (dict_mv);
                  if (length > MV_MAX_STRING)
                    {
                      /* XXX truncate graphemes not bytes */
                      msg (SE, _("Truncating missing value to maximum "
                                 "acceptable length (%d bytes)."),
                           MV_MAX_STRING);
                      length = MV_MAX_STRING;
                    }
                  memset (value, ' ', MV_MAX_STRING);
                  memcpy (value, dict_mv, length);
                  free (dict_mv);

                  if (!mv_add_str (&mv, value))
                    ok = false;

                  lex_get (lexer);
                  lex_match (lexer, T_COMMA);
                }
            }

          for (i = 0; i < nv; i++)
            {
              if (mv_is_resizable (&mv, var_get_width (v[i])))
                var_set_missing_values (v[i], &mv);
              else
                {
                  msg (SE, _("Missing values provided are too long to assign "
                             "to variable of width %d."),
                       var_get_width (v[i]));
                  ok = false;
                }
            }

          mv_destroy (&mv);
        }

      lex_match (lexer, T_SLASH);
      free (v);
      v = NULL;
    }

  free (v);
  return ok ? CMD_SUCCESS : CMD_FAILURE;

error:
  free (v);
  return CMD_FAILURE;
}
Example #3
0
/* Merge the dictionary for file F into master dictionary M. */
static bool
merge_dictionary (struct dictionary *const m, struct comb_file *f)
{
  struct dictionary *d = f->dict;
  const struct string_array *d_docs, *m_docs;
  int i;

  if (dict_get_label (m) == NULL)
    dict_set_label (m, dict_get_label (d));

  d_docs = dict_get_documents (d);
  m_docs = dict_get_documents (m);


  /* FIXME: If the input files have different encodings, then
     the result is undefined.
     The correct thing to do would be to convert to an encoding
     which can cope with all the input files (eg UTF-8).
   */
  if ( 0 != strcmp (dict_get_encoding (f->dict), dict_get_encoding (m)))
    msg (MW, _("Combining files with incompatible encodings. String data may "
               "not be represented correctly."));

  if (d_docs != NULL)
    {
      if (m_docs == NULL)
        dict_set_documents (m, d_docs);
      else
        {
          struct string_array new_docs;
          size_t i;

          new_docs.n = m_docs->n + d_docs->n;
          new_docs.strings = xmalloc (new_docs.n * sizeof *new_docs.strings);
          for (i = 0; i < m_docs->n; i++)
            new_docs.strings[i] = m_docs->strings[i];
          for (i = 0; i < d_docs->n; i++)
            new_docs.strings[m_docs->n + i] = d_docs->strings[i];

          dict_set_documents (m, &new_docs);

          free (new_docs.strings);
        }
    }

  for (i = 0; i < dict_get_var_cnt (d); i++)
    {
      struct variable *dv = dict_get_var (d, i);
      struct variable *mv = dict_lookup_var (m, var_get_name (dv));

      if (dict_class_from_id (var_get_name (dv)) == DC_SCRATCH)
        continue;

      if (mv != NULL)
        {
          if (var_get_width (mv) != var_get_width (dv))
            {
              const char *var_name = var_get_name (dv);
              struct string s = DS_EMPTY_INITIALIZER;
              const char *file_name;

              file_name = f->handle ? fh_get_name (f->handle) : "*";
              ds_put_format (&s,
                             _("Variable %s in file %s has different "
                               "type or width from the same variable in "
                               "earlier file."),
                             var_name, file_name);
              ds_put_cstr (&s, "  ");
              if (var_is_numeric (dv))
                ds_put_format (&s, _("In file %s, %s is numeric."),
                               file_name, var_name);
              else
                ds_put_format (&s, _("In file %s, %s is a string variable "
                                     "with width %d."),
                               file_name, var_name, var_get_width (dv));
              ds_put_cstr (&s, "  ");
              if (var_is_numeric (mv))
                ds_put_format (&s, _("In an earlier file, %s was numeric."),
                               var_name);
              else
                ds_put_format (&s, _("In an earlier file, %s was a string "
                                     "variable with width %d."),
                               var_name, var_get_width (mv));
              msg (SE, "%s", ds_cstr (&s));
              ds_destroy (&s);
              return false;
            }

          if (var_has_value_labels (dv) && !var_has_value_labels (mv))
            var_set_value_labels (mv, var_get_value_labels (dv));
          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));
        }
      else
        mv = dict_clone_var_assert (m, dv);
    }

  return true;
}